diff options
Diffstat (limited to 'drivers/staging')
241 files changed, 19065 insertions, 12428 deletions
diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c index 351f983ef914..57ed58065eba 100644 --- a/drivers/staging/axis-fifo/axis-fifo.c +++ b/drivers/staging/axis-fifo/axis-fifo.c @@ -33,6 +33,7 @@ #include <linux/uaccess.h> #include <linux/jiffies.h> #include <linux/miscdevice.h> +#include <linux/debugfs.h> /* ---------------------------- * driver parameters @@ -44,6 +45,8 @@ #define READ_BUF_SIZE 128U /* read buffer length in words */ #define WRITE_BUF_SIZE 128U /* write buffer length in words */ +#define AXIS_FIFO_DEBUG_REG_NAME_MAX_LEN 4 + /* ---------------------------- * IP register offsets * ---------------------------- @@ -137,180 +140,13 @@ struct axis_fifo { struct device *dt_device; /* device created from the device tree */ struct miscdevice miscdev; -}; - -/* ---------------------------- - * sysfs entries - * ---------------------------- - */ - -static ssize_t sysfs_write(struct device *dev, const char *buf, - size_t count, unsigned int addr_offset) -{ - struct axis_fifo *fifo = dev_get_drvdata(dev); - unsigned long tmp; - int rc; - - rc = kstrtoul(buf, 0, &tmp); - if (rc < 0) - return rc; - - iowrite32(tmp, fifo->base_addr + addr_offset); - - return count; -} - -static ssize_t sysfs_read(struct device *dev, char *buf, - unsigned int addr_offset) -{ - struct axis_fifo *fifo = dev_get_drvdata(dev); - unsigned int read_val; - - read_val = ioread32(fifo->base_addr + addr_offset); - return sysfs_emit(buf, "0x%x\n", read_val); -} - -static ssize_t isr_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_write(dev, buf, count, XLLF_ISR_OFFSET); -} - -static ssize_t isr_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_read(dev, buf, XLLF_ISR_OFFSET); -} - -static DEVICE_ATTR_RW(isr); - -static ssize_t ier_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_write(dev, buf, count, XLLF_IER_OFFSET); -} - -static ssize_t ier_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_read(dev, buf, XLLF_IER_OFFSET); -} - -static DEVICE_ATTR_RW(ier); - -static ssize_t tdfr_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_write(dev, buf, count, XLLF_TDFR_OFFSET); -} - -static DEVICE_ATTR_WO(tdfr); - -static ssize_t tdfv_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_read(dev, buf, XLLF_TDFV_OFFSET); -} - -static DEVICE_ATTR_RO(tdfv); - -static ssize_t tdfd_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_write(dev, buf, count, XLLF_TDFD_OFFSET); -} -static DEVICE_ATTR_WO(tdfd); - -static ssize_t tlr_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_write(dev, buf, count, XLLF_TLR_OFFSET); -} - -static DEVICE_ATTR_WO(tlr); - -static ssize_t rdfr_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_write(dev, buf, count, XLLF_RDFR_OFFSET); -} - -static DEVICE_ATTR_WO(rdfr); - -static ssize_t rdfo_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_read(dev, buf, XLLF_RDFO_OFFSET); -} - -static DEVICE_ATTR_RO(rdfo); - -static ssize_t rdfd_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_read(dev, buf, XLLF_RDFD_OFFSET); -} - -static DEVICE_ATTR_RO(rdfd); - -static ssize_t rlr_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_read(dev, buf, XLLF_RLR_OFFSET); -} - -static DEVICE_ATTR_RO(rlr); - -static ssize_t srr_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_write(dev, buf, count, XLLF_SRR_OFFSET); -} - -static DEVICE_ATTR_WO(srr); - -static ssize_t tdr_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_write(dev, buf, count, XLLF_TDR_OFFSET); -} - -static DEVICE_ATTR_WO(tdr); - -static ssize_t rdr_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_read(dev, buf, XLLF_RDR_OFFSET); -} - -static DEVICE_ATTR_RO(rdr); - -static struct attribute *axis_fifo_attrs[] = { - &dev_attr_isr.attr, - &dev_attr_ier.attr, - &dev_attr_tdfr.attr, - &dev_attr_tdfv.attr, - &dev_attr_tdfd.attr, - &dev_attr_tlr.attr, - &dev_attr_rdfr.attr, - &dev_attr_rdfo.attr, - &dev_attr_rdfd.attr, - &dev_attr_rlr.attr, - &dev_attr_srr.attr, - &dev_attr_tdr.attr, - &dev_attr_rdr.attr, - NULL, -}; - -static const struct attribute_group axis_fifo_attrs_group = { - .name = "ip_registers", - .attrs = axis_fifo_attrs, + struct dentry *debugfs_dir; }; -static const struct attribute_group *axis_fifo_attrs_groups[] = { - &axis_fifo_attrs_group, - NULL, +struct axis_fifo_debug_reg { + const char * const name; + unsigned int offset; }; /* ---------------------------- @@ -711,6 +547,37 @@ static const struct file_operations fops = { .write = axis_fifo_write }; +static int axis_fifo_debugfs_regs_show(struct seq_file *m, void *p) +{ + static const struct axis_fifo_debug_reg regs[] = { + {"isr", XLLF_ISR_OFFSET}, + {"ier", XLLF_IER_OFFSET}, + {"tdfv", XLLF_TDFV_OFFSET}, + {"rdfo", XLLF_RDFO_OFFSET}, + { /* Sentinel */ }, + }; + const struct axis_fifo_debug_reg *reg; + struct axis_fifo *fifo = m->private; + + for (reg = regs; reg->name; ++reg) { + u32 val = ioread32(fifo->base_addr + reg->offset); + + seq_printf(m, "%*s: 0x%08x\n", AXIS_FIFO_DEBUG_REG_NAME_MAX_LEN, + reg->name, val); + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(axis_fifo_debugfs_regs); + +static void axis_fifo_debugfs_init(struct axis_fifo *fifo) +{ + fifo->debugfs_dir = debugfs_create_dir(dev_name(fifo->dt_device), NULL); + + debugfs_create_file("regs", 0444, fifo->debugfs_dir, fifo, + &axis_fifo_debugfs_regs_fops); +} + /* read named property from the device tree */ static int get_dts_property(struct axis_fifo *fifo, char *name, unsigned int *var) @@ -877,12 +744,13 @@ static int axis_fifo_probe(struct platform_device *pdev) fifo->miscdev.fops = &fops; fifo->miscdev.minor = MISC_DYNAMIC_MINOR; fifo->miscdev.name = device_name; - fifo->miscdev.groups = axis_fifo_attrs_groups; fifo->miscdev.parent = dev; rc = misc_register(&fifo->miscdev); if (rc < 0) goto err_initial; + axis_fifo_debugfs_init(fifo); + return 0; err_initial: @@ -895,6 +763,7 @@ static void axis_fifo_remove(struct platform_device *pdev) struct device *dev = &pdev->dev; struct axis_fifo *fifo = dev_get_drvdata(dev); + debugfs_remove(fifo->debugfs_dir); misc_deregister(&fifo->miscdev); dev_set_drvdata(dev, NULL); } diff --git a/drivers/staging/fbtft/Kconfig b/drivers/staging/fbtft/Kconfig index dcf6a70455cc..c2655768209a 100644 --- a/drivers/staging/fbtft/Kconfig +++ b/drivers/staging/fbtft/Kconfig @@ -8,160 +8,136 @@ menuconfig FB_TFT select FB_BACKLIGHT select FB_SYSMEM_HELPERS_DEFERRED +if FB_TFT + config FB_TFT_AGM1264K_FL tristate "FB driver for the AGM1264K-FL LCD display" - depends on FB_TFT help Framebuffer support for the AGM1264K-FL LCD display (two Samsung KS0108 compatible chips) config FB_TFT_BD663474 tristate "FB driver for the BD663474 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for BD663474 config FB_TFT_HX8340BN tristate "FB driver for the HX8340BN LCD Controller" - depends on FB_TFT help Generic Framebuffer support for HX8340BN config FB_TFT_HX8347D tristate "FB driver for the HX8347D LCD Controller" - depends on FB_TFT help Generic Framebuffer support for HX8347D config FB_TFT_HX8353D tristate "FB driver for the HX8353D LCD Controller" - depends on FB_TFT help Generic Framebuffer support for HX8353D config FB_TFT_HX8357D tristate "FB driver for the HX8357D LCD Controller" - depends on FB_TFT help Generic Framebuffer support for HX8357D config FB_TFT_ILI9163 tristate "FB driver for the ILI9163 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for ILI9163 config FB_TFT_ILI9320 tristate "FB driver for the ILI9320 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for ILI9320 config FB_TFT_ILI9325 tristate "FB driver for the ILI9325 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for ILI9325 config FB_TFT_ILI9340 tristate "FB driver for the ILI9340 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for ILI9340 config FB_TFT_ILI9341 tristate "FB driver for the ILI9341 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for ILI9341 config FB_TFT_ILI9481 tristate "FB driver for the ILI9481 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for ILI9481 config FB_TFT_ILI9486 tristate "FB driver for the ILI9486 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for ILI9486 config FB_TFT_PCD8544 tristate "FB driver for the PCD8544 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for PCD8544 config FB_TFT_RA8875 tristate "FB driver for the RA8875 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for RA8875 config FB_TFT_S6D02A1 tristate "FB driver for the S6D02A1 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for S6D02A1 config FB_TFT_S6D1121 tristate "FB driver for the S6D1211 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for S6D1121 config FB_TFT_SEPS525 tristate "FB driver for the SEPS525 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for SEPS525 Say Y if you have such a display that utilizes this controller. config FB_TFT_SH1106 tristate "FB driver for the SH1106 OLED Controller" - depends on FB_TFT help Framebuffer support for SH1106 config FB_TFT_SSD1289 tristate "FB driver for the SSD1289 LCD Controller" - depends on FB_TFT help Framebuffer support for SSD1289 config FB_TFT_SSD1305 tristate "FB driver for the SSD1305 OLED Controller" - depends on FB_TFT help Framebuffer support for SSD1305 config FB_TFT_SSD1306 tristate "FB driver for the SSD1306 OLED Controller" - depends on FB_TFT help Framebuffer support for SSD1306 config FB_TFT_SSD1331 tristate "FB driver for the SSD1331 LCD Controller" - depends on FB_TFT help Framebuffer support for SSD1331 config FB_TFT_SSD1351 tristate "FB driver for the SSD1351 LCD Controller" - depends on FB_TFT help Framebuffer support for SSD1351 config FB_TFT_ST7735R tristate "FB driver for the ST7735R LCD Controller" - depends on FB_TFT help Generic Framebuffer support for ST7735R config FB_TFT_ST7789V tristate "FB driver for the ST7789V LCD Controller" - depends on FB_TFT help This enables generic framebuffer support for the Sitronix ST7789V display controller. The controller is intended for small color @@ -171,30 +147,27 @@ config FB_TFT_ST7789V config FB_TFT_TINYLCD tristate "FB driver for tinylcd.com display" - depends on FB_TFT help Custom Framebuffer support for tinylcd.com display config FB_TFT_TLS8204 tristate "FB driver for the TLS8204 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for TLS8204 config FB_TFT_UC1611 tristate "FB driver for the UC1611 LCD controller" - depends on FB_TFT help Generic Framebuffer support for UC1611 config FB_TFT_UC1701 tristate "FB driver for the UC1701 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for UC1701 config FB_TFT_UPD161704 tristate "FB driver for the uPD161704 LCD Controller" - depends on FB_TFT help Generic Framebuffer support for uPD161704 + +endif diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index da9c64152a60..9e7b84071174 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -568,18 +568,13 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, height = display->height; } - vmem_size = display->width * display->height * bpp / 8; - vmem = vzalloc(vmem_size); - if (!vmem) - goto alloc_fail; - fbdefio = devm_kzalloc(dev, sizeof(struct fb_deferred_io), GFP_KERNEL); if (!fbdefio) - goto alloc_fail; + return NULL; buf = devm_kzalloc(dev, 128, GFP_KERNEL); if (!buf) - goto alloc_fail; + return NULL; if (display->gamma_num && display->gamma_len) { gamma_curves = devm_kcalloc(dev, @@ -588,12 +583,17 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, sizeof(gamma_curves[0]), GFP_KERNEL); if (!gamma_curves) - goto alloc_fail; + return NULL; } info = framebuffer_alloc(sizeof(struct fbtft_par), dev); if (!info) - goto alloc_fail; + return NULL; + + vmem_size = display->width * display->height * bpp / 8; + vmem = vzalloc(vmem_size); + if (!vmem) + goto release_framebuf; info->screen_buffer = vmem; info->fbops = &fbtft_ops; @@ -612,7 +612,8 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, info->fix.line_length = width * bpp / 8; info->fix.accel = FB_ACCEL_NONE; info->fix.smem_len = vmem_size; - fb_deferred_io_init(info); + if (fb_deferred_io_init(info)) + goto release_screen_buffer; info->var.rotate = pdata->rotate; info->var.xres = width; @@ -652,7 +653,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, if (par->gamma.curves && gamma) { if (fbtft_gamma_parse_str(par, par->gamma.curves, gamma, strlen(gamma))) - goto release_framebuf; + goto cleanup_deferred; } /* Transmit buffer */ @@ -667,9 +668,9 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, #endif if (txbuflen > 0) { - txbuf = devm_kzalloc(par->info->device, txbuflen, GFP_KERNEL); + txbuf = kzalloc(txbuflen, GFP_KERNEL); if (!txbuf) - goto release_framebuf; + goto cleanup_deferred; par->txbuf.buf = txbuf; par->txbuf.len = txbuflen; } @@ -691,12 +692,12 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, return info; +cleanup_deferred: + fb_deferred_io_cleanup(info); +release_screen_buffer: + vfree(info->screen_buffer); release_framebuf: framebuffer_release(info); - -alloc_fail: - vfree(vmem); - return NULL; } EXPORT_SYMBOL(fbtft_framebuffer_alloc); @@ -709,6 +710,9 @@ EXPORT_SYMBOL(fbtft_framebuffer_alloc); */ void fbtft_framebuffer_release(struct fb_info *info) { + struct fbtft_par *par = info->par; + + kfree(par->txbuf.buf); fb_deferred_io_cleanup(info); vfree(info->screen_buffer); framebuffer_release(info); diff --git a/drivers/staging/gpib/TODO b/drivers/staging/gpib/TODO index bf2c39742548..ab41a7f9ca5b 100644 --- a/drivers/staging/gpib/TODO +++ b/drivers/staging/gpib/TODO @@ -1,6 +1,9 @@ TODO: - checkpatch.pl fixes -- fix device drivers that are broken ("depends on BROKEN" in Kconfig) + These checks should be ignored: + CHECK:ALLOC_SIZEOF_STRUCT: Prefer kmalloc(sizeof(*board->private_data)...) over kmalloc(sizeof(struct xxx_priv)...) + ./gpio/gpib_bitbang.c:50: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parenthese + This warning will be addressed later: WARNING:UNDOCUMENTED_DT_STRING: DT compatible string - tidy-up comments: - there are some "//comments" and "// comments" scattered around - sometimes they are misaligned diff --git a/drivers/staging/gpib/agilent_82350b/agilent_82350b.c b/drivers/staging/gpib/agilent_82350b/agilent_82350b.c index 445b9380ff98..94bbb3b6576d 100644 --- a/drivers/staging/gpib/agilent_82350b/agilent_82350b.c +++ b/drivers/staging/gpib/agilent_82350b/agilent_82350b.c @@ -27,10 +27,10 @@ MODULE_DESCRIPTION("GPIB driver for Agilent 82350b"); static int read_transfer_counter(struct agilent_82350b_priv *a_priv); static unsigned short read_and_clear_event_status(struct gpib_board *board); static void set_transfer_counter(struct agilent_82350b_priv *a_priv, int count); -static int agilent_82350b_write(struct gpib_board *board, uint8_t *buffer, +static int agilent_82350b_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written); -static int agilent_82350b_accel_read(struct gpib_board *board, uint8_t *buffer, +static int agilent_82350b_accel_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { @@ -39,7 +39,7 @@ static int agilent_82350b_accel_read(struct gpib_board *board, uint8_t *buffer, int retval = 0; unsigned short event_status; int i, num_fifo_bytes; - //hardware doesn't support checking for end-of-string character when using fifo + /* hardware doesn't support checking for end-of-string character when using fifo */ if (tms_priv->eos_flags & REOS) return tms9914_read(board, tms_priv, buffer, length, end, bytes_read); @@ -50,9 +50,9 @@ static int agilent_82350b_accel_read(struct gpib_board *board, uint8_t *buffer, *bytes_read = 0; if (length == 0) return 0; - //disable fifo for the moment + /* disable fifo for the moment */ writeb(DIRECTION_GPIB_TO_HOST, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG); - // handle corner case of board not in holdoff and one byte might slip in early + /* handle corner case of board not in holdoff and one byte might slip in early */ if (tms_priv->holdoff_active == 0 && length > 1) { size_t num_bytes; @@ -67,7 +67,8 @@ static int agilent_82350b_accel_read(struct gpib_board *board, uint8_t *buffer, tms9914_release_holdoff(tms_priv); i = 0; num_fifo_bytes = length - 1; - write_byte(tms_priv, tms_priv->imr0_bits & ~HR_BIIE, IMR0); // disable BI interrupts + /* disable BI interrupts */ + write_byte(tms_priv, tms_priv->imr0_bits & ~HR_BIIE, IMR0); while (i < num_fifo_bytes && *end == 0) { int block_size; int j; @@ -111,17 +112,18 @@ static int agilent_82350b_accel_read(struct gpib_board *board, uint8_t *buffer, break; } } - write_byte(tms_priv, tms_priv->imr0_bits, IMR0); // re-enable BI interrupts + /* re-enable BI interrupts */ + write_byte(tms_priv, tms_priv->imr0_bits, IMR0); *bytes_read += i; buffer += i; length -= i; writeb(DIRECTION_GPIB_TO_HOST, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG); if (retval < 0) return retval; - // read last bytes if we havn't received an END yet + /* read last bytes if we havn't received an END yet */ if (*end == 0) { size_t num_bytes; - // try to make sure we holdoff after last byte read + /* try to make sure we holdoff after last byte read */ retval = tms9914_read(board, tms_priv, buffer, length, end, &num_bytes); *bytes_read += num_bytes; if (retval < 0) @@ -145,7 +147,7 @@ static int translate_wait_return_value(struct gpib_board *board, int retval) return 0; } -static int agilent_82350b_accel_write(struct gpib_board *board, uint8_t *buffer, +static int agilent_82350b_accel_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { @@ -169,7 +171,7 @@ static int agilent_82350b_accel_write(struct gpib_board *board, uint8_t *buffer, event_status = read_and_clear_event_status(board); #ifdef EXPERIMENTAL - // wait for previous BO to complete if any + /* wait for previous BO to complete if any */ retval = wait_event_interruptible(board->wait, test_bit(DEV_CLEAR_BN, &tms_priv->state) || test_bit(WRITE_READY_BN, &tms_priv->state) || @@ -192,7 +194,7 @@ static int agilent_82350b_accel_write(struct gpib_board *board, uint8_t *buffer, block_size = min(fifotransferlength - i, agilent_82350b_fifo_size); set_transfer_counter(a_priv, block_size); for (j = 0; j < block_size; ++j, ++i) { - // load data into board's sram + /* load data into board's sram */ writeb(buffer[i], a_priv->sram_base + j); } writeb(ENABLE_TI_TO_SRAM, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG); @@ -262,7 +264,7 @@ static irqreturn_t agilent_82350b_interrupt(int irq, void *arg) tms9914_interrupt_have_status(board, &a_priv->tms9914_priv, tms9914_status1, tms9914_status2); } -//write-clear status bits + /* write-clear status bits */ if (event_status & (BUFFER_END_STATUS_BIT | TERM_COUNT_STATUS_BIT)) { writeb(event_status & (BUFFER_END_STATUS_BIT | TERM_COUNT_STATUS_BIT), a_priv->gpib_base + EVENT_STATUS_REG); @@ -292,12 +294,12 @@ static void set_transfer_counter(struct agilent_82350b_priv *a_priv, int count) writeb(complement & 0xff, a_priv->gpib_base + XFER_COUNT_LO_REG); writeb((complement >> 8) & 0xff, a_priv->gpib_base + XFER_COUNT_MID_REG); - //I don't think the hi count reg is even used, but oh well + /* I don't think the hi count reg is even used, but oh well */ writeb((complement >> 16) & 0xf, a_priv->gpib_base + XFER_COUNT_HI_REG); } -// wrappers for interface functions -static int agilent_82350b_read(struct gpib_board *board, uint8_t *buffer, +/* wrappers for interface functions */ +static int agilent_82350b_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct agilent_82350b_priv *priv = board->private_data; @@ -305,7 +307,7 @@ static int agilent_82350b_read(struct gpib_board *board, uint8_t *buffer, return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read); } -static int agilent_82350b_write(struct gpib_board *board, uint8_t *buffer, +static int agilent_82350b_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { @@ -314,7 +316,7 @@ static int agilent_82350b_write(struct gpib_board *board, uint8_t *buffer, return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written); } -static int agilent_82350b_command(struct gpib_board *board, uint8_t *buffer, +static int agilent_82350b_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { @@ -339,9 +341,7 @@ static int agilent_82350b_go_to_standby(struct gpib_board *board) return tms9914_go_to_standby(board, &priv->tms9914_priv); } -static void agilent_82350b_request_system_control(struct gpib_board *board, - int request_control) - +static int agilent_82350b_request_system_control(struct gpib_board *board, int request_control) { struct agilent_82350b_priv *a_priv = board->private_data; @@ -355,7 +355,7 @@ static void agilent_82350b_request_system_control(struct gpib_board *board, writeb(0, a_priv->gpib_base + INTERNAL_CONFIG_REG); } writeb(a_priv->card_mode_bits, a_priv->gpib_base + CARD_MODE_REG); - tms9914_request_system_control(board, &a_priv->tms9914_priv, request_control); + return tms9914_request_system_control(board, &a_priv->tms9914_priv, request_control); } static void agilent_82350b_interface_clear(struct gpib_board *board, int assert) @@ -373,7 +373,7 @@ static void agilent_82350b_remote_enable(struct gpib_board *board, int enable) tms9914_remote_enable(board, &priv->tms9914_priv, enable); } -static int agilent_82350b_enable_eos(struct gpib_board *board, uint8_t eos_byte, +static int agilent_82350b_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct agilent_82350b_priv *priv = board->private_data; @@ -412,7 +412,7 @@ static int agilent_82350b_secondary_address(struct gpib_board *board, return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable); } -static int agilent_82350b_parallel_poll(struct gpib_board *board, uint8_t *result) +static int agilent_82350b_parallel_poll(struct gpib_board *board, u8 *result) { struct agilent_82350b_priv *priv = board->private_data; @@ -420,7 +420,7 @@ static int agilent_82350b_parallel_poll(struct gpib_board *board, uint8_t *resul } static void agilent_82350b_parallel_poll_configure(struct gpib_board *board, - uint8_t config) + u8 config) { struct agilent_82350b_priv *priv = board->private_data; @@ -434,14 +434,14 @@ static void agilent_82350b_parallel_poll_response(struct gpib_board *board, int tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist); } -static void agilent_82350b_serial_poll_response(struct gpib_board *board, uint8_t status) +static void agilent_82350b_serial_poll_response(struct gpib_board *board, u8 status) { struct agilent_82350b_priv *priv = board->private_data; tms9914_serial_poll_response(board, &priv->tms9914_priv, status); } -static uint8_t agilent_82350b_serial_poll_status(struct gpib_board *board) +static u8 agilent_82350b_serial_poll_status(struct gpib_board *board) { struct agilent_82350b_priv *priv = board->private_data; @@ -492,7 +492,7 @@ static void agilent_82350b_free_private(struct gpib_board *board) } static int init_82350a_hardware(struct gpib_board *board, - const gpib_board_config_t *config) + const struct gpib_board_config *config) { struct agilent_82350b_priv *a_priv = board->private_data; static const unsigned int firmware_length = 5302; @@ -511,18 +511,18 @@ static int init_82350a_hardware(struct gpib_board *board, PLX9050_PCI_RETRY_DELAY_BITS(64) | PLX9050_DIRECT_SLAVE_LOCK_ENABLE_BIT; -// load borg data + /* load borg data */ borg_status = readb(a_priv->borg_base); if ((borg_status & BORG_DONE_BIT)) return 0; - // need to programme borg + /* need to programme borg */ if (!config->init_data || config->init_data_length != firmware_length) { dev_err(board->gpib_dev, "the 82350A board requires firmware after powering on.\n"); return -EIO; } dev_dbg(board->gpib_dev, "Loading firmware...\n"); - // tickle the borg + /* tickle the borg */ writel(plx_cntrl_static_bits | PLX9050_USER3_DATA_BIT, a_priv->plx_base + PLX9050_CNTRL_REG); usleep_range(1000, 2000); @@ -563,7 +563,7 @@ static int test_sram(struct gpib_board *board) struct agilent_82350b_priv *a_priv = board->private_data; unsigned int i; const unsigned int sram_length = pci_resource_len(a_priv->pci_device, SRAM_82350A_REGION); - // test SRAM + /* test SRAM */ const unsigned int byte_mask = 0xff; for (i = 0; i < sram_length; ++i) { @@ -587,7 +587,7 @@ static int test_sram(struct gpib_board *board) } static int agilent_82350b_generic_attach(struct gpib_board *board, - const gpib_board_config_t *config, + const struct gpib_board_config *config, int use_fifos) { @@ -606,7 +606,7 @@ static int agilent_82350b_generic_attach(struct gpib_board *board, tms_priv->write_byte = tms9914_iomem_write_byte; tms_priv->offset = 1; - // find board + /* find board */ a_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_AGILENT, PCI_DEVICE_ID_82350B, NULL); if (a_priv->pci_device) { @@ -702,7 +702,7 @@ static int agilent_82350b_generic_attach(struct gpib_board *board, writeb(a_priv->card_mode_bits, a_priv->gpib_base + CARD_MODE_REG); if (a_priv->model == MODEL_82350A) { - // enable PCI interrupts for 82350a + /* enable PCI interrupts for 82350a */ writel(PLX9050_LINTR1_EN_BIT | PLX9050_LINTR2_POLARITY_BIT | PLX9050_PCI_INTR_EN_BIT, a_priv->plx_base + PLX9050_INTCSR_REG); @@ -713,7 +713,7 @@ static int agilent_82350b_generic_attach(struct gpib_board *board, a_priv->gpib_base + EVENT_ENABLE_REG); writeb(ENABLE_TERM_COUNT_INTERRUPT_BIT | ENABLE_BUFFER_END_INTERRUPT_BIT | ENABLE_TMS9914_INTERRUPTS_BIT, a_priv->gpib_base + INTERRUPT_ENABLE_REG); - //write-clear event status bits + /* write-clear event status bits */ writeb(BUFFER_END_STATUS_BIT | TERM_COUNT_STATUS_BIT, a_priv->gpib_base + EVENT_STATUS_REG); } else { @@ -730,13 +730,13 @@ static int agilent_82350b_generic_attach(struct gpib_board *board, } static int agilent_82350b_unaccel_attach(struct gpib_board *board, - const gpib_board_config_t *config) + const struct gpib_board_config *config) { return agilent_82350b_generic_attach(board, config, 0); } static int agilent_82350b_accel_attach(struct gpib_board *board, - const gpib_board_config_t *config) + const struct gpib_board_config *config) { return agilent_82350b_generic_attach(board, config, 1); } @@ -747,7 +747,7 @@ static void agilent_82350b_detach(struct gpib_board *board) struct tms9914_priv *tms_priv; if (a_priv) { - if (a_priv->plx_base) // disable interrupts + if (a_priv->plx_base) /* disable interrupts */ writel(0, a_priv->plx_base + PLX9050_INTCSR_REG); tms_priv = &a_priv->tms9914_priv; @@ -773,7 +773,7 @@ static void agilent_82350b_detach(struct gpib_board *board) agilent_82350b_free_private(board); } -static gpib_interface_t agilent_82350b_unaccel_interface = { +static struct gpib_interface agilent_82350b_unaccel_interface = { .name = "agilent_82350b_unaccel", .attach = agilent_82350b_unaccel_attach, .detach = agilent_82350b_detach, @@ -790,7 +790,7 @@ static gpib_interface_t agilent_82350b_unaccel_interface = { .parallel_poll = agilent_82350b_parallel_poll, .parallel_poll_configure = agilent_82350b_parallel_poll_configure, .parallel_poll_response = agilent_82350b_parallel_poll_response, - .local_parallel_poll_mode = NULL, // XXX + .local_parallel_poll_mode = NULL, /* XXX */ .line_status = agilent_82350b_line_status, .update_status = agilent_82350b_update_status, .primary_address = agilent_82350b_primary_address, @@ -801,7 +801,7 @@ static gpib_interface_t agilent_82350b_unaccel_interface = { .return_to_local = agilent_82350b_return_to_local, }; -static gpib_interface_t agilent_82350b_interface = { +static struct gpib_interface agilent_82350b_interface = { .name = "agilent_82350b", .attach = agilent_82350b_accel_attach, .detach = agilent_82350b_detach, @@ -818,7 +818,7 @@ static gpib_interface_t agilent_82350b_interface = { .parallel_poll = agilent_82350b_parallel_poll, .parallel_poll_configure = agilent_82350b_parallel_poll_configure, .parallel_poll_response = agilent_82350b_parallel_poll_response, - .local_parallel_poll_mode = NULL, // XXX + .local_parallel_poll_mode = NULL, /* XXX */ .line_status = agilent_82350b_line_status, .update_status = agilent_82350b_update_status, .primary_address = agilent_82350b_primary_address, diff --git a/drivers/staging/gpib/agilent_82350b/agilent_82350b.h b/drivers/staging/gpib/agilent_82350b/agilent_82350b.h index 1573230c619d..ef841957297f 100644 --- a/drivers/staging/gpib/agilent_82350b/agilent_82350b.h +++ b/drivers/staging/gpib/agilent_82350b/agilent_82350b.h @@ -41,11 +41,11 @@ enum board_model { MODEL_82351A }; -// struct which defines private_data for board +/* struct which defines private_data for board */ struct agilent_82350b_priv { struct tms9914_priv tms9914_priv; struct pci_dev *pci_device; - void __iomem *plx_base; //82350a only + void __iomem *plx_base; /* 82350a only */ void __iomem *gpib_base; void __iomem *sram_base; void __iomem *misc_base; @@ -57,12 +57,12 @@ struct agilent_82350b_priv { bool using_fifos; }; -//registers +/* registers */ enum agilent_82350b_gpib_registers { CARD_MODE_REG = 0x1, - CONFIG_DATA_REG = 0x2, // 82350A specific + CONFIG_DATA_REG = 0x2, /* 82350A specific */ INTERRUPT_ENABLE_REG = 0x3, EVENT_STATUS_REG = 0x4, EVENT_ENABLE_REG = 0x5, @@ -76,8 +76,8 @@ enum agilent_82350b_gpib_registers XFER_COUNT_HI_REG = 0xe, TMS9914_BASE_REG = 0x10, INTERNAL_CONFIG_REG = 0x18, - IMR0_READ_REG = 0x19, //read - T1_DELAY_REG = 0x19, // write + IMR0_READ_REG = 0x19, /* read */ + T1_DELAY_REG = 0x19, /* write */ IMR1_READ_REG = 0x1a, ADR_READ_REG = 0x1b, SPMR_READ_REG = 0x1c, @@ -89,7 +89,7 @@ enum agilent_82350b_gpib_registers enum card_mode_bits { - ACTIVE_CONTROLLER_BIT = 0x2, // read-only + ACTIVE_CONTROLLER_BIT = 0x2, /* read-only */ CM_SYSTEM_CONTROLLER_BIT = 0x8, ENABLE_BUS_MONITOR_BIT = 0x10, ENABLE_PCI_IRQ_BIT = 0x20, @@ -115,15 +115,15 @@ enum event_status_bits { TMS9914_IRQ_STATUS_BIT = 0x1, IRQ_STATUS_BIT = 0x2, - BUFFER_END_STATUS_BIT = 0x10, // write-clear - TERM_COUNT_STATUS_BIT = 0x20, // write-clear + BUFFER_END_STATUS_BIT = 0x10, /* write-clear */ + TERM_COUNT_STATUS_BIT = 0x20, /* write-clear */ }; enum stream_status_bits { - HALTED_STATUS_BIT = 0x1, //read - RESTART_STREAM_BIT = 0x1, //write + HALTED_STATUS_BIT = 0x1, /* read */ + RESTART_STREAM_BIT = 0x1, /* write */ }; enum internal_config_bits @@ -135,9 +135,9 @@ enum internal_config_bits enum sram_access_control_bits { - DIRECTION_GPIB_TO_HOST = 0x20, // transfer direction - ENABLE_TI_TO_SRAM = 0x40, // enable fifo - ENABLE_FAST_TALKER = 0x80 // added for 82350A (not used) + DIRECTION_GPIB_TO_HOST = 0x20, /* transfer direction */ + ENABLE_TI_TO_SRAM = 0x40, /* enable fifo */ + ENABLE_FAST_TALKER = 0x80 /* added for 82350A (not used) */ }; enum borg_bits diff --git a/drivers/staging/gpib/agilent_82357a/agilent_82357a.c b/drivers/staging/gpib/agilent_82357a/agilent_82357a.c index da229965d98e..b923dc606d1d 100644 --- a/drivers/staging/gpib/agilent_82357a/agilent_82357a.c +++ b/drivers/staging/gpib/agilent_82357a/agilent_82357a.c @@ -26,7 +26,7 @@ static struct usb_interface *agilent_82357a_driver_interfaces[MAX_NUM_82357A_INT static DEFINE_MUTEX(agilent_82357a_hotplug_lock); // protect board insertion and removal static unsigned int agilent_82357a_update_status(struct gpib_board *board, - unsigned int clear_mask); + unsigned int clear_mask); static int agilent_82357a_take_control_internal(struct gpib_board *board, int synchronous); @@ -34,16 +34,17 @@ static void agilent_82357a_bulk_complete(struct urb *urb) { struct agilent_82357a_urb_ctx *context = urb->context; - up(&context->complete); + complete(&context->complete); } static void agilent_82357a_timeout_handler(struct timer_list *t) { - struct agilent_82357a_priv *a_priv = from_timer(a_priv, t, bulk_timer); + struct agilent_82357a_priv *a_priv = timer_container_of(a_priv, t, + bulk_timer); struct agilent_82357a_urb_ctx *context = &a_priv->context; context->timed_out = 1; - up(&context->complete); + complete(&context->complete); } static int agilent_82357a_send_bulk_msg(struct agilent_82357a_priv *a_priv, void *data, @@ -74,7 +75,7 @@ static int agilent_82357a_send_bulk_msg(struct agilent_82357a_priv *a_priv, void } usb_dev = interface_to_usbdev(a_priv->bus_interface); out_pipe = usb_sndbulkpipe(usb_dev, a_priv->bulk_out_endpoint); - sema_init(&context->complete, 0); + init_completion(&context->complete); context->timed_out = 0; usb_fill_bulk_urb(a_priv->bulk_urb, usb_dev, out_pipe, data, data_length, &agilent_82357a_bulk_complete, context); @@ -89,7 +90,7 @@ static int agilent_82357a_send_bulk_msg(struct agilent_82357a_priv *a_priv, void goto cleanup; } mutex_unlock(&a_priv->bulk_alloc_lock); - if (down_interruptible(&context->complete)) { + if (wait_for_completion_interruptible(&context->complete)) { retval = -ERESTARTSYS; goto cleanup; } @@ -142,7 +143,7 @@ static int agilent_82357a_receive_bulk_msg(struct agilent_82357a_priv *a_priv, v } usb_dev = interface_to_usbdev(a_priv->bus_interface); in_pipe = usb_rcvbulkpipe(usb_dev, AGILENT_82357_BULK_IN_ENDPOINT); - sema_init(&context->complete, 0); + init_completion(&context->complete); context->timed_out = 0; usb_fill_bulk_urb(a_priv->bulk_urb, usb_dev, in_pipe, data, data_length, &agilent_82357a_bulk_complete, context); @@ -157,7 +158,7 @@ static int agilent_82357a_receive_bulk_msg(struct agilent_82357a_priv *a_priv, v goto cleanup; } mutex_unlock(&a_priv->bulk_alloc_lock); - if (down_interruptible(&context->complete)) { + if (wait_for_completion_interruptible(&context->complete)) { retval = -ERESTARTSYS; goto cleanup; } @@ -420,10 +421,10 @@ cleanup: } // interface functions -int agilent_82357a_command(struct gpib_board *board, uint8_t *buffer, size_t length, +int agilent_82357a_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written); -static int agilent_82357a_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end, +static int agilent_82357a_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *nbytes) { int retval; @@ -524,9 +525,10 @@ static int agilent_82357a_read(struct gpib_board *board, uint8_t *buffer, size_t } kfree(in_data); - /* Fix for a bug in 9914A that does not return the contents of ADSR - * when the board is in listener active state and ATN is not asserted. - * Set ATN here to obtain a valid board level ibsta + /* + * Fix for a bug in 9914A that does not return the contents of ADSR + * when the board is in listener active state and ATN is not asserted. + * Set ATN here to obtain a valid board level ibsta */ agilent_82357a_take_control_internal(board, 0); @@ -535,7 +537,7 @@ static int agilent_82357a_read(struct gpib_board *board, uint8_t *buffer, size_t } static ssize_t agilent_82357a_generic_write(struct gpib_board *board, - uint8_t *buffer, size_t length, + u8 *buffer, size_t length, int send_commands, int send_eoi, size_t *bytes_written) { @@ -675,13 +677,13 @@ static ssize_t agilent_82357a_generic_write(struct gpib_board *board, return 0; } -static int agilent_82357a_write(struct gpib_board *board, uint8_t *buffer, +static int agilent_82357a_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { return agilent_82357a_generic_write(board, buffer, length, 0, send_eoi, bytes_written); } -int agilent_82357a_command(struct gpib_board *board, uint8_t *buffer, size_t length, +int agilent_82357a_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { return agilent_82357a_generic_write(board, buffer, length, 1, 0, bytes_written); @@ -715,9 +717,10 @@ static int agilent_82357a_take_control(struct gpib_board *board, int synchronous if (!a_priv->bus_interface) return -ENODEV; -/* It looks like the 9914 does not handle tcs properly. - * See comment above tms9914_take_control_workaround() in - * drivers/gpib/tms9914/tms9914_aux.c +/* + * It looks like the 9914 does not handle tcs properly. + * See comment above tms9914_take_control_workaround() in + * drivers/gpib/tms9914/tms9914_aux.c */ if (synchronous) return -ETIMEDOUT; @@ -754,9 +757,7 @@ static int agilent_82357a_go_to_standby(struct gpib_board *board) return 0; } -//FIXME should change prototype to return int -static void agilent_82357a_request_system_control(struct gpib_board *board, - int request_control) +static int agilent_82357a_request_system_control(struct gpib_board *board, int request_control) { struct agilent_82357a_priv *a_priv = board->private_data; struct usb_device *usb_dev; @@ -765,7 +766,7 @@ static void agilent_82357a_request_system_control(struct gpib_board *board, int i = 0; if (!a_priv->bus_interface) - return; // -ENODEV; + return -ENODEV; usb_dev = interface_to_usbdev(a_priv->bus_interface); /* 82357B needs bit to be set in 9914 AUXCR register */ @@ -774,9 +775,7 @@ static void agilent_82357a_request_system_control(struct gpib_board *board, writes[i].value = AUX_RQC; a_priv->hw_control_bits |= SYSTEM_CONTROLLER; } else { - writes[i].value = AUX_RLC; - a_priv->is_cic = 0; - a_priv->hw_control_bits &= ~SYSTEM_CONTROLLER; + return -EINVAL; } ++i; writes[i].address = HW_CONTROL; @@ -785,7 +784,7 @@ static void agilent_82357a_request_system_control(struct gpib_board *board, retval = agilent_82357a_write_registers(a_priv, writes, i); if (retval) dev_err(&usb_dev->dev, "write_registers() returned error\n"); - return;// retval; + return retval; } static void agilent_82357a_interface_clear(struct gpib_board *board, int assert) @@ -832,7 +831,7 @@ static void agilent_82357a_remote_enable(struct gpib_board *board, int enable) return;// 0; } -static int agilent_82357a_enable_eos(struct gpib_board *board, uint8_t eos_byte, +static int agilent_82357a_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct agilent_82357a_priv *a_priv = board->private_data; @@ -946,7 +945,7 @@ static int agilent_82357a_secondary_address(struct gpib_board *board, return 0; } -static int agilent_82357a_parallel_poll(struct gpib_board *board, uint8_t *result) +static int agilent_82357a_parallel_poll(struct gpib_board *board, u8 *result) { struct agilent_82357a_priv *a_priv = board->private_data; struct usb_device *usb_dev; @@ -988,7 +987,7 @@ static int agilent_82357a_parallel_poll(struct gpib_board *board, uint8_t *resul return 0; } -static void agilent_82357a_parallel_poll_configure(struct gpib_board *board, uint8_t config) +static void agilent_82357a_parallel_poll_configure(struct gpib_board *board, u8 config) { //board can only be system controller return;// 0; @@ -1000,13 +999,13 @@ static void agilent_82357a_parallel_poll_response(struct gpib_board *board, int return;// 0; } -static void agilent_82357a_serial_poll_response(struct gpib_board *board, uint8_t status) +static void agilent_82357a_serial_poll_response(struct gpib_board *board, u8 status) { //board can only be system controller return;// 0; } -static uint8_t agilent_82357a_serial_poll_status(struct gpib_board *board) +static u8 agilent_82357a_serial_poll_status(struct gpib_board *board) { //board can only be system controller return 0; @@ -1292,7 +1291,7 @@ static int agilent_82357a_init(struct gpib_board *board) } static inline int agilent_82357a_device_match(struct usb_interface *interface, - const gpib_board_config_t *config) + const struct gpib_board_config *config) { struct usb_device * const usbdev = interface_to_usbdev(interface); @@ -1305,7 +1304,7 @@ static inline int agilent_82357a_device_match(struct usb_interface *interface, return 1; } -static int agilent_82357a_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int agilent_82357a_attach(struct gpib_board *board, const struct gpib_board_config *config) { int retval; int i; @@ -1432,7 +1431,7 @@ static void agilent_82357a_detach(struct gpib_board *board) mutex_unlock(&agilent_82357a_hotplug_lock); } -static gpib_interface_t agilent_82357a_gpib_interface = { +static struct gpib_interface agilent_82357a_gpib_interface = { .name = "agilent_82357a", .attach = agilent_82357a_attach, .detach = agilent_82357a_detach, @@ -1591,7 +1590,7 @@ static int agilent_82357a_driver_resume(struct usb_interface *interface) { struct usb_device *usb_dev = interface_to_usbdev(interface); struct gpib_board *board; - int i, retval; + int i, retval = 0; mutex_lock(&agilent_82357a_hotplug_lock); @@ -1602,8 +1601,10 @@ static int agilent_82357a_driver_resume(struct usb_interface *interface) break; } } - if (i == MAX_NUM_82357A_INTERFACES) + if (i == MAX_NUM_82357A_INTERFACES) { + retval = -ENOENT; goto resume_exit; + } struct agilent_82357a_priv *a_priv = board->private_data; @@ -1626,7 +1627,7 @@ static int agilent_82357a_driver_resume(struct usb_interface *interface) return retval; } // set/unset system controller - agilent_82357a_request_system_control(board, board->master); + retval = agilent_82357a_request_system_control(board, board->master); // toggle ifc if master if (board->master) { agilent_82357a_interface_clear(board, 1); @@ -1644,7 +1645,7 @@ static int agilent_82357a_driver_resume(struct usb_interface *interface) resume_exit: mutex_unlock(&agilent_82357a_hotplug_lock); - return 0; + return retval; } static struct usb_driver agilent_82357a_bus_driver = { diff --git a/drivers/staging/gpib/agilent_82357a/agilent_82357a.h b/drivers/staging/gpib/agilent_82357a/agilent_82357a.h index cdbc3ec5d8bd..23aa4799eb86 100644 --- a/drivers/staging/gpib/agilent_82357a/agilent_82357a.h +++ b/drivers/staging/gpib/agilent_82357a/agilent_82357a.h @@ -6,7 +6,7 @@ #include <linux/kernel.h> #include <linux/mutex.h> -#include <linux/semaphore.h> +#include <linux/completion.h> #include <linux/usb.h> #include <linux/timer.h> #include <linux/compiler_attributes.h> @@ -115,7 +115,7 @@ enum xfer_abort_type { #define INTERRUPT_BUF_LEN 8 struct agilent_82357a_urb_ctx { - struct semaphore complete; + struct completion complete; unsigned timed_out : 1; }; diff --git a/drivers/staging/gpib/cb7210/cb7210.c b/drivers/staging/gpib/cb7210/cb7210.c index 6b22a33a8c4f..3e2397898a9b 100644 --- a/drivers/staging/gpib/cb7210/cb7210.c +++ b/drivers/staging/gpib/cb7210/cb7210.c @@ -27,7 +27,7 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("GPIB driver Measurement Computing boards using cb7210.2 and cbi488.2"); -static int cb7210_read(struct gpib_board *board, uint8_t *buffer, size_t length, +static int cb7210_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read); static inline int have_fifo_word(const struct cb7210_priv *cb_priv) @@ -76,7 +76,7 @@ static inline void input_fifo_enable(struct gpib_board *board, int enable) spin_unlock_irqrestore(&board->spinlock, flags); } -static int fifo_read(struct gpib_board *board, struct cb7210_priv *cb_priv, uint8_t *buffer, +static int fifo_read(struct gpib_board *board, struct cb7210_priv *cb_priv, u8 *buffer, size_t length, int *end, size_t *bytes_read) { ssize_t retval = 0; @@ -170,7 +170,7 @@ static int fifo_read(struct gpib_board *board, struct cb7210_priv *cb_priv, uint return retval; } -static int cb7210_accel_read(struct gpib_board *board, uint8_t *buffer, +static int cb7210_accel_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { ssize_t retval; @@ -264,7 +264,7 @@ static inline void output_fifo_enable(struct gpib_board *board, int enable) spin_unlock_irqrestore(&board->spinlock, flags); } -static int fifo_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fifo_write(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { size_t count = 0; @@ -350,7 +350,7 @@ static int fifo_write(struct gpib_board *board, uint8_t *buffer, size_t length, return retval; } -static int cb7210_accel_write(struct gpib_board *board, uint8_t *buffer, +static int cb7210_accel_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct cb7210_priv *cb_priv = board->private_data; @@ -533,14 +533,14 @@ static irqreturn_t cb7210_interrupt(int irq, void *arg) return cb7210_internal_interrupt(arg); } -static int cb_pci_attach(struct gpib_board *board, const gpib_board_config_t *config); -static int cb_isa_attach(struct gpib_board *board, const gpib_board_config_t *config); +static int cb_pci_attach(struct gpib_board *board, const struct gpib_board_config *config); +static int cb_isa_attach(struct gpib_board *board, const struct gpib_board_config *config); static void cb_pci_detach(struct gpib_board *board); static void cb_isa_detach(struct gpib_board *board); // wrappers for interface functions -static int cb7210_read(struct gpib_board *board, uint8_t *buffer, size_t length, +static int cb7210_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct cb7210_priv *priv = board->private_data; @@ -548,7 +548,7 @@ static int cb7210_read(struct gpib_board *board, uint8_t *buffer, size_t length, return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); } -static int cb7210_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int cb7210_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct cb7210_priv *priv = board->private_data; @@ -556,7 +556,7 @@ static int cb7210_write(struct gpib_board *board, uint8_t *buffer, size_t length return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); } -static int cb7210_command(struct gpib_board *board, uint8_t *buffer, size_t length, +static int cb7210_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { struct cb7210_priv *priv = board->private_data; @@ -578,7 +578,7 @@ static int cb7210_go_to_standby(struct gpib_board *board) return nec7210_go_to_standby(board, &priv->nec7210_priv); } -static void cb7210_request_system_control(struct gpib_board *board, int request_control) +static int cb7210_request_system_control(struct gpib_board *board, int request_control) { struct cb7210_priv *priv = board->private_data; struct nec7210_priv *nec_priv = &priv->nec7210_priv; @@ -589,7 +589,7 @@ static void cb7210_request_system_control(struct gpib_board *board, int request_ priv->hs_mode_bits &= ~HS_SYS_CONTROL; cb7210_write_byte(priv, priv->hs_mode_bits, HS_MODE); - nec7210_request_system_control(board, nec_priv, request_control); + return nec7210_request_system_control(board, nec_priv, request_control); } static void cb7210_interface_clear(struct gpib_board *board, int assert) @@ -606,7 +606,7 @@ static void cb7210_remote_enable(struct gpib_board *board, int enable) nec7210_remote_enable(board, &priv->nec7210_priv, enable); } -static int cb7210_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits) +static int cb7210_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct cb7210_priv *priv = board->private_data; @@ -641,14 +641,14 @@ static int cb7210_secondary_address(struct gpib_board *board, unsigned int addre return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); } -static int cb7210_parallel_poll(struct gpib_board *board, uint8_t *result) +static int cb7210_parallel_poll(struct gpib_board *board, u8 *result) { struct cb7210_priv *priv = board->private_data; return nec7210_parallel_poll(board, &priv->nec7210_priv, result); } -static void cb7210_parallel_poll_configure(struct gpib_board *board, uint8_t configuration) +static void cb7210_parallel_poll_configure(struct gpib_board *board, u8 configuration) { struct cb7210_priv *priv = board->private_data; @@ -662,14 +662,14 @@ static void cb7210_parallel_poll_response(struct gpib_board *board, int ist) nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); } -static void cb7210_serial_poll_response(struct gpib_board *board, uint8_t status) +static void cb7210_serial_poll_response(struct gpib_board *board, u8 status) { struct cb7210_priv *priv = board->private_data; nec7210_serial_poll_response(board, &priv->nec7210_priv, status); } -static uint8_t cb7210_serial_poll_status(struct gpib_board *board) +static u8 cb7210_serial_poll_status(struct gpib_board *board) { struct cb7210_priv *priv = board->private_data; @@ -686,7 +686,7 @@ static void cb7210_return_to_local(struct gpib_board *board) write_byte(nec_priv, AUX_RTL, AUXMR); } -static gpib_interface_t cb_pci_unaccel_interface = { +static struct gpib_interface cb_pci_unaccel_interface = { .name = "cbi_pci_unaccel", .attach = cb_pci_attach, .detach = cb_pci_detach, @@ -714,7 +714,7 @@ static gpib_interface_t cb_pci_unaccel_interface = { .return_to_local = cb7210_return_to_local, }; -static gpib_interface_t cb_pci_accel_interface = { +static struct gpib_interface cb_pci_accel_interface = { .name = "cbi_pci_accel", .attach = cb_pci_attach, .detach = cb_pci_detach, @@ -742,7 +742,7 @@ static gpib_interface_t cb_pci_accel_interface = { .return_to_local = cb7210_return_to_local, }; -static gpib_interface_t cb_pci_interface = { +static struct gpib_interface cb_pci_interface = { .name = "cbi_pci", .attach = cb_pci_attach, .detach = cb_pci_detach, @@ -769,7 +769,7 @@ static gpib_interface_t cb_pci_interface = { .return_to_local = cb7210_return_to_local, }; -static gpib_interface_t cb_isa_unaccel_interface = { +static struct gpib_interface cb_isa_unaccel_interface = { .name = "cbi_isa_unaccel", .attach = cb_isa_attach, .detach = cb_isa_detach, @@ -797,7 +797,7 @@ static gpib_interface_t cb_isa_unaccel_interface = { .return_to_local = cb7210_return_to_local, }; -static gpib_interface_t cb_isa_interface = { +static struct gpib_interface cb_isa_interface = { .name = "cbi_isa", .attach = cb_isa_attach, .detach = cb_isa_detach, @@ -824,7 +824,7 @@ static gpib_interface_t cb_isa_interface = { .return_to_local = cb7210_return_to_local, }; -static gpib_interface_t cb_isa_accel_interface = { +static struct gpib_interface cb_isa_accel_interface = { .name = "cbi_isa_accel", .attach = cb_isa_attach, .detach = cb_isa_detach, @@ -905,7 +905,8 @@ static int cb7210_init(struct cb7210_priv *cb_priv, struct gpib_board *board) cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE); write_byte(nec_priv, AUX_LO_SPEED, AUXMR); - /* set clock register for maximum (20 MHz) driving frequency + /* + * set clock register for maximum (20 MHz) driving frequency * ICR should be set to clock in megahertz (1-15) and to zero * for clocks faster than 15 MHz (max 20MHz) */ @@ -926,7 +927,7 @@ static int cb7210_init(struct cb7210_priv *cb_priv, struct gpib_board *board) return 0; } -static int cb_pci_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int cb_pci_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct cb7210_priv *cb_priv; struct nec7210_priv *nec_priv; @@ -1031,7 +1032,7 @@ static void cb_pci_detach(struct gpib_board *board) cb7210_generic_detach(board); } -static int cb_isa_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int cb_isa_attach(struct gpib_board *board, const struct gpib_board_config *config) { int isr_flags = 0; struct cb7210_priv *cb_priv; @@ -1133,7 +1134,7 @@ static struct pci_driver cb7210_pci_driver = { static int cb_gpib_config(struct pcmcia_device *link); static void cb_gpib_release(struct pcmcia_device *link); -static int cb_pcmcia_attach(struct gpib_board *board, const gpib_board_config_t *config); +static int cb_pcmcia_attach(struct gpib_board *board, const struct gpib_board_config *config); static void cb_pcmcia_detach(struct gpib_board *board); /* @@ -1183,8 +1184,7 @@ struct local_info { static int cb_gpib_probe(struct pcmcia_device *link) { struct local_info *info; - -// int ret, i; + int ret; /* Allocate space for private device-specific data */ info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -1210,8 +1210,16 @@ static int cb_gpib_probe(struct pcmcia_device *link) /* Register with Card Services */ curr_dev = link; - return cb_gpib_config(link); -} /* gpib_attach */ + ret = cb_gpib_config(link); + if (ret) + goto free_info; + + return 0; + +free_info: + kfree(info); + return ret; +} /* * This deletes a driver "instance". The device is de-registered @@ -1246,13 +1254,8 @@ static int cb_gpib_config_iteration(struct pcmcia_device *link, void *priv_data) static int cb_gpib_config(struct pcmcia_device *link) { - struct pcmcia_device *handle; - struct local_info *dev; int retval; - handle = link; - dev = link->priv; - retval = pcmcia_loop_config(link, &cb_gpib_config_iteration, NULL); if (retval) { dev_warn(&link->dev, "no configuration found\n"); @@ -1275,9 +1278,9 @@ static int cb_gpib_config(struct pcmcia_device *link) } /* gpib_config */ /* - * After a card is removed, gpib_release() will unregister the net - * device, and release the PCMCIA configuration. If the device is - * still open, this will be postponed until it is closed. + * After a card is removed, gpib_release() will unregister the net + * device, and release the PCMCIA configuration. If the device is + * still open, this will be postponed until it is closed. */ static void cb_gpib_release(struct pcmcia_device *link) @@ -1333,7 +1336,7 @@ static void cb_pcmcia_cleanup_module(void) pcmcia_unregister_driver(&cb_gpib_cs_driver); } -static gpib_interface_t cb_pcmcia_unaccel_interface = { +static struct gpib_interface cb_pcmcia_unaccel_interface = { .name = "cbi_pcmcia_unaccel", .attach = cb_pcmcia_attach, .detach = cb_pcmcia_detach, @@ -1361,7 +1364,7 @@ static gpib_interface_t cb_pcmcia_unaccel_interface = { .return_to_local = cb7210_return_to_local, }; -static gpib_interface_t cb_pcmcia_interface = { +static struct gpib_interface cb_pcmcia_interface = { .name = "cbi_pcmcia", .attach = cb_pcmcia_attach, .detach = cb_pcmcia_detach, @@ -1389,7 +1392,7 @@ static gpib_interface_t cb_pcmcia_interface = { .return_to_local = cb7210_return_to_local, }; -static gpib_interface_t cb_pcmcia_accel_interface = { +static struct gpib_interface cb_pcmcia_accel_interface = { .name = "cbi_pcmcia_accel", .attach = cb_pcmcia_attach, .detach = cb_pcmcia_detach, @@ -1417,7 +1420,7 @@ static gpib_interface_t cb_pcmcia_accel_interface = { .return_to_local = cb7210_return_to_local, }; -static int cb_pcmcia_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int cb_pcmcia_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct cb7210_priv *cb_priv; struct nec7210_priv *nec_priv; diff --git a/drivers/staging/gpib/cb7210/cb7210.h b/drivers/staging/gpib/cb7210/cb7210.h index 2108fe7a8ce5..13f127563ab3 100644 --- a/drivers/staging/gpib/cb7210/cb7210.h +++ b/drivers/staging/gpib/cb7210/cb7210.h @@ -73,8 +73,8 @@ static inline int cb7210_page_in_bits(unsigned int page) return 0x50 | (page & 0xf); } -static inline uint8_t cb7210_paged_read_byte(struct cb7210_priv *cb_priv, - unsigned int register_num, unsigned int page) +static inline u8 cb7210_paged_read_byte(struct cb7210_priv *cb_priv, + unsigned int register_num, unsigned int page) { struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; u8 retval; @@ -89,8 +89,8 @@ static inline uint8_t cb7210_paged_read_byte(struct cb7210_priv *cb_priv, } // don't use for register_num < 8, since it doesn't lock -static inline uint8_t cb7210_read_byte(const struct cb7210_priv *cb_priv, - enum hs_regs register_num) +static inline u8 cb7210_read_byte(const struct cb7210_priv *cb_priv, + enum hs_regs register_num) { const struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; u8 retval; @@ -99,7 +99,7 @@ static inline uint8_t cb7210_read_byte(const struct cb7210_priv *cb_priv, return retval; } -static inline void cb7210_paged_write_byte(struct cb7210_priv *cb_priv, uint8_t data, +static inline void cb7210_paged_write_byte(struct cb7210_priv *cb_priv, u8 data, unsigned int register_num, unsigned int page) { struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; @@ -113,7 +113,7 @@ static inline void cb7210_paged_write_byte(struct cb7210_priv *cb_priv, uint8_t } // don't use for register_num < 8, since it doesn't lock -static inline void cb7210_write_byte(const struct cb7210_priv *cb_priv, uint8_t data, +static inline void cb7210_write_byte(const struct cb7210_priv *cb_priv, u8 data, enum hs_regs register_num) { const struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; @@ -134,7 +134,8 @@ enum bus_status_bits { /* CBI 488.2 HS control */ -/* when both bit 0 and 1 are set, it +/* + * when both bit 0 and 1 are set, it * 1 clears the transmit state machine to an initial condition * 2 clears any residual interrupts left latched on cbi488.2 * 3 resets all control bits in HS_MODE to zero @@ -189,11 +190,12 @@ static inline unsigned int irq_bits(unsigned int irq) } enum cb7210_aux_cmds { -/* AUX_RTL2 is an undocumented aux command which causes cb7210 to assert - * (and keep asserted) local rtl message. This is used in conjunction - * with the (stupid) cb7210 implementation - * of the normal nec7210 AUX_RTL aux command, which - * causes the rtl message to toggle between on and off. +/* + * AUX_RTL2 is an undocumented aux command which causes cb7210 to assert + * (and keep asserted) local rtl message. This is used in conjunction + * with the (stupid) cb7210 implementation + * of the normal nec7210 AUX_RTL aux command, which + * causes the rtl message to toggle between on and off. */ AUX_RTL2 = 0xd, AUX_LO_SPEED = 0x40, diff --git a/drivers/staging/gpib/cec/cec_gpib.c b/drivers/staging/gpib/cec/cec_gpib.c index a822fa428cd0..0c9d10ee7cd2 100644 --- a/drivers/staging/gpib/cec/cec_gpib.c +++ b/drivers/staging/gpib/cec/cec_gpib.c @@ -40,12 +40,12 @@ static irqreturn_t cec_interrupt(int irq, void *arg) #define CEC_DEV_ID 0x5cec #define CEC_SUBID 0x9050 -static int cec_pci_attach(struct gpib_board *board, const gpib_board_config_t *config); +static int cec_pci_attach(struct gpib_board *board, const struct gpib_board_config *config); static void cec_pci_detach(struct gpib_board *board); // wrappers for interface functions -static int cec_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end, +static int cec_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct cec_priv *priv = board->private_data; @@ -53,7 +53,7 @@ static int cec_read(struct gpib_board *board, uint8_t *buffer, size_t length, in return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); } -static int cec_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi, +static int cec_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct cec_priv *priv = board->private_data; @@ -61,7 +61,7 @@ static int cec_write(struct gpib_board *board, uint8_t *buffer, size_t length, i return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); } -static int cec_command(struct gpib_board *board, uint8_t *buffer, +static int cec_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { struct cec_priv *priv = board->private_data; @@ -83,11 +83,11 @@ static int cec_go_to_standby(struct gpib_board *board) return nec7210_go_to_standby(board, &priv->nec7210_priv); } -static void cec_request_system_control(struct gpib_board *board, int request_control) +static int cec_request_system_control(struct gpib_board *board, int request_control) { struct cec_priv *priv = board->private_data; - nec7210_request_system_control(board, &priv->nec7210_priv, request_control); + return nec7210_request_system_control(board, &priv->nec7210_priv, request_control); } static void cec_interface_clear(struct gpib_board *board, int assert) @@ -104,7 +104,7 @@ static void cec_remote_enable(struct gpib_board *board, int enable) nec7210_remote_enable(board, &priv->nec7210_priv, enable); } -static int cec_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits) +static int cec_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct cec_priv *priv = board->private_data; @@ -139,14 +139,14 @@ static int cec_secondary_address(struct gpib_board *board, unsigned int address, return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); } -static int cec_parallel_poll(struct gpib_board *board, uint8_t *result) +static int cec_parallel_poll(struct gpib_board *board, u8 *result) { struct cec_priv *priv = board->private_data; return nec7210_parallel_poll(board, &priv->nec7210_priv, result); } -static void cec_parallel_poll_configure(struct gpib_board *board, uint8_t config) +static void cec_parallel_poll_configure(struct gpib_board *board, u8 config) { struct cec_priv *priv = board->private_data; @@ -160,14 +160,14 @@ static void cec_parallel_poll_response(struct gpib_board *board, int ist) nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); } -static void cec_serial_poll_response(struct gpib_board *board, uint8_t status) +static void cec_serial_poll_response(struct gpib_board *board, u8 status) { struct cec_priv *priv = board->private_data; nec7210_serial_poll_response(board, &priv->nec7210_priv, status); } -static uint8_t cec_serial_poll_status(struct gpib_board *board) +static u8 cec_serial_poll_status(struct gpib_board *board) { struct cec_priv *priv = board->private_data; @@ -188,7 +188,7 @@ static void cec_return_to_local(struct gpib_board *board) nec7210_return_to_local(board, &priv->nec7210_priv); } -static gpib_interface_t cec_pci_interface = { +static struct gpib_interface cec_pci_interface = { .name = "cec_pci", .attach = cec_pci_attach, .detach = cec_pci_detach, @@ -265,7 +265,7 @@ static void cec_init(struct cec_priv *cec_priv, const struct gpib_board *board) nec7210_board_online(nec_priv, board); } -static int cec_pci_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int cec_pci_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct cec_priv *cec_priv; struct nec7210_priv *nec_priv; @@ -302,7 +302,7 @@ static int cec_pci_attach(struct gpib_board *board, const gpib_board_config_t *c return -EBUSY; cec_priv->plx_iobase = pci_resource_start(cec_priv->pci_device, 1); - nec_priv->iobase = pci_resource_start(cec_priv->pci_device, 3); + nec_priv->iobase = pci_resource_start(cec_priv->pci_device, 3); isr_flags |= IRQF_SHARED; if (request_irq(cec_priv->pci_device->irq, cec_interrupt, isr_flags, DRV_NAME, board)) { diff --git a/drivers/staging/gpib/common/gpib_os.c b/drivers/staging/gpib/common/gpib_os.c index 8456b97290b8..2a0465ce16c4 100644 --- a/drivers/staging/gpib/common/gpib_os.c +++ b/drivers/staging/gpib/common/gpib_os.c @@ -26,35 +26,37 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("GPIB base support"); MODULE_ALIAS_CHARDEV_MAJOR(GPIB_CODE); -static int board_type_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, unsigned long arg); -static int read_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, +static int board_type_ioctl(struct gpib_file_private *file_priv, + struct gpib_board *board, unsigned long arg); +static int read_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board, unsigned long arg); -static int write_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, +static int write_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board, unsigned long arg); -static int command_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, +static int command_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board, unsigned long arg); static int open_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg); static int close_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg); static int serial_poll_ioctl(struct gpib_board *board, unsigned long arg); -static int wait_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, unsigned long arg); +static int wait_ioctl(struct gpib_file_private *file_priv, + struct gpib_board *board, unsigned long arg); static int parallel_poll_ioctl(struct gpib_board *board, unsigned long arg); static int online_ioctl(struct gpib_board *board, unsigned long arg); static int remote_enable_ioctl(struct gpib_board *board, unsigned long arg); static int take_control_ioctl(struct gpib_board *board, unsigned long arg); static int line_status_ioctl(struct gpib_board *board, unsigned long arg); -static int pad_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv, +static int pad_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv, unsigned long arg); -static int sad_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv, +static int sad_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv, unsigned long arg); static int eos_ioctl(struct gpib_board *board, unsigned long arg); static int request_service_ioctl(struct gpib_board *board, unsigned long arg); static int request_service2_ioctl(struct gpib_board *board, unsigned long arg); -static int iobase_ioctl(gpib_board_config_t *config, unsigned long arg); -static int irq_ioctl(gpib_board_config_t *config, unsigned long arg); -static int dma_ioctl(gpib_board_config_t *config, unsigned long arg); -static int autospoll_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv, +static int iobase_ioctl(struct gpib_board_config *config, unsigned long arg); +static int irq_ioctl(struct gpib_board_config *config, unsigned long arg); +static int dma_ioctl(struct gpib_board_config *config, unsigned long arg); +static int autospoll_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv, unsigned long arg); -static int mutex_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv, +static int mutex_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv, unsigned long arg); static int timeout_ioctl(struct gpib_board *board, unsigned long arg); static int status_bytes_ioctl(struct gpib_board *board, unsigned long arg); @@ -64,15 +66,16 @@ static int set_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long ar static int get_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long arg); static int query_board_rsv_ioctl(struct gpib_board *board, unsigned long arg); static int interface_clear_ioctl(struct gpib_board *board, unsigned long arg); -static int select_pci_ioctl(gpib_board_config_t *config, unsigned long arg); -static int select_device_path_ioctl(gpib_board_config_t *config, unsigned long arg); +static int select_pci_ioctl(struct gpib_board_config *config, unsigned long arg); +static int select_device_path_ioctl(struct gpib_board_config *config, unsigned long arg); static int event_ioctl(struct gpib_board *board, unsigned long arg); static int request_system_control_ioctl(struct gpib_board *board, unsigned long arg); static int t1_delay_ioctl(struct gpib_board *board, unsigned long arg); -static int cleanup_open_devices(gpib_file_private_t *file_priv, struct gpib_board *board); +static int cleanup_open_devices(struct gpib_file_private *file_priv, struct gpib_board *board); -static int pop_gpib_event_nolock(struct gpib_board *board, gpib_event_queue_t *queue, short *event_type); +static int pop_gpib_event_nolock(struct gpib_board *board, + struct gpib_event_queue *queue, short *event_type); /* * Timer functions @@ -82,7 +85,7 @@ static int pop_gpib_event_nolock(struct gpib_board *board, gpib_event_queue_t *q static void watchdog_timeout(struct timer_list *t) { - struct gpib_board *board = from_timer(board, t, timer); + struct gpib_board *board = timer_container_of(board, t, timer); set_bit(TIMO_NUM, &board->status); wake_up_interruptible(&board->wait); @@ -119,7 +122,8 @@ int io_timed_out(struct gpib_board *board) return 0; } -/* this is a function instead of a constant because of Suse +/* + * this is a function instead of a constant because of Suse * defining HZ to be a function call to get_hz() */ static inline int pseudo_irq_period(void) @@ -129,7 +133,8 @@ static inline int pseudo_irq_period(void) static void pseudo_irq_handler(struct timer_list *t) { - struct gpib_pseudo_irq *pseudo_irq = from_timer(pseudo_irq, t, timer); + struct gpib_pseudo_irq *pseudo_irq = timer_container_of(pseudo_irq, t, + timer); if (pseudo_irq->handler) pseudo_irq->handler(0, pseudo_irq->board); @@ -170,7 +175,7 @@ EXPORT_SYMBOL(gpib_free_pseudo_irq); static const unsigned int serial_timeout = 1000000; -unsigned int num_status_bytes(const gpib_status_queue_t *dev) +unsigned int num_status_bytes(const struct gpib_status_queue *dev) { if (!dev) return 0; @@ -178,10 +183,10 @@ unsigned int num_status_bytes(const gpib_status_queue_t *dev) } // push status byte onto back of status byte fifo -int push_status_byte(struct gpib_board *board, gpib_status_queue_t *device, u8 poll_byte) +int push_status_byte(struct gpib_board *board, struct gpib_status_queue *device, u8 poll_byte) { struct list_head *head = &device->status_bytes; - status_byte_t *status; + struct gpib_status_byte *status; static const unsigned int max_num_status_bytes = 1024; int retval; @@ -194,7 +199,7 @@ int push_status_byte(struct gpib_board *board, gpib_status_queue_t *device, u8 p return retval; } - status = kmalloc(sizeof(status_byte_t), GFP_KERNEL); + status = kmalloc(sizeof(*status), GFP_KERNEL); if (!status) return -ENOMEM; @@ -212,11 +217,11 @@ int push_status_byte(struct gpib_board *board, gpib_status_queue_t *device, u8 p } // pop status byte from front of status byte fifo -int pop_status_byte(struct gpib_board *board, gpib_status_queue_t *device, u8 *poll_byte) +int pop_status_byte(struct gpib_board *board, struct gpib_status_queue *device, u8 *poll_byte) { struct list_head *head = &device->status_bytes; struct list_head *front = head->next; - status_byte_t *status; + struct gpib_status_byte *status; if (num_status_bytes(device) == 0) return -EIO; @@ -229,7 +234,7 @@ int pop_status_byte(struct gpib_board *board, gpib_status_queue_t *device, u8 *p return -EPIPE; } - status = list_entry(front, status_byte_t, list); + status = list_entry(front, struct gpib_status_byte, list); *poll_byte = status->poll_byte; list_del(front); @@ -243,14 +248,14 @@ int pop_status_byte(struct gpib_board *board, gpib_status_queue_t *device, u8 *p return 0; } -gpib_status_queue_t *get_gpib_status_queue(struct gpib_board *board, unsigned int pad, int sad) +struct gpib_status_queue *get_gpib_status_queue(struct gpib_board *board, unsigned int pad, int sad) { - gpib_status_queue_t *device; + struct gpib_status_queue *device; struct list_head *list_ptr; const struct list_head *head = &board->device_list; for (list_ptr = head->next; list_ptr != head; list_ptr = list_ptr->next) { - device = list_entry(list_ptr, gpib_status_queue_t, list); + device = list_entry(list_ptr, struct gpib_status_queue, list); if (gpib_address_equal(device->pad, device->sad, pad, sad)) return device; } @@ -258,10 +263,10 @@ gpib_status_queue_t *get_gpib_status_queue(struct gpib_board *board, unsigned in return NULL; } -int get_serial_poll_byte(struct gpib_board *board, unsigned int pad, int sad, unsigned int usec_timeout, - uint8_t *poll_byte) +int get_serial_poll_byte(struct gpib_board *board, unsigned int pad, int sad, + unsigned int usec_timeout, u8 *poll_byte) { - gpib_status_queue_t *device; + struct gpib_status_queue *device; device = get_gpib_status_queue(board, pad, sad); if (num_status_bytes(device)) @@ -291,7 +296,8 @@ int autopoll_all_devices(struct gpib_board *board) } dev_dbg(board->gpib_dev, "complete\n"); - /* need to wake wait queue in case someone is + /* + * need to wake wait queue in case someone is * waiting on RQS */ wake_up_interruptible(&board->wait); @@ -334,7 +340,7 @@ static int setup_serial_poll(struct gpib_board *board, unsigned int usec_timeout } static int read_serial_poll_byte(struct gpib_board *board, unsigned int pad, - int sad, unsigned int usec_timeout, uint8_t *result) + int sad, unsigned int usec_timeout, u8 *result) { u8 cmd_string[8]; int end_flag; @@ -405,7 +411,7 @@ static int cleanup_serial_poll(struct gpib_board *board, unsigned int usec_timeo } static int serial_poll_single(struct gpib_board *board, unsigned int pad, int sad, - unsigned int usec_timeout, uint8_t *result) + unsigned int usec_timeout, u8 *result) { int retval, cleanup_retval; @@ -427,7 +433,7 @@ int serial_poll_all(struct gpib_board *board, unsigned int usec_timeout) int retval = 0; struct list_head *cur; const struct list_head *head = NULL; - gpib_status_queue_t *device; + struct gpib_status_queue *device; u8 result; unsigned int num_bytes = 0; @@ -440,7 +446,7 @@ int serial_poll_all(struct gpib_board *board, unsigned int usec_timeout) return retval; for (cur = head->next; cur != head; cur = cur->next) { - device = list_entry(cur, gpib_status_queue_t, list); + device = list_entry(cur, struct gpib_status_queue, list); retval = read_serial_poll_byte(board, device->pad, device->sad, usec_timeout, &result); if (retval < 0) @@ -470,7 +476,7 @@ int serial_poll_all(struct gpib_board *board, unsigned int usec_timeout) */ int dvrsp(struct gpib_board *board, unsigned int pad, int sad, - unsigned int usec_timeout, uint8_t *result) + unsigned int usec_timeout, u8 *result) { int status = ibstatus(board); int retval; @@ -492,8 +498,8 @@ int dvrsp(struct gpib_board *board, unsigned int pad, int sad, return retval; } -static gpib_descriptor_t *handle_to_descriptor(const gpib_file_private_t *file_priv, - int handle) +static struct gpib_descriptor *handle_to_descriptor(const struct gpib_file_private *file_priv, + int handle) { if (handle < 0 || handle >= GPIB_MAX_NUM_DESCRIPTORS) { pr_err("gpib: invalid handle %i\n", handle); @@ -503,11 +509,11 @@ static gpib_descriptor_t *handle_to_descriptor(const gpib_file_private_t *file_p return file_priv->descriptors[handle]; } -static int init_gpib_file_private(gpib_file_private_t *priv) +static int init_gpib_file_private(struct gpib_file_private *priv) { memset(priv, 0, sizeof(*priv)); atomic_set(&priv->holding_mutex, 0); - priv->descriptors[0] = kmalloc(sizeof(gpib_descriptor_t), GFP_KERNEL); + priv->descriptors[0] = kmalloc(sizeof(struct gpib_descriptor), GFP_KERNEL); if (!priv->descriptors[0]) { pr_err("gpib: failed to allocate default board descriptor\n"); return -ENOMEM; @@ -522,7 +528,7 @@ int ibopen(struct inode *inode, struct file *filep) { unsigned int minor = iminor(inode); struct gpib_board *board; - gpib_file_private_t *priv; + struct gpib_file_private *priv; if (minor >= GPIB_MAX_NUM_BOARDS) { pr_err("gpib: invalid minor number of device file\n"); @@ -531,12 +537,12 @@ int ibopen(struct inode *inode, struct file *filep) board = &board_array[minor]; - filep->private_data = kmalloc(sizeof(gpib_file_private_t), GFP_KERNEL); + filep->private_data = kmalloc(sizeof(struct gpib_file_private), GFP_KERNEL); if (!filep->private_data) return -ENOMEM; priv = filep->private_data; - init_gpib_file_private((gpib_file_private_t *)filep->private_data); + init_gpib_file_private((struct gpib_file_private *)filep->private_data); if (board->use_count == 0) { int retval; @@ -560,8 +566,8 @@ int ibclose(struct inode *inode, struct file *filep) { unsigned int minor = iminor(inode); struct gpib_board *board; - gpib_file_private_t *priv = filep->private_data; - gpib_descriptor_t *desc; + struct gpib_file_private *priv = filep->private_data; + struct gpib_descriptor *desc; if (minor >= GPIB_MAX_NUM_BOARDS) { pr_err("gpib: invalid minor number of device file\n"); @@ -604,9 +610,9 @@ int ibclose(struct inode *inode, struct file *filep) long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg) { - unsigned int minor = iminor(filep->f_path.dentry->d_inode); + unsigned int minor = iminor(file_inode(filep)); struct gpib_board *board; - gpib_file_private_t *file_priv = filep->private_data; + struct gpib_file_private *file_priv = filep->private_data; long retval = -ENOTTY; if (minor >= GPIB_MAX_NUM_BOARDS) { @@ -665,8 +671,9 @@ long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg) retval = board_info_ioctl(board, arg); goto done; case IBMUTEX: - /* Need to unlock board->big_gpib_mutex before potentially locking board->user_mutex - * to maintain consistent locking order + /* + * Need to unlock board->big_gpib_mutex before potentially locking board->user_mutex + * to maintain consistent locking order */ mutex_unlock(&board->big_gpib_mutex); return mutex_ioctl(board, file_priv, arg); @@ -736,8 +743,9 @@ long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg) retval = take_control_ioctl(board, arg); goto done; case IBCMD: - /* IO ioctls can take a long time, we need to unlock board->big_gpib_mutex - * before we call them. + /* + * IO ioctls can take a long time, we need to unlock board->big_gpib_mutex + * before we call them. */ mutex_unlock(&board->big_gpib_mutex); return command_ioctl(file_priv, board, arg); @@ -760,8 +768,9 @@ long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg) retval = query_board_rsv_ioctl(board, arg); goto done; case IBRD: - /* IO ioctls can take a long time, we need to unlock board->big_gpib_mutex - * before we call them. + /* + * IO ioctls can take a long time, we need to unlock board->big_gpib_mutex + * before we call them. */ mutex_unlock(&board->big_gpib_mutex); return read_ioctl(file_priv, board, arg); @@ -790,8 +799,9 @@ long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg) retval = timeout_ioctl(board, arg); goto done; case IBWRT: - /* IO ioctls can take a long time, we need to unlock board->big_gpib_mutex - * before we call them. + /* + * IO ioctls can take a long time, we need to unlock board->big_gpib_mutex + * before we call them. */ mutex_unlock(&board->big_gpib_mutex); return write_ioctl(file_priv, board, arg); @@ -806,10 +816,11 @@ done: return retval; } -static int board_type_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, unsigned long arg) +static int board_type_ioctl(struct gpib_file_private *file_priv, + struct gpib_board *board, unsigned long arg) { struct list_head *list_ptr; - board_type_ioctl_t cmd; + struct gpib_board_type_ioctl cmd; int retval; if (!capable(CAP_SYS_ADMIN)) @@ -817,15 +828,16 @@ static int board_type_ioctl(gpib_file_private_t *file_priv, struct gpib_board *b if (board->online) return -EBUSY; - retval = copy_from_user(&cmd, (void __user *)arg, sizeof(board_type_ioctl_t)); + retval = copy_from_user(&cmd, (void __user *)arg, + sizeof(struct gpib_board_type_ioctl)); if (retval) - return retval; + return -EFAULT; for (list_ptr = registered_drivers.next; list_ptr != ®istered_drivers; list_ptr = list_ptr->next) { - gpib_interface_list_t *entry; + struct gpib_interface_list *entry; - entry = list_entry(list_ptr, gpib_interface_list_t, list); + entry = list_entry(list_ptr, struct gpib_interface_list, list); if (strcmp(entry->interface->name, cmd.name) == 0) { int i; int had_module = file_priv->got_module; @@ -857,16 +869,16 @@ static int board_type_ioctl(gpib_file_private_t *file_priv, struct gpib_board *b return -EINVAL; } -static int read_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, +static int read_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board, unsigned long arg) { - read_write_ioctl_t read_cmd; + struct gpib_read_write_ioctl read_cmd; u8 __user *userbuf; unsigned long remain; int end_flag = 0; int retval; ssize_t read_ret = 0; - gpib_descriptor_t *desc; + struct gpib_descriptor *desc; size_t nbytes; retval = copy_from_user(&read_cmd, (void __user *)arg, sizeof(read_cmd)); @@ -913,7 +925,8 @@ static int read_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, } read_cmd.completed_transfer_count = read_cmd.requested_transfer_count - remain; read_cmd.end = end_flag; - /* suppress errors (for example due to timeout or interruption by device clear) + /* + * suppress errors (for example due to timeout or interruption by device clear) * if all bytes got sent. This prevents races that can occur in the various drivers * if a device receives a device clear immediately after a transfer completes and * the driver code wasn't careful enough to handle that case. @@ -932,15 +945,15 @@ static int read_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, return read_ret; } -static int command_ioctl(gpib_file_private_t *file_priv, +static int command_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board, unsigned long arg) { - read_write_ioctl_t cmd; + struct gpib_read_write_ioctl cmd; u8 __user *userbuf; unsigned long remain; int retval; int fault = 0; - gpib_descriptor_t *desc; + struct gpib_descriptor *desc; size_t bytes_written; int no_clear_io_in_prog; @@ -967,10 +980,11 @@ static int command_ioctl(gpib_file_private_t *file_priv, if (!access_ok(userbuf, remain)) return -EFAULT; - /* Write buffer loads till we empty the user supplied buffer. - * Call drivers at least once, even if remain is zero, in - * order to allow them to insure previous commands were - * completely finished, in the case of a restarted ioctl. + /* + * Write buffer loads till we empty the user supplied buffer. + * Call drivers at least once, even if remain is zero, in + * order to allow them to insure previous commands were + * completely finished, in the case of a restarted ioctl. */ atomic_set(&desc->io_in_progress, 1); @@ -1016,15 +1030,15 @@ static int command_ioctl(gpib_file_private_t *file_priv, return retval; } -static int write_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, +static int write_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board, unsigned long arg) { - read_write_ioctl_t write_cmd; + struct gpib_read_write_ioctl write_cmd; u8 __user *userbuf; unsigned long remain; int retval = 0; int fault; - gpib_descriptor_t *desc; + struct gpib_descriptor *desc; fault = copy_from_user(&write_cmd, (void __user *)arg, sizeof(write_cmd)); if (fault) @@ -1068,7 +1082,8 @@ static int write_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, break; } write_cmd.completed_transfer_count = write_cmd.requested_transfer_count - remain; - /* suppress errors (for example due to timeout or interruption by device clear) + /* + * suppress errors (for example due to timeout or interruption by device clear) * if all bytes got sent. This prevents races that can occur in the various drivers * if a device receives a device clear immediately after a transfer completes and * the driver code wasn't careful enough to handle that case. @@ -1089,8 +1104,8 @@ static int write_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, static int status_bytes_ioctl(struct gpib_board *board, unsigned long arg) { - gpib_status_queue_t *device; - spoll_bytes_ioctl_t cmd; + struct gpib_status_queue *device; + struct gpib_spoll_bytes_ioctl cmd; int retval; retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)); @@ -1114,13 +1129,14 @@ static int increment_open_device_count(struct gpib_board *board, struct list_hea unsigned int pad, int sad) { struct list_head *list_ptr; - gpib_status_queue_t *device; + struct gpib_status_queue *device; - /* first see if address has already been opened, then increment + /* + * first see if address has already been opened, then increment * open count */ for (list_ptr = head->next; list_ptr != head; list_ptr = list_ptr->next) { - device = list_entry(list_ptr, gpib_status_queue_t, list); + device = list_entry(list_ptr, struct gpib_status_queue, list); if (gpib_address_equal(device->pad, device->sad, pad, sad)) { dev_dbg(board->gpib_dev, "incrementing open count for pad %i, sad %i\n", device->pad, device->sad); @@ -1129,8 +1145,8 @@ static int increment_open_device_count(struct gpib_board *board, struct list_hea } } - /* otherwise we need to allocate a new gpib_status_queue_t */ - device = kmalloc(sizeof(gpib_status_queue_t), GFP_ATOMIC); + /* otherwise we need to allocate a new struct gpib_status_queue */ + device = kmalloc(sizeof(struct gpib_status_queue), GFP_ATOMIC); if (!device) return -ENOMEM; init_gpib_status_queue(device); @@ -1148,11 +1164,11 @@ static int increment_open_device_count(struct gpib_board *board, struct list_hea static int subtract_open_device_count(struct gpib_board *board, struct list_head *head, unsigned int pad, int sad, unsigned int count) { - gpib_status_queue_t *device; + struct gpib_status_queue *device; struct list_head *list_ptr; for (list_ptr = head->next; list_ptr != head; list_ptr = list_ptr->next) { - device = list_entry(list_ptr, gpib_status_queue_t, list); + device = list_entry(list_ptr, struct gpib_status_queue, list); if (gpib_address_equal(device->pad, device->sad, pad, sad)) { dev_dbg(board->gpib_dev, "decrementing open count for pad %i, sad %i\n", device->pad, device->sad); @@ -1180,13 +1196,13 @@ static inline int decrement_open_device_count(struct gpib_board *board, struct l return subtract_open_device_count(board, head, pad, sad, 1); } -static int cleanup_open_devices(gpib_file_private_t *file_priv, struct gpib_board *board) +static int cleanup_open_devices(struct gpib_file_private *file_priv, struct gpib_board *board) { int retval = 0; int i; for (i = 0; i < GPIB_MAX_NUM_DESCRIPTORS; i++) { - gpib_descriptor_t *desc; + struct gpib_descriptor *desc; desc = file_priv->descriptors[i]; if (!desc) @@ -1207,9 +1223,9 @@ static int cleanup_open_devices(gpib_file_private_t *file_priv, struct gpib_boar static int open_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg) { - open_dev_ioctl_t open_dev_cmd; + struct gpib_open_dev_ioctl open_dev_cmd; int retval; - gpib_file_private_t *file_priv = filep->private_data; + struct gpib_file_private *file_priv = filep->private_data; int i; retval = copy_from_user(&open_dev_cmd, (void __user *)arg, sizeof(open_dev_cmd)); @@ -1225,7 +1241,7 @@ static int open_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned mutex_unlock(&file_priv->descriptors_mutex); return -ERANGE; } - file_priv->descriptors[i] = kmalloc(sizeof(gpib_descriptor_t), GFP_KERNEL); + file_priv->descriptors[i] = kmalloc(sizeof(struct gpib_descriptor), GFP_KERNEL); if (!file_priv->descriptors[i]) { mutex_unlock(&file_priv->descriptors_mutex); return -ENOMEM; @@ -1242,7 +1258,8 @@ static int open_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned if (retval < 0) return retval; - /* clear stuck srq state, since we may be able to find service request on + /* + * clear stuck srq state, since we may be able to find service request on * the new device */ atomic_set(&board->stuck_srq, 0); @@ -1257,8 +1274,8 @@ static int open_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned static int close_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg) { - close_dev_ioctl_t cmd; - gpib_file_private_t *file_priv = filep->private_data; + struct gpib_close_dev_ioctl cmd; + struct gpib_file_private *file_priv = filep->private_data; int retval; retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)); @@ -1284,7 +1301,7 @@ static int close_dev_ioctl(struct file *filep, struct gpib_board *board, unsigne static int serial_poll_ioctl(struct gpib_board *board, unsigned long arg) { - serial_poll_ioctl_t serial_cmd; + struct gpib_serial_poll_ioctl serial_cmd; int retval; retval = copy_from_user(&serial_cmd, (void __user *)arg, sizeof(serial_cmd)); @@ -1303,12 +1320,12 @@ static int serial_poll_ioctl(struct gpib_board *board, unsigned long arg) return 0; } -static int wait_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, +static int wait_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board, unsigned long arg) { - wait_ioctl_t wait_cmd; + struct gpib_wait_ioctl wait_cmd; int retval; - gpib_descriptor_t *desc; + struct gpib_descriptor *desc; retval = copy_from_user(&wait_cmd, (void __user *)arg, sizeof(wait_cmd)); if (retval) @@ -1348,7 +1365,7 @@ static int parallel_poll_ioctl(struct gpib_board *board, unsigned long arg) static int online_ioctl(struct gpib_board *board, unsigned long arg) { - online_ioctl_t online_cmd; + struct gpib_online_ioctl online_cmd; int retval; void __user *init_data = NULL; @@ -1430,12 +1447,12 @@ static int line_status_ioctl(struct gpib_board *board, unsigned long arg) return 0; } -static int pad_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv, +static int pad_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv, unsigned long arg) { - pad_ioctl_t cmd; + struct gpib_pad_ioctl cmd; int retval; - gpib_descriptor_t *desc; + struct gpib_descriptor *desc; retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)); if (retval) @@ -1466,12 +1483,12 @@ static int pad_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv, return 0; } -static int sad_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv, +static int sad_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv, unsigned long arg) { - sad_ioctl_t cmd; + struct gpib_sad_ioctl cmd; int retval; - gpib_descriptor_t *desc; + struct gpib_descriptor *desc; retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)); if (retval) @@ -1503,7 +1520,7 @@ static int sad_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv, static int eos_ioctl(struct gpib_board *board, unsigned long arg) { - eos_ioctl_t eos_cmd; + struct gpib_eos_ioctl eos_cmd; int retval; retval = copy_from_user(&eos_cmd, (void __user *)arg, sizeof(eos_cmd)); @@ -1527,11 +1544,11 @@ static int request_service_ioctl(struct gpib_board *board, unsigned long arg) static int request_service2_ioctl(struct gpib_board *board, unsigned long arg) { - request_service2_t request_service2_cmd; + struct gpib_request_service2 request_service2_cmd; int retval; retval = copy_from_user(&request_service2_cmd, (void __user *)arg, - sizeof(request_service2_t)); + sizeof(struct gpib_request_service2)); if (retval) return -EFAULT; @@ -1539,7 +1556,7 @@ static int request_service2_ioctl(struct gpib_board *board, unsigned long arg) request_service2_cmd.new_reason_for_service); } -static int iobase_ioctl(gpib_board_config_t *config, unsigned long arg) +static int iobase_ioctl(struct gpib_board_config *config, unsigned long arg) { u64 base_addr; int retval; @@ -1558,7 +1575,7 @@ static int iobase_ioctl(gpib_board_config_t *config, unsigned long arg) return 0; } -static int irq_ioctl(gpib_board_config_t *config, unsigned long arg) +static int irq_ioctl(struct gpib_board_config *config, unsigned long arg) { unsigned int irq; int retval; @@ -1575,7 +1592,7 @@ static int irq_ioctl(gpib_board_config_t *config, unsigned long arg) return 0; } -static int dma_ioctl(gpib_board_config_t *config, unsigned long arg) +static int dma_ioctl(struct gpib_board_config *config, unsigned long arg) { unsigned int dma_channel; int retval; @@ -1592,12 +1609,12 @@ static int dma_ioctl(gpib_board_config_t *config, unsigned long arg) return 0; } -static int autospoll_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv, +static int autospoll_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv, unsigned long arg) { - autospoll_ioctl_t enable; + short enable; int retval; - gpib_descriptor_t *desc; + struct gpib_descriptor *desc; retval = copy_from_user(&enable, (void __user *)arg, sizeof(enable)); if (retval) @@ -1630,7 +1647,7 @@ static int autospoll_ioctl(struct gpib_board *board, gpib_file_private_t *file_p return retval; } -static int mutex_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv, +static int mutex_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv, unsigned long arg) { int retval, lock_mutex; @@ -1687,7 +1704,7 @@ static int timeout_ioctl(struct gpib_board *board, unsigned long arg) static int ppc_ioctl(struct gpib_board *board, unsigned long arg) { - ppoll_config_ioctl_t cmd; + struct gpib_ppoll_config_ioctl cmd; int retval; retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)); @@ -1713,7 +1730,7 @@ static int ppc_ioctl(struct gpib_board *board, unsigned long arg) static int set_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long arg) { - local_ppoll_mode_ioctl_t cmd; + short cmd; int retval; retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)); @@ -1730,7 +1747,7 @@ static int set_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long ar static int get_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long arg) { - local_ppoll_mode_ioctl_t cmd; + short cmd; int retval; cmd = board->local_ppoll_mode; @@ -1757,7 +1774,7 @@ static int query_board_rsv_ioctl(struct gpib_board *board, unsigned long arg) static int board_info_ioctl(const struct gpib_board *board, unsigned long arg) { - board_info_ioctl_t info; + struct gpib_board_info_ioctl info = { }; int retval; info.pad = board->pad; @@ -1790,9 +1807,9 @@ static int interface_clear_ioctl(struct gpib_board *board, unsigned long arg) return ibsic(board, usec_duration); } -static int select_pci_ioctl(gpib_board_config_t *config, unsigned long arg) +static int select_pci_ioctl(struct gpib_board_config *config, unsigned long arg) { - select_pci_ioctl_t selection; + struct gpib_select_pci_ioctl selection; int retval; if (!capable(CAP_SYS_ADMIN)) @@ -1808,19 +1825,20 @@ static int select_pci_ioctl(gpib_board_config_t *config, unsigned long arg) return 0; } -static int select_device_path_ioctl(gpib_board_config_t *config, unsigned long arg) +static int select_device_path_ioctl(struct gpib_board_config *config, unsigned long arg) { - select_device_path_ioctl_t *selection; + struct gpib_select_device_path_ioctl *selection; int retval; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - selection = vmalloc(sizeof(select_device_path_ioctl_t)); + selection = vmalloc(sizeof(struct gpib_select_device_path_ioctl)); if (!selection) return -ENOMEM; - retval = copy_from_user(selection, (void __user *)arg, sizeof(select_device_path_ioctl_t)); + retval = copy_from_user(selection, (void __user *)arg, + sizeof(struct gpib_select_device_path_ioctl)); if (retval) { vfree(selection); return -EFAULT; @@ -1836,16 +1854,16 @@ static int select_device_path_ioctl(gpib_board_config_t *config, unsigned long a return 0; } -unsigned int num_gpib_events(const gpib_event_queue_t *queue) +unsigned int num_gpib_events(const struct gpib_event_queue *queue) { return queue->num_events; } static int push_gpib_event_nolock(struct gpib_board *board, short event_type) { - gpib_event_queue_t *queue = &board->event_queue; + struct gpib_event_queue *queue = &board->event_queue; struct list_head *head = &queue->event_head; - gpib_event_t *event; + struct gpib_event *event; static const unsigned int max_num_events = 1024; int retval; @@ -1858,7 +1876,7 @@ static int push_gpib_event_nolock(struct gpib_board *board, short event_type) return retval; } - event = kmalloc(sizeof(gpib_event_t), GFP_ATOMIC); + event = kmalloc(sizeof(struct gpib_event), GFP_ATOMIC); if (!event) { queue->dropped_event = 1; dev_err(board->gpib_dev, "failed to allocate memory for event\n"); @@ -1888,23 +1906,24 @@ int push_gpib_event(struct gpib_board *board, short event_type) retval = push_gpib_event_nolock(board, event_type); spin_unlock_irqrestore(&board->event_queue.lock, flags); - if (event_type == EventDevTrg) + if (event_type == EVENT_DEV_TRG) board->status |= DTAS; - if (event_type == EventDevClr) + if (event_type == EVENT_DEV_CLR) board->status |= DCAS; return retval; } EXPORT_SYMBOL(push_gpib_event); -static int pop_gpib_event_nolock(struct gpib_board *board, gpib_event_queue_t *queue, short *event_type) +static int pop_gpib_event_nolock(struct gpib_board *board, + struct gpib_event_queue *queue, short *event_type) { struct list_head *head = &queue->event_head; struct list_head *front = head->next; - gpib_event_t *event; + struct gpib_event *event; if (num_gpib_events(queue) == 0) { - *event_type = EventNone; + *event_type = EVENT_NONE; return 0; } @@ -1916,7 +1935,7 @@ static int pop_gpib_event_nolock(struct gpib_board *board, gpib_event_queue_t *q return -EPIPE; } - event = list_entry(front, gpib_event_t, list); + event = list_entry(front, struct gpib_event, list); *event_type = event->event_type; list_del(front); @@ -1931,7 +1950,7 @@ static int pop_gpib_event_nolock(struct gpib_board *board, gpib_event_queue_t *q } // pop event from front of event queue -int pop_gpib_event(struct gpib_board *board, gpib_event_queue_t *queue, short *event_type) +int pop_gpib_event(struct gpib_board *board, struct gpib_event_queue *queue, short *event_type) { unsigned long flags; int retval; @@ -1944,7 +1963,7 @@ int pop_gpib_event(struct gpib_board *board, gpib_event_queue_t *queue, short *e static int event_ioctl(struct gpib_board *board, unsigned long arg) { - event_ioctl_t user_event; + short user_event; int retval; short event; @@ -1963,21 +1982,19 @@ static int event_ioctl(struct gpib_board *board, unsigned long arg) static int request_system_control_ioctl(struct gpib_board *board, unsigned long arg) { - rsc_ioctl_t request_control; + int request_control; int retval; retval = copy_from_user(&request_control, (void __user *)arg, sizeof(request_control)); if (retval) return -EFAULT; - ibrsc(board, request_control); - - return 0; + return ibrsc(board, request_control); } static int t1_delay_ioctl(struct gpib_board *board, unsigned long arg) { - t1_delay_ioctl_t cmd; + unsigned int cmd; unsigned int delay; int retval; @@ -2011,7 +2028,7 @@ struct gpib_board board_array[GPIB_MAX_NUM_BOARDS]; LIST_HEAD(registered_drivers); -void init_gpib_descriptor(gpib_descriptor_t *desc) +void init_gpib_descriptor(struct gpib_descriptor *desc) { desc->pad = 0; desc->sad = -1; @@ -2020,9 +2037,9 @@ void init_gpib_descriptor(gpib_descriptor_t *desc) atomic_set(&desc->io_in_progress, 0); } -int gpib_register_driver(gpib_interface_t *interface, struct module *provider_module) +int gpib_register_driver(struct gpib_interface *interface, struct module *provider_module) { - struct gpib_interface_list_struct *entry; + struct gpib_interface_list *entry; entry = kmalloc(sizeof(*entry), GFP_KERNEL); if (!entry) @@ -2036,7 +2053,7 @@ int gpib_register_driver(gpib_interface_t *interface, struct module *provider_mo } EXPORT_SYMBOL(gpib_register_driver); -void gpib_unregister_driver(gpib_interface_t *interface) +void gpib_unregister_driver(struct gpib_interface *interface) { int i; struct list_head *list_ptr; @@ -2053,9 +2070,9 @@ void gpib_unregister_driver(gpib_interface_t *interface) } } for (list_ptr = registered_drivers.next; list_ptr != ®istered_drivers;) { - gpib_interface_list_t *entry; + struct gpib_interface_list *entry; - entry = list_entry(list_ptr, gpib_interface_list_t, list); + entry = list_entry(list_ptr, struct gpib_interface_list, list); list_ptr = list_ptr->next; if (entry->interface == interface) { list_del(&entry->list); @@ -2065,9 +2082,9 @@ void gpib_unregister_driver(gpib_interface_t *interface) } EXPORT_SYMBOL(gpib_unregister_driver); -static void init_gpib_board_config(gpib_board_config_t *config) +static void init_gpib_board_config(struct gpib_board_config *config) { - memset(config, 0, sizeof(gpib_board_config_t)); + memset(config, 0, sizeof(struct gpib_board_config)); config->pci_bus = -1; config->pci_slot = -1; } @@ -2143,7 +2160,7 @@ static void init_board_array(struct gpib_board *board_array, unsigned int length } } -void init_gpib_status_queue(gpib_status_queue_t *device) +void init_gpib_status_queue(struct gpib_status_queue *device) { INIT_LIST_HEAD(&device->list); INIT_LIST_HEAD(&device->status_bytes); @@ -2208,7 +2225,7 @@ int gpib_match_device_path(struct device *dev, const char *device_path_in) } EXPORT_SYMBOL(gpib_match_device_path); -struct pci_dev *gpib_pci_get_device(const gpib_board_config_t *config, unsigned int vendor_id, +struct pci_dev *gpib_pci_get_device(const struct gpib_board_config *config, unsigned int vendor_id, unsigned int device_id, struct pci_dev *from) { struct pci_dev *pci_device = from; @@ -2227,7 +2244,7 @@ struct pci_dev *gpib_pci_get_device(const gpib_board_config_t *config, unsigned } EXPORT_SYMBOL(gpib_pci_get_device); -struct pci_dev *gpib_pci_get_subsys(const gpib_board_config_t *config, unsigned int vendor_id, +struct pci_dev *gpib_pci_get_subsys(const struct gpib_board_config *config, unsigned int vendor_id, unsigned int device_id, unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from) diff --git a/drivers/staging/gpib/common/iblib.c b/drivers/staging/gpib/common/iblib.c index b297261818f2..549280d9a6e9 100644 --- a/drivers/staging/gpib/common/iblib.c +++ b/drivers/staging/gpib/common/iblib.c @@ -33,9 +33,10 @@ int ibcac(struct gpib_board *board, int sync, int fallback_to_async) return 0; if (sync && (status & LACS) == 0) - /* tcs (take control synchronously) can only possibly work when - * controller is listener. Error code also needs to be -ETIMEDOUT - * or it will giveout without doing fallback. + /* + * tcs (take control synchronously) can only possibly work when + * controller is listener. Error code also needs to be -ETIMEDOUT + * or it will giveout without doing fallback. */ retval = -ETIMEDOUT; else @@ -50,7 +51,8 @@ int ibcac(struct gpib_board *board, int sync, int fallback_to_async) return retval; } -/* After ATN is asserted, it should cause any connected devices +/* + * After ATN is asserted, it should cause any connected devices * to start listening for command bytes and leave acceptor idle state. * So if ATN is asserted and neither NDAC or NRFD are asserted, * then there are no devices and ibcmd should error out immediately. @@ -96,7 +98,7 @@ static int check_for_command_acceptors(struct gpib_board *board) * must be called to initialize the GPIB and enable * the interface to leave the controller idle state. */ -int ibcmd(struct gpib_board *board, uint8_t *buf, size_t length, size_t *bytes_written) +int ibcmd(struct gpib_board *board, u8 *buf, size_t length, size_t *bytes_written) { ssize_t ret = 0; int status; @@ -218,7 +220,8 @@ int ibonline(struct gpib_board *board) board->interface->detach(board); return retval; } - /* nios2nommu on 2.6.11 uclinux kernel has weird problems + /* + * nios2nommu on 2.6.11 uclinux kernel has weird problems * with autospoll thread causing huge slowdowns */ #ifndef CONFIG_NIOS2 @@ -297,7 +300,7 @@ int iblines(const struct gpib_board *board, short *lines) * calling ibcmd. */ -int ibrd(struct gpib_board *board, uint8_t *buf, size_t length, int *end_flag, size_t *nbytes) +int ibrd(struct gpib_board *board, u8 *buf, size_t length, int *end_flag, size_t *nbytes) { ssize_t ret = 0; int retval; @@ -313,7 +316,8 @@ int ibrd(struct gpib_board *board, uint8_t *buf, size_t length, int *end_flag, s if (retval < 0) return retval; } - /* XXX resetting timer here could cause timeouts take longer than they should, + /* + * XXX resetting timer here could cause timeouts take longer than they should, * since read_ioctl calls this * function in a loop, there is probably a similar problem with writes/commands */ @@ -343,7 +347,7 @@ ibrd_out: * 1. Prior to conducting the poll the interface is placed * in the controller active state. */ -int ibrpp(struct gpib_board *board, uint8_t *result) +int ibrpp(struct gpib_board *board, u8 *result) { int retval = 0; @@ -358,7 +362,7 @@ int ibrpp(struct gpib_board *board, uint8_t *result) return retval; } -int ibppc(struct gpib_board *board, uint8_t configuration) +int ibppc(struct gpib_board *board, u8 configuration) { configuration &= 0x1f; board->interface->parallel_poll_configure(board, configuration); @@ -367,7 +371,7 @@ int ibppc(struct gpib_board *board, uint8_t configuration) return 0; } -int ibrsv2(struct gpib_board *board, uint8_t status_byte, int new_reason_for_service) +int ibrsv2(struct gpib_board *board, u8 status_byte, int new_reason_for_service) { int board_status = ibstatus(board); const unsigned int MSS = status_byte & request_service_bit; @@ -418,12 +422,21 @@ int ibsic(struct gpib_board *board, unsigned int usec_duration) return 0; } - /* FIXME make int */ -void ibrsc(struct gpib_board *board, int request_control) +int ibrsc(struct gpib_board *board, int request_control) { + int retval; + + if (!board->interface->request_system_control) + return -EPERM; + + retval = board->interface->request_system_control(board, request_control); + + if (retval) + return retval; + board->master = request_control != 0; - if (board->interface->request_system_control) - board->interface->request_system_control(board, request_control); + + return 0; } /* @@ -506,15 +519,16 @@ int ibstatus(struct gpib_board *board) return general_ibstatus(board, NULL, 0, 0, NULL); } -int general_ibstatus(struct gpib_board *board, const gpib_status_queue_t *device, - int clear_mask, int set_mask, gpib_descriptor_t *desc) +int general_ibstatus(struct gpib_board *board, const struct gpib_status_queue *device, + int clear_mask, int set_mask, struct gpib_descriptor *desc) { int status = 0; short line_status; if (board->private_data) { status = board->interface->update_status(board, clear_mask); - /* XXX should probably stop having drivers use TIMO bit in + /* + * XXX should probably stop having drivers use TIMO bit in * board->status to avoid confusion */ status &= ~TIMO; @@ -560,7 +574,7 @@ struct wait_info { static void wait_timeout(struct timer_list *t) { - struct wait_info *winfo = from_timer(winfo, t, timer); + struct wait_info *winfo = timer_container_of(winfo, t, timer); winfo->timed_out = 1; wake_up_interruptible(&winfo->board->wait); @@ -573,8 +587,8 @@ static void init_wait_info(struct wait_info *winfo) timer_setup_on_stack(&winfo->timer, wait_timeout, 0); } -static int wait_satisfied(struct wait_info *winfo, gpib_status_queue_t *status_queue, - int wait_mask, int *status, gpib_descriptor_t *desc) +static int wait_satisfied(struct wait_info *winfo, struct gpib_status_queue *status_queue, + int wait_mask, int *status, struct gpib_descriptor *desc) { struct gpib_board *board = winfo->board; int temp_status; @@ -611,7 +625,7 @@ static void start_wait_timer(struct wait_info *winfo) static void remove_wait_timer(struct wait_info *winfo) { timer_delete_sync(&winfo->timer); - destroy_timer_on_stack(&winfo->timer); + timer_destroy_on_stack(&winfo->timer); } /* @@ -623,10 +637,10 @@ static void remove_wait_timer(struct wait_info *winfo) * no condition is waited for. */ int ibwait(struct gpib_board *board, int wait_mask, int clear_mask, int set_mask, - int *status, unsigned long usec_timeout, gpib_descriptor_t *desc) + int *status, unsigned long usec_timeout, struct gpib_descriptor *desc) { int retval = 0; - gpib_status_queue_t *status_queue; + struct gpib_status_queue *status_queue; struct wait_info winfo; if (desc->is_board) @@ -677,7 +691,7 @@ int ibwait(struct gpib_board *board, int wait_mask, int clear_mask, int set_mask * well as the interface board itself must be * addressed by calling ibcmd. */ -int ibwrt(struct gpib_board *board, uint8_t *buf, size_t cnt, int send_eoi, size_t *bytes_written) +int ibwrt(struct gpib_board *board, u8 *buf, size_t cnt, int send_eoi, size_t *bytes_written) { int ret = 0; int retval; diff --git a/drivers/staging/gpib/common/ibsys.h b/drivers/staging/gpib/common/ibsys.h index 19960af809c2..e5a148f513a8 100644 --- a/drivers/staging/gpib/common/ibsys.h +++ b/drivers/staging/gpib/common/ibsys.h @@ -22,10 +22,13 @@ int gpib_allocate_board(struct gpib_board *board); void gpib_deallocate_board(struct gpib_board *board); -unsigned int num_status_bytes(const gpib_status_queue_t *dev); -int push_status_byte(struct gpib_board *board, gpib_status_queue_t *device, uint8_t poll_byte); -int pop_status_byte(struct gpib_board *board, gpib_status_queue_t *device, uint8_t *poll_byte); -gpib_status_queue_t *get_gpib_status_queue(struct gpib_board *board, unsigned int pad, int sad); +unsigned int num_status_bytes(const struct gpib_status_queue *dev); +int push_status_byte(struct gpib_board *board, struct gpib_status_queue *device, + u8 poll_byte); +int pop_status_byte(struct gpib_board *board, struct gpib_status_queue *device, + u8 *poll_byte); +struct gpib_status_queue *get_gpib_status_queue(struct gpib_board *board, + unsigned int pad, int sad); int get_serial_poll_byte(struct gpib_board *board, unsigned int pad, int sad, - unsigned int usec_timeout, uint8_t *poll_byte); + unsigned int usec_timeout, u8 *poll_byte); int autopoll_all_devices(struct gpib_board *board); diff --git a/drivers/staging/gpib/eastwood/fluke_gpib.c b/drivers/staging/gpib/eastwood/fluke_gpib.c index a6b1ac169f94..491356433249 100644 --- a/drivers/staging/gpib/eastwood/fluke_gpib.c +++ b/drivers/staging/gpib/eastwood/fluke_gpib.c @@ -24,15 +24,17 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("GPIB Driver for Fluke cda devices"); -static int fluke_attach_holdoff_all(struct gpib_board *board, const gpib_board_config_t *config); -static int fluke_attach_holdoff_end(struct gpib_board *board, const gpib_board_config_t *config); +static int fluke_attach_holdoff_all(struct gpib_board *board, + const struct gpib_board_config *config); +static int fluke_attach_holdoff_end(struct gpib_board *board, + const struct gpib_board_config *config); static void fluke_detach(struct gpib_board *board); static int fluke_config_dma(struct gpib_board *board, int output); static irqreturn_t fluke_gpib_internal_interrupt(struct gpib_board *board); static struct platform_device *fluke_gpib_pdev; -static uint8_t fluke_locking_read_byte(struct nec7210_priv *nec_priv, unsigned int register_number) +static u8 fluke_locking_read_byte(struct nec7210_priv *nec_priv, unsigned int register_number) { u8 retval; unsigned long flags; @@ -43,7 +45,7 @@ static uint8_t fluke_locking_read_byte(struct nec7210_priv *nec_priv, unsigned i return retval; } -static void fluke_locking_write_byte(struct nec7210_priv *nec_priv, uint8_t byte, +static void fluke_locking_write_byte(struct nec7210_priv *nec_priv, u8 byte, unsigned int register_number) { unsigned long flags; @@ -54,7 +56,7 @@ static void fluke_locking_write_byte(struct nec7210_priv *nec_priv, uint8_t byte } // wrappers for interface functions -static int fluke_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end, +static int fluke_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct fluke_priv *priv = board->private_data; @@ -62,7 +64,7 @@ static int fluke_read(struct gpib_board *board, uint8_t *buffer, size_t length, return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); } -static int fluke_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fluke_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct fluke_priv *priv = board->private_data; @@ -70,7 +72,7 @@ static int fluke_write(struct gpib_board *board, uint8_t *buffer, size_t length, return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); } -static int fluke_command(struct gpib_board *board, uint8_t *buffer, +static int fluke_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { struct fluke_priv *priv = board->private_data; @@ -92,12 +94,12 @@ static int fluke_go_to_standby(struct gpib_board *board) return nec7210_go_to_standby(board, &priv->nec7210_priv); } -static void fluke_request_system_control(struct gpib_board *board, int request_control) +static int fluke_request_system_control(struct gpib_board *board, int request_control) { struct fluke_priv *priv = board->private_data; struct nec7210_priv *nec_priv = &priv->nec7210_priv; - nec7210_request_system_control(board, nec_priv, request_control); + return nec7210_request_system_control(board, nec_priv, request_control); } static void fluke_interface_clear(struct gpib_board *board, int assert) @@ -114,7 +116,7 @@ static void fluke_remote_enable(struct gpib_board *board, int enable) nec7210_remote_enable(board, &priv->nec7210_priv, enable); } -static int fluke_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits) +static int fluke_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct fluke_priv *priv = board->private_data; @@ -149,14 +151,14 @@ static int fluke_secondary_address(struct gpib_board *board, unsigned int addres return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); } -static int fluke_parallel_poll(struct gpib_board *board, uint8_t *result) +static int fluke_parallel_poll(struct gpib_board *board, u8 *result) { struct fluke_priv *priv = board->private_data; return nec7210_parallel_poll(board, &priv->nec7210_priv, result); } -static void fluke_parallel_poll_configure(struct gpib_board *board, uint8_t configuration) +static void fluke_parallel_poll_configure(struct gpib_board *board, u8 configuration) { struct fluke_priv *priv = board->private_data; @@ -170,14 +172,14 @@ static void fluke_parallel_poll_response(struct gpib_board *board, int ist) nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); } -static void fluke_serial_poll_response(struct gpib_board *board, uint8_t status) +static void fluke_serial_poll_response(struct gpib_board *board, u8 status) { struct fluke_priv *priv = board->private_data; nec7210_serial_poll_response(board, &priv->nec7210_priv, status); } -static uint8_t fluke_serial_poll_status(struct gpib_board *board) +static u8 fluke_serial_poll_status(struct gpib_board *board) { struct fluke_priv *priv = board->private_data; @@ -254,7 +256,8 @@ static int lacs_or_read_ready(struct gpib_board *board) return retval; } -/* Wait until it is possible for a read to do something useful. This +/* + * Wait until it is possible for a read to do something useful. This * is not essential, it only exists to prevent RFD holdoff from being released pointlessly. */ static int wait_for_read(struct gpib_board *board) @@ -276,7 +279,8 @@ static int wait_for_read(struct gpib_board *board) return retval; } -/* Check if the SH state machine is in SGNS. We check twice since there is a very small chance +/* + * Check if the SH state machine is in SGNS. We check twice since there is a very small chance * we could be blowing through SGNS from SIDS to SDYS if there is already a * byte available in the handshake state machine. We are interested * in the case where the handshake is stuck in SGNS due to no byte being @@ -310,7 +314,8 @@ static int source_handshake_is_sids_or_sgns(struct fluke_priv *e_priv) (source_handshake_bits == SOURCE_HANDSHAKE_SIDS_BITS); } -/* Wait until the gpib chip is ready to accept a data out byte. +/* + * Wait until the gpib chip is ready to accept a data out byte. * If the chip is SGNS it is probably waiting for a a byte to * be written to it. */ @@ -371,7 +376,7 @@ static void fluke_dma_callback(void *arg) spin_unlock_irqrestore(&board->spinlock, flags); } -static int fluke_dma_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fluke_dma_write(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { struct fluke_priv *e_priv = board->private_data; @@ -441,7 +446,8 @@ static int fluke_dma_write(struct gpib_board *board, uint8_t *buffer, size_t len if (test_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state)) fluke_dma_callback(board); - /* if everything went fine, try to wait until last byte is actually + /* + * if everything went fine, try to wait until last byte is actually * transmitted across gpib (but don't try _too_ hard) */ if (retval == 0) @@ -456,7 +462,7 @@ cleanup: return retval; } -static int fluke_accel_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fluke_accel_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct fluke_priv *e_priv = board->private_data; @@ -508,7 +514,8 @@ static int fluke_accel_write(struct gpib_board *board, uint8_t *buffer, size_t l if (WARN_ON_ONCE(remainder != 1)) return -EFAULT; - /* wait until we are sure we will be able to write the data byte + /* + * wait until we are sure we will be able to write the data byte * into the chip before we send AUX_SEOI. This prevents a timeout * scenerio where we send AUX_SEOI but then timeout without getting * any bytes into the gpib chip. This will result in the first byte @@ -539,12 +546,14 @@ static int fluke_get_dma_residue(struct dma_chan *chan, dma_cookie_t cookie) return result; } dmaengine_tx_status(chan, cookie, &state); - // hardware doesn't support resume, so dont call this - // method unless the dma transfer is done. + /* + * hardware doesn't support resume, so dont call this + * method unless the dma transfer is done. + */ return state.residue; } -static int fluke_dma_read(struct gpib_board *board, uint8_t *buffer, +static int fluke_dma_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct fluke_priv *e_priv = board->private_data; @@ -608,7 +617,8 @@ static int fluke_dma_read(struct gpib_board *board, uint8_t *buffer, if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) retval = -EINTR; - /* If we woke up because of end, wait until the dma transfer has pulled + /* + * If we woke up because of end, wait until the dma transfer has pulled * the data byte associated with the end before we cancel the dma transfer. */ if (test_bit(RECEIVED_END_BN, &nec_priv->state)) { @@ -625,7 +635,8 @@ static int fluke_dma_read(struct gpib_board *board, uint8_t *buffer, // stop the dma transfer nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); - /* delay a little just to make sure any bytes in dma controller's fifo get + /* + * delay a little just to make sure any bytes in dma controller's fifo get * written to memory before we disable it */ usleep_range(10, 15); @@ -641,14 +652,17 @@ static int fluke_dma_read(struct gpib_board *board, uint8_t *buffer, dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE); memcpy(buffer, e_priv->dma_buffer, *bytes_read); - /* If we got an end interrupt, figure out if it was + /* + * If we got an end interrupt, figure out if it was * associated with the last byte we dma'd or with a * byte still sitting on the cb7210. */ spin_lock_irqsave(&board->spinlock, flags); if (test_bit(READ_READY_BN, &nec_priv->state) == 0) { - // There is no byte sitting on the cb7210. If we - // saw an end interrupt, we need to deal with it now + /* + * There is no byte sitting on the cb7210. If we + * saw an end interrupt, we need to deal with it now + */ if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state)) *end = 1; } @@ -657,7 +671,7 @@ static int fluke_dma_read(struct gpib_board *board, uint8_t *buffer, return retval; } -static int fluke_accel_read(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fluke_accel_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct fluke_priv *e_priv = board->private_data; @@ -698,7 +712,7 @@ static int fluke_accel_read(struct gpib_board *board, uint8_t *buffer, size_t le return retval; } -static gpib_interface_t fluke_unaccel_interface = { +static struct gpib_interface fluke_unaccel_interface = { .name = "fluke_unaccel", .attach = fluke_attach_holdoff_all, .detach = fluke_detach, @@ -725,7 +739,8 @@ static gpib_interface_t fluke_unaccel_interface = { .return_to_local = fluke_return_to_local, }; -/* fluke_hybrid uses dma for writes but not for reads. Added +/* + * fluke_hybrid uses dma for writes but not for reads. Added * to deal with occasional corruption of bytes seen when doing dma * reads. From looking at the cb7210 vhdl, I believe the corruption * is due to a hardware bug triggered by the cpu reading a cb7210 @@ -733,7 +748,7 @@ static gpib_interface_t fluke_unaccel_interface = { * register just as the dma controller is also doing a read. */ -static gpib_interface_t fluke_hybrid_interface = { +static struct gpib_interface fluke_hybrid_interface = { .name = "fluke_hybrid", .attach = fluke_attach_holdoff_all, .detach = fluke_detach, @@ -760,7 +775,7 @@ static gpib_interface_t fluke_hybrid_interface = { .return_to_local = fluke_return_to_local, }; -static gpib_interface_t fluke_interface = { +static struct gpib_interface fluke_interface = { .name = "fluke", .attach = fluke_attach_holdoff_end, .detach = fluke_detach, @@ -802,7 +817,7 @@ irqreturn_t fluke_gpib_internal_interrupt(struct gpib_board *board) status2 = read_byte(nec_priv, ISR2); if (status0 & FLUKE_IFCI_BIT) { - push_gpib_event(board, EventIFC); + push_gpib_event(board, EVENT_IFC); retval = IRQ_HANDLED; } @@ -914,7 +929,8 @@ static int fluke_init(struct fluke_priv *e_priv, struct gpib_board *board, int h nec7210_board_reset(nec_priv, board); write_byte(nec_priv, AUX_LO_SPEED, AUXMR); - /* set clock register for driving frequency + /* + * set clock register for driving frequency * ICR should be set to clock in megahertz (1-15) and to zero * for clocks faster than 15 MHz (max 20MHz) */ @@ -933,7 +949,8 @@ static int fluke_init(struct fluke_priv *e_priv, struct gpib_board *board, int h return 0; } -/* This function is passed to dma_request_channel() in order to +/* + * This function is passed to dma_request_channel() in order to * select the pl330 dma channel which has been hardwired to * the gpib controller. */ @@ -943,7 +960,7 @@ static bool gpib_dma_channel_filter(struct dma_chan *chan, void *filter_param) return chan->chan_id == 0; } -static int fluke_attach_impl(struct gpib_board *board, const gpib_board_config_t *config, +static int fluke_attach_impl(struct gpib_board *board, const struct gpib_board_config *config, unsigned int handshake_mode) { struct fluke_priv *e_priv; @@ -1024,10 +1041,8 @@ static int fluke_attach_impl(struct gpib_board *board, const gpib_board_config_t } irq = platform_get_irq(fluke_gpib_pdev, 0); - if (irq < 0) { - dev_err(&fluke_gpib_pdev->dev, "failed to obtain IRQ\n"); + if (irq < 0) return -EBUSY; - } retval = request_irq(irq, fluke_gpib_interrupt, isr_flags, fluke_gpib_pdev->name, board); if (retval) { dev_err(&fluke_gpib_pdev->dev, @@ -1042,19 +1057,21 @@ static int fluke_attach_impl(struct gpib_board *board, const gpib_board_config_t e_priv->dma_channel = dma_request_channel(dma_cap, gpib_dma_channel_filter, NULL); if (!e_priv->dma_channel) { dev_err(board->gpib_dev, "failed to allocate a dma channel.\n"); - // we don't error out here because unaccel interface will still - // work without dma + /* + * we don't error out here because unaccel interface will still + * work without dma + */ } return fluke_init(e_priv, board, handshake_mode); } -int fluke_attach_holdoff_all(struct gpib_board *board, const gpib_board_config_t *config) +int fluke_attach_holdoff_all(struct gpib_board *board, const struct gpib_board_config *config) { return fluke_attach_impl(board, config, HR_HLDA); } -int fluke_attach_holdoff_end(struct gpib_board *board, const gpib_board_config_t *config) +int fluke_attach_holdoff_end(struct gpib_board *board, const struct gpib_board_config *config) { return fluke_attach_impl(board, config, HR_HLDE); } diff --git a/drivers/staging/gpib/eastwood/fluke_gpib.h b/drivers/staging/gpib/eastwood/fluke_gpib.h index 3e4348196b42..493c200d0bbf 100644 --- a/drivers/staging/gpib/eastwood/fluke_gpib.h +++ b/drivers/staging/gpib/eastwood/fluke_gpib.h @@ -55,8 +55,10 @@ enum state1_bits { SOURCE_HANDSHAKE_MASK = 0x7 }; -// we customized the cb7210 vhdl to give the "data in" status -// on the unused bit 7 of the address0 register. +/* + * we customized the cb7210 vhdl to give the "data in" status + * on the unused bit 7 of the address0 register. + */ enum cb7210_address0 { DATA_IN_STATUS = 0x80 }; @@ -67,8 +69,8 @@ static inline int cb7210_page_in_bits(unsigned int page) } // don't use without locking nec_priv->register_page_lock -static inline uint8_t fluke_read_byte_nolock(struct nec7210_priv *nec_priv, - int register_num) +static inline u8 fluke_read_byte_nolock(struct nec7210_priv *nec_priv, + int register_num) { u8 retval; @@ -77,14 +79,14 @@ static inline uint8_t fluke_read_byte_nolock(struct nec7210_priv *nec_priv, } // don't use without locking nec_priv->register_page_lock -static inline void fluke_write_byte_nolock(struct nec7210_priv *nec_priv, uint8_t data, +static inline void fluke_write_byte_nolock(struct nec7210_priv *nec_priv, u8 data, int register_num) { writel(data, nec_priv->mmiobase + register_num * nec_priv->offset); } -static inline uint8_t fluke_paged_read_byte(struct fluke_priv *e_priv, - unsigned int register_num, unsigned int page) +static inline u8 fluke_paged_read_byte(struct fluke_priv *e_priv, + unsigned int register_num, unsigned int page) { struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; u8 retval; @@ -99,7 +101,7 @@ static inline uint8_t fluke_paged_read_byte(struct fluke_priv *e_priv, return retval; } -static inline void fluke_paged_write_byte(struct fluke_priv *e_priv, uint8_t data, +static inline void fluke_paged_write_byte(struct fluke_priv *e_priv, u8 data, unsigned int register_num, unsigned int page) { struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; @@ -124,11 +126,12 @@ enum bus_status_bits { }; enum cb7210_aux_cmds { -/* AUX_RTL2 is an undocumented aux command which causes cb7210 to assert - * (and keep asserted) local rtl message. This is used in conjunction - * with the (stupid) cb7210 implementation - * of the normal nec7210 AUX_RTL aux command, which - * causes the rtl message to toggle between on and off. +/* + * AUX_RTL2 is an undocumented aux command which causes cb7210 to assert + * (and keep asserted) local rtl message. This is used in conjunction + * with the (stupid) cb7210 implementation + * of the normal nec7210 AUX_RTL aux command, which + * causes the rtl message to toggle between on and off. */ AUX_RTL2 = 0xd, AUX_NBAF = 0xe, // new byte available false (also clears seoi) diff --git a/drivers/staging/gpib/fmh_gpib/fmh_gpib.c b/drivers/staging/gpib/fmh_gpib/fmh_gpib.c index 53f4b3fccc3c..4138f3d2bae7 100644 --- a/drivers/staging/gpib/fmh_gpib/fmh_gpib.c +++ b/drivers/staging/gpib/fmh_gpib/fmh_gpib.c @@ -32,13 +32,15 @@ MODULE_DESCRIPTION("GPIB Driver for fmh_gpib_core"); MODULE_AUTHOR("Frank Mori Hess <fmh6jj@gmail.com>"); static irqreturn_t fmh_gpib_interrupt(int irq, void *arg); -static int fmh_gpib_attach_holdoff_all(struct gpib_board *board, const gpib_board_config_t *config); -static int fmh_gpib_attach_holdoff_end(struct gpib_board *board, const gpib_board_config_t *config); +static int fmh_gpib_attach_holdoff_all(struct gpib_board *board, + const struct gpib_board_config *config); +static int fmh_gpib_attach_holdoff_end(struct gpib_board *board, + const struct gpib_board_config *config); static void fmh_gpib_detach(struct gpib_board *board); static int fmh_gpib_pci_attach_holdoff_all(struct gpib_board *board, - const gpib_board_config_t *config); + const struct gpib_board_config *config); static int fmh_gpib_pci_attach_holdoff_end(struct gpib_board *board, - const gpib_board_config_t *config); + const struct gpib_board_config *config); static void fmh_gpib_pci_detach(struct gpib_board *board); static int fmh_gpib_config_dma(struct gpib_board *board, int output); static irqreturn_t fmh_gpib_internal_interrupt(struct gpib_board *board); @@ -46,7 +48,7 @@ static struct platform_driver fmh_gpib_platform_driver; static struct pci_driver fmh_gpib_pci_driver; // wrappers for interface functions -static int fmh_gpib_read(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fmh_gpib_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct fmh_priv *priv = board->private_data; @@ -54,7 +56,7 @@ static int fmh_gpib_read(struct gpib_board *board, uint8_t *buffer, size_t lengt return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); } -static int fmh_gpib_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fmh_gpib_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct fmh_priv *priv = board->private_data; @@ -62,7 +64,7 @@ static int fmh_gpib_write(struct gpib_board *board, uint8_t *buffer, size_t leng return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); } -static int fmh_gpib_command(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fmh_gpib_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { struct fmh_priv *priv = board->private_data; @@ -84,12 +86,12 @@ static int fmh_gpib_go_to_standby(struct gpib_board *board) return nec7210_go_to_standby(board, &priv->nec7210_priv); } -static void fmh_gpib_request_system_control(struct gpib_board *board, int request_control) +static int fmh_gpib_request_system_control(struct gpib_board *board, int request_control) { struct fmh_priv *priv = board->private_data; struct nec7210_priv *nec_priv = &priv->nec7210_priv; - nec7210_request_system_control(board, nec_priv, request_control); + return nec7210_request_system_control(board, nec_priv, request_control); } static void fmh_gpib_interface_clear(struct gpib_board *board, int assert) @@ -106,7 +108,7 @@ static void fmh_gpib_remote_enable(struct gpib_board *board, int enable) nec7210_remote_enable(board, &priv->nec7210_priv, enable); } -static int fmh_gpib_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits) +static int fmh_gpib_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct fmh_priv *priv = board->private_data; @@ -141,14 +143,14 @@ static int fmh_gpib_secondary_address(struct gpib_board *board, unsigned int add return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); } -static int fmh_gpib_parallel_poll(struct gpib_board *board, uint8_t *result) +static int fmh_gpib_parallel_poll(struct gpib_board *board, u8 *result) { struct fmh_priv *priv = board->private_data; return nec7210_parallel_poll(board, &priv->nec7210_priv, result); } -static void fmh_gpib_parallel_poll_configure(struct gpib_board *board, uint8_t configuration) +static void fmh_gpib_parallel_poll_configure(struct gpib_board *board, u8 configuration) { struct fmh_priv *priv = board->private_data; @@ -169,7 +171,8 @@ static void fmh_gpib_local_parallel_poll_mode(struct gpib_board *board, int loca if (local) { write_byte(&priv->nec7210_priv, AUX_I_REG | LOCAL_PPOLL_MODE_BIT, AUXMR); } else { - /* For fmh_gpib_core, remote parallel poll config mode is unaffected by the + /* + * For fmh_gpib_core, remote parallel poll config mode is unaffected by the * state of the disable bit of the parallel poll register (unlike the tnt4882). * So, we don't need to worry about that. */ @@ -177,7 +180,7 @@ static void fmh_gpib_local_parallel_poll_mode(struct gpib_board *board, int loca } } -static void fmh_gpib_serial_poll_response2(struct gpib_board *board, uint8_t status, +static void fmh_gpib_serial_poll_response2(struct gpib_board *board, u8 status, int new_reason_for_service) { struct fmh_priv *priv = board->private_data; @@ -195,7 +198,8 @@ static void fmh_gpib_serial_poll_response2(struct gpib_board *board, uint8_t sta } if (reqt) { - /* It may seem like a race to issue reqt before updating + /* + * It may seem like a race to issue reqt before updating * the status byte, but it is not. The chip does not * issue the reqt until the SPMR is written to at * a later time. @@ -204,7 +208,8 @@ static void fmh_gpib_serial_poll_response2(struct gpib_board *board, uint8_t sta } else if (reqf) { write_byte(&priv->nec7210_priv, AUX_REQF, AUXMR); } - /* We need to always zero bit 6 of the status byte before writing it to + /* + * We need to always zero bit 6 of the status byte before writing it to * the SPMR to insure we are using * serial poll mode SP1, and not accidentally triggering mode SP3. */ @@ -212,7 +217,7 @@ static void fmh_gpib_serial_poll_response2(struct gpib_board *board, uint8_t sta spin_unlock_irqrestore(&board->spinlock, flags); } -static uint8_t fmh_gpib_serial_poll_status(struct gpib_board *board) +static u8 fmh_gpib_serial_poll_status(struct gpib_board *board) { struct fmh_priv *priv = board->private_data; @@ -333,7 +338,8 @@ static int wait_for_rx_fifo_half_full_or_end(struct gpib_board *board) return retval; } -/* Wait until the gpib chip is ready to accept a data out byte. +/* + * Wait until the gpib chip is ready to accept a data out byte. */ static int wait_for_data_out_ready(struct gpib_board *board) { @@ -377,7 +383,8 @@ static void fmh_gpib_dma_callback(void *arg) spin_unlock_irqrestore(&board->spinlock, flags); } -/* returns true when all the bytes of a write have been transferred to +/* + * returns true when all the bytes of a write have been transferred to * the chip and successfully transferred out over the gpib bus. */ static int fmh_gpib_all_bytes_are_sent(struct fmh_priv *e_priv) @@ -391,7 +398,7 @@ static int fmh_gpib_all_bytes_are_sent(struct fmh_priv *e_priv) return 1; } -static int fmh_gpib_dma_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fmh_gpib_dma_write(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { struct fmh_priv *e_priv = board->private_data; @@ -469,7 +476,7 @@ cleanup: return retval; } -static int fmh_gpib_accel_write(struct gpib_board *board, uint8_t *buffer, +static int fmh_gpib_accel_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct fmh_priv *e_priv = board->private_data; @@ -523,7 +530,8 @@ static int fmh_gpib_accel_write(struct gpib_board *board, uint8_t *buffer, if (WARN_ON_ONCE(remainder != 1)) return -EFAULT; - /* wait until we are sure we will be able to write the data byte + /* + * wait until we are sure we will be able to write the data byte * into the chip before we send AUX_SEOI. This prevents a timeout * scenario where we send AUX_SEOI but then timeout without getting * any bytes into the gpib chip. This will result in the first byte @@ -554,8 +562,10 @@ static int fmh_gpib_get_dma_residue(struct dma_chan *chan, dma_cookie_t cookie) return result; } dmaengine_tx_status(chan, cookie, &state); - // dma330 hardware doesn't support resume, so dont call this - // method unless the dma transfer is done. + /* + * dma330 hardware doesn't support resume, so dont call this + * method unless the dma transfer is done. + */ return state.residue; } @@ -581,10 +591,11 @@ static int wait_for_tx_fifo_half_empty(struct gpib_board *board) return retval; } -/* supports writing a chunk of data whose length must fit into the hardware'd xfer counter, +/* + * supports writing a chunk of data whose length must fit into the hardware'd xfer counter, * called in a loop by fmh_gpib_fifo_write() */ -static int fmh_gpib_fifo_write_countable(struct gpib_board *board, uint8_t *buffer, +static int fmh_gpib_fifo_write_countable(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct fmh_priv *e_priv = board->private_data; @@ -650,7 +661,7 @@ cleanup: return retval; } -static int fmh_gpib_fifo_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fmh_gpib_fifo_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct fmh_priv *e_priv = board->private_data; @@ -697,7 +708,7 @@ static int fmh_gpib_fifo_write(struct gpib_board *board, uint8_t *buffer, size_t return retval; } -static int fmh_gpib_dma_read(struct gpib_board *board, uint8_t *buffer, +static int fmh_gpib_dma_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct fmh_priv *e_priv = board->private_data; @@ -768,8 +779,10 @@ static int fmh_gpib_dma_read(struct gpib_board *board, uint8_t *buffer, // stop the dma transfer nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG); - // give time for pl330 to transfer any in-flight data, since - // pl330 will throw it away when dmaengine_pause is called. + /* + * give time for pl330 to transfer any in-flight data, since + * pl330 will throw it away when dmaengine_pause is called. + */ usleep_range(10, 15); residue = fmh_gpib_get_dma_residue(e_priv->dma_channel, dma_cookie); if (WARN_ON_ONCE(residue > length || residue < 0)) @@ -793,14 +806,17 @@ static int fmh_gpib_dma_read(struct gpib_board *board, uint8_t *buffer, buffer[(*bytes_read)++] = fifos_read(e_priv, FIFO_DATA_REG) & fifo_data_mask; } - /* If we got an end interrupt, figure out if it was + /* + * If we got an end interrupt, figure out if it was * associated with the last byte we dma'd or with a * byte still sitting on the cb7210. */ spin_lock_irqsave(&board->spinlock, flags); if (*bytes_read > 0 && test_bit(READ_READY_BN, &nec_priv->state) == 0) { - // If there is no byte sitting on the cb7210 and we - // saw an end, we need to deal with it now + /* + * If there is no byte sitting on the cb7210 and we + * saw an end, we need to deal with it now + */ if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state)) *end = 1; } @@ -819,7 +835,8 @@ static void fmh_gpib_release_rfd_holdoff(struct gpib_board *board, struct fmh_pr ext_status_1 = read_byte(nec_priv, EXT_STATUS_1_REG); - /* if there is an end byte sitting on the chip, don't release + /* + * if there is an end byte sitting on the chip, don't release * holdoff. We want it left set after we read out the end * byte. */ @@ -828,7 +845,8 @@ static void fmh_gpib_release_rfd_holdoff(struct gpib_board *board, struct fmh_pr if (ext_status_1 & RFD_HOLDOFF_STATUS_BIT) write_byte(nec_priv, AUX_FH, AUXMR); - /* Check if an end byte raced in before we executed the AUX_FH command. + /* + * Check if an end byte raced in before we executed the AUX_FH command. * If it did, we want to make sure the rfd holdoff is in effect. The end * byte can arrive since * AUX_RFD_HOLDOFF_ASAP doesn't immediately force the acceptor handshake @@ -846,7 +864,7 @@ static void fmh_gpib_release_rfd_holdoff(struct gpib_board *board, struct fmh_pr spin_unlock_irqrestore(&board->spinlock, flags); } -static int fmh_gpib_accel_read(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fmh_gpib_accel_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct fmh_priv *e_priv = board->private_data; @@ -893,10 +911,11 @@ static int fmh_gpib_accel_read(struct gpib_board *board, uint8_t *buffer, size_t return retval; } -/* Read a chunk of data whose length is within the limits of the hardware's +/* + * Read a chunk of data whose length is within the limits of the hardware's * xfer counter. Called in a loop from fmh_gpib_fifo_read(). */ -static int fmh_gpib_fifo_read_countable(struct gpib_board *board, uint8_t *buffer, +static int fmh_gpib_fifo_read_countable(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct fmh_priv *e_priv = board->private_data; @@ -954,7 +973,7 @@ cleanup: return retval; } -static int fmh_gpib_fifo_read(struct gpib_board *board, uint8_t *buffer, size_t length, +static int fmh_gpib_fifo_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct fmh_priv *e_priv = board->private_data; @@ -969,7 +988,8 @@ static int fmh_gpib_fifo_read(struct gpib_board *board, uint8_t *buffer, size_t *end = 0; *bytes_read = 0; - /* Do a little prep with data in interrupt so that following wait_for_read() + /* + * Do a little prep with data in interrupt so that following wait_for_read() * will wake up if a data byte is received. */ nec7210_set_reg_bits(nec_priv, IMR1, HR_DIIE, HR_DIIE); @@ -1011,7 +1031,7 @@ static int fmh_gpib_fifo_read(struct gpib_board *board, uint8_t *buffer, size_t return retval; } -static gpib_interface_t fmh_gpib_unaccel_interface = { +static struct gpib_interface fmh_gpib_unaccel_interface = { .name = "fmh_gpib_unaccel", .attach = fmh_gpib_attach_holdoff_all, .detach = fmh_gpib_detach, @@ -1039,7 +1059,7 @@ static gpib_interface_t fmh_gpib_unaccel_interface = { .return_to_local = fmh_gpib_return_to_local, }; -static gpib_interface_t fmh_gpib_interface = { +static struct gpib_interface fmh_gpib_interface = { .name = "fmh_gpib", .attach = fmh_gpib_attach_holdoff_end, .detach = fmh_gpib_detach, @@ -1067,7 +1087,7 @@ static gpib_interface_t fmh_gpib_interface = { .return_to_local = fmh_gpib_return_to_local, }; -static gpib_interface_t fmh_gpib_pci_interface = { +static struct gpib_interface fmh_gpib_pci_interface = { .name = "fmh_gpib_pci", .attach = fmh_gpib_pci_attach_holdoff_end, .detach = fmh_gpib_pci_detach, @@ -1095,7 +1115,7 @@ static gpib_interface_t fmh_gpib_pci_interface = { .return_to_local = fmh_gpib_return_to_local, }; -static gpib_interface_t fmh_gpib_pci_unaccel_interface = { +static struct gpib_interface fmh_gpib_pci_unaccel_interface = { .name = "fmh_gpib_pci_unaccel", .attach = fmh_gpib_pci_attach_holdoff_all, .detach = fmh_gpib_pci_detach, @@ -1136,7 +1156,7 @@ irqreturn_t fmh_gpib_internal_interrupt(struct gpib_board *board) fifo_status = fifos_read(priv, FIFO_CONTROL_STATUS_REG); if (status0 & IFC_INTERRUPT_BIT) { - push_gpib_event(board, EventIFC); + push_gpib_event(board, EVENT_IFC); retval = IRQ_HANDLED; } @@ -1166,7 +1186,8 @@ irqreturn_t fmh_gpib_internal_interrupt(struct gpib_board *board) clear_bit(RFD_HOLDOFF_BN, &nec_priv->state); if (ext_status_1 & END_STATUS_BIT) { - /* only set RECEIVED_END while there is still a data + /* + * only set RECEIVED_END while there is still a data * byte sitting in the chip, to avoid spuriously * setting it multiple times after it has been cleared * during a read. @@ -1179,7 +1200,8 @@ irqreturn_t fmh_gpib_internal_interrupt(struct gpib_board *board) if ((fifo_status & TX_FIFO_HALF_EMPTY_INTERRUPT_IS_ENABLED) && (fifo_status & TX_FIFO_HALF_EMPTY)) { - /* We really only want to clear the + /* + * We really only want to clear the * TX_FIFO_HALF_EMPTY_INTERRUPT_ENABLE bit in the * FIFO_CONTROL_STATUS_REG. Since we are not being * careful, this also has a side effect of disabling @@ -1193,7 +1215,8 @@ irqreturn_t fmh_gpib_internal_interrupt(struct gpib_board *board) if ((fifo_status & RX_FIFO_HALF_FULL_INTERRUPT_IS_ENABLED) && (fifo_status & RX_FIFO_HALF_FULL)) { - /* We really only want to clear the + /* + * We really only want to clear the * RX_FIFO_HALF_FULL_INTERRUPT_ENABLE bit in the * FIFO_CONTROL_STATUS_REG. Since we are not being * careful, this also has a side effect of disabling @@ -1335,7 +1358,7 @@ static int fmh_gpib_init(struct fmh_priv *e_priv, struct gpib_board *board, int /* Match callback for driver_find_device */ static int fmh_gpib_device_match(struct device *dev, const void *data) { - const gpib_board_config_t *config = data; + const struct gpib_board_config *config = data; if (dev_get_drvdata(dev)) return 0; @@ -1351,7 +1374,7 @@ static int fmh_gpib_device_match(struct device *dev, const void *data) return 1; } -static int fmh_gpib_attach_impl(struct gpib_board *board, const gpib_board_config_t *config, +static int fmh_gpib_attach_impl(struct gpib_board *board, const struct gpib_board_config *config, unsigned int handshake_mode, int acquire_dma) { struct fmh_priv *e_priv; @@ -1424,10 +1447,8 @@ static int fmh_gpib_attach_impl(struct gpib_board *board, const gpib_board_confi (unsigned long)resource_size(e_priv->dma_port_res)); irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(board->dev, "request for IRQ failed\n"); + if (irq < 0) return -EBUSY; - } retval = request_irq(irq, fmh_gpib_interrupt, IRQF_SHARED, pdev->name, board); if (retval) { dev_err(board->dev, @@ -1444,7 +1465,8 @@ static int fmh_gpib_attach_impl(struct gpib_board *board, const gpib_board_confi return -EIO; } } - /* in the future we might want to know the half-fifo size + /* + * in the future we might want to know the half-fifo size * (dma_burst_length) even when not using dma, so go ahead an * initialize it unconditionally. */ @@ -1454,12 +1476,12 @@ static int fmh_gpib_attach_impl(struct gpib_board *board, const gpib_board_confi return fmh_gpib_init(e_priv, board, handshake_mode); } -int fmh_gpib_attach_holdoff_all(struct gpib_board *board, const gpib_board_config_t *config) +int fmh_gpib_attach_holdoff_all(struct gpib_board *board, const struct gpib_board_config *config) { return fmh_gpib_attach_impl(board, config, HR_HLDA, 0); } -int fmh_gpib_attach_holdoff_end(struct gpib_board *board, const gpib_board_config_t *config) +int fmh_gpib_attach_holdoff_end(struct gpib_board *board, const struct gpib_board_config *config) { return fmh_gpib_attach_impl(board, config, HR_HLDE, 1); } @@ -1497,7 +1519,8 @@ void fmh_gpib_detach(struct gpib_board *board) fmh_gpib_generic_detach(board); } -static int fmh_gpib_pci_attach_impl(struct gpib_board *board, const gpib_board_config_t *config, +static int fmh_gpib_pci_attach_impl(struct gpib_board *board, + const struct gpib_board_config *config, unsigned int handshake_mode) { struct fmh_priv *e_priv; @@ -1570,12 +1593,14 @@ static int fmh_gpib_pci_attach_impl(struct gpib_board *board, const gpib_board_c return fmh_gpib_init(e_priv, board, handshake_mode); } -int fmh_gpib_pci_attach_holdoff_all(struct gpib_board *board, const gpib_board_config_t *config) +int fmh_gpib_pci_attach_holdoff_all(struct gpib_board *board, + const struct gpib_board_config *config) { return fmh_gpib_pci_attach_impl(board, config, HR_HLDA); } -int fmh_gpib_pci_attach_holdoff_end(struct gpib_board *board, const gpib_board_config_t *config) +int fmh_gpib_pci_attach_holdoff_end(struct gpib_board *board, + const struct gpib_board_config *config) { int retval; struct fmh_priv *e_priv; @@ -1631,7 +1656,6 @@ MODULE_DEVICE_TABLE(of, fmh_gpib_of_match); static struct platform_driver fmh_gpib_platform_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = fmh_gpib_of_match, }, .probe = &fmh_gpib_platform_probe diff --git a/drivers/staging/gpib/fmh_gpib/fmh_gpib.h b/drivers/staging/gpib/fmh_gpib/fmh_gpib.h index de6fd2164414..e7602d7e1401 100644 --- a/drivers/staging/gpib/fmh_gpib/fmh_gpib.h +++ b/drivers/staging/gpib/fmh_gpib/fmh_gpib.h @@ -124,13 +124,13 @@ static const unsigned int fifo_data_mask = 0x00ff; static const unsigned int fifo_xfer_counter_mask = 0x0fff; static const unsigned int fifo_max_burst_length_mask = 0x00ff; -static inline uint8_t gpib_cs_read_byte(struct nec7210_priv *nec_priv, - unsigned int register_num) +static inline u8 gpib_cs_read_byte(struct nec7210_priv *nec_priv, + unsigned int register_num) { return readb(nec_priv->mmiobase + register_num * nec_priv->offset); } -static inline void gpib_cs_write_byte(struct nec7210_priv *nec_priv, uint8_t data, +static inline void gpib_cs_write_byte(struct nec7210_priv *nec_priv, u8 data, unsigned int register_num) { writeb(data, nec_priv->mmiobase + register_num * nec_priv->offset); diff --git a/drivers/staging/gpib/gpio/gpib_bitbang.c b/drivers/staging/gpib/gpio/gpib_bitbang.c index 86bdd381472a..17884810fd69 100644 --- a/drivers/staging/gpib/gpio/gpib_bitbang.c +++ b/drivers/staging/gpib/gpio/gpib_bitbang.c @@ -32,7 +32,8 @@ #define ENABLE_IRQ(IRQ, TYPE) irq_set_irq_type(IRQ, TYPE) #define DISABLE_IRQ(IRQ) irq_set_irq_type(IRQ, IRQ_TYPE_NONE) -/* Debug print levels: +/* + * Debug print levels: * 0 = load/unload info and errors that make the driver fail; * 1 = + warnings for unforeseen events that may break the current * operation and lead to a timeout, but do not affect the @@ -65,7 +66,6 @@ #include <linux/gpio/machine.h> #include <linux/gpio.h> #include <linux/irq.h> -#include <linux/leds.h> static int sn7516x_used = 1, sn7516x; module_param(sn7516x_used, int, 0660); @@ -135,19 +135,14 @@ enum lines_t { #define SN7516X_PINS 4 #define NUM_PINS (GPIB_PINS + SN7516X_PINS) -DEFINE_LED_TRIGGER(ledtrig_gpib); -#define ACT_LED_ON do { \ +#define ACT_LED_ON do { \ if (ACT_LED) \ - gpiod_direction_output(ACT_LED, 1); \ - else \ - led_trigger_event(ledtrig_gpib, LED_FULL); } \ - while (0) -#define ACT_LED_OFF do { \ + gpiod_direction_output(ACT_LED, 1); \ + } while (0) +#define ACT_LED_OFF do { \ if (ACT_LED) \ - gpiod_direction_output(ACT_LED, 0); \ - else \ - led_trigger_event(ledtrig_gpib, LED_OFF); } \ - while (0) + gpiod_direction_output(ACT_LED, 0); \ + } while (0) static struct gpio_desc *all_descriptors[GPIB_PINS + SN7516X_PINS]; @@ -174,7 +169,7 @@ static struct gpio_desc *all_descriptors[GPIB_PINS + SN7516X_PINS]; #define TE all_descriptors[18] #define ACT_LED all_descriptors[19] -/* YOGA dapter uses a global enable for the buffer chips, re-using the TE pin */ +/* YOGA adapter uses a global enable for the buffer chips, re-using the TE pin */ #define YOGA_ENABLE TE static int gpios_vector[] = { @@ -311,7 +306,6 @@ struct bb_priv { int dav_seq; long all_irqs; int dav_idle; - int atn_asserted; enum talker_function_state talker_state; enum listener_function_state listener_state; @@ -324,7 +318,7 @@ static void set_data_lines(u8 byte); static u8 get_data_lines(void); static void set_data_lines_input(void); static void set_data_lines_output(void); -static inline int check_for_eos(struct bb_priv *priv, uint8_t byte); +static inline int check_for_eos(struct bb_priv *priv, u8 byte); static void set_atn(struct gpib_board *board, int atn_asserted); static inline void SET_DIR_WRITE(struct bb_priv *priv); @@ -353,7 +347,7 @@ static char printable(char x) * * ***************************************************************************/ -static int bb_read(struct gpib_board *board, uint8_t *buffer, size_t length, +static int bb_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct bb_priv *priv = board->private_data; @@ -491,7 +485,7 @@ dav_exit: * * ***************************************************************************/ -static int bb_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int bb_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { unsigned long flags; @@ -522,7 +516,7 @@ static int bb_write(struct gpib_board *board, uint8_t *buffer, size_t length, gpiod_get_value(NRFD), gpiod_get_value(NDAC)); if (gpiod_get_value(NRFD) && gpiod_get_value(NDAC)) { /* check for listener */ - retval = -ENODEV; + retval = -ENOTCONN; goto write_end; } @@ -619,7 +613,8 @@ static irqreturn_t bb_NRFD_interrupt(int irq, void *arg) goto nrfd_exit; } - if (priv->atn_asserted && priv->w_cnt >= priv->length) { // test for end of transfer + if (priv->w_cnt >= priv->length) { // test for missed NDAC end of transfer + dev_err(board->gpib_dev, "Unexpected NRFD exit\n"); priv->write_done = 1; priv->w_busy = 0; wake_up_interruptible(&board->wait); @@ -691,14 +686,14 @@ static irqreturn_t bb_NDAC_interrupt(int irq, void *arg) dbg_printk(3, "accepted %zu\n", priv->w_cnt - 1); - if (!priv->atn_asserted && priv->w_cnt >= priv->length) { // test for end of transfer + gpiod_set_value(DAV, 1); // Data not available + priv->dav_tx = 1; + priv->phase = 510; + + if (priv->w_cnt >= priv->length) { // test for end of transfer priv->write_done = 1; priv->w_busy = 0; wake_up_interruptible(&board->wait); - } else { - gpiod_set_value(DAV, 1); // Data not available - priv->dav_tx = 1; - priv->phase = 510; } ndac_exit: @@ -728,7 +723,7 @@ static irqreturn_t bb_SRQ_interrupt(int irq, void *arg) return IRQ_HANDLED; } -static int bb_command(struct gpib_board *board, uint8_t *buffer, +static int bb_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { size_t ret; @@ -855,6 +850,7 @@ static void set_atn(struct gpib_board *board, int atn_asserted) priv->listener_state = listener_addressed; if (priv->talker_state == talker_active) priv->talker_state = talker_addressed; + SET_DIR_WRITE(priv); // need to be able to read bus NRFD/NDAC } else { if (priv->listener_state == listener_addressed) { priv->listener_state = listener_active; @@ -864,14 +860,12 @@ static void set_atn(struct gpib_board *board, int atn_asserted) priv->talker_state = talker_active; } gpiod_direction_output(_ATN, !atn_asserted); - priv->atn_asserted = atn_asserted; } static int bb_take_control(struct gpib_board *board, int synchronous) { dbg_printk(2, "%d\n", synchronous); set_atn(board, 1); - set_bit(CIC_NUM, &board->status); return 0; } @@ -882,16 +876,24 @@ static int bb_go_to_standby(struct gpib_board *board) return 0; } -static void bb_request_system_control(struct gpib_board *board, int request_control) +static int bb_request_system_control(struct gpib_board *board, int request_control) { + struct bb_priv *priv = board->private_data; + dbg_printk(2, "%d\n", request_control); - if (request_control) { - set_bit(CIC_NUM, &board->status); - // drive DAV & EOI false, enable NRFD & NDAC irqs - SET_DIR_WRITE(board->private_data); - } else { - clear_bit(CIC_NUM, &board->status); - } + if (!request_control) + return -EINVAL; + + gpiod_direction_output(REN, 1); /* user space must enable REN if needed */ + gpiod_direction_output(IFC, 1); /* user space must toggle IFC if needed */ + if (sn7516x) + gpiod_direction_output(DC, 0); /* enable ATN as output on SN75161/2 */ + + gpiod_direction_input(SRQ); + + ENABLE_IRQ(priv->irq_SRQ, IRQ_TYPE_EDGE_FALLING); + + return 0; } static void bb_interface_clear(struct gpib_board *board, int assert) @@ -903,6 +905,7 @@ static void bb_interface_clear(struct gpib_board *board, int assert) gpiod_direction_output(IFC, 0); priv->talker_state = talker_idle; priv->listener_state = listener_idle; + set_bit(CIC_NUM, &board->status); } else { gpiod_direction_output(IFC, 1); } @@ -920,7 +923,7 @@ static void bb_remote_enable(struct gpib_board *board, int enable) } } -static int bb_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits) +static int bb_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct bb_priv *priv = board->private_data; @@ -987,12 +990,12 @@ static int bb_secondary_address(struct gpib_board *board, unsigned int address, return 0; } -static int bb_parallel_poll(struct gpib_board *board, uint8_t *result) +static int bb_parallel_poll(struct gpib_board *board, u8 *result) { return -ENOENT; } -static void bb_parallel_poll_configure(struct gpib_board *board, uint8_t config) +static void bb_parallel_poll_configure(struct gpib_board *board, u8 config) { } @@ -1000,11 +1003,11 @@ static void bb_parallel_poll_response(struct gpib_board *board, int ist) { } -static void bb_serial_poll_response(struct gpib_board *board, uint8_t status) +static void bb_serial_poll_response(struct gpib_board *board, u8 status) { } -static uint8_t bb_serial_poll_status(struct gpib_board *board) +static u8 bb_serial_poll_status(struct gpib_board *board) { return 0; // -ENOENT; } @@ -1120,8 +1123,7 @@ static void release_gpios(void) static int allocate_gpios(struct gpib_board *board) { - int j, retval = 0; - bool error = false; + int j; int table_index = 0; char name[256]; struct gpio_desc *desc; @@ -1132,8 +1134,8 @@ static int allocate_gpios(struct gpib_board *board) return -ENOENT; } - lookup_table = lookup_tables[0]; - lookup_table->dev_id = dev_name(board->gpib_dev); + lookup_table = lookup_tables[table_index]; + lookup_table->dev_id = dev_name(board->gpib_dev); gpiod_add_lookup_table(lookup_table); dbg_printk(1, "Allocating gpios using table index %d\n", table_index); @@ -1150,30 +1152,26 @@ try_again: gpiod_remove_lookup_table(lookup_table); table_index++; lookup_table = lookup_tables[table_index]; - if (lookup_table) { - dbg_printk(1, "Allocation failed, now using table_index %d\n", - table_index); - lookup_table->dev_id = dev_name(board->gpib_dev); - gpiod_add_lookup_table(lookup_table); - goto try_again; + if (!lookup_table) { + dev_err(board->gpib_dev, "Unable to obtain gpio descriptor for pin %d error %ld\n", + gpios_vector[j], PTR_ERR(desc)); + goto alloc_gpios_fail; } - dev_err(board->gpib_dev, "Unable to obtain gpio descriptor for pin %d error %ld\n", - gpios_vector[j], PTR_ERR(desc)); - error = true; - break; + dbg_printk(1, "Allocation failed, now using table_index %d\n", table_index); + lookup_table->dev_id = dev_name(board->gpib_dev); + gpiod_add_lookup_table(lookup_table); + goto try_again; } all_descriptors[j] = desc; } - if (error) { /* undo what already done */ - release_gpios(); - retval = -1; - } - if (lookup_table) - gpiod_remove_lookup_table(lookup_table); - // Initialize LED trigger - led_trigger_register_simple("gpib", &ledtrig_gpib); - return retval; + gpiod_remove_lookup_table(lookup_table); + + return 0; + +alloc_gpios_fail: + release_gpios(); + return -1; } static void bb_detach(struct gpib_board *board) @@ -1184,8 +1182,6 @@ static void bb_detach(struct gpib_board *board) if (!board->private_data) return; - led_trigger_unregister_simple(ledtrig_gpib); - bb_free_irq(board, &priv->irq_DAV, NAME "_DAV"); bb_free_irq(board, &priv->irq_NRFD, NAME "_NRFD"); bb_free_irq(board, &priv->irq_NDAC, NAME "_NDAC"); @@ -1206,7 +1202,7 @@ static void bb_detach(struct gpib_board *board) free_private(board); } -static int bb_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int bb_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct bb_priv *priv; int retval = 0; @@ -1245,7 +1241,6 @@ static int bb_attach(struct gpib_board *board, const gpib_board_config_t *config gpios_vector[&(D06) - &all_descriptors[0]] = YOGA_D06_pin_nr; gpios_vector[&(PE) - &all_descriptors[0]] = -1; gpios_vector[&(DC) - &all_descriptors[0]] = -1; - gpios_vector[&(ACT_LED) - &all_descriptors[0]] = -1; } else { dev_err(board->gpib_dev, "Unrecognized pin map %s\n", pin_map); goto bb_attach_fail; @@ -1256,7 +1251,8 @@ static int bb_attach(struct gpib_board *board, const gpib_board_config_t *config if (allocate_gpios(board)) goto bb_attach_fail; -/* Configure SN7516X control lines. +/* + * Configure SN7516X control lines. * drive ATN, IFC and REN as outputs only when master * i.e. system controller. In this mode can only be the CIC * When not master then enable device mode ATN, IFC & REN as inputs @@ -1266,6 +1262,10 @@ static int bb_attach(struct gpib_board *board, const gpib_board_config_t *config gpiod_direction_output(TE, 1); gpiod_direction_output(PE, 1); } +/* Set main control lines to a known state */ + gpiod_direction_output(IFC, 1); + gpiod_direction_output(REN, 1); + gpiod_direction_output(_ATN, 1); if (strcmp(PINMAP_2, pin_map) == 0) { /* YOGA: enable level shifters */ gpiod_direction_output(YOGA_ENABLE, 1); @@ -1293,8 +1293,6 @@ static int bb_attach(struct gpib_board *board, const gpib_board_config_t *config IRQF_TRIGGER_NONE)) goto bb_attach_fail_r; - ENABLE_IRQ(priv->irq_SRQ, IRQ_TYPE_EDGE_FALLING); - dbg_printk(0, "attached board %d\n", board->minor); goto bb_attach_out; @@ -1306,7 +1304,7 @@ bb_attach_out: return retval; } -static gpib_interface_t bb_interface = { +static struct gpib_interface bb_interface = { .name = NAME, .attach = bb_attach, .detach = bb_detach, @@ -1364,7 +1362,7 @@ inline long usec_diff(struct timespec64 *a, struct timespec64 *b) (a->tv_nsec - b->tv_nsec) / 1000); } -static inline int check_for_eos(struct bb_priv *priv, uint8_t byte) +static inline int check_for_eos(struct bb_priv *priv, u8 byte) { if (priv->eos_check) return 0; diff --git a/drivers/staging/gpib/hp_82335/hp82335.c b/drivers/staging/gpib/hp_82335/hp82335.c index fd23b1cb80f9..d0e47ef77c87 100644 --- a/drivers/staging/gpib/hp_82335/hp82335.c +++ b/drivers/staging/gpib/hp_82335/hp82335.c @@ -4,8 +4,9 @@ * copyright : (C) 2002 by Frank Mori Hess * ***************************************************************************/ -/*should enable ATN interrupts (and update board->status on occurrence), - * implement recovery from bus errors (if necessary) +/* + * should enable ATN interrupts (and update board->status on occurrence), + * implement recovery from bus errors (if necessary) */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -24,12 +25,12 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("GPIB driver for HP 82335 interface cards"); -static int hp82335_attach(struct gpib_board *board, const gpib_board_config_t *config); +static int hp82335_attach(struct gpib_board *board, const struct gpib_board_config *config); static void hp82335_detach(struct gpib_board *board); static irqreturn_t hp82335_interrupt(int irq, void *arg); // wrappers for interface functions -static int hp82335_read(struct gpib_board *board, uint8_t *buffer, size_t length, +static int hp82335_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct hp82335_priv *priv = board->private_data; @@ -37,7 +38,7 @@ static int hp82335_read(struct gpib_board *board, uint8_t *buffer, size_t length return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read); } -static int hp82335_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi, +static int hp82335_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct hp82335_priv *priv = board->private_data; @@ -45,7 +46,7 @@ static int hp82335_write(struct gpib_board *board, uint8_t *buffer, size_t lengt return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written); } -static int hp82335_command(struct gpib_board *board, uint8_t *buffer, size_t length, +static int hp82335_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { struct hp82335_priv *priv = board->private_data; @@ -67,11 +68,11 @@ static int hp82335_go_to_standby(struct gpib_board *board) return tms9914_go_to_standby(board, &priv->tms9914_priv); } -static void hp82335_request_system_control(struct gpib_board *board, int request_control) +static int hp82335_request_system_control(struct gpib_board *board, int request_control) { struct hp82335_priv *priv = board->private_data; - tms9914_request_system_control(board, &priv->tms9914_priv, request_control); + return tms9914_request_system_control(board, &priv->tms9914_priv, request_control); } static void hp82335_interface_clear(struct gpib_board *board, int assert) @@ -88,7 +89,7 @@ static void hp82335_remote_enable(struct gpib_board *board, int enable) tms9914_remote_enable(board, &priv->tms9914_priv, enable); } -static int hp82335_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits) +static int hp82335_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct hp82335_priv *priv = board->private_data; @@ -123,14 +124,14 @@ static int hp82335_secondary_address(struct gpib_board *board, unsigned int addr return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable); } -static int hp82335_parallel_poll(struct gpib_board *board, uint8_t *result) +static int hp82335_parallel_poll(struct gpib_board *board, u8 *result) { struct hp82335_priv *priv = board->private_data; return tms9914_parallel_poll(board, &priv->tms9914_priv, result); } -static void hp82335_parallel_poll_configure(struct gpib_board *board, uint8_t config) +static void hp82335_parallel_poll_configure(struct gpib_board *board, u8 config) { struct hp82335_priv *priv = board->private_data; @@ -144,14 +145,14 @@ static void hp82335_parallel_poll_response(struct gpib_board *board, int ist) tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist); } -static void hp82335_serial_poll_response(struct gpib_board *board, uint8_t status) +static void hp82335_serial_poll_response(struct gpib_board *board, u8 status) { struct hp82335_priv *priv = board->private_data; tms9914_serial_poll_response(board, &priv->tms9914_priv, status); } -static uint8_t hp82335_serial_poll_status(struct gpib_board *board) +static u8 hp82335_serial_poll_status(struct gpib_board *board) { struct hp82335_priv *priv = board->private_data; @@ -179,7 +180,7 @@ static void hp82335_return_to_local(struct gpib_board *board) tms9914_return_to_local(board, &priv->tms9914_priv); } -static gpib_interface_t hp82335_interface = { +static struct gpib_interface hp82335_interface = { .name = "hp82335", .attach = hp82335_attach, .detach = hp82335_detach, @@ -226,12 +227,12 @@ static inline unsigned int tms9914_to_hp82335_offset(unsigned int register_num) return 0x1ff8 + register_num; } -static uint8_t hp82335_read_byte(struct tms9914_priv *priv, unsigned int register_num) +static u8 hp82335_read_byte(struct tms9914_priv *priv, unsigned int register_num) { return tms9914_iomem_read_byte(priv, tms9914_to_hp82335_offset(register_num)); } -static void hp82335_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num) +static void hp82335_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num) { tms9914_iomem_write_byte(priv, data, tms9914_to_hp82335_offset(register_num)); } @@ -243,7 +244,7 @@ static void hp82335_clear_interrupt(struct hp82335_priv *hp_priv) writeb(0, tms_priv->mmiobase + HPREG_INTR_CLEAR); } -static int hp82335_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int hp82335_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct hp82335_priv *hp_priv; struct tms9914_priv *tms_priv; diff --git a/drivers/staging/gpib/hp_82341/hp_82341.c b/drivers/staging/gpib/hp_82341/hp_82341.c index f52e673dc869..e5c1997ce7d9 100644 --- a/drivers/staging/gpib/hp_82341/hp_82341.c +++ b/drivers/staging/gpib/hp_82341/hp_82341.c @@ -25,11 +25,11 @@ MODULE_DESCRIPTION("GPIB driver for hp 82341a/b/c/d boards"); static unsigned short read_and_clear_event_status(struct gpib_board *board); static void set_transfer_counter(struct hp_82341_priv *hp_priv, int count); static int read_transfer_counter(struct hp_82341_priv *hp_priv); -static int hp_82341_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi, +static int hp_82341_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written); static irqreturn_t hp_82341_interrupt(int irq, void *arg); -static int hp_82341_accel_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end, +static int hp_82341_accel_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct hp_82341_priv *hp_priv = board->private_data; @@ -51,11 +51,12 @@ static int hp_82341_accel_read(struct gpib_board *board, uint8_t *buffer, size_t return 0; //disable fifo for the moment outb(DIRECTION_GPIB_TO_HOST_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG); - // Handle corner case of board not in holdoff and one byte has slipped in already. - // Also, board sometimes has problems (spurious 1 byte reads) when read fifo is - // started up with board in - // TACS under certain data holdoff conditions. Doing a 1 byte tms9914-style - // read avoids these problems. + /* + * Handle corner case of board not in holdoff and one byte has slipped in already. + * Also, board sometimes has problems (spurious 1 byte reads) when read fifo is + * started up with board in TACS under certain data holdoff conditions. + * Doing a 1 byte tms9914-style read avoids these problems. + */ if (/*tms_priv->holdoff_active == 0 && */length > 1) { size_t num_bytes; @@ -78,10 +79,7 @@ static int hp_82341_accel_read(struct gpib_board *board, uint8_t *buffer, size_t int j; int count; - if (num_fifo_bytes - i < hp_82341_fifo_size) - block_size = num_fifo_bytes - i; - else - block_size = hp_82341_fifo_size; + block_size = min(num_fifo_bytes - i, hp_82341_fifo_size); set_transfer_counter(hp_priv, block_size); outb(ENABLE_TI_BUFFER_BIT | DIRECTION_GPIB_TO_HOST_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG); @@ -172,7 +170,7 @@ static int restart_write_fifo(struct gpib_board *board, struct hp_82341_priv *hp return 0; } -static int hp_82341_accel_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int hp_82341_accel_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct hp_82341_priv *hp_priv = board->private_data; @@ -194,10 +192,7 @@ static int hp_82341_accel_write(struct gpib_board *board, uint8_t *buffer, size_ for (i = 0; i < fifo_xfer_len;) { int block_size; - if (fifo_xfer_len - i < hp_82341_fifo_size) - block_size = fifo_xfer_len - i; - else - block_size = hp_82341_fifo_size; + block_size = min(fifo_xfer_len - i, hp_82341_fifo_size); set_transfer_counter(hp_priv, block_size); // load data into board's fifo for (j = 0; j < block_size;) { @@ -250,12 +245,12 @@ static int hp_82341_accel_write(struct gpib_board *board, uint8_t *buffer, size_ return 0; } -static int hp_82341_attach(struct gpib_board *board, const gpib_board_config_t *config); +static int hp_82341_attach(struct gpib_board *board, const struct gpib_board_config *config); static void hp_82341_detach(struct gpib_board *board); // wrappers for interface functions -static int hp_82341_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end, +static int hp_82341_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct hp_82341_priv *priv = board->private_data; @@ -263,7 +258,7 @@ static int hp_82341_read(struct gpib_board *board, uint8_t *buffer, size_t lengt return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read); } -static int hp_82341_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi, +static int hp_82341_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct hp_82341_priv *priv = board->private_data; @@ -271,7 +266,7 @@ static int hp_82341_write(struct gpib_board *board, uint8_t *buffer, size_t leng return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written); } -static int hp_82341_command(struct gpib_board *board, uint8_t *buffer, size_t length, +static int hp_82341_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { struct hp_82341_priv *priv = board->private_data; @@ -293,7 +288,7 @@ static int hp_82341_go_to_standby(struct gpib_board *board) return tms9914_go_to_standby(board, &priv->tms9914_priv); } -static void hp_82341_request_system_control(struct gpib_board *board, int request_control) +static int hp_82341_request_system_control(struct gpib_board *board, int request_control) { struct hp_82341_priv *priv = board->private_data; @@ -302,7 +297,7 @@ static void hp_82341_request_system_control(struct gpib_board *board, int reques else priv->mode_control_bits &= ~SYSTEM_CONTROLLER_BIT; outb(priv->mode_control_bits, priv->iobase[0] + MODE_CONTROL_STATUS_REG); - tms9914_request_system_control(board, &priv->tms9914_priv, request_control); + return tms9914_request_system_control(board, &priv->tms9914_priv, request_control); } static void hp_82341_interface_clear(struct gpib_board *board, int assert) @@ -319,7 +314,7 @@ static void hp_82341_remote_enable(struct gpib_board *board, int enable) tms9914_remote_enable(board, &priv->tms9914_priv, enable); } -static int hp_82341_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits) +static int hp_82341_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct hp_82341_priv *priv = board->private_data; @@ -354,14 +349,14 @@ static int hp_82341_secondary_address(struct gpib_board *board, unsigned int add return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable); } -static int hp_82341_parallel_poll(struct gpib_board *board, uint8_t *result) +static int hp_82341_parallel_poll(struct gpib_board *board, u8 *result) { struct hp_82341_priv *priv = board->private_data; return tms9914_parallel_poll(board, &priv->tms9914_priv, result); } -static void hp_82341_parallel_poll_configure(struct gpib_board *board, uint8_t config) +static void hp_82341_parallel_poll_configure(struct gpib_board *board, u8 config) { struct hp_82341_priv *priv = board->private_data; @@ -375,14 +370,14 @@ static void hp_82341_parallel_poll_response(struct gpib_board *board, int ist) tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist); } -static void hp_82341_serial_poll_response(struct gpib_board *board, uint8_t status) +static void hp_82341_serial_poll_response(struct gpib_board *board, u8 status) { struct hp_82341_priv *priv = board->private_data; tms9914_serial_poll_response(board, &priv->tms9914_priv, status); } -static uint8_t hp_82341_serial_poll_status(struct gpib_board *board) +static u8 hp_82341_serial_poll_status(struct gpib_board *board) { struct hp_82341_priv *priv = board->private_data; @@ -410,7 +405,7 @@ static void hp_82341_return_to_local(struct gpib_board *board) tms9914_return_to_local(board, &priv->tms9914_priv); } -static gpib_interface_t hp_82341_unaccel_interface = { +static struct gpib_interface hp_82341_unaccel_interface = { .name = "hp_82341_unaccel", .attach = hp_82341_attach, .detach = hp_82341_detach, @@ -438,7 +433,7 @@ static gpib_interface_t hp_82341_unaccel_interface = { .return_to_local = hp_82341_return_to_local, }; -static gpib_interface_t hp_82341_interface = { +static struct gpib_interface hp_82341_interface = { .name = "hp_82341", .attach = hp_82341_attach, .detach = hp_82341_detach, @@ -479,12 +474,12 @@ static void hp_82341_free_private(struct gpib_board *board) board->private_data = NULL; } -static uint8_t hp_82341_read_byte(struct tms9914_priv *priv, unsigned int register_num) +static u8 hp_82341_read_byte(struct tms9914_priv *priv, unsigned int register_num) { return inb(priv->iobase + register_num); } -static void hp_82341_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num) +static void hp_82341_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num) { outb(data, priv->iobase + register_num); } @@ -619,7 +614,8 @@ static int hp_82341_load_firmware_array(struct hp_82341_priv *hp_priv, return 0; } -static int hp_82341_load_firmware(struct hp_82341_priv *hp_priv, const gpib_board_config_t *config) +static int hp_82341_load_firmware(struct hp_82341_priv *hp_priv, + const struct gpib_board_config *config) { if (config->init_data_length == 0) { if (xilinx_done(hp_priv)) @@ -686,7 +682,7 @@ static int clear_xilinx(struct hp_82341_priv *hp_priv) return 0; } -static int hp_82341_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int hp_82341_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct hp_82341_priv *hp_priv; struct tms9914_priv *tms_priv; diff --git a/drivers/staging/gpib/include/gpibP.h b/drivers/staging/gpib/include/gpibP.h index 0c71a038e444..1b27f37e0ba0 100644 --- a/drivers/staging/gpib/include/gpibP.h +++ b/drivers/staging/gpib/include/gpibP.h @@ -11,23 +11,24 @@ #include "gpib_types.h" #include "gpib_proto.h" -#include "gpib_user.h" +#include "gpib_cmd.h" +#include "gpib.h" #include "gpib_ioctl.h" #include <linux/fs.h> #include <linux/interrupt.h> #include <linux/io.h> -int gpib_register_driver(gpib_interface_t *interface, struct module *mod); -void gpib_unregister_driver(gpib_interface_t *interface); -struct pci_dev *gpib_pci_get_device(const gpib_board_config_t *config, unsigned int vendor_id, +int gpib_register_driver(struct gpib_interface *interface, struct module *mod); +void gpib_unregister_driver(struct gpib_interface *interface); +struct pci_dev *gpib_pci_get_device(const struct gpib_board_config *config, unsigned int vendor_id, unsigned int device_id, struct pci_dev *from); -struct pci_dev *gpib_pci_get_subsys(const gpib_board_config_t *config, unsigned int vendor_id, +struct pci_dev *gpib_pci_get_subsys(const struct gpib_board_config *config, unsigned int vendor_id, unsigned int device_id, unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from); -unsigned int num_gpib_events(const gpib_event_queue_t *queue); +unsigned int num_gpib_events(const struct gpib_event_queue *queue); int push_gpib_event(struct gpib_board *board, short event_type); -int pop_gpib_event(struct gpib_board *board, gpib_event_queue_t *queue, short *event_type); +int pop_gpib_event(struct gpib_board *board, struct gpib_event_queue *queue, short *event_type); int gpib_request_pseudo_irq(struct gpib_board *board, irqreturn_t (*handler)(int, void *)); void gpib_free_pseudo_irq(struct gpib_board *board); int gpib_match_device_path(struct device *dev, const char *device_path_in); diff --git a/drivers/staging/gpib/include/gpib_cmd.h b/drivers/staging/gpib/include/gpib_cmd.h new file mode 100644 index 000000000000..9e96a3bfa22d --- /dev/null +++ b/drivers/staging/gpib/include/gpib_cmd.h @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _GPIB_CMD_H +#define _GPIB_CMD_H + +#include <linux/types.h> + +/* Command byte definitions tests and functions */ + +/* mask of bits that actually matter in a command byte */ +enum { + gpib_command_mask = 0x7f, +}; + +/* Possible GPIB command messages */ + +enum cmd_byte { + GTL = 0x1, /* go to local */ + SDC = 0x4, /* selected device clear */ + PP_CONFIG = 0x5, + GET = 0x8, /* group execute trigger */ + TCT = 0x9, /* take control */ + LLO = 0x11, /* local lockout */ + DCL = 0x14, /* device clear */ + PPU = 0x15, /* parallel poll unconfigure */ + SPE = 0x18, /* serial poll enable */ + SPD = 0x19, /* serial poll disable */ + CFE = 0x1f, /* configure enable */ + LAD = 0x20, /* value to be 'ored' in to obtain listen address */ + UNL = 0x3F, /* unlisten */ + TAD = 0x40, /* value to be 'ored' in to obtain talk address */ + UNT = 0x5F, /* untalk */ + SAD = 0x60, /* my secondary address (base) */ + PPE = 0x60, /* parallel poll enable (base) */ + PPD = 0x70 /* parallel poll disable */ +}; + +/* confine address to range 0 to 30. */ +static inline unsigned int gpib_address_restrict(u32 addr) +{ + addr &= 0x1f; + if (addr == 0x1f) + addr = 0; + return addr; +} + +static inline u8 MLA(u32 addr) +{ + return gpib_address_restrict(addr) | LAD; +} + +static inline u8 MTA(u32 addr) +{ + return gpib_address_restrict(addr) | TAD; +} + +static inline u8 MSA(u32 addr) +{ + return (addr & 0x1f) | SAD; +} + +static inline s32 gpib_address_equal(u32 pad1, s32 sad1, u32 pad2, s32 sad2) +{ + if (pad1 == pad2) { + if (sad1 == sad2) + return 1; + if (sad1 < 0 && sad2 < 0) + return 1; + } + + return 0; +} + +static inline s32 is_PPE(u8 command) +{ + return (command & 0x70) == 0x60; +} + +static inline s32 is_PPD(u8 command) +{ + return (command & 0x70) == 0x70; +} + +static inline s32 in_addressed_command_group(u8 command) +{ + return (command & 0x70) == 0x0; +} + +static inline s32 in_universal_command_group(u8 command) +{ + return (command & 0x70) == 0x10; +} + +static inline s32 in_listen_address_group(u8 command) +{ + return (command & 0x60) == 0x20; +} + +static inline s32 in_talk_address_group(u8 command) +{ + return (command & 0x60) == 0x40; +} + +static inline s32 in_primary_command_group(u8 command) +{ + return in_addressed_command_group(command) || + in_universal_command_group(command) || + in_listen_address_group(command) || + in_talk_address_group(command); +} + +#endif /* _GPIB_CMD_H */ diff --git a/drivers/staging/gpib/include/gpib_proto.h b/drivers/staging/gpib/include/gpib_proto.h index 2c7dfc02f517..42e736e3b7cd 100644 --- a/drivers/staging/gpib/include/gpib_proto.h +++ b/drivers/staging/gpib/include/gpib_proto.h @@ -8,12 +8,8 @@ int ibopen(struct inode *inode, struct file *filep); int ibclose(struct inode *inode, struct file *file); long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg); -int osInit(void); -void osReset(void); void os_start_timer(struct gpib_board *board, unsigned int usec_timeout); void os_remove_timer(struct gpib_board *board); -void osSendEOI(void); -void osSendEOI(void); void init_gpib_board(struct gpib_board *board); static inline unsigned long usec_to_jiffies(unsigned int usec) { @@ -23,34 +19,31 @@ static inline unsigned long usec_to_jiffies(unsigned int usec) }; int serial_poll_all(struct gpib_board *board, unsigned int usec_timeout); -void init_gpib_descriptor(gpib_descriptor_t *desc); +void init_gpib_descriptor(struct gpib_descriptor *desc); int dvrsp(struct gpib_board *board, unsigned int pad, int sad, - unsigned int usec_timeout, uint8_t *result); -int ibAPWait(struct gpib_board *board, int pad); -int ibAPrsp(struct gpib_board *board, int padsad, char *spb); -void ibAPE(struct gpib_board *board, int pad, int v); + unsigned int usec_timeout, u8 *result); int ibcac(struct gpib_board *board, int sync, int fallback_to_async); -int ibcmd(struct gpib_board *board, uint8_t *buf, size_t length, size_t *bytes_written); +int ibcmd(struct gpib_board *board, u8 *buf, size_t length, size_t *bytes_written); int ibgts(struct gpib_board *board); int ibonline(struct gpib_board *board); int iboffline(struct gpib_board *board); int iblines(const struct gpib_board *board, short *lines); -int ibrd(struct gpib_board *board, uint8_t *buf, size_t length, int *end_flag, size_t *bytes_read); -int ibrpp(struct gpib_board *board, uint8_t *buf); -int ibrsv2(struct gpib_board *board, uint8_t status_byte, int new_reason_for_service); -void ibrsc(struct gpib_board *board, int request_control); +int ibrd(struct gpib_board *board, u8 *buf, size_t length, int *end_flag, size_t *bytes_read); +int ibrpp(struct gpib_board *board, u8 *buf); +int ibrsv2(struct gpib_board *board, u8 status_byte, int new_reason_for_service); +int ibrsc(struct gpib_board *board, int request_control); int ibsic(struct gpib_board *board, unsigned int usec_duration); int ibsre(struct gpib_board *board, int enable); int ibpad(struct gpib_board *board, unsigned int addr); int ibsad(struct gpib_board *board, int addr); int ibeos(struct gpib_board *board, int eos, int eosflags); int ibwait(struct gpib_board *board, int wait_mask, int clear_mask, int set_mask, - int *status, unsigned long usec_timeout, gpib_descriptor_t *desc); -int ibwrt(struct gpib_board *board, uint8_t *buf, size_t cnt, int send_eoi, size_t *bytes_written); + int *status, unsigned long usec_timeout, struct gpib_descriptor *desc); +int ibwrt(struct gpib_board *board, u8 *buf, size_t cnt, int send_eoi, size_t *bytes_written); int ibstatus(struct gpib_board *board); -int general_ibstatus(struct gpib_board *board, const gpib_status_queue_t *device, - int clear_mask, int set_mask, gpib_descriptor_t *desc); +int general_ibstatus(struct gpib_board *board, const struct gpib_status_queue *device, + int clear_mask, int set_mask, struct gpib_descriptor *desc); int io_timed_out(struct gpib_board *board); -int ibppc(struct gpib_board *board, uint8_t configuration); +int ibppc(struct gpib_board *board, u8 configuration); #endif /* GPIB_PROTO_INCLUDED */ diff --git a/drivers/staging/gpib/include/gpib_types.h b/drivers/staging/gpib/include/gpib_types.h index 2d9b9be683f8..db040c80d778 100644 --- a/drivers/staging/gpib/include/gpib_types.h +++ b/drivers/staging/gpib/include/gpib_types.h @@ -8,12 +8,7 @@ #define _GPIB_TYPES_H #ifdef __KERNEL__ -/* gpib_interface_t defines the interface - * between the board-specific details dealt with in the drivers - * and generic interface provided by gpib-common. - * This really should be in a different header file. - */ -#include "gpib_user.h" +#include "gpib.h" #include <linux/atomic.h> #include <linux/device.h> #include <linux/mutex.h> @@ -22,11 +17,10 @@ #include <linux/timer.h> #include <linux/interrupt.h> -typedef struct gpib_interface_struct gpib_interface_t; struct gpib_board; /* config parameters that are only used by driver attach functions */ -typedef struct { +struct gpib_board_config { /* firmware blob */ void *init_data; int init_data_length; @@ -37,11 +31,13 @@ typedef struct { unsigned int ibirq; /* dma channel to use for non-pnp cards (set by core, driver should make local copy) */ unsigned int ibdma; - /* pci bus of card, useful for distinguishing multiple identical pci cards + /* + * pci bus of card, useful for distinguishing multiple identical pci cards * (negative means don't care) */ int pci_bus; - /* pci slot of card, useful for distinguishing multiple identical pci cards + /* + * pci slot of card, useful for distinguishing multiple identical pci cards * (negative means don't care) */ int pci_slot; @@ -49,16 +45,23 @@ typedef struct { char *device_path; /* serial number of hardware to attach */ char *serial_number; -} gpib_board_config_t; +}; -struct gpib_interface_struct { +/* + * struct gpib_interface defines the interface + * between the board-specific details dealt with in the drivers + * and generic interface provided by gpib-common. + * This really should be in a different header file. + */ +struct gpib_interface { /* name of board */ char *name; /* attach() initializes board and allocates resources */ - int (*attach)(struct gpib_board *board, const gpib_board_config_t *config); + int (*attach)(struct gpib_board *board, const struct gpib_board_config *config); /* detach() shuts down board and frees resources */ void (*detach)(struct gpib_board *board); - /* read() should read at most 'length' bytes from the bus into + /* + * read() should read at most 'length' bytes from the bus into * 'buffer'. It should return when it fills the buffer or * encounters an END (EOI and or EOS if appropriate). It should set 'end' * to be nonzero if the read was terminated by an END, otherwise 'end' @@ -68,76 +71,88 @@ struct gpib_interface_struct { * return indicates error. * nbytes returns number of bytes read */ - int (*read)(struct gpib_board *board, uint8_t *buffer, size_t length, int *end, + int (*read)(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read); - /* write() should write 'length' bytes from buffer to the bus. + /* + * write() should write 'length' bytes from buffer to the bus. * If the boolean value send_eoi is nonzero, then EOI should * be sent along with the last byte. Returns number of bytes * written or negative value on error. */ - int (*write)(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi, + int (*write)(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written); - /* command() writes the command bytes in 'buffer' to the bus + /* + * command() writes the command bytes in 'buffer' to the bus * Returns zero on success or negative value on error. */ - int (*command)(struct gpib_board *board, uint8_t *buffer, size_t length, + int (*command)(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written); - /* Take control (assert ATN). If 'asyncronous' is nonzero, take + /* + * Take control (assert ATN). If 'asyncronous' is nonzero, take * control asyncronously (assert ATN immediately without waiting * for other processes to complete first). Should not return * until board becomes controller in charge. Returns zero no success, * nonzero on error. */ int (*take_control)(struct gpib_board *board, int asyncronous); - /* De-assert ATN. Returns zero on success, nonzer on error. + /* + * De-assert ATN. Returns zero on success, nonzer on error. */ int (*go_to_standby)(struct gpib_board *board); /* request/release control of the IFC and REN lines (system controller) */ - void (*request_system_control)(struct gpib_board *board, int request_control); - /* Asserts or de-asserts 'interface clear' (IFC) depending on + int (*request_system_control)(struct gpib_board *board, int request_control); + /* + * Asserts or de-asserts 'interface clear' (IFC) depending on * boolean value of 'assert' */ void (*interface_clear)(struct gpib_board *board, int assert); - /* Sends remote enable command if 'enable' is nonzero, disables remote mode + /* + * Sends remote enable command if 'enable' is nonzero, disables remote mode * if 'enable' is zero */ void (*remote_enable)(struct gpib_board *board, int enable); - /* enable END for reads, when byte 'eos' is received. If + /* + * enable END for reads, when byte 'eos' is received. If * 'compare_8_bits' is nonzero, then all 8 bits are compared * with the eos bytes. Otherwise only the 7 least significant * bits are compared. */ - int (*enable_eos)(struct gpib_board *board, uint8_t eos, int compare_8_bits); + int (*enable_eos)(struct gpib_board *board, u8 eos, int compare_8_bits); /* disable END on eos byte (END on EOI only)*/ void (*disable_eos)(struct gpib_board *board); /* configure parallel poll */ - void (*parallel_poll_configure)(struct gpib_board *board, uint8_t configuration); + void (*parallel_poll_configure)(struct gpib_board *board, u8 configuration); /* conduct parallel poll */ - int (*parallel_poll)(struct gpib_board *board, uint8_t *result); + int (*parallel_poll)(struct gpib_board *board, u8 *result); /* set/clear ist (individual status bit) */ void (*parallel_poll_response)(struct gpib_board *board, int ist); /* select local parallel poll configuration mode PP2 versus remote PP1 */ void (*local_parallel_poll_mode)(struct gpib_board *board, int local); - /* Returns current status of the bus lines. Should be set to + /* + * Returns current status of the bus lines. Should be set to * NULL if your board does not have the ability to query the * state of the bus lines. */ int (*line_status)(const struct gpib_board *board); - /* updates and returns the board's current status. + /* + * updates and returns the board's current status. * The meaning of the bits are specified in gpib_user.h * in the IBSTA section. The driver does not need to * worry about setting the CMPL, END, TIMO, or ERR bits. */ unsigned int (*update_status)(struct gpib_board *board, unsigned int clear_mask); - /* Sets primary address 0-30 for gpib interface card. + /* + * Sets primary address 0-30 for gpib interface card. */ int (*primary_address)(struct gpib_board *board, unsigned int address); - /* Sets and enables, or disables secondary address 0-30 + /* + * Sets and enables, or disables secondary address 0-30 * for gpib interface card. */ int (*secondary_address)(struct gpib_board *board, unsigned int address, int enable); - /* Sets the byte the board should send in response to a serial poll. + /* + * Sets the byte the board should send in response to a serial poll. * This function should also start or stop requests for service via * IEEE 488.2 reqt/reqf, based on MSS (bit 6 of the status_byte). * If the more flexible serial_poll_response2 is implemented by the @@ -149,8 +164,9 @@ struct gpib_interface_struct { * by IEEE 488.2 section 11.3.3.4.3 "Allowed Coupled Control of * STB, reqt, and reqf". */ - void (*serial_poll_response)(struct gpib_board *board, uint8_t status_byte); - /* Sets the byte the board should send in response to a serial poll. + void (*serial_poll_response)(struct gpib_board *board, u8 status_byte); + /* + * Sets the byte the board should send in response to a serial poll. * This function should also request service via IEEE 488.2 reqt/reqf * based on MSS (bit 6 of the status_byte) and new_reason_for_service. * reqt should be set true if new_reason_for_service is true, @@ -164,11 +180,12 @@ struct gpib_interface_struct { * If this method is left NULL by the driver, then the user library * function ibrsv2 will not work. */ - void (*serial_poll_response2)(struct gpib_board *board, uint8_t status_byte, + void (*serial_poll_response2)(struct gpib_board *board, u8 status_byte, int new_reason_for_service); - /* returns the byte the board will send in response to a serial poll. + /* + * returns the byte the board will send in response to a serial poll. */ - uint8_t (*serial_poll_status)(struct gpib_board *board); + u8 (*serial_poll_status)(struct gpib_board *board); /* adjust T1 delay */ int (*t1_delay)(struct gpib_board *board, unsigned int nano_sec); /* go to local mode */ @@ -179,14 +196,14 @@ struct gpib_interface_struct { unsigned skip_check_for_command_acceptors : 1; }; -typedef struct { +struct gpib_event_queue { struct list_head event_head; spinlock_t lock; // for access to event list unsigned int num_events; unsigned dropped_event : 1; -} gpib_event_queue_t; +}; -static inline void init_event_queue(gpib_event_queue_t *queue) +static inline void init_event_queue(struct gpib_event_queue *queue) { INIT_LIST_HEAD(&queue->event_head); queue->num_events = 0; @@ -210,20 +227,22 @@ static inline void init_gpib_pseudo_irq(struct gpib_pseudo_irq *pseudo_irq) } /* list so we can make a linked list of drivers */ -typedef struct gpib_interface_list_struct { +struct gpib_interface_list { struct list_head list; - gpib_interface_t *interface; + struct gpib_interface *interface; struct module *module; -} gpib_interface_list_t; +}; -/* One struct gpib_board is allocated for each physical board in the computer. +/* + * One struct gpib_board is allocated for each physical board in the computer. * It provides storage for variables local to each board, and interface * functions for performing operations on the board */ struct gpib_board { /* functions used by this board */ - gpib_interface_t *interface; - /* Pointer to module whose use count we should increment when + struct gpib_interface *interface; + /* + * Pointer to module whose use count we should increment when * interface is in use */ struct module *provider_module; @@ -231,20 +250,24 @@ struct gpib_board { u8 *buffer; /* length of buffer */ unsigned int buffer_length; - /* Used to hold the board's current status (see update_status() above) + /* + * Used to hold the board's current status (see update_status() above) */ unsigned long status; - /* Driver should only sleep on this wait queue. It is special in that the + /* + * Driver should only sleep on this wait queue. It is special in that the * core will wake this queue and set the TIMO bit in 'status' when the * watchdog timer times out. */ wait_queue_head_t wait; - /* Lock that only allows one process to access this board at a time. + /* + * Lock that only allows one process to access this board at a time. * Has to be first in any locking order, since it can be locked over * multiple ioctls. */ struct mutex user_mutex; - /* Mutex which compensates for removal of "big kernel lock" from kernel. + /* + * Mutex which compensates for removal of "big kernel lock" from kernel. * Should not be held for extended waits. */ struct mutex big_gpib_mutex; @@ -259,7 +282,8 @@ struct gpib_board { struct device *dev; /* gpib_common device gpibN */ struct device *gpib_dev; - /* 'private_data' can be used as seen fit by the driver to + /* + * 'private_data' can be used as seen fit by the driver to * store additional variables for this board */ void *private_data; @@ -284,34 +308,36 @@ struct gpib_board { /* autospoll kernel thread */ struct task_struct *autospoll_task; /* queue for recording received trigger/clear/ifc events */ - gpib_event_queue_t event_queue; + struct gpib_event_queue event_queue; /* minor number for this board's device file */ int minor; /* struct to deal with polling mode*/ struct gpib_pseudo_irq pseudo_irq; /* error dong autopoll */ atomic_t stuck_srq; - gpib_board_config_t config; + struct gpib_board_config config; /* Flag that indicates whether board is system controller of the bus */ unsigned master : 1; /* individual status bit */ unsigned ist : 1; - /* one means local parallel poll mode ieee 488.1 PP2 (or no parallel poll PP0), + /* + * one means local parallel poll mode ieee 488.1 PP2 (or no parallel poll PP0), * zero means remote parallel poll configuration mode ieee 488.1 PP1 */ unsigned local_ppoll_mode : 1; }; /* element of event queue */ -typedef struct { +struct gpib_event { struct list_head list; short event_type; -} gpib_event_t; +}; -/* Each board has a list of gpib_status_queue_t to keep track of all open devices +/* + * Each board has a list of gpib_status_queue to keep track of all open devices * on the bus, so we know what address to poll when we get a service request */ -typedef struct { +struct gpib_status_queue { /* list_head so we can make a linked list of devices */ struct list_head list; unsigned int pad; /* primary gpib address */ @@ -323,31 +349,31 @@ typedef struct { unsigned int reference_count; /* flags loss of status byte error due to limit on size of queue */ unsigned dropped_byte : 1; -} gpib_status_queue_t; +}; -typedef struct { +struct gpib_status_byte { struct list_head list; u8 poll_byte; -} status_byte_t; +}; -void init_gpib_status_queue(gpib_status_queue_t *device); +void init_gpib_status_queue(struct gpib_status_queue *device); /* Used to store device-descriptor-specific information */ -typedef struct { +struct gpib_descriptor { unsigned int pad; /* primary gpib address */ int sad; /* secondary gpib address (negative means disabled) */ atomic_t io_in_progress; unsigned is_board : 1; unsigned autopoll_enabled : 1; -} gpib_descriptor_t; +}; -typedef struct { +struct gpib_file_private { atomic_t holding_mutex; - gpib_descriptor_t *descriptors[GPIB_MAX_NUM_DESCRIPTORS]; + struct gpib_descriptor *descriptors[GPIB_MAX_NUM_DESCRIPTORS]; /* locked while descriptors are being allocated/deallocated */ struct mutex descriptors_mutex; unsigned got_module : 1; -} gpib_file_private_t; +}; #endif /* __KERNEL__ */ diff --git a/drivers/staging/gpib/include/nec7210.h b/drivers/staging/gpib/include/nec7210.h index 069896456230..312217b4580e 100644 --- a/drivers/staging/gpib/include/nec7210.h +++ b/drivers/staging/gpib/include/nec7210.h @@ -1,4 +1,4 @@ -//* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0 */ /*************************************************************************** * copyright : (C) 2002 by Frank Mori Hess @@ -78,19 +78,19 @@ enum { }; // interface functions -int nec7210_read(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer, +int nec7210_read(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer, size_t length, int *end, size_t *bytes_read); -int nec7210_write(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer, +int nec7210_write(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written); -int nec7210_command(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer, +int nec7210_command(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer, size_t length, size_t *bytes_written); int nec7210_take_control(struct gpib_board *board, struct nec7210_priv *priv, int syncronous); int nec7210_go_to_standby(struct gpib_board *board, struct nec7210_priv *priv); -void nec7210_request_system_control(struct gpib_board *board, - struct nec7210_priv *priv, int request_control); +int nec7210_request_system_control(struct gpib_board *board, + struct nec7210_priv *priv, int request_control); void nec7210_interface_clear(struct gpib_board *board, struct nec7210_priv *priv, int assert); void nec7210_remote_enable(struct gpib_board *board, struct nec7210_priv *priv, int enable); -int nec7210_enable_eos(struct gpib_board *board, struct nec7210_priv *priv, uint8_t eos_bytes, +int nec7210_enable_eos(struct gpib_board *board, struct nec7210_priv *priv, u8 eos_bytes, int compare_8_bits); void nec7210_disable_eos(struct gpib_board *board, struct nec7210_priv *priv); unsigned int nec7210_update_status(struct gpib_board *board, struct nec7210_priv *priv, @@ -100,14 +100,14 @@ int nec7210_primary_address(const struct gpib_board *board, struct nec7210_priv *priv, unsigned int address); int nec7210_secondary_address(const struct gpib_board *board, struct nec7210_priv *priv, unsigned int address, int enable); -int nec7210_parallel_poll(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *result); -void nec7210_serial_poll_response(struct gpib_board *board, struct nec7210_priv *priv, uint8_t status); +int nec7210_parallel_poll(struct gpib_board *board, struct nec7210_priv *priv, u8 *result); +void nec7210_serial_poll_response(struct gpib_board *board, + struct nec7210_priv *priv, u8 status); void nec7210_parallel_poll_configure(struct gpib_board *board, struct nec7210_priv *priv, unsigned int configuration); void nec7210_parallel_poll_response(struct gpib_board *board, struct nec7210_priv *priv, int ist); -uint8_t nec7210_serial_poll_status(struct gpib_board *board, - struct nec7210_priv *priv); +u8 nec7210_serial_poll_status(struct gpib_board *board, struct nec7210_priv *priv); int nec7210_t1_delay(struct gpib_board *board, struct nec7210_priv *priv, unsigned int nano_sec); void nec7210_return_to_local(const struct gpib_board *board, struct nec7210_priv *priv); @@ -119,18 +119,18 @@ unsigned int nec7210_set_reg_bits(struct nec7210_priv *priv, unsigned int reg, unsigned int mask, unsigned int bits); void nec7210_set_handshake_mode(struct gpib_board *board, struct nec7210_priv *priv, int mode); void nec7210_release_rfd_holdoff(struct gpib_board *board, struct nec7210_priv *priv); -uint8_t nec7210_read_data_in(struct gpib_board *board, struct nec7210_priv *priv, int *end); +u8 nec7210_read_data_in(struct gpib_board *board, struct nec7210_priv *priv, int *end); // wrappers for io functions -uint8_t nec7210_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num); -void nec7210_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned int register_num); -uint8_t nec7210_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num); -void nec7210_iomem_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned int register_num); -uint8_t nec7210_locking_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num); -void nec7210_locking_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, +u8 nec7210_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_ioport_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num); +u8 nec7210_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_iomem_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num); +u8 nec7210_locking_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_locking_ioport_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num); -uint8_t nec7210_locking_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num); -void nec7210_locking_iomem_write_byte(struct nec7210_priv *priv, uint8_t data, +u8 nec7210_locking_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_locking_iomem_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num); // interrupt service routine diff --git a/drivers/staging/gpib/include/nec7210_registers.h b/drivers/staging/gpib/include/nec7210_registers.h index 888803dd97f9..97c53ac8e805 100644 --- a/drivers/staging/gpib/include/nec7210_registers.h +++ b/drivers/staging/gpib/include/nec7210_registers.h @@ -17,7 +17,8 @@ enum nec7210_chipset { TNT5004, // NI (minor differences to TNT4882) }; -/* nec7210 register numbers (might need to be multiplied by +/* + * nec7210 register numbers (might need to be multiplied by * a board-dependent offset to get actually io address offset) */ // write registers diff --git a/drivers/staging/gpib/include/tms9914.h b/drivers/staging/gpib/include/tms9914.h index 424c95ad85c6..50a9d3b22619 100644 --- a/drivers/staging/gpib/include/tms9914.h +++ b/drivers/staging/gpib/include/tms9914.h @@ -1,4 +1,4 @@ -//* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0 */ /*************************************************************************** * copyright : (C) 2002 by Frank Mori Hess @@ -79,24 +79,25 @@ enum { }; // interface functions -int tms9914_read(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer, +int tms9914_read(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer, size_t length, int *end, size_t *bytes_read); -int tms9914_write(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer, +int tms9914_write(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written); -int tms9914_command(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer, +int tms9914_command(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer, size_t length, size_t *bytes_written); int tms9914_take_control(struct gpib_board *board, struct tms9914_priv *priv, int syncronous); -/* alternate version of tms9914_take_control which works around buggy tcs +/* + * alternate version of tms9914_take_control which works around buggy tcs * implementation. */ int tms9914_take_control_workaround(struct gpib_board *board, struct tms9914_priv *priv, int syncronous); int tms9914_go_to_standby(struct gpib_board *board, struct tms9914_priv *priv); -void tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv, - int request_control); +int tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv, + int request_control); void tms9914_interface_clear(struct gpib_board *board, struct tms9914_priv *priv, int assert); void tms9914_remote_enable(struct gpib_board *board, struct tms9914_priv *priv, int enable); -int tms9914_enable_eos(struct gpib_board *board, struct tms9914_priv *priv, uint8_t eos_bytes, +int tms9914_enable_eos(struct gpib_board *board, struct tms9914_priv *priv, u8 eos_bytes, int compare_8_bits); void tms9914_disable_eos(struct gpib_board *board, struct tms9914_priv *priv); unsigned int tms9914_update_status(struct gpib_board *board, struct tms9914_priv *priv, @@ -105,13 +106,14 @@ int tms9914_primary_address(struct gpib_board *board, struct tms9914_priv *priv, unsigned int address); int tms9914_secondary_address(struct gpib_board *board, struct tms9914_priv *priv, unsigned int address, int enable); -int tms9914_parallel_poll(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *result); +int tms9914_parallel_poll(struct gpib_board *board, struct tms9914_priv *priv, u8 *result); void tms9914_parallel_poll_configure(struct gpib_board *board, - struct tms9914_priv *priv, uint8_t config); + struct tms9914_priv *priv, u8 config); void tms9914_parallel_poll_response(struct gpib_board *board, struct tms9914_priv *priv, int ist); -void tms9914_serial_poll_response(struct gpib_board *board, struct tms9914_priv *priv, uint8_t status); -uint8_t tms9914_serial_poll_status(struct gpib_board *board, struct tms9914_priv *priv); +void tms9914_serial_poll_response(struct gpib_board *board, + struct tms9914_priv *priv, u8 status); +u8 tms9914_serial_poll_status(struct gpib_board *board, struct tms9914_priv *priv); int tms9914_line_status(const struct gpib_board *board, struct tms9914_priv *priv); unsigned int tms9914_t1_delay(struct gpib_board *board, struct tms9914_priv *priv, unsigned int nano_sec); @@ -124,10 +126,10 @@ void tms9914_release_holdoff(struct tms9914_priv *priv); void tms9914_set_holdoff_mode(struct tms9914_priv *priv, enum tms9914_holdoff_mode mode); // wrappers for io functions -uint8_t tms9914_ioport_read_byte(struct tms9914_priv *priv, unsigned int register_num); -void tms9914_ioport_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num); -uint8_t tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register_num); -void tms9914_iomem_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num); +u8 tms9914_ioport_read_byte(struct tms9914_priv *priv, unsigned int register_num); +void tms9914_ioport_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num); +u8 tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register_num); +void tms9914_iomem_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num); // interrupt service routine irqreturn_t tms9914_interrupt(struct gpib_board *board, struct tms9914_priv *priv); @@ -139,7 +141,8 @@ enum { ms9914_num_registers = 8, }; -/* tms9914 register numbers (might need to be multiplied by +/* + * tms9914 register numbers (might need to be multiplied by * a board-dependent offset to get actually io address offset) */ // write registers diff --git a/drivers/staging/gpib/ines/ines.h b/drivers/staging/gpib/ines/ines.h index ff27f055a0ff..f0210ce2470d 100644 --- a/drivers/staging/gpib/ines/ines.h +++ b/drivers/staging/gpib/ines/ines.h @@ -35,44 +35,6 @@ struct ines_priv { u8 extend_mode_bits; }; -// interface functions -int ines_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read); -int ines_write(struct gpib_board *board, uint8_t *buffer, size_t length, - int send_eoi, size_t *bytes_written); -int ines_accel_read(struct gpib_board *board, uint8_t *buffer, size_t length, - int *end, size_t *bytes_read); -int ines_accel_write(struct gpib_board *board, uint8_t *buffer, size_t length, - int send_eoi, size_t *bytes_written); -int ines_command(struct gpib_board *board, uint8_t *buffer, size_t length, size_t *bytes_written); -int ines_take_control(struct gpib_board *board, int synchronous); -int ines_go_to_standby(struct gpib_board *board); -void ines_request_system_control(struct gpib_board *board, int request_control); -void ines_interface_clear(struct gpib_board *board, int assert); -void ines_remote_enable(struct gpib_board *board, int enable); -int ines_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits); -void ines_disable_eos(struct gpib_board *board); -unsigned int ines_update_status(struct gpib_board *board, unsigned int clear_mask); -int ines_primary_address(struct gpib_board *board, unsigned int address); -int ines_secondary_address(struct gpib_board *board, unsigned int address, int enable); -int ines_parallel_poll(struct gpib_board *board, uint8_t *result); -void ines_parallel_poll_configure(struct gpib_board *board, uint8_t config); -void ines_parallel_poll_response(struct gpib_board *board, int ist); -void ines_serial_poll_response(struct gpib_board *board, uint8_t status); -uint8_t ines_serial_poll_status(struct gpib_board *board); -int ines_line_status(const struct gpib_board *board); -int ines_t1_delay(struct gpib_board *board, unsigned int nano_sec); -void ines_return_to_local(struct gpib_board *board); - -// interrupt service routines -irqreturn_t ines_pci_interrupt(int irq, void *arg); -irqreturn_t ines_interrupt(struct gpib_board *board); - -// utility functions -void ines_free_private(struct gpib_board *board); -int ines_generic_attach(struct gpib_board *board); -void ines_online(struct ines_priv *priv, const struct gpib_board *board, int use_accel); -void ines_set_xfer_counter(struct ines_priv *priv, unsigned int count); - /* inb/outb wrappers */ static inline unsigned int ines_inb(struct ines_priv *priv, unsigned int register_number) { @@ -87,11 +49,6 @@ static inline void ines_outb(struct ines_priv *priv, unsigned int value, register_number * priv->nec7210_priv.offset); } -// pcmcia init/cleanup - -int ines_pcmcia_init_module(void); -void ines_pcmcia_cleanup_module(void); - enum ines_regs { // read FIFO_STATUS = 0x8, diff --git a/drivers/staging/gpib/ines/ines_gpib.c b/drivers/staging/gpib/ines/ines_gpib.c index d93eb05dab90..c851fd014f48 100644 --- a/drivers/staging/gpib/ines/ines_gpib.c +++ b/drivers/staging/gpib/ines/ines_gpib.c @@ -25,7 +25,9 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("GPIB driver for Ines iGPIB 72010"); -int ines_line_status(const struct gpib_board *board) +static irqreturn_t ines_interrupt(struct gpib_board *board); + +static int ines_line_status(const struct gpib_board *board) { int status = VALID_ALL; int bcm_bits; @@ -55,7 +57,7 @@ int ines_line_status(const struct gpib_board *board) return status; } -void ines_set_xfer_counter(struct ines_priv *priv, unsigned int count) +static void ines_set_xfer_counter(struct ines_priv *priv, unsigned int count) { if (count > 0xffff) { pr_err("bug! tried to set xfer counter > 0xffff\n"); @@ -65,7 +67,7 @@ void ines_set_xfer_counter(struct ines_priv *priv, unsigned int count) ines_outb(priv, count & 0xff, XFER_COUNT_LOWER); } -int ines_t1_delay(struct gpib_board *board, unsigned int nano_sec) +static int ines_t1_delay(struct gpib_board *board, unsigned int nano_sec) { struct ines_priv *ines_priv = board->private_data; struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv; @@ -95,7 +97,7 @@ static inline unsigned short num_in_fifo_bytes(struct ines_priv *ines_priv) return ines_inb(ines_priv, IN_FIFO_COUNT); } -static ssize_t pio_read(struct gpib_board *board, struct ines_priv *ines_priv, uint8_t *buffer, +static ssize_t pio_read(struct gpib_board *board, struct ines_priv *ines_priv, u8 *buffer, size_t length, size_t *nbytes) { ssize_t retval = 0; @@ -133,8 +135,8 @@ static ssize_t pio_read(struct gpib_board *board, struct ines_priv *ines_priv, u return retval; } -int ines_accel_read(struct gpib_board *board, uint8_t *buffer, - size_t length, int *end, size_t *bytes_read) +static int ines_accel_read(struct gpib_board *board, u8 *buffer, + size_t length, int *end, size_t *bytes_read) { ssize_t retval = 0; struct ines_priv *ines_priv = board->private_data; @@ -213,8 +215,8 @@ static int ines_write_wait(struct gpib_board *board, struct ines_priv *ines_priv return 0; } -int ines_accel_write(struct gpib_board *board, uint8_t *buffer, size_t length, - int send_eoi, size_t *bytes_written) +static int ines_accel_write(struct gpib_board *board, u8 *buffer, size_t length, + int send_eoi, size_t *bytes_written) { size_t count = 0; ssize_t retval = 0; @@ -264,7 +266,7 @@ int ines_accel_write(struct gpib_board *board, uint8_t *buffer, size_t length, return retval; } -irqreturn_t ines_pci_interrupt(int irq, void *arg) +static irqreturn_t ines_pci_interrupt(int irq, void *arg) { struct gpib_board *board = arg; struct ines_priv *priv = board->private_data; @@ -281,7 +283,7 @@ irqreturn_t ines_pci_interrupt(int irq, void *arg) return ines_interrupt(board); } -irqreturn_t ines_interrupt(struct gpib_board *board) +static irqreturn_t ines_interrupt(struct gpib_board *board) { struct ines_priv *priv = board->private_data; struct nec7210_priv *nec_priv = &priv->nec7210_priv; @@ -295,7 +297,7 @@ irqreturn_t ines_interrupt(struct gpib_board *board) isr3_bits = ines_inb(priv, ISR3); isr4_bits = ines_inb(priv, ISR4); if (isr3_bits & IFC_ACTIVE_BIT) { - push_gpib_event(board, EventIFC); + push_gpib_event(board, EVENT_IFC); wake++; } if (isr3_bits & FIFO_ERROR_BIT) @@ -313,9 +315,9 @@ irqreturn_t ines_interrupt(struct gpib_board *board) return IRQ_HANDLED; } -static int ines_pci_attach(struct gpib_board *board, const gpib_board_config_t *config); -static int ines_pci_accel_attach(struct gpib_board *board, const gpib_board_config_t *config); -static int ines_isa_attach(struct gpib_board *board, const gpib_board_config_t *config); +static int ines_pci_attach(struct gpib_board *board, const struct gpib_board_config *config); +static int ines_pci_accel_attach(struct gpib_board *board, const struct gpib_board_config *config); +static int ines_isa_attach(struct gpib_board *board, const struct gpib_board_config *config); static void ines_pci_detach(struct gpib_board *board); static void ines_isa_detach(struct gpib_board *board); @@ -393,8 +395,8 @@ static struct ines_pci_id pci_ids[] = { static const int num_pci_chips = ARRAY_SIZE(pci_ids); // wrappers for interface functions -int ines_read(struct gpib_board *board, uint8_t *buffer, size_t length, - int *end, size_t *bytes_read) +static int ines_read(struct gpib_board *board, u8 *buffer, size_t length, + int *end, size_t *bytes_read) { struct ines_priv *priv = board->private_data; struct nec7210_priv *nec_priv = &priv->nec7210_priv; @@ -412,134 +414,134 @@ int ines_read(struct gpib_board *board, uint8_t *buffer, size_t length, return retval; } -int ines_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi, - size_t *bytes_written) +static int ines_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, + size_t *bytes_written) { struct ines_priv *priv = board->private_data; return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); } -int ines_command(struct gpib_board *board, uint8_t *buffer, size_t length, size_t *bytes_written) +static int ines_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { struct ines_priv *priv = board->private_data; return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written); } -int ines_take_control(struct gpib_board *board, int synchronous) +static int ines_take_control(struct gpib_board *board, int synchronous) { struct ines_priv *priv = board->private_data; return nec7210_take_control(board, &priv->nec7210_priv, synchronous); } -int ines_go_to_standby(struct gpib_board *board) +static int ines_go_to_standby(struct gpib_board *board) { struct ines_priv *priv = board->private_data; return nec7210_go_to_standby(board, &priv->nec7210_priv); } -void ines_request_system_control(struct gpib_board *board, int request_control) +static int ines_request_system_control(struct gpib_board *board, int request_control) { struct ines_priv *priv = board->private_data; - nec7210_request_system_control(board, &priv->nec7210_priv, request_control); + return nec7210_request_system_control(board, &priv->nec7210_priv, request_control); } -void ines_interface_clear(struct gpib_board *board, int assert) +static void ines_interface_clear(struct gpib_board *board, int assert) { struct ines_priv *priv = board->private_data; nec7210_interface_clear(board, &priv->nec7210_priv, assert); } -void ines_remote_enable(struct gpib_board *board, int enable) +static void ines_remote_enable(struct gpib_board *board, int enable) { struct ines_priv *priv = board->private_data; nec7210_remote_enable(board, &priv->nec7210_priv, enable); } -int ines_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits) +static int ines_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct ines_priv *priv = board->private_data; return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits); } -void ines_disable_eos(struct gpib_board *board) +static void ines_disable_eos(struct gpib_board *board) { struct ines_priv *priv = board->private_data; nec7210_disable_eos(board, &priv->nec7210_priv); } -unsigned int ines_update_status(struct gpib_board *board, unsigned int clear_mask) +static unsigned int ines_update_status(struct gpib_board *board, unsigned int clear_mask) { struct ines_priv *priv = board->private_data; return nec7210_update_status(board, &priv->nec7210_priv, clear_mask); } -int ines_primary_address(struct gpib_board *board, unsigned int address) +static int ines_primary_address(struct gpib_board *board, unsigned int address) { struct ines_priv *priv = board->private_data; return nec7210_primary_address(board, &priv->nec7210_priv, address); } -int ines_secondary_address(struct gpib_board *board, unsigned int address, int enable) +static int ines_secondary_address(struct gpib_board *board, unsigned int address, int enable) { struct ines_priv *priv = board->private_data; return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); } -int ines_parallel_poll(struct gpib_board *board, uint8_t *result) +static int ines_parallel_poll(struct gpib_board *board, u8 *result) { struct ines_priv *priv = board->private_data; return nec7210_parallel_poll(board, &priv->nec7210_priv, result); } -void ines_parallel_poll_configure(struct gpib_board *board, uint8_t config) +static void ines_parallel_poll_configure(struct gpib_board *board, u8 config) { struct ines_priv *priv = board->private_data; nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config); } -void ines_parallel_poll_response(struct gpib_board *board, int ist) +static void ines_parallel_poll_response(struct gpib_board *board, int ist) { struct ines_priv *priv = board->private_data; nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); } -void ines_serial_poll_response(struct gpib_board *board, uint8_t status) +static void ines_serial_poll_response(struct gpib_board *board, u8 status) { struct ines_priv *priv = board->private_data; nec7210_serial_poll_response(board, &priv->nec7210_priv, status); } -uint8_t ines_serial_poll_status(struct gpib_board *board) +static u8 ines_serial_poll_status(struct gpib_board *board) { struct ines_priv *priv = board->private_data; return nec7210_serial_poll_status(board, &priv->nec7210_priv); } -void ines_return_to_local(struct gpib_board *board) +static void ines_return_to_local(struct gpib_board *board) { struct ines_priv *priv = board->private_data; nec7210_return_to_local(board, &priv->nec7210_priv); } -static gpib_interface_t ines_pci_unaccel_interface = { +static struct gpib_interface ines_pci_unaccel_interface = { .name = "ines_pci_unaccel", .attach = ines_pci_attach, .detach = ines_pci_detach, @@ -567,7 +569,7 @@ static gpib_interface_t ines_pci_unaccel_interface = { .return_to_local = ines_return_to_local, }; -static gpib_interface_t ines_pci_interface = { +static struct gpib_interface ines_pci_interface = { .name = "ines_pci", .attach = ines_pci_accel_attach, .detach = ines_pci_detach, @@ -595,7 +597,7 @@ static gpib_interface_t ines_pci_interface = { .return_to_local = ines_return_to_local, }; -static gpib_interface_t ines_pci_accel_interface = { +static struct gpib_interface ines_pci_accel_interface = { .name = "ines_pci_accel", .attach = ines_pci_accel_attach, .detach = ines_pci_detach, @@ -623,7 +625,7 @@ static gpib_interface_t ines_pci_accel_interface = { .return_to_local = ines_return_to_local, }; -static gpib_interface_t ines_isa_interface = { +static struct gpib_interface ines_isa_interface = { .name = "ines_isa", .attach = ines_isa_attach, .detach = ines_isa_detach, @@ -664,13 +666,13 @@ static int ines_allocate_private(struct gpib_board *board) return 0; } -void ines_free_private(struct gpib_board *board) +static void ines_free_private(struct gpib_board *board) { kfree(board->private_data); board->private_data = NULL; } -int ines_generic_attach(struct gpib_board *board) +static int ines_generic_attach(struct gpib_board *board) { struct ines_priv *ines_priv; struct nec7210_priv *nec_priv; @@ -690,7 +692,7 @@ int ines_generic_attach(struct gpib_board *board) return 0; } -void ines_online(struct ines_priv *ines_priv, const struct gpib_board *board, int use_accel) +static void ines_online(struct ines_priv *ines_priv, const struct gpib_board *board, int use_accel) { struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv; @@ -724,7 +726,7 @@ void ines_online(struct ines_priv *ines_priv, const struct gpib_board *board, in nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE | HR_DIIE, 0); } -static int ines_common_pci_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ines_common_pci_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct ines_priv *ines_priv; struct nec7210_priv *nec_priv; @@ -852,7 +854,7 @@ static int ines_common_pci_attach(struct gpib_board *board, const gpib_board_con return 0; } -int ines_pci_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ines_pci_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct ines_priv *ines_priv; int retval; @@ -867,7 +869,7 @@ int ines_pci_attach(struct gpib_board *board, const gpib_board_config_t *config) return 0; } -int ines_pci_accel_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ines_pci_accel_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct ines_priv *ines_priv; int retval; @@ -884,7 +886,7 @@ int ines_pci_accel_attach(struct gpib_board *board, const gpib_board_config_t *c static const int ines_isa_iosize = 0x20; -int ines_isa_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ines_isa_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct ines_priv *ines_priv; struct nec7210_priv *nec_priv; @@ -915,7 +917,7 @@ int ines_isa_attach(struct gpib_board *board, const gpib_board_config_t *config) return 0; } -void ines_pci_detach(struct gpib_board *board) +static void ines_pci_detach(struct gpib_board *board) { struct ines_priv *ines_priv = board->private_data; struct nec7210_priv *nec_priv; @@ -949,7 +951,7 @@ void ines_pci_detach(struct gpib_board *board) ines_free_private(board); } -void ines_isa_detach(struct gpib_board *board) +static void ines_isa_detach(struct gpib_board *board) { struct ines_priv *ines_priv = board->private_data; struct nec7210_priv *nec_priv; @@ -990,48 +992,49 @@ static struct pci_driver ines_pci_driver = { static const int ines_pcmcia_iosize = 0x20; -/* The event() function is this driver's Card Services event handler. - * It will be called by Card Services when an appropriate card status - * event is received. The config() and release() entry points are - * used to configure or release a socket, in response to card insertion - * and ejection events. They are invoked from the gpib event - * handler. +/* + * The event() function is this driver's Card Services event handler. + * It will be called by Card Services when an appropriate card status + * event is received. The config() and release() entry points are + * used to configure or release a socket, in response to card insertion + * and ejection events. They are invoked from the gpib event + * handler. */ static int ines_gpib_config(struct pcmcia_device *link); static void ines_gpib_release(struct pcmcia_device *link); -static int ines_pcmcia_attach(struct gpib_board *board, const gpib_board_config_t *config); -static int ines_pcmcia_accel_attach(struct gpib_board *board, const gpib_board_config_t *config); +static int ines_pcmcia_attach(struct gpib_board *board, const struct gpib_board_config *config); +static int ines_pcmcia_accel_attach(struct gpib_board *board, + const struct gpib_board_config *config); static void ines_pcmcia_detach(struct gpib_board *board); -static irqreturn_t ines_pcmcia_interrupt(int irq, void *arg); static int ines_common_pcmcia_attach(struct gpib_board *board); /* * A linked list of "instances" of the gpib device. Each actual - * PCMCIA card corresponds to one device instance, and is described - * by one dev_link_t structure (defined in ds.h). + * PCMCIA card corresponds to one device instance, and is described + * by one dev_link_t structure (defined in ds.h). * - * You may not want to use a linked list for this -- for example, the - * memory card driver uses an array of dev_link_t pointers, where minor - * device numbers are used to derive the corresponding array index. + * You may not want to use a linked list for this -- for example, the + * memory card driver uses an array of dev_link_t pointers, where minor + * device numbers are used to derive the corresponding array index. */ static struct pcmcia_device *curr_dev; /* - * A dev_link_t structure has fields for most things that are needed - * to keep track of a socket, but there will usually be some device - * specific information that also needs to be kept track of. The - * 'priv' pointer in a dev_link_t structure can be used to point to - * a device-specific private data structure, like this. + * A dev_link_t structure has fields for most things that are needed + * to keep track of a socket, but there will usually be some device + * specific information that also needs to be kept track of. The + * 'priv' pointer in a dev_link_t structure can be used to point to + * a device-specific private data structure, like this. * - * A driver needs to provide a dev_node_t structure for each device - * on a card. In some cases, there is only one device per card (for - * example, ethernet cards, modems). In other cases, there may be - * many actual or logical devices (SCSI adapters, memory cards with - * multiple partitions). The dev_node_t structures need to be kept - * in a linked list starting at the 'dev' field of a dev_link_t - * structure. We allocate them in the card's private data structure, - * because they generally can't be allocated dynamically. + * A driver needs to provide a dev_node_t structure for each device + * on a card. In some cases, there is only one device per card (for + * example, ethernet cards, modems). In other cases, there may be + * many actual or logical devices (SCSI adapters, memory cards with + * multiple partitions). The dev_node_t structures need to be kept + * in a linked list starting at the 'dev' field of a dev_link_t + * structure. We allocate them in the card's private data structure, + * because they generally can't be allocated dynamically. */ struct local_info { @@ -1042,13 +1045,13 @@ struct local_info { }; /* - * gpib_attach() creates an "instance" of the driver, allocating - * local data structures for one device. The device is registered - * with Card Services. + * gpib_attach() creates an "instance" of the driver, allocating + * local data structures for one device. The device is registered + * with Card Services. * - * The dev_link structure is initialized, but we don't actually - * configure the card at this point -- we wait until we receive a - * card insertion event. + * The dev_link structure is initialized, but we don't actually + * configure the card at this point -- we wait until we receive a + * card insertion event. */ static int ines_gpib_probe(struct pcmcia_device *link) { @@ -1079,10 +1082,10 @@ static int ines_gpib_probe(struct pcmcia_device *link) } /* - * This deletes a driver "instance". The device is de-registered - * with Card Services. If it has been released, all local data - * structures are freed. Otherwise, the structures will be freed - * when the device is released. + * This deletes a driver "instance". The device is de-registered + * with Card Services. If it has been released, all local data + * structures are freed. Otherwise, the structures will be freed + * when the device is released. */ static void ines_gpib_remove(struct pcmcia_device *link) { @@ -1103,18 +1106,15 @@ static int ines_gpib_config_iteration(struct pcmcia_device *link, void *priv_dat } /* - * gpib_config() is scheduled to run after a CARD_INSERTION event - * is received, to configure the PCMCIA socket, and to make the - * device available to the system. + * gpib_config() is scheduled to run after a CARD_INSERTION event + * is received, to configure the PCMCIA socket, and to make the + * device available to the system. */ static int ines_gpib_config(struct pcmcia_device *link) { - struct local_info *dev; int retval; void __iomem *virt; - dev = link->priv; - retval = pcmcia_loop_config(link, &ines_gpib_config_iteration, NULL); if (retval) { dev_warn(&link->dev, "no configuration found\n"); @@ -1125,8 +1125,9 @@ static int ines_gpib_config(struct pcmcia_device *link) dev_dbg(&link->dev, "ines_cs: manufacturer: 0x%x card: 0x%x\n", link->manf_id, link->card_id); - /* for the ines card we have to setup the configuration registers in - * attribute memory here + /* + * for the ines card we have to setup the configuration registers in + * attribute memory here */ link->resource[2]->flags |= WIN_MEMORY_TYPE_AM | WIN_DATA_WIDTH_8 | WIN_ENABLE; link->resource[2]->end = 0x1000; @@ -1159,9 +1160,9 @@ static int ines_gpib_config(struct pcmcia_device *link) } /* gpib_config */ /* - * After a card is removed, gpib_release() will unregister the net - * device, and release the PCMCIA configuration. If the device is - * still open, this will be postponed until it is closed. + * After a card is removed, gpib_release() will unregister the net + * device, and release the PCMCIA configuration. If the device is + * still open, this will be postponed until it is closed. */ static void ines_gpib_release(struct pcmcia_device *link) @@ -1210,12 +1211,12 @@ static struct pcmcia_driver ines_gpib_cs_driver = { .resume = ines_gpib_resume, }; -void ines_pcmcia_cleanup_module(void) +static void ines_pcmcia_cleanup_module(void) { pcmcia_unregister_driver(&ines_gpib_cs_driver); } -static gpib_interface_t ines_pcmcia_unaccel_interface = { +static struct gpib_interface ines_pcmcia_unaccel_interface = { .name = "ines_pcmcia_unaccel", .attach = ines_pcmcia_attach, .detach = ines_pcmcia_detach, @@ -1243,7 +1244,7 @@ static gpib_interface_t ines_pcmcia_unaccel_interface = { .return_to_local = ines_return_to_local, }; -static gpib_interface_t ines_pcmcia_accel_interface = { +static struct gpib_interface ines_pcmcia_accel_interface = { .name = "ines_pcmcia_accel", .attach = ines_pcmcia_accel_attach, .detach = ines_pcmcia_detach, @@ -1271,7 +1272,7 @@ static gpib_interface_t ines_pcmcia_accel_interface = { .return_to_local = ines_return_to_local, }; -static gpib_interface_t ines_pcmcia_interface = { +static struct gpib_interface ines_pcmcia_interface = { .name = "ines_pcmcia", .attach = ines_pcmcia_accel_attach, .detach = ines_pcmcia_detach, @@ -1299,14 +1300,14 @@ static gpib_interface_t ines_pcmcia_interface = { .return_to_local = ines_return_to_local, }; -irqreturn_t ines_pcmcia_interrupt(int irq, void *arg) +static irqreturn_t ines_pcmcia_interrupt(int irq, void *arg) { struct gpib_board *board = arg; return ines_interrupt(board); } -int ines_common_pcmcia_attach(struct gpib_board *board) +static int ines_common_pcmcia_attach(struct gpib_board *board) { struct ines_priv *ines_priv; struct nec7210_priv *nec_priv; @@ -1345,7 +1346,7 @@ int ines_common_pcmcia_attach(struct gpib_board *board) return 0; } -int ines_pcmcia_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ines_pcmcia_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct ines_priv *ines_priv; int retval; @@ -1360,7 +1361,8 @@ int ines_pcmcia_attach(struct gpib_board *board, const gpib_board_config_t *conf return 0; } -int ines_pcmcia_accel_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ines_pcmcia_accel_attach(struct gpib_board *board, + const struct gpib_board_config *config) { struct ines_priv *ines_priv; int retval; @@ -1375,7 +1377,7 @@ int ines_pcmcia_accel_attach(struct gpib_board *board, const gpib_board_config_t return 0; } -void ines_pcmcia_detach(struct gpib_board *board) +static void ines_pcmcia_detach(struct gpib_board *board) { struct ines_priv *ines_priv = board->private_data; struct nec7210_priv *nec_priv; @@ -1484,7 +1486,7 @@ static void __exit ines_exit_module(void) gpib_unregister_driver(&ines_pci_unaccel_interface); gpib_unregister_driver(&ines_pci_accel_interface); gpib_unregister_driver(&ines_isa_interface); -#ifdef GPIB__PCMCIA +#ifdef CONFIG_GPIB_PCMCIA gpib_unregister_driver(&ines_pcmcia_interface); gpib_unregister_driver(&ines_pcmcia_unaccel_interface); gpib_unregister_driver(&ines_pcmcia_accel_interface); diff --git a/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c b/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c index faf96e9cc4a1..dd68c4843490 100644 --- a/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c +++ b/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c @@ -36,16 +36,16 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("GPIB driver for LPVO usb devices"); /* - * Table of devices that work with this driver. + * Table of devices that work with this driver. * - * Currently, only one device is known to be used in the - * lpvo_usb_gpib adapter (FTDI 0403:6001). - * If your adapter uses a different chip, insert a line - * in the following table with proper <Vendor-id>, <Product-id>. + * Currently, only one device is known to be used in the + * lpvo_usb_gpib adapter (FTDI 0403:6001). + * If your adapter uses a different chip, insert a line + * in the following table with proper <Vendor-id>, <Product-id>. * - * To have your chip automatically handled by the driver, - * update files "/usr/local/etc/modprobe.d/lpvo_usb_gpib.conf" - * and /usr/local/etc/udev/rules.d/99-lpvo_usb_gpib.rules. + * To have your chip automatically handled by the driver, + * update files "/usr/local/etc/modprobe.d/lpvo_usb_gpib.conf" + * and /usr/local/etc/udev/rules.d/99-lpvo_usb_gpib.rules. * */ @@ -56,18 +56,18 @@ static const struct usb_device_id skel_table[] = { MODULE_DEVICE_TABLE(usb, skel_table); /* - * *** Diagnostics and Debug *** - * To enable the diagnostic and debug messages either compile with DEBUG set - * or control via the dynamic debug mechanisms. - * The module parameter "debug" controls the sending of debug messages to - * syslog. By default it is set to 0 - * debug = 0: only attach/detach messages are sent - * 1: every action is logged - * 2: extended logging; each single exchanged byte is documented - * (about twice the log volume of [1]) - * To switch debug level: - * At module loading: modprobe lpvo_usb_gpib debug={0,1,2} - * On the fly: echo {0,1,2} > /sys/modules/lpvo_usb_gpib/parameters/debug + * *** Diagnostics and Debug *** + * To enable the diagnostic and debug messages either compile with DEBUG set + * or control via the dynamic debug mechanisms. + * The module parameter "debug" controls the sending of debug messages to + * syslog. By default it is set to 0 + * debug = 0: only attach/detach messages are sent + * 1: every action is logged + * 2: extended logging; each single exchanged byte is documented + * (about twice the log volume of [1]) + * To switch debug level: + * At module loading: modprobe lpvo_usb_gpib debug={0,1,2} + * On the fly: echo {0,1,2} > /sys/modules/lpvo_usb_gpib/parameters/debug */ static int debug; @@ -169,10 +169,10 @@ static void show_status(struct gpib_board *board) } /* - * GLOBAL VARIABLES: required for - * pairing among gpib minor and usb minor. - * MAX_DEV is the max number of usb-gpib adapters; free - * to change as you like, but no more than 32 + * GLOBAL VARIABLES: required for + * pairing among gpib minor and usb minor. + * MAX_DEV is the max number of usb-gpib adapters; free + * to change as you like, but no more than 32 */ #define MAX_DEV 8 @@ -182,7 +182,7 @@ static int assigned_usb_minors; /* mask of filled slots */ static struct mutex minors_lock; /* operations on usb_minors are to be protected */ /* - * usb-skeleton prototypes + * usb-skeleton prototypes */ struct usb_skel; @@ -192,7 +192,7 @@ static int skel_do_open(struct gpib_board *, int); static int skel_do_release(struct gpib_board *); /* - * usec_diff : take difference in MICROsec between two 'timespec' + * usec_diff : take difference in MICROsec between two 'timespec' * (unix time in sec and NANOsec) */ @@ -203,7 +203,7 @@ static inline int usec_diff(struct timespec64 *a, struct timespec64 *b) } /* - * *** these routines are specific to the usb-gpib adapter *** + * *** these routines are specific to the usb-gpib adapter *** */ /** @@ -262,13 +262,11 @@ static int send_command(struct gpib_board *board, char *msg, int leng) } /* - * * set_control_line() - Set the value of a single gpib control line * * @board: the gpib_board_struct data area for this gpib interface * @line: line mask * @value: line new value (0/1) - * */ static int set_control_line(struct gpib_board *board, int line, int value) @@ -368,7 +366,7 @@ static void set_timeout(struct gpib_board *board) } /* - * now the standard interface functions - attach and detach + * now the standard interface functions - attach and detach */ /** @@ -384,7 +382,7 @@ static void set_timeout(struct gpib_board *board) * detach() will be called. Always. */ -static int usb_gpib_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int usb_gpib_attach(struct gpib_board *board, const struct gpib_board_config *config) { int retval, j; u32 base = config->ibbase; @@ -464,7 +462,8 @@ static int usb_gpib_attach(struct gpib_board *board, const gpib_board_config_t * if (retval != ACK) return -EIO; - /* We must setup debug mode because we need the extended instruction + /* + * We must setup debug mode because we need the extended instruction * set to cope with the Core (gpib_common) point of view */ @@ -473,7 +472,8 @@ static int usb_gpib_attach(struct gpib_board *board, const gpib_board_config_t * if (retval != ACK) return -EIO; - /* We must keep REN off after an IFC because so it is + /* + * We must keep REN off after an IFC because so it is * assumed by the Core */ @@ -654,7 +654,8 @@ static int usb_gpib_line_status(const struct gpib_board *board) DIA_LOG(1, "%s\n", "request"); - /* if we are on the wait queue (board->wait), do not hurry + /* + * if we are on the wait queue (board->wait), do not hurry * reading status line; instead, pause a little */ @@ -705,9 +706,10 @@ static int usb_gpib_line_status(const struct gpib_board *board) /* parallel_poll */ -static int usb_gpib_parallel_poll(struct gpib_board *board, uint8_t *result) +static int usb_gpib_parallel_poll(struct gpib_board *board, u8 *result) { - /* request parallel poll asserting ATN | EOI; + /* + * request parallel poll asserting ATN | EOI; * we suppose ATN already asserted */ @@ -789,7 +791,6 @@ static int usb_gpib_read(struct gpib_board *board, return -EIO; else return -ETIME; - return 0; } /* allocate buffer for multibyte read */ @@ -909,15 +910,13 @@ static void usb_gpib_remote_enable(struct gpib_board *board, int enable) /* request_system_control */ -static void usb_gpib_request_system_control(struct gpib_board *board, - int request_control) +static int usb_gpib_request_system_control(struct gpib_board *board, int request_control) { - if (request_control) - set_bit(CIC_NUM, &board->status); - else - clear_bit(CIC_NUM, &board->status); + if (!request_control) + return -EINVAL; DIA_LOG(1, "done with %d -> %lx\n", request_control, board->status); + return 0; } /* take_control */ @@ -997,7 +996,7 @@ static int usb_gpib_write(struct gpib_board *board, /* parallel_poll configure */ static void usb_gpib_parallel_poll_configure(struct gpib_board *board, - uint8_t configuration) + u8 configuration) { } @@ -1031,13 +1030,13 @@ static int usb_gpib_secondary_address(struct gpib_board *board, /* serial_poll_response */ -static void usb_gpib_serial_poll_response(struct gpib_board *board, uint8_t status) +static void usb_gpib_serial_poll_response(struct gpib_board *board, u8 status) { } /* serial_poll_status */ -static uint8_t usb_gpib_serial_poll_status(struct gpib_board *board) +static u8 usb_gpib_serial_poll_status(struct gpib_board *board) { return 0; } @@ -1053,7 +1052,7 @@ static int usb_gpib_t1_delay(struct gpib_board *board, unsigned int nano_sec) * *** module dispatch table and init/exit functions *** */ -static gpib_interface_t usb_gpib_interface = { +static struct gpib_interface usb_gpib_interface = { .name = NAME, .attach = usb_gpib_attach, .detach = usb_gpib_detach, @@ -1083,13 +1082,13 @@ static gpib_interface_t usb_gpib_interface = { }; /* - * usb_gpib_init_module(), usb_gpib_exit_module() + * usb_gpib_init_module(), usb_gpib_exit_module() * - * This functions are called every time a new device is detected - * and registered or is removed and unregistered. - * We must take note of created and destroyed usb minors to be used - * when usb_gpib_attach() and usb_gpib_detach() will be called on - * request by gpib_config. + * This functions are called every time a new device is detected + * and registered or is removed and unregistered. + * We must take note of created and destroyed usb minors to be used + * when usb_gpib_attach() and usb_gpib_detach() will be called on + * request by gpib_config. */ static int usb_gpib_init_module(struct usb_interface *interface) @@ -1107,8 +1106,9 @@ static int usb_gpib_init_module(struct usb_interface *interface) goto exit; } } else { - /* check if minor is already registered - maybe useless, but if - * it happens the code is inconsistent somewhere + /* + * check if minor is already registered - maybe useless, but if + * it happens the code is inconsistent somewhere */ for (j = 0 ; j < MAX_DEV ; j++) { @@ -1162,12 +1162,11 @@ exit: } /* - * Default latency time (16 msec) is too long. - * We must use 1 msec (best); anyhow, no more than 5 msec. - * - * Defines and function taken and modified from the kernel tree - * (see ftdi_sio.h and ftdi_sio.c). + * Default latency time (16 msec) is too long. + * We must use 1 msec (best); anyhow, no more than 5 msec. * + * Defines and function taken and modified from the kernel tree + * (see ftdi_sio.h and ftdi_sio.c). */ #define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ @@ -1235,7 +1234,8 @@ static int write_latency_timer(struct usb_device *udev) /* private defines */ #define MAX_TRANSFER (PAGE_SIZE - 512) -/* MAX_TRANSFER is chosen so that the VM is not stressed by +/* + * MAX_TRANSFER is chosen so that the VM is not stressed by * allocations > PAGE_SIZE and the number of packets in a page * is an integer 512 is the largest possible packet on EHCI */ @@ -1280,7 +1280,7 @@ static void skel_delete(struct kref *kref) } /* - * skel_do_open() - to be called by usb_gpib_attach + * skel_do_open() - to be called by usb_gpib_attach */ static int skel_do_open(struct gpib_board *board, int subminor) @@ -1317,7 +1317,7 @@ exit: } /* - * skel_do_release() - to be called by usb_gpib_detach + * skel_do_release() - to be called by usb_gpib_detach */ static int skel_do_release(struct gpib_board *board) @@ -1340,7 +1340,7 @@ static int skel_do_release(struct gpib_board *board) } /* - * read functions + * read functions */ static void skel_read_bulk_callback(struct urb *urb) @@ -1405,7 +1405,7 @@ static int skel_do_read_io(struct usb_skel *dev, size_t count) } /* - * skel_do_read() - read operations from lpvo_usb_gpib + * skel_do_read() - read operations from lpvo_usb_gpib */ static ssize_t skel_do_read(struct usb_skel *dev, char *buffer, size_t count) @@ -1482,7 +1482,8 @@ retry: * all data has been used * actual IO needs to be done */ - /* it seems that requests for less than dev->bulk_in_size + /* + * it seems that requests for less than dev->bulk_in_size * are not accepted */ rv = skel_do_read_io(dev, dev->bulk_in_size); @@ -1496,7 +1497,8 @@ retry: * data is available - chunk tells us how much shall be copied */ - /* Condition dev->bulk_in_copied > 0 maybe will never happen. In case, + /* + * Condition dev->bulk_in_copied > 0 maybe will never happen. In case, * signal the event and copy using the original procedure, i.e., copy * first two bytes also */ @@ -1551,7 +1553,7 @@ exit: } /* - * write functions + * write functions */ static void skel_write_bulk_callback(struct urb *urb) @@ -1581,7 +1583,7 @@ static void skel_write_bulk_callback(struct urb *urb) } /* - * skel_do_write() - write operations from lpvo_usb_gpib + * skel_do_write() - write operations from lpvo_usb_gpib */ static ssize_t skel_do_write(struct usb_skel *dev, const char *buffer, size_t count) @@ -1686,7 +1688,7 @@ exit: } /* - * services for the user space devices + * services for the user space devices */ #if USER_DEVICE /* conditional compilation of user space device */ @@ -1771,7 +1773,7 @@ static int skel_release(struct inode *inode, struct file *file) } /* - * user space access to read function + * user space access to read function */ static ssize_t skel_read(struct file *file, char __user *buffer, size_t count, @@ -1800,7 +1802,7 @@ static ssize_t skel_read(struct file *file, char __user *buffer, size_t count, } /* - * user space access to write function + * user space access to write function */ static ssize_t skel_write(struct file *file, const char __user *user_buffer, diff --git a/drivers/staging/gpib/nec7210/nec7210.c b/drivers/staging/gpib/nec7210/nec7210.c index 846c0a3fa1dc..34a1cae4f486 100644 --- a/drivers/staging/gpib/nec7210/nec7210.c +++ b/drivers/staging/gpib/nec7210/nec7210.c @@ -23,7 +23,7 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("GPIB library code for NEC uPD7210"); -int nec7210_enable_eos(struct gpib_board *board, struct nec7210_priv *priv, uint8_t eos_byte, +int nec7210_enable_eos(struct gpib_board *board, struct nec7210_priv *priv, u8 eos_byte, int compare_8_bits) { write_byte(priv, eos_byte, EOSR); @@ -44,7 +44,7 @@ void nec7210_disable_eos(struct gpib_board *board, struct nec7210_priv *priv) } EXPORT_SYMBOL(nec7210_disable_eos); -int nec7210_parallel_poll(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *result) +int nec7210_parallel_poll(struct gpib_board *board, struct nec7210_priv *priv, u8 *result) { int ret; @@ -79,14 +79,15 @@ void nec7210_parallel_poll_response(struct gpib_board *board, struct nec7210_pri write_byte(priv, AUX_CPPF, AUXMR); } EXPORT_SYMBOL(nec7210_parallel_poll_response); -/* This is really only adequate for chips that do a 488.2 style reqt/reqf +/* + * This is really only adequate for chips that do a 488.2 style reqt/reqf * based on bit 6 of the SPMR (see chapter 11.3.3 of 488.2). For simpler chips that simply * set rsv directly based on bit 6, we either need to do more hardware setup to expose * the 488.2 capability (for example with NI chips), or we need to implement the * 488.2 set srv state machine in the driver (if that is even viable). */ void nec7210_serial_poll_response(struct gpib_board *board, - struct nec7210_priv *priv, uint8_t status) + struct nec7210_priv *priv, u8 status) { unsigned long flags; @@ -103,7 +104,7 @@ void nec7210_serial_poll_response(struct gpib_board *board, } EXPORT_SYMBOL(nec7210_serial_poll_response); -uint8_t nec7210_serial_poll_status(struct gpib_board *board, struct nec7210_priv *priv) +u8 nec7210_serial_poll_status(struct gpib_board *board, struct nec7210_priv *priv) { return read_byte(priv, SPSR); } @@ -202,7 +203,8 @@ unsigned int nec7210_update_status_nolock(struct gpib_board *board, struct nec72 set_bit(SPOLL_NUM, &board->status); } - /* we rely on the interrupt handler to set the + /* + * we rely on the interrupt handler to set the * rest of the status bits */ @@ -251,7 +253,7 @@ void nec7210_set_handshake_mode(struct gpib_board *board, struct nec7210_priv *p } EXPORT_SYMBOL(nec7210_set_handshake_mode); -uint8_t nec7210_read_data_in(struct gpib_board *board, struct nec7210_priv *priv, int *end) +u8 nec7210_read_data_in(struct gpib_board *board, struct nec7210_priv *priv, int *end) { unsigned long flags; u8 data; @@ -330,14 +332,15 @@ int nec7210_go_to_standby(struct gpib_board *board, struct nec7210_priv *priv) } EXPORT_SYMBOL(nec7210_go_to_standby); -void nec7210_request_system_control(struct gpib_board *board, struct nec7210_priv *priv, - int request_control) +int nec7210_request_system_control(struct gpib_board *board, struct nec7210_priv *priv, + int request_control) { if (request_control == 0) { write_byte(priv, AUX_CREN, AUXMR); write_byte(priv, AUX_CIFC, AUXMR); write_byte(priv, AUX_DSC, AUXMR); } + return 0; } EXPORT_SYMBOL(nec7210_request_system_control); @@ -415,7 +418,7 @@ static inline short nec7210_atn_has_changed(struct gpib_board *board, struct nec return -1; } -int nec7210_command(struct gpib_board *board, struct nec7210_priv *priv, uint8_t +int nec7210_command(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer, size_t length, size_t *bytes_written) { int retval = 0; @@ -464,7 +467,7 @@ int nec7210_command(struct gpib_board *board, struct nec7210_priv *priv, uint8_t } EXPORT_SYMBOL(nec7210_command); -static int pio_read(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer, +static int pio_read(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer, size_t length, int *end, size_t *bytes_read) { ssize_t retval = 0; @@ -482,7 +485,8 @@ static int pio_read(struct gpib_board *board, struct nec7210_priv *priv, uint8_t } if (test_bit(READ_READY_BN, &priv->state)) { if (*bytes_read == 0) { - /* We set the handshake mode here because we know + /* + * We set the handshake mode here because we know * no new bytes will arrive (it has already arrived * and is awaiting being read out of the chip) while we are changing * modes. This ensures we can reliably keep track @@ -568,7 +572,7 @@ static ssize_t __dma_read(struct gpib_board *board, struct nec7210_priv *priv, s return retval ? retval : count; } -static ssize_t dma_read(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer, +static ssize_t dma_read(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer, size_t length) { size_t remain = length; @@ -595,7 +599,7 @@ static ssize_t dma_read(struct gpib_board *board, struct nec7210_priv *priv, uin } #endif -int nec7210_read(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer, +int nec7210_read(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer, size_t length, int *end, size_t *bytes_read) { ssize_t retval = 0; @@ -642,7 +646,7 @@ static int pio_write_wait(struct gpib_board *board, struct nec7210_priv *priv, return 0; } -static int pio_write(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer, +static int pio_write(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer, size_t length, size_t *bytes_written) { size_t last_count = 0; @@ -662,7 +666,8 @@ static int pio_write(struct gpib_board *board, struct nec7210_priv *priv, uint8_ if (retval == -EIO) { /* resend last byte on bus error */ *bytes_written = last_count; - /* we can get unrecoverable bus errors, + /* + * we can get unrecoverable bus errors, * so give up after a while */ bus_error_count++; @@ -742,7 +747,7 @@ static ssize_t __dma_write(struct gpib_board *board, struct nec7210_priv *priv, return retval ? retval : length; } -static ssize_t dma_write(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer, +static ssize_t dma_write(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer, size_t length) { size_t remain = length; @@ -767,7 +772,7 @@ static ssize_t dma_write(struct gpib_board *board, struct nec7210_priv *priv, ui } #endif int nec7210_write(struct gpib_board *board, struct nec7210_priv *priv, - uint8_t *buffer, size_t length, int send_eoi, + u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { int retval = 0; @@ -805,7 +810,8 @@ int nec7210_write(struct gpib_board *board, struct nec7210_priv *priv, if (send_eoi) { size_t num_bytes; - /* We need to wait to make sure we will immediately be able to write the data byte + /* + * We need to wait to make sure we will immediately be able to write the data byte * into the chip before sending the associated AUX_SEOI command. This is really * only needed for length==1 since otherwise the earlier calls to pio_write * will have dont the wait already. @@ -827,7 +833,7 @@ int nec7210_write(struct gpib_board *board, struct nec7210_priv *priv, EXPORT_SYMBOL(nec7210_write); /* - * interrupt service routine + * interrupt service routine */ irqreturn_t nec7210_interrupt(struct gpib_board *board, struct nec7210_priv *priv) { @@ -932,13 +938,13 @@ irqreturn_t nec7210_interrupt_have_status(struct gpib_board *board, // ignore device clear events if we are controller in charge if ((address_status_bits & HR_CIC) == 0) { - push_gpib_event(board, EventDevClr); + push_gpib_event(board, EVENT_DEV_CLR); set_bit(DEV_CLEAR_BN, &priv->state); } } if (status1 & HR_DET) - push_gpib_event(board, EventDevTrg); + push_gpib_event(board, EVENT_DEV_TRG); // Addressing status has changed if (status2 & HR_ADSC) @@ -1012,16 +1018,17 @@ EXPORT_SYMBOL(nec7210_board_online); #ifdef CONFIG_HAS_IOPORT /* wrappers for io */ -uint8_t nec7210_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num) +u8 nec7210_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num) { return inb(priv->iobase + register_num * priv->offset); } EXPORT_SYMBOL(nec7210_ioport_read_byte); -void nec7210_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned int register_num) +void nec7210_ioport_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num) { if (register_num == AUXMR) - /* locking makes absolutely sure noone accesses the + /* + * locking makes absolutely sure noone accesses the * AUXMR register faster than once per microsecond */ nec7210_locking_ioport_write_byte(priv, data, register_num); @@ -1031,7 +1038,7 @@ void nec7210_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned EXPORT_SYMBOL(nec7210_ioport_write_byte); /* locking variants of io wrappers, for chips that page-in registers */ -uint8_t nec7210_locking_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num) +u8 nec7210_locking_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num) { u8 retval; unsigned long flags; @@ -1043,7 +1050,7 @@ uint8_t nec7210_locking_ioport_read_byte(struct nec7210_priv *priv, unsigned int } EXPORT_SYMBOL(nec7210_locking_ioport_read_byte); -void nec7210_locking_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, +void nec7210_locking_ioport_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num) { unsigned long flags; @@ -1057,16 +1064,17 @@ void nec7210_locking_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, EXPORT_SYMBOL(nec7210_locking_ioport_write_byte); #endif -uint8_t nec7210_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num) +u8 nec7210_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num) { return readb(priv->mmiobase + register_num * priv->offset); } EXPORT_SYMBOL(nec7210_iomem_read_byte); -void nec7210_iomem_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned int register_num) +void nec7210_iomem_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num) { if (register_num == AUXMR) - /* locking makes absolutely sure noone accesses the + /* + * locking makes absolutely sure noone accesses the * AUXMR register faster than once per microsecond */ nec7210_locking_iomem_write_byte(priv, data, register_num); @@ -1075,7 +1083,7 @@ void nec7210_iomem_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned } EXPORT_SYMBOL(nec7210_iomem_write_byte); -uint8_t nec7210_locking_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num) +u8 nec7210_locking_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num) { u8 retval; unsigned long flags; @@ -1087,7 +1095,7 @@ uint8_t nec7210_locking_iomem_read_byte(struct nec7210_priv *priv, unsigned int } EXPORT_SYMBOL(nec7210_locking_iomem_read_byte); -void nec7210_locking_iomem_write_byte(struct nec7210_priv *priv, uint8_t data, +void nec7210_locking_iomem_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num) { unsigned long flags; diff --git a/drivers/staging/gpib/ni_usb/ni_usb_gpib.c b/drivers/staging/gpib/ni_usb/ni_usb_gpib.c index 9f1b9927f025..73ea72f34c0a 100644 --- a/drivers/staging/gpib/ni_usb/ni_usb_gpib.c +++ b/drivers/staging/gpib/ni_usb/ni_usb_gpib.c @@ -74,7 +74,8 @@ static unsigned short ni_usb_timeout_code(unsigned int usec) return 0xff; else if (usec <= 300000000) return 0x01; - /* NI driver actually uses 0xff for timeout T1000s, which is a bug in their code. + /* + * NI driver actually uses 0xff for timeout T1000s, which is a bug in their code. * I've verified on a usb-b that a code of 0x2 is correct for a 1000 sec timeout */ else if (usec <= 1000000000) @@ -92,7 +93,8 @@ static void ni_usb_bulk_complete(struct urb *urb) static void ni_usb_timeout_handler(struct timer_list *t) { - struct ni_usb_priv *ni_priv = from_timer(ni_priv, t, bulk_timer); + struct ni_usb_priv *ni_priv = timer_container_of(ni_priv, t, + bulk_timer); struct ni_usb_urb_ctx *context = &ni_priv->context; context->timed_out = 1; @@ -232,7 +234,8 @@ static int ni_usb_nonblocking_receive_bulk_msg(struct ni_usb_priv *ni_priv, mutex_unlock(&ni_priv->bulk_transfer_lock); if (interruptible) { if (wait_for_completion_interruptible(&context->complete)) { - /* If we got interrupted by a signal while + /* + * If we got interrupted by a signal while * waiting for the usb gpib to respond, we * should send a stop command so it will * finish up with whatever it was doing and @@ -240,8 +243,9 @@ static int ni_usb_nonblocking_receive_bulk_msg(struct ni_usb_priv *ni_priv, */ ni_usb_stop(ni_priv); retval = -ERESTARTSYS; - /* now do an uninterruptible wait, it shouldn't take long - * for the board to respond now. + /* + * now do an uninterruptible wait, it shouldn't take long + * for the board to respond now. */ wait_for_completion(&context->complete); } @@ -586,7 +590,7 @@ static int ni_usb_write_registers(struct ni_usb_priv *ni_priv, } // interface functions -static int ni_usb_read(struct gpib_board *board, uint8_t *buffer, size_t length, +static int ni_usb_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { int retval, parse_retval; @@ -684,7 +688,8 @@ static int ni_usb_read(struct gpib_board *board, uint8_t *buffer, size_t length, retval = 0; break; case NIUSB_ABORTED_ERROR: - /* this is expected if ni_usb_receive_bulk_msg got + /* + * this is expected if ni_usb_receive_bulk_msg got * interrupted by a signal and returned -ERESTARTSYS */ break; @@ -716,7 +721,7 @@ static int ni_usb_read(struct gpib_board *board, uint8_t *buffer, size_t length, return retval; } -static int ni_usb_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int ni_usb_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { int retval; @@ -794,7 +799,8 @@ static int ni_usb_write(struct gpib_board *board, uint8_t *buffer, size_t length retval = 0; break; case NIUSB_ABORTED_ERROR: - /* this is expected if ni_usb_receive_bulk_msg got + /* + * this is expected if ni_usb_receive_bulk_msg got * interrupted by a signal and returned -ERESTARTSYS */ break; @@ -819,7 +825,7 @@ static int ni_usb_write(struct gpib_board *board, uint8_t *buffer, size_t length return retval; } -static int ni_usb_command_chunk(struct gpib_board *board, uint8_t *buffer, size_t length, +static int ni_usb_command_chunk(struct gpib_board *board, u8 *buffer, size_t length, size_t *command_bytes_written) { int retval; @@ -893,7 +899,8 @@ static int ni_usb_command_chunk(struct gpib_board *board, uint8_t *buffer, size_ case NIUSB_NO_ERROR: break; case NIUSB_ABORTED_ERROR: - /* this is expected if ni_usb_receive_bulk_msg got + /* + * this is expected if ni_usb_receive_bulk_msg got * interrupted by a signal and returned -ERESTARTSYS */ break; @@ -912,7 +919,7 @@ static int ni_usb_command_chunk(struct gpib_board *board, uint8_t *buffer, size_ return 0; } -static int ni_usb_command(struct gpib_board *board, uint8_t *buffer, size_t length, +static int ni_usb_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { size_t count; @@ -1049,7 +1056,7 @@ static int ni_usb_go_to_standby(struct gpib_board *board) return 0; } -static void ni_usb_request_system_control(struct gpib_board *board, int request_control) +static int ni_usb_request_system_control(struct gpib_board *board, int request_control) { int retval; struct ni_usb_priv *ni_priv = board->private_data; @@ -1059,7 +1066,7 @@ static void ni_usb_request_system_control(struct gpib_board *board, int request_ unsigned int ibsta; if (!ni_priv->bus_interface) - return; // -ENODEV; + return -ENODEV; usb_dev = interface_to_usbdev(ni_priv->bus_interface); if (request_control) { writes[i].device = NIUSB_SUBDEV_TNT4882; @@ -1091,12 +1098,12 @@ static void ni_usb_request_system_control(struct gpib_board *board, int request_ retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta); if (retval < 0) { dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval); - return; // retval; + return retval; } if (!request_control) ni_priv->ren_state = 0; ni_usb_soft_update_status(board, ibsta, 0); - return; // 0; + return 0; } //FIXME maybe the interface should have a "pulse interface clear" function that can return an error? @@ -1176,7 +1183,7 @@ static void ni_usb_remote_enable(struct gpib_board *board, int enable) return;// 0; } -static int ni_usb_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits) +static int ni_usb_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct ni_usb_priv *ni_priv = board->private_data; @@ -1192,8 +1199,9 @@ static int ni_usb_enable_eos(struct gpib_board *board, uint8_t eos_byte, int com static void ni_usb_disable_eos(struct gpib_board *board) { struct ni_usb_priv *ni_priv = board->private_data; - /* adapter gets unhappy if you don't zero all the bits - * for the eos mode and eos char (returns error 4 on reads). + /* + * adapter gets unhappy if you don't zero all the bits + * for the eos mode and eos char (returns error 4 on reads). */ ni_priv->eos_mode = 0; ni_priv->eos_char = 0; @@ -1334,7 +1342,7 @@ static int ni_usb_secondary_address(struct gpib_board *board, unsigned int addre return 0; } -static int ni_usb_parallel_poll(struct gpib_board *board, uint8_t *result) +static int ni_usb_parallel_poll(struct gpib_board *board, u8 *result) { int retval; struct ni_usb_priv *ni_priv = board->private_data; @@ -1389,7 +1397,7 @@ static int ni_usb_parallel_poll(struct gpib_board *board, uint8_t *result) return retval; } -static void ni_usb_parallel_poll_configure(struct gpib_board *board, uint8_t config) +static void ni_usb_parallel_poll_configure(struct gpib_board *board, u8 config) { int retval; struct ni_usb_priv *ni_priv = board->private_data; @@ -1467,7 +1475,7 @@ static void ni_usb_serial_poll_response(struct gpib_board *board, u8 status) return;// 0; } -static uint8_t ni_usb_serial_poll_status(struct gpib_board *board) +static u8 ni_usb_serial_poll_status(struct gpib_board *board) { return 0; } @@ -2045,8 +2053,10 @@ static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv) unexpected = 1; } ++j; - // MC usb-488 (and sometimes NI-USB-HS?) sends 0x8 here; MC usb-488A sends 0x7 here - // NI-USB-HS+ sends 0x0 + /* + * MC usb-488 (and sometimes NI-USB-HS?) sends 0x8 here; MC usb-488A sends 0x7 here + * NI-USB-HS+ sends 0x0 + */ if (buffer[j] != 0x1 && buffer[j] != 0x8 && buffer[j] != 0x7 && buffer[j] != 0x0) { // [3] dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x0, 0x1, 0x7 or 0x8\n", @@ -2069,10 +2079,10 @@ static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv) } if (buffer[++j] != 0x0) { // [6] ready = 1; - // NI-USB-HS+ sends 0xf here + // NI-USB-HS+ sends 0xf or 0x19 here if (buffer[j] != 0x2 && buffer[j] != 0xe && buffer[j] != 0xf && - buffer[j] != 0x16) { - dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x2, 0xe, 0xf or 0x16\n", + buffer[j] != 0x16 && buffer[j] != 0x19) { + dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x2, 0xe, 0xf, 0x16 or 0x19\n", j, (int)buffer[j]); unexpected = 1; } @@ -2100,11 +2110,11 @@ static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv) j, (int)buffer[j]); unexpected = 1; } - if (buffer[++j] != 0x0) { + if (buffer[++j] != 0x0) { // [10] MC usb-488 sends 0x7 here, new HS+ sends 0x59 ready = 1; - if (buffer[j] != 0x96 && buffer[j] != 0x7 && buffer[j] != 0x6e) { -// [10] MC usb-488 sends 0x7 here - dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x96, 0x07 or 0x6e\n", + if (buffer[j] != 0x96 && buffer[j] != 0x7 && buffer[j] != 0x6e && + buffer[j] != 0x59) { + dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x96, 0x07, 0x6e or 0x59\n", j, (int)buffer[j]); unexpected = 1; } @@ -2127,7 +2137,8 @@ ready_out: return retval; } -/* This does some extra init for HS+ models, as observed on Windows. One of the +/* + * This does some extra init for HS+ models, as observed on Windows. One of the * control requests causes the LED to stop blinking. * I'm not sure what the other 2 requests do. None of these requests are actually required * for the adapter to work, maybe they do some init for the analyzer interface @@ -2198,14 +2209,14 @@ static int ni_usb_hs_plus_extra_init(struct ni_usb_priv *ni_priv) } static inline int ni_usb_device_match(struct usb_interface *interface, - const gpib_board_config_t *config) + const struct gpib_board_config *config) { if (gpib_match_device_path(&interface->dev, config->device_path) == 0) return 0; return 1; } -static int ni_usb_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ni_usb_attach(struct gpib_board *board, const struct gpib_board_config *config) { int retval; int i, index; @@ -2343,8 +2354,10 @@ static void ni_usb_detach(struct gpib_board *board) struct ni_usb_priv *ni_priv; mutex_lock(&ni_usb_hotplug_lock); -// under windows, software unplug does chip_reset nec7210 aux command, -// then writes 0x0 to address 0x10 of device 3 + /* + * under windows, software unplug does chip_reset nec7210 aux command, + * then writes 0x0 to address 0x10 of device 3 + */ ni_priv = board->private_data; if (ni_priv) { if (ni_priv->bus_interface) { @@ -2361,7 +2374,7 @@ static void ni_usb_detach(struct gpib_board *board) mutex_unlock(&ni_usb_hotplug_lock); } -static gpib_interface_t ni_usb_gpib_interface = { +static struct gpib_interface ni_usb_gpib_interface = { .name = "ni_usb_b", .attach = ni_usb_attach, .detach = ni_usb_detach, diff --git a/drivers/staging/gpib/ni_usb/ni_usb_gpib.h b/drivers/staging/gpib/ni_usb/ni_usb_gpib.h index 4b297db09a9b..b011e131201c 100644 --- a/drivers/staging/gpib/ni_usb/ni_usb_gpib.h +++ b/drivers/staging/gpib/ni_usb/ni_usb_gpib.h @@ -113,27 +113,37 @@ enum ni_usb_bulk_ids { enum ni_usb_error_codes { NIUSB_NO_ERROR = 0, - /* NIUSB_ABORTED_ERROR occurs when I/O is interrupted early by - * doing a NI_USB_STOP_REQUEST on the control endpoint. + /* + * NIUSB_ABORTED_ERROR occurs when I/O is interrupted early by + * doing a NI_USB_STOP_REQUEST on the control endpoint. */ NIUSB_ABORTED_ERROR = 1, - // NIUSB_READ_ATN_ERROR occurs when you do a board read while - // ATN is set + /* + * NIUSB_READ_ATN_ERROR occurs when you do a board read while + * ATN is set + */ NIUSB_ATN_STATE_ERROR = 2, - // NIUSB_ADDRESSING_ERROR occurs when you do a board - // read/write as CIC but are not in LACS/TACS + /* + * NIUSB_ADDRESSING_ERROR occurs when you do a board + * read/write as CIC but are not in LACS/TACS + */ NIUSB_ADDRESSING_ERROR = 3, - /* NIUSB_EOSMODE_ERROR occurs on reads if any eos mode or char + /* + * NIUSB_EOSMODE_ERROR occurs on reads if any eos mode or char * bits are set when REOS is not set. * Have also seen error 4 if you try to send more than 16 * command bytes at once on a usb-b. */ NIUSB_EOSMODE_ERROR = 4, - // NIUSB_NO_BUS_ERROR occurs when you try to write a command - // byte but there are no devices connected to the gpib bus + /* + * NIUSB_NO_BUS_ERROR occurs when you try to write a command + * byte but there are no devices connected to the gpib bus + */ NIUSB_NO_BUS_ERROR = 5, - // NIUSB_NO_LISTENER_ERROR occurs when you do a board write as - // CIC with no listener + /* + * NIUSB_NO_LISTENER_ERROR occurs when you do a board write as + * CIC with no listener + */ NIUSB_NO_LISTENER_ERROR = 8, // get NIUSB_TIMEOUT_ERROR on board read/write timeout NIUSB_TIMEOUT_ERROR = 10, diff --git a/drivers/staging/gpib/pc2/pc2_gpib.c b/drivers/staging/gpib/pc2/pc2_gpib.c index 96d3c09f2273..2282492025b7 100644 --- a/drivers/staging/gpib/pc2/pc2_gpib.c +++ b/drivers/staging/gpib/pc2/pc2_gpib.c @@ -90,7 +90,7 @@ irqreturn_t pc2a_interrupt(int irq, void *arg) } // wrappers for interface functions -static int pc2_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end, +static int pc2_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct pc2_priv *priv = board->private_data; @@ -98,7 +98,7 @@ static int pc2_read(struct gpib_board *board, uint8_t *buffer, size_t length, in return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); } -static int pc2_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi, +static int pc2_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct pc2_priv *priv = board->private_data; @@ -106,7 +106,8 @@ static int pc2_write(struct gpib_board *board, uint8_t *buffer, size_t length, i return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); } -static int pc2_command(struct gpib_board *board, uint8_t *buffer, size_t length, size_t *bytes_written) +static int pc2_command(struct gpib_board *board, u8 *buffer, + size_t length, size_t *bytes_written) { struct pc2_priv *priv = board->private_data; @@ -127,11 +128,11 @@ static int pc2_go_to_standby(struct gpib_board *board) return nec7210_go_to_standby(board, &priv->nec7210_priv); } -static void pc2_request_system_control(struct gpib_board *board, int request_control) +static int pc2_request_system_control(struct gpib_board *board, int request_control) { struct pc2_priv *priv = board->private_data; - nec7210_request_system_control(board, &priv->nec7210_priv, request_control); + return nec7210_request_system_control(board, &priv->nec7210_priv, request_control); } static void pc2_interface_clear(struct gpib_board *board, int assert) @@ -148,7 +149,7 @@ static void pc2_remote_enable(struct gpib_board *board, int enable) nec7210_remote_enable(board, &priv->nec7210_priv, enable); } -static int pc2_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits) +static int pc2_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct pc2_priv *priv = board->private_data; @@ -183,14 +184,14 @@ static int pc2_secondary_address(struct gpib_board *board, unsigned int address, return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); } -static int pc2_parallel_poll(struct gpib_board *board, uint8_t *result) +static int pc2_parallel_poll(struct gpib_board *board, u8 *result) { struct pc2_priv *priv = board->private_data; return nec7210_parallel_poll(board, &priv->nec7210_priv, result); } -static void pc2_parallel_poll_configure(struct gpib_board *board, uint8_t config) +static void pc2_parallel_poll_configure(struct gpib_board *board, u8 config) { struct pc2_priv *priv = board->private_data; @@ -204,14 +205,14 @@ static void pc2_parallel_poll_response(struct gpib_board *board, int ist) nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); } -static void pc2_serial_poll_response(struct gpib_board *board, uint8_t status) +static void pc2_serial_poll_response(struct gpib_board *board, u8 status) { struct pc2_priv *priv = board->private_data; nec7210_serial_poll_response(board, &priv->nec7210_priv, status); } -static uint8_t pc2_serial_poll_status(struct gpib_board *board) +static u8 pc2_serial_poll_status(struct gpib_board *board) { struct pc2_priv *priv = board->private_data; @@ -251,7 +252,7 @@ static void free_private(struct gpib_board *board) board->private_data = NULL; } -static int pc2_generic_attach(struct gpib_board *board, const gpib_board_config_t *config, +static int pc2_generic_attach(struct gpib_board *board, const struct gpib_board_config *config, enum nec7210_chipset chipset) { struct pc2_priv *pc2_priv; @@ -267,8 +268,9 @@ static int pc2_generic_attach(struct gpib_board *board, const gpib_board_config_ nec_priv->type = chipset; #ifndef PC2_DMA - /* board->dev hasn't been initialized, so forget about DMA until this driver - * is adapted to use isa_register_driver. + /* + * board->dev hasn't been initialized, so forget about DMA until this driver + * is adapted to use isa_register_driver. */ if (config->ibdma) // driver needs to be adapted to use isa_register_driver to get a struct device* @@ -294,7 +296,7 @@ static int pc2_generic_attach(struct gpib_board *board, const gpib_board_config_ return 0; } -static int pc2_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int pc2_attach(struct gpib_board *board, const struct gpib_board_config *config) { int isr_flags = 0; struct pc2_priv *pc2_priv; @@ -365,7 +367,7 @@ static void pc2_detach(struct gpib_board *board) free_private(board); } -static int pc2a_common_attach(struct gpib_board *board, const gpib_board_config_t *config, +static int pc2a_common_attach(struct gpib_board *board, const struct gpib_board_config *config, unsigned int num_registers, enum nec7210_chipset chipset) { unsigned int i, j; @@ -459,17 +461,17 @@ static int pc2a_common_attach(struct gpib_board *board, const gpib_board_config_ return 0; } -static int pc2a_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int pc2a_attach(struct gpib_board *board, const struct gpib_board_config *config) { return pc2a_common_attach(board, config, pc2a_iosize, NEC7210); } -static int pc2a_cb7210_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int pc2a_cb7210_attach(struct gpib_board *board, const struct gpib_board_config *config) { return pc2a_common_attach(board, config, pc2a_iosize, CB7210); } -static int pc2_2a_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int pc2_2a_attach(struct gpib_board *board, const struct gpib_board_config *config) { return pc2a_common_attach(board, config, pc2_2a_iosize, NAT4882); } @@ -517,7 +519,7 @@ static void pc2_2a_detach(struct gpib_board *board) pc2a_common_detach(board, pc2_2a_iosize); } -static gpib_interface_t pc2_interface = { +static struct gpib_interface pc2_interface = { .name = "pcII", .attach = pc2_attach, .detach = pc2_detach, @@ -545,7 +547,7 @@ static gpib_interface_t pc2_interface = { .return_to_local = pc2_return_to_local, }; -static gpib_interface_t pc2a_interface = { +static struct gpib_interface pc2a_interface = { .name = "pcIIa", .attach = pc2a_attach, .detach = pc2a_detach, @@ -573,7 +575,7 @@ static gpib_interface_t pc2a_interface = { .return_to_local = pc2_return_to_local, }; -static gpib_interface_t pc2a_cb7210_interface = { +static struct gpib_interface pc2a_cb7210_interface = { .name = "pcIIa_cb7210", .attach = pc2a_cb7210_attach, .detach = pc2a_detach, @@ -601,7 +603,7 @@ static gpib_interface_t pc2a_cb7210_interface = { .return_to_local = pc2_return_to_local, }; -static gpib_interface_t pc2_2a_interface = { +static struct gpib_interface pc2_2a_interface = { .name = "pcII_IIa", .attach = pc2_2a_attach, .detach = pc2_2a_detach, diff --git a/drivers/staging/gpib/tms9914/tms9914.c b/drivers/staging/gpib/tms9914/tms9914.c index 2abda9d7dfcb..04d57108efc7 100644 --- a/drivers/staging/gpib/tms9914/tms9914.c +++ b/drivers/staging/gpib/tms9914/tms9914.c @@ -53,7 +53,8 @@ int tms9914_take_control(struct gpib_board *board, struct tms9914_priv *priv, in } EXPORT_SYMBOL_GPL(tms9914_take_control); -/* The agilent 82350B has a buggy implementation of tcs which interferes with the +/* + * The agilent 82350B has a buggy implementation of tcs which interferes with the * operation of tca. It appears to be based on the controller state machine * described in the TI 9900 TMS9914A data manual published in 1982. This * manual describes tcs as putting the controller into a CWAS @@ -66,7 +67,8 @@ EXPORT_SYMBOL_GPL(tms9914_take_control); * The rest of the tms9914 based drivers still use tms9914_take_control * directly (which does issue tcs). */ -int tms9914_take_control_workaround(struct gpib_board *board, struct tms9914_priv *priv, int synchronous) +int tms9914_take_control_workaround(struct gpib_board *board, + struct tms9914_priv *priv, int synchronous) { if (synchronous) return -ETIMEDOUT; @@ -116,8 +118,8 @@ void tms9914_remote_enable(struct gpib_board *board, struct tms9914_priv *priv, } EXPORT_SYMBOL_GPL(tms9914_remote_enable); -void tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv, - int request_control) +int tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv, + int request_control) { if (request_control) { write_byte(priv, AUX_RQC, AUXCR); @@ -125,6 +127,7 @@ void tms9914_request_system_control(struct gpib_board *board, struct tms9914_pri clear_bit(CIC_NUM, &board->status); write_byte(priv, AUX_RLC, AUXCR); } + return 0; } EXPORT_SYMBOL_GPL(tms9914_request_system_control); @@ -192,7 +195,7 @@ void tms9914_release_holdoff(struct tms9914_priv *priv) } EXPORT_SYMBOL_GPL(tms9914_release_holdoff); -int tms9914_enable_eos(struct gpib_board *board, struct tms9914_priv *priv, uint8_t eos_byte, +int tms9914_enable_eos(struct gpib_board *board, struct tms9914_priv *priv, u8 eos_byte, int compare_8_bits) { priv->eos = eos_byte; @@ -209,7 +212,7 @@ void tms9914_disable_eos(struct gpib_board *board, struct tms9914_priv *priv) } EXPORT_SYMBOL(tms9914_disable_eos); -int tms9914_parallel_poll(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *result) +int tms9914_parallel_poll(struct gpib_board *board, struct tms9914_priv *priv, u8 *result) { // execute parallel poll write_byte(priv, AUX_CS | AUX_RPP, AUXCR); @@ -235,7 +238,7 @@ static void set_ppoll_reg(struct tms9914_priv *priv, int enable, } void tms9914_parallel_poll_configure(struct gpib_board *board, - struct tms9914_priv *priv, uint8_t config) + struct tms9914_priv *priv, u8 config) { priv->ppoll_enable = (config & PPC_DISABLE) == 0; priv->ppoll_line = (config & PPC_DIO_MASK) + 1; @@ -251,7 +254,8 @@ void tms9914_parallel_poll_response(struct gpib_board *board, } EXPORT_SYMBOL(tms9914_parallel_poll_response); -void tms9914_serial_poll_response(struct gpib_board *board, struct tms9914_priv *priv, uint8_t status) +void tms9914_serial_poll_response(struct gpib_board *board, + struct tms9914_priv *priv, u8 status) { unsigned long flags; @@ -266,7 +270,7 @@ void tms9914_serial_poll_response(struct gpib_board *board, struct tms9914_priv } EXPORT_SYMBOL(tms9914_serial_poll_response); -uint8_t tms9914_serial_poll_status(struct gpib_board *board, struct tms9914_priv *priv) +u8 tms9914_serial_poll_status(struct gpib_board *board, struct tms9914_priv *priv) { u8 status; unsigned long flags; @@ -279,7 +283,8 @@ uint8_t tms9914_serial_poll_status(struct gpib_board *board, struct tms9914_priv } EXPORT_SYMBOL(tms9914_serial_poll_status); -int tms9914_primary_address(struct gpib_board *board, struct tms9914_priv *priv, unsigned int address) +int tms9914_primary_address(struct gpib_board *board, + struct tms9914_priv *priv, unsigned int address) { // put primary address in address0 write_byte(priv, address & ADDRESS_MASK, ADR); @@ -321,7 +326,8 @@ static void update_talker_state(struct tms9914_priv *priv, unsigned int address_ if (address_status_bits & HR_ATN) priv->talker_state = talker_addressed; else - /* this could also be serial_poll_active, but the tms9914 provides no + /* + * this could also be serial_poll_active, but the tms9914 provides no * way to distinguish, so we'll assume talker_active */ priv->talker_state = talker_active; @@ -416,7 +422,7 @@ int tms9914_line_status(const struct gpib_board *board, struct tms9914_priv *pri } EXPORT_SYMBOL(tms9914_line_status); -static int check_for_eos(struct tms9914_priv *priv, uint8_t byte) +static int check_for_eos(struct tms9914_priv *priv, u8 byte) { static const u8 seven_bit_compare_mask = 0x7f; @@ -449,7 +455,8 @@ static int wait_for_read_byte(struct gpib_board *board, struct tms9914_priv *pri return 0; } -static inline uint8_t tms9914_read_data_in(struct gpib_board *board, struct tms9914_priv *priv, int *end) +static inline u8 tms9914_read_data_in(struct gpib_board *board, + struct tms9914_priv *priv, int *end) { unsigned long flags; u8 data; @@ -480,7 +487,7 @@ static inline uint8_t tms9914_read_data_in(struct gpib_board *board, struct tms9 return data; } -static int pio_read(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer, +static int pio_read(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer, size_t length, int *end, size_t *bytes_read) { ssize_t retval = 0; @@ -501,7 +508,7 @@ static int pio_read(struct gpib_board *board, struct tms9914_priv *priv, uint8_t return retval; } -int tms9914_read(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer, +int tms9914_read(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer, size_t length, int *end, size_t *bytes_read) { ssize_t retval = 0; @@ -561,7 +568,7 @@ static int pio_write_wait(struct gpib_board *board, struct tms9914_priv *priv) return 0; } -static int pio_write(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer, +static int pio_write(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer, size_t length, size_t *bytes_written) { ssize_t retval = 0; @@ -585,8 +592,8 @@ static int pio_write(struct gpib_board *board, struct tms9914_priv *priv, uint8_ return length; } -int tms9914_write(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer, size_t length, - int send_eoi, size_t *bytes_written) +int tms9914_write(struct gpib_board *board, struct tms9914_priv *priv, + u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { ssize_t retval = 0; @@ -620,7 +627,8 @@ int tms9914_write(struct gpib_board *board, struct tms9914_priv *priv, uint8_t * } EXPORT_SYMBOL(tms9914_write); -static void check_my_address_state(struct gpib_board *board, struct tms9914_priv *priv, int cmd_byte) +static void check_my_address_state(struct gpib_board *board, + struct tms9914_priv *priv, int cmd_byte) { if (cmd_byte == MLA(board->pad)) { priv->primary_listen_addressed = 1; @@ -655,7 +663,7 @@ static void check_my_address_state(struct gpib_board *board, struct tms9914_priv } } -int tms9914_command(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer, +int tms9914_command(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer, size_t length, size_t *bytes_written) { int retval = 0; @@ -736,9 +744,10 @@ irqreturn_t tms9914_interrupt_have_status(struct gpib_board *board, struct tms99 unsigned short command_byte = read_byte(priv, CPTR) & gpib_command_mask; switch (command_byte) { - case PPConfig: + case PP_CONFIG: priv->ppoll_configure_state = 1; - /* AUX_PTS generates another UNC interrupt on the next command byte + /* + * AUX_PTS generates another UNC interrupt on the next command byte * if it is in the secondary address group (such as PPE and PPD). */ write_byte(priv, AUX_PTS, AUXCR); @@ -764,7 +773,7 @@ irqreturn_t tms9914_interrupt_have_status(struct gpib_board *board, struct tms99 break; } - if (in_primary_command_group(command_byte) && command_byte != PPConfig) + if (in_primary_command_group(command_byte) && command_byte != PP_CONFIG) priv->ppoll_configure_state = 0; } @@ -774,18 +783,18 @@ irqreturn_t tms9914_interrupt_have_status(struct gpib_board *board, struct tms99 } if (status1 & HR_IFC) { - push_gpib_event(board, EventIFC); + push_gpib_event(board, EVENT_IFC); clear_bit(CIC_NUM, &board->status); } if (status1 & HR_GET) { - push_gpib_event(board, EventDevTrg); + push_gpib_event(board, EVENT_DEV_TRG); // clear dac holdoff write_byte(priv, AUX_VAL, AUXCR); } if (status1 & HR_DCAS) { - push_gpib_event(board, EventDevClr); + push_gpib_event(board, EVENT_DEV_CLR); // clear dac holdoff write_byte(priv, AUX_VAL, AUXCR); set_bit(DEV_CLEAR_BN, &priv->state); @@ -859,14 +868,14 @@ EXPORT_SYMBOL_GPL(tms9914_online); #ifdef CONFIG_HAS_IOPORT // wrapper for inb -uint8_t tms9914_ioport_read_byte(struct tms9914_priv *priv, unsigned int register_num) +u8 tms9914_ioport_read_byte(struct tms9914_priv *priv, unsigned int register_num) { return inb(priv->iobase + register_num * priv->offset); } EXPORT_SYMBOL_GPL(tms9914_ioport_read_byte); // wrapper for outb -void tms9914_ioport_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num) +void tms9914_ioport_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num) { outb(data, priv->iobase + register_num * priv->offset); if (register_num == AUXCR) @@ -876,14 +885,14 @@ EXPORT_SYMBOL_GPL(tms9914_ioport_write_byte); #endif // wrapper for readb -uint8_t tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register_num) +u8 tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register_num) { return readb(priv->mmiobase + register_num * priv->offset); } EXPORT_SYMBOL_GPL(tms9914_iomem_read_byte); // wrapper for writeb -void tms9914_iomem_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num) +void tms9914_iomem_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num) { writeb(data, priv->mmiobase + register_num * priv->offset); if (register_num == AUXCR) diff --git a/drivers/staging/gpib/tnt4882/tnt4882_gpib.c b/drivers/staging/gpib/tnt4882/tnt4882_gpib.c index c35b084b6fd0..a17b69e34986 100644 --- a/drivers/staging/gpib/tnt4882/tnt4882_gpib.c +++ b/drivers/staging/gpib/tnt4882/tnt4882_gpib.c @@ -236,7 +236,7 @@ static int fifo_xfer_done(struct tnt4882_priv *tnt_priv) return retval; } -static int drain_fifo_words(struct tnt4882_priv *tnt_priv, uint8_t *buffer, int num_bytes) +static int drain_fifo_words(struct tnt4882_priv *tnt_priv, u8 *buffer, int num_bytes) { int count = 0; struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv; @@ -258,7 +258,8 @@ static void tnt4882_release_holdoff(struct gpib_board *board, struct tnt4882_pri sasr_bits = tnt_readb(tnt_priv, SASR); - /*tnt4882 not in one-chip mode won't always release holdoff unless we + /* + * tnt4882 not in one-chip mode won't always release holdoff unless we * are in the right mode when release handshake command is given */ if (sasr_bits & AEHS_BIT) /* holding off due to holdoff on end mode*/ { @@ -274,7 +275,7 @@ static void tnt4882_release_holdoff(struct gpib_board *board, struct tnt4882_pri } } -static int tnt4882_accel_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end, +static int tnt4882_accel_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { size_t count = 0; @@ -384,7 +385,8 @@ static int tnt4882_accel_read(struct gpib_board *board, uint8_t *buffer, size_t nec7210_set_reg_bits(nec_priv, IMR1, HR_ENDIE, 0); nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); - /* force handling of any pending interrupts (seems to be needed + /* + * force handling of any pending interrupts (seems to be needed * to keep interrupts from getting hosed, plus for syncing * with RECEIVED_END below) */ @@ -448,7 +450,7 @@ static int write_wait(struct gpib_board *board, struct tnt4882_priv *tnt_priv, return 0; } -static int generic_write(struct gpib_board *board, uint8_t *buffer, size_t length, +static int generic_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, int send_commands, size_t *bytes_written) { size_t count = 0; @@ -531,7 +533,8 @@ static int generic_write(struct gpib_board *board, uint8_t *buffer, size_t lengt nec7210_set_reg_bits(nec_priv, IMR1, HR_ERR, 0x0); nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0x0); - /* force handling of any interrupts that happened + /* + * force handling of any interrupts that happened * while they were masked (this appears to be needed) */ tnt4882_internal_interrupt(board); @@ -539,13 +542,13 @@ static int generic_write(struct gpib_board *board, uint8_t *buffer, size_t lengt return retval; } -static int tnt4882_accel_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi, - size_t *bytes_written) +static int tnt4882_accel_write(struct gpib_board *board, u8 *buffer, + size_t length, int send_eoi, size_t *bytes_written) { return generic_write(board, buffer, length, send_eoi, 0, bytes_written); } -static int tnt4882_command(struct gpib_board *board, uint8_t *buffer, size_t length, +static int tnt4882_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { return generic_write(board, buffer, length, 0, 1, bytes_written); @@ -566,7 +569,7 @@ static irqreturn_t tnt4882_internal_interrupt(struct gpib_board *board) imr3_bits = priv->imr3_bits; if (isr0_bits & TNT_IFCI_BIT) - push_gpib_event(board, EventIFC); + push_gpib_event(board, EVENT_IFC); //XXX don't need this wakeup, one below should do? // wake_up_interruptible(&board->wait); @@ -592,7 +595,7 @@ static irqreturn_t tnt4882_interrupt(int irq, void *arg) } // wrappers for interface functions -static int tnt4882_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end, +static int tnt4882_read(struct gpib_board *board, u8 *buffer, size_t length, int *end, size_t *bytes_read) { struct tnt4882_priv *priv = board->private_data; @@ -612,7 +615,7 @@ static int tnt4882_read(struct gpib_board *board, uint8_t *buffer, size_t length return retval; } -static int tnt4882_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi, +static int tnt4882_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, size_t *bytes_written) { struct tnt4882_priv *priv = board->private_data; @@ -620,7 +623,7 @@ static int tnt4882_write(struct gpib_board *board, uint8_t *buffer, size_t lengt return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); } -static int tnt4882_command_unaccel(struct gpib_board *board, uint8_t *buffer, +static int tnt4882_command_unaccel(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written) { struct tnt4882_priv *priv = board->private_data; @@ -642,19 +645,21 @@ static int tnt4882_go_to_standby(struct gpib_board *board) return nec7210_go_to_standby(board, &priv->nec7210_priv); } -static void tnt4882_request_system_control(struct gpib_board *board, int request_control) +static int tnt4882_request_system_control(struct gpib_board *board, int request_control) { struct tnt4882_priv *priv = board->private_data; + int retval; if (request_control) { tnt_writeb(priv, SETSC, CMDR); udelay(1); } - nec7210_request_system_control(board, &priv->nec7210_priv, request_control); + retval = nec7210_request_system_control(board, &priv->nec7210_priv, request_control); if (!request_control) { tnt_writeb(priv, CLRSC, CMDR); udelay(1); } + return retval; } static void tnt4882_interface_clear(struct gpib_board *board, int assert) @@ -671,7 +676,7 @@ static void tnt4882_remote_enable(struct gpib_board *board, int enable) nec7210_remote_enable(board, &priv->nec7210_priv, enable); } -static int tnt4882_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits) +static int tnt4882_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) { struct tnt4882_priv *priv = board->private_data; @@ -718,7 +723,7 @@ static int tnt4882_secondary_address(struct gpib_board *board, unsigned int addr return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); } -static int tnt4882_parallel_poll(struct gpib_board *board, uint8_t *result) +static int tnt4882_parallel_poll(struct gpib_board *board, u8 *result) { struct tnt4882_priv *tnt_priv = board->private_data; @@ -735,7 +740,7 @@ static int tnt4882_parallel_poll(struct gpib_board *board, uint8_t *result) } } -static void tnt4882_parallel_poll_configure(struct gpib_board *board, uint8_t config) +static void tnt4882_parallel_poll_configure(struct gpib_board *board, u8 config) { struct tnt4882_priv *priv = board->private_data; @@ -760,17 +765,18 @@ static void tnt4882_parallel_poll_response(struct gpib_board *board, int ist) nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); } -/* this is just used by the old nec7210 isa interfaces, the newer +/* + * this is just used by the old nec7210 isa interfaces, the newer * boards use tnt4882_serial_poll_response2 */ -static void tnt4882_serial_poll_response(struct gpib_board *board, uint8_t status) +static void tnt4882_serial_poll_response(struct gpib_board *board, u8 status) { struct tnt4882_priv *priv = board->private_data; nec7210_serial_poll_response(board, &priv->nec7210_priv, status); } -static void tnt4882_serial_poll_response2(struct gpib_board *board, uint8_t status, +static void tnt4882_serial_poll_response2(struct gpib_board *board, u8 status, int new_reason_for_service) { struct tnt4882_priv *priv = board->private_data; @@ -788,7 +794,8 @@ static void tnt4882_serial_poll_response2(struct gpib_board *board, uint8_t stat priv->nec7210_priv.srq_pending = 0; } if (reqt) - /* It may seem like a race to issue reqt before updating + /* + * It may seem like a race to issue reqt before updating * the status byte, but it is not. The chip does not * issue the reqt until the SPMR is written to at * a later time. @@ -796,7 +803,8 @@ static void tnt4882_serial_poll_response2(struct gpib_board *board, uint8_t stat write_byte(&priv->nec7210_priv, AUX_REQT, AUXMR); else if (reqf) write_byte(&priv->nec7210_priv, AUX_REQF, AUXMR); - /* We need to always zero bit 6 of the status byte before writing it to + /* + * We need to always zero bit 6 of the status byte before writing it to * the SPMR to insure we are using * serial poll mode SP1, and not accidentally triggering mode SP3. */ @@ -804,7 +812,7 @@ static void tnt4882_serial_poll_response2(struct gpib_board *board, uint8_t stat spin_unlock_irqrestore(&board->spinlock, flags); } -static uint8_t tnt4882_serial_poll_status(struct gpib_board *board) +static u8 tnt4882_serial_poll_status(struct gpib_board *board) { struct tnt4882_priv *priv = board->private_data; @@ -898,7 +906,7 @@ static void tnt4882_init(struct tnt4882_priv *tnt_priv, const struct gpib_board tnt_writeb(tnt_priv, tnt_priv->imr0_bits, IMR0); } -static int ni_pci_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ni_pci_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct tnt4882_priv *tnt_priv; struct nec7210_priv *nec_priv; @@ -1019,7 +1027,7 @@ static int ni_isapnp_find(struct pnp_dev **dev) return 0; } -static int ni_isa_attach_common(struct gpib_board *board, const gpib_board_config_t *config, +static int ni_isa_attach_common(struct gpib_board *board, const struct gpib_board_config *config, enum nec7210_chipset chipset) { struct tnt4882_priv *tnt_priv; @@ -1075,17 +1083,17 @@ static int ni_isa_attach_common(struct gpib_board *board, const gpib_board_confi return 0; } -static int ni_tnt_isa_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ni_tnt_isa_attach(struct gpib_board *board, const struct gpib_board_config *config) { return ni_isa_attach_common(board, config, TNT4882); } -static int ni_nat4882_isa_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ni_nat4882_isa_attach(struct gpib_board *board, const struct gpib_board_config *config) { return ni_isa_attach_common(board, config, NAT4882); } -static int ni_nec_isa_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ni_nec_isa_attach(struct gpib_board *board, const struct gpib_board_config *config) { return ni_isa_attach_common(board, config, NEC7210); } @@ -1116,7 +1124,7 @@ static int tnt4882_pci_probe(struct pci_dev *dev, const struct pci_device_id *id return 0; } -static gpib_interface_t ni_pci_interface = { +static struct gpib_interface ni_pci_interface = { .name = "ni_pci", .attach = ni_pci_attach, .detach = ni_pci_detach, @@ -1144,7 +1152,7 @@ static gpib_interface_t ni_pci_interface = { .return_to_local = tnt4882_return_to_local, }; -static gpib_interface_t ni_pci_accel_interface = { +static struct gpib_interface ni_pci_accel_interface = { .name = "ni_pci_accel", .attach = ni_pci_attach, .detach = ni_pci_detach, @@ -1172,7 +1180,7 @@ static gpib_interface_t ni_pci_accel_interface = { .return_to_local = tnt4882_return_to_local, }; -static gpib_interface_t ni_isa_interface = { +static struct gpib_interface ni_isa_interface = { .name = "ni_isa", .attach = ni_tnt_isa_attach, .detach = ni_isa_detach, @@ -1200,7 +1208,7 @@ static gpib_interface_t ni_isa_interface = { .return_to_local = tnt4882_return_to_local, }; -static gpib_interface_t ni_nat4882_isa_interface = { +static struct gpib_interface ni_nat4882_isa_interface = { .name = "ni_nat4882_isa", .attach = ni_nat4882_isa_attach, .detach = ni_isa_detach, @@ -1228,7 +1236,7 @@ static gpib_interface_t ni_nat4882_isa_interface = { .return_to_local = tnt4882_return_to_local, }; -static gpib_interface_t ni_nec_isa_interface = { +static struct gpib_interface ni_nec_isa_interface = { .name = "ni_nec_isa", .attach = ni_nec_isa_attach, .detach = ni_isa_detach, @@ -1256,7 +1264,7 @@ static gpib_interface_t ni_nec_isa_interface = { .return_to_local = tnt4882_return_to_local, }; -static gpib_interface_t ni_isa_accel_interface = { +static struct gpib_interface ni_isa_accel_interface = { .name = "ni_isa_accel", .attach = ni_tnt_isa_attach, .detach = ni_isa_detach, @@ -1284,7 +1292,7 @@ static gpib_interface_t ni_isa_accel_interface = { .return_to_local = tnt4882_return_to_local, }; -static gpib_interface_t ni_nat4882_isa_accel_interface = { +static struct gpib_interface ni_nat4882_isa_accel_interface = { .name = "ni_nat4882_isa_accel", .attach = ni_nat4882_isa_attach, .detach = ni_isa_detach, @@ -1312,7 +1320,7 @@ static gpib_interface_t ni_nat4882_isa_accel_interface = { .return_to_local = tnt4882_return_to_local, }; -static gpib_interface_t ni_nec_isa_accel_interface = { +static struct gpib_interface ni_nec_isa_accel_interface = { .name = "ni_nec_isa_accel", .attach = ni_nec_isa_attach, .detach = ni_isa_detach, @@ -1371,8 +1379,8 @@ MODULE_DEVICE_TABLE(pnp, tnt4882_pnp_table); #endif #ifdef CONFIG_GPIB_PCMCIA -static gpib_interface_t ni_pcmcia_interface; -static gpib_interface_t ni_pcmcia_accel_interface; +static struct gpib_interface ni_pcmcia_interface; +static struct gpib_interface ni_pcmcia_accel_interface; static int __init init_ni_gpib_cs(void); static void __exit exit_ni_gpib_cs(void); #endif @@ -1581,10 +1589,10 @@ static int ni_gpib_probe(struct pcmcia_device *link) } /* - * This deletes a driver "instance". The device is de-registered - * with Card Services. If it has been released, all local data - * structures are freed. Otherwise, the structures will be freed - * when the device is released. + * This deletes a driver "instance". The device is de-registered + * with Card Services. If it has been released, all local data + * structures are freed. Otherwise, the structures will be freed + * when the device is released. */ static void ni_gpib_remove(struct pcmcia_device *link) { @@ -1611,9 +1619,9 @@ static int ni_gpib_config_iteration(struct pcmcia_device *link, void *priv_data) } /* - * ni_gpib_config() is scheduled to run after a CARD_INSERTION event - * is received, to configure the PCMCIA socket, and to make the - * device available to the system. + * ni_gpib_config() is scheduled to run after a CARD_INSERTION event + * is received, to configure the PCMCIA socket, and to make the + * device available to the system. */ static int ni_gpib_config(struct pcmcia_device *link) { @@ -1702,7 +1710,7 @@ static void __exit exit_ni_gpib_cs(void) static const int pcmcia_gpib_iosize = 32; -static int ni_pcmcia_attach(struct gpib_board *board, const gpib_board_config_t *config) +static int ni_pcmcia_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct local_info_t *info; struct tnt4882_priv *tnt_priv; @@ -1769,7 +1777,7 @@ static void ni_pcmcia_detach(struct gpib_board *board) tnt4882_free_private(board); } -static gpib_interface_t ni_pcmcia_interface = { +static struct gpib_interface ni_pcmcia_interface = { .name = "ni_pcmcia", .attach = ni_pcmcia_attach, .detach = ni_pcmcia_detach, @@ -1797,7 +1805,7 @@ static gpib_interface_t ni_pcmcia_interface = { .return_to_local = tnt4882_return_to_local, }; -static gpib_interface_t ni_pcmcia_accel_interface = { +static struct gpib_interface ni_pcmcia_accel_interface = { .name = "ni_pcmcia_accel", .attach = ni_pcmcia_attach, .detach = ni_pcmcia_detach, diff --git a/drivers/staging/gpib/uapi/gpib.h b/drivers/staging/gpib/uapi/gpib.h new file mode 100644 index 000000000000..ddf82a4d989f --- /dev/null +++ b/drivers/staging/gpib/uapi/gpib.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _GPIB_H +#define _GPIB_H + +#define GPIB_MAX_NUM_BOARDS 16 +#define GPIB_MAX_NUM_DESCRIPTORS 0x1000 + +enum ibsta_bit_numbers { + DCAS_NUM = 0, + DTAS_NUM = 1, + LACS_NUM = 2, + TACS_NUM = 3, + ATN_NUM = 4, + CIC_NUM = 5, + REM_NUM = 6, + LOK_NUM = 7, + CMPL_NUM = 8, + EVENT_NUM = 9, + SPOLL_NUM = 10, + RQS_NUM = 11, + SRQI_NUM = 12, + END_NUM = 13, + TIMO_NUM = 14, + ERR_NUM = 15 +}; + +/* IBSTA status bits (returned by all functions) */ +enum ibsta_bits { + DCAS = (1 << DCAS_NUM), /* device clear state */ + DTAS = (1 << DTAS_NUM), /* device trigger state */ + LACS = (1 << LACS_NUM), /* GPIB interface is addressed as Listener */ + TACS = (1 << TACS_NUM), /* GPIB interface is addressed as Talker */ + ATN = (1 << ATN_NUM), /* Attention is asserted */ + CIC = (1 << CIC_NUM), /* GPIB interface is Controller-in-Charge */ + REM = (1 << REM_NUM), /* remote state */ + LOK = (1 << LOK_NUM), /* lockout state */ + CMPL = (1 << CMPL_NUM), /* I/O is complete */ + EVENT = (1 << EVENT_NUM), /* DCAS, DTAS, or IFC has occurred */ + SPOLL = (1 << SPOLL_NUM), /* board serial polled by busmaster */ + RQS = (1 << RQS_NUM), /* Device requesting service */ + SRQI = (1 << SRQI_NUM), /* SRQ is asserted */ + END = (1 << END_NUM), /* EOI or EOS encountered */ + TIMO = (1 << TIMO_NUM), /* Time limit on I/O or wait function exceeded */ + ERR = (1 << ERR_NUM), /* Function call terminated on error */ + + device_status_mask = ERR | TIMO | END | CMPL | RQS, + board_status_mask = ERR | TIMO | END | CMPL | SPOLL | + EVENT | LOK | REM | CIC | ATN | TACS | LACS | DTAS | DCAS | SRQI, +}; + +/* End-of-string (EOS) modes for use with ibeos */ + +enum eos_flags { + EOS_MASK = 0x1c00, + REOS = 0x0400, /* Terminate reads on EOS */ + XEOS = 0x800, /* assert EOI when EOS char is sent */ + BIN = 0x1000 /* Do 8-bit compare on EOS */ +}; + +/* GPIB Bus Control Lines bit vector */ +enum bus_control_line { + VALID_DAV = 0x01, + VALID_NDAC = 0x02, + VALID_NRFD = 0x04, + VALID_IFC = 0x08, + VALID_REN = 0x10, + VALID_SRQ = 0x20, + VALID_ATN = 0x40, + VALID_EOI = 0x80, + VALID_ALL = 0xff, + BUS_DAV = 0x0100, /* DAV line status bit */ + BUS_NDAC = 0x0200, /* NDAC line status bit */ + BUS_NRFD = 0x0400, /* NRFD line status bit */ + BUS_IFC = 0x0800, /* IFC line status bit */ + BUS_REN = 0x1000, /* REN line status bit */ + BUS_SRQ = 0x2000, /* SRQ line status bit */ + BUS_ATN = 0x4000, /* ATN line status bit */ + BUS_EOI = 0x8000 /* EOI line status bit */ +}; + +enum ppe_bits { + PPC_DISABLE = 0x10, + PPC_SENSE = 0x8, /* parallel poll sense bit */ + PPC_DIO_MASK = 0x7 +}; + +enum { + request_service_bit = 0x40, +}; + +enum gpib_events { + EVENT_NONE = 0, + EVENT_DEV_TRG = 1, + EVENT_DEV_CLR = 2, + EVENT_IFC = 3 +}; + +#endif /* _GPIB_H */ + diff --git a/drivers/staging/gpib/uapi/gpib_ioctl.h b/drivers/staging/gpib/uapi/gpib_ioctl.h index 6202865278ea..55bf5e55507a 100644 --- a/drivers/staging/gpib/uapi/gpib_ioctl.h +++ b/drivers/staging/gpib/uapi/gpib_ioctl.h @@ -12,158 +12,156 @@ #define GPIB_CODE 160 -typedef struct { +struct gpib_board_type_ioctl { char name[100]; -} board_type_ioctl_t; +}; /* argument for read/write/command ioctls */ -typedef struct { - uint64_t buffer_ptr; - unsigned int requested_transfer_count; - unsigned int completed_transfer_count; - int end; /* end flag return for reads, end io suppression request for cmd*/ - int handle; -} read_write_ioctl_t; - -typedef struct { - unsigned int handle; - unsigned int pad; - int sad; - unsigned is_board : 1; -} open_dev_ioctl_t; - -typedef struct { - unsigned int handle; -} close_dev_ioctl_t; - -typedef struct { - unsigned int pad; - int sad; - uint8_t status_byte; -} serial_poll_ioctl_t; - -typedef struct { - int eos; - int eos_flags; -} eos_ioctl_t; - -typedef struct { - int handle; - int wait_mask; - int clear_mask; - int set_mask; - int ibsta; - int pad; - int sad; - unsigned int usec_timeout; -} wait_ioctl_t; - -typedef struct { - uint64_t init_data_ptr; - int init_data_length; - int online; -} online_ioctl_t; - -typedef struct { - unsigned int num_bytes; - unsigned int pad; - int sad; -} spoll_bytes_ioctl_t; - -typedef struct { - unsigned int pad; - int sad; - int parallel_poll_configuration; - int autopolling; - int is_system_controller; - unsigned int t1_delay; +struct gpib_read_write_ioctl { + __u64 buffer_ptr; + __u32 requested_transfer_count; + __u32 completed_transfer_count; + __s32 end; /* end flag return for reads, end io suppression request for cmd*/ + __s32 handle; +}; + +struct gpib_open_dev_ioctl { + __u32 handle; + __u32 pad; + __s32 sad; + __u32 is_board; +}; + +struct gpib_close_dev_ioctl { + __u32 handle; +}; + +struct gpib_serial_poll_ioctl { + __u32 pad; + __s32 sad; + __u8 status_byte; + __u8 padding[3]; // align to 32 bit boundary +}; + +struct gpib_eos_ioctl { + __s32 eos; + __s32 eos_flags; +}; + +struct gpib_wait_ioctl { + __s32 handle; + __s32 wait_mask; + __s32 clear_mask; + __s32 set_mask; + __s32 ibsta; + __s32 pad; + __s32 sad; + __u32 usec_timeout; +}; + +struct gpib_online_ioctl { + __u64 init_data_ptr; + __s32 init_data_length; + __s32 online; +}; + +struct gpib_spoll_bytes_ioctl { + __u32 num_bytes; + __u32 pad; + __s32 sad; +}; + +struct gpib_board_info_ioctl { + __u32 pad; + __s32 sad; + __s32 parallel_poll_configuration; + __s32 autopolling; + __s32 is_system_controller; + __u32 t1_delay; unsigned ist : 1; unsigned no_7_bit_eos : 1; -} board_info_ioctl_t; + unsigned padding :30; // align to 32 bit boundary +}; -typedef struct { - int pci_bus; - int pci_slot; -} select_pci_ioctl_t; +struct gpib_select_pci_ioctl { + __s32 pci_bus; + __s32 pci_slot; +}; -typedef struct { - uint8_t config; +struct gpib_ppoll_config_ioctl { + __u8 config; unsigned set_ist : 1; unsigned clear_ist : 1; -} ppoll_config_ioctl_t; + unsigned padding :22; // align to 32 bit boundary +}; -typedef struct { - unsigned int handle; - unsigned int pad; -} pad_ioctl_t; +struct gpib_pad_ioctl { + __u32 handle; + __u32 pad; +}; -typedef struct { - unsigned int handle; - int sad; -} sad_ioctl_t; +struct gpib_sad_ioctl { + __u32 handle; + __s32 sad; +}; // select a piece of hardware to attach by its sysfs device path -typedef struct { +struct gpib_select_device_path_ioctl { char device_path[0x1000]; -} select_device_path_ioctl_t; - -typedef short event_ioctl_t; -typedef int rsc_ioctl_t; -typedef unsigned int t1_delay_ioctl_t; -typedef short autospoll_ioctl_t; -typedef short local_ppoll_mode_ioctl_t; +}; // update status byte and request service -typedef struct { - uint8_t status_byte; - int new_reason_for_service; -} request_service2_t; +struct gpib_request_service2 { + __u8 status_byte; + __u8 padding[3]; // align to 32 bit boundary + __s32 new_reason_for_service; +}; /* Standard functions. */ enum gpib_ioctl { - IBRD = _IOWR(GPIB_CODE, 100, read_write_ioctl_t), - IBWRT = _IOWR(GPIB_CODE, 101, read_write_ioctl_t), - IBCMD = _IOWR(GPIB_CODE, 102, read_write_ioctl_t), - IBOPENDEV = _IOWR(GPIB_CODE, 3, open_dev_ioctl_t), - IBCLOSEDEV = _IOW(GPIB_CODE, 4, close_dev_ioctl_t), - IBWAIT = _IOWR(GPIB_CODE, 5, wait_ioctl_t), - IBRPP = _IOWR(GPIB_CODE, 6, uint8_t), - - IBSIC = _IOW(GPIB_CODE, 9, unsigned int), - IBSRE = _IOW(GPIB_CODE, 10, int), + IBRD = _IOWR(GPIB_CODE, 100, struct gpib_read_write_ioctl), + IBWRT = _IOWR(GPIB_CODE, 101, struct gpib_read_write_ioctl), + IBCMD = _IOWR(GPIB_CODE, 102, struct gpib_read_write_ioctl), + IBOPENDEV = _IOWR(GPIB_CODE, 3, struct gpib_open_dev_ioctl), + IBCLOSEDEV = _IOW(GPIB_CODE, 4, struct gpib_close_dev_ioctl), + IBWAIT = _IOWR(GPIB_CODE, 5, struct gpib_wait_ioctl), + IBRPP = _IOWR(GPIB_CODE, 6, __u8), + + IBSIC = _IOW(GPIB_CODE, 9, __u32), + IBSRE = _IOW(GPIB_CODE, 10, __s32), IBGTS = _IO(GPIB_CODE, 11), - IBCAC = _IOW(GPIB_CODE, 12, int), - IBLINES = _IOR(GPIB_CODE, 14, short), - IBPAD = _IOW(GPIB_CODE, 15, pad_ioctl_t), - IBSAD = _IOW(GPIB_CODE, 16, sad_ioctl_t), - IBTMO = _IOW(GPIB_CODE, 17, unsigned int), - IBRSP = _IOWR(GPIB_CODE, 18, serial_poll_ioctl_t), - IBEOS = _IOW(GPIB_CODE, 19, eos_ioctl_t), - IBRSV = _IOW(GPIB_CODE, 20, uint8_t), - CFCBASE = _IOW(GPIB_CODE, 21, uint64_t), - CFCIRQ = _IOW(GPIB_CODE, 22, unsigned int), - CFCDMA = _IOW(GPIB_CODE, 23, unsigned int), - CFCBOARDTYPE = _IOW(GPIB_CODE, 24, board_type_ioctl_t), - - IBMUTEX = _IOW(GPIB_CODE, 26, int), - IBSPOLL_BYTES = _IOWR(GPIB_CODE, 27, spoll_bytes_ioctl_t), - IBPPC = _IOW(GPIB_CODE, 28, ppoll_config_ioctl_t), - IBBOARD_INFO = _IOR(GPIB_CODE, 29, board_info_ioctl_t), - - IBQUERY_BOARD_RSV = _IOR(GPIB_CODE, 31, int), - IBSELECT_PCI = _IOWR(GPIB_CODE, 32, select_pci_ioctl_t), - IBEVENT = _IOR(GPIB_CODE, 33, event_ioctl_t), - IBRSC = _IOW(GPIB_CODE, 34, rsc_ioctl_t), - IB_T1_DELAY = _IOW(GPIB_CODE, 35, t1_delay_ioctl_t), + IBCAC = _IOW(GPIB_CODE, 12, __s32), + IBLINES = _IOR(GPIB_CODE, 14, __s16), + IBPAD = _IOW(GPIB_CODE, 15, struct gpib_pad_ioctl), + IBSAD = _IOW(GPIB_CODE, 16, struct gpib_sad_ioctl), + IBTMO = _IOW(GPIB_CODE, 17, __u32), + IBRSP = _IOWR(GPIB_CODE, 18, struct gpib_serial_poll_ioctl), + IBEOS = _IOW(GPIB_CODE, 19, struct gpib_eos_ioctl), + IBRSV = _IOW(GPIB_CODE, 20, __u8), + CFCBASE = _IOW(GPIB_CODE, 21, __u64), + CFCIRQ = _IOW(GPIB_CODE, 22, __u32), + CFCDMA = _IOW(GPIB_CODE, 23, __u32), + CFCBOARDTYPE = _IOW(GPIB_CODE, 24, struct gpib_board_type_ioctl), + + IBMUTEX = _IOW(GPIB_CODE, 26, __s32), + IBSPOLL_BYTES = _IOWR(GPIB_CODE, 27, struct gpib_spoll_bytes_ioctl), + IBPPC = _IOW(GPIB_CODE, 28, struct gpib_ppoll_config_ioctl), + IBBOARD_INFO = _IOR(GPIB_CODE, 29, struct gpib_board_info_ioctl), + + IBQUERY_BOARD_RSV = _IOR(GPIB_CODE, 31, __s32), + IBSELECT_PCI = _IOWR(GPIB_CODE, 32, struct gpib_select_pci_ioctl), + IBEVENT = _IOR(GPIB_CODE, 33, __s16), + IBRSC = _IOW(GPIB_CODE, 34, __s32), + IB_T1_DELAY = _IOW(GPIB_CODE, 35, __u32), IBLOC = _IO(GPIB_CODE, 36), - IBAUTOSPOLL = _IOW(GPIB_CODE, 38, autospoll_ioctl_t), - IBONL = _IOW(GPIB_CODE, 39, online_ioctl_t), - IBPP2_SET = _IOW(GPIB_CODE, 40, local_ppoll_mode_ioctl_t), - IBPP2_GET = _IOR(GPIB_CODE, 41, local_ppoll_mode_ioctl_t), - IBSELECT_DEVICE_PATH = _IOW(GPIB_CODE, 43, select_device_path_ioctl_t), + IBAUTOSPOLL = _IOW(GPIB_CODE, 38, __s16), + IBONL = _IOW(GPIB_CODE, 39, struct gpib_online_ioctl), + IBPP2_SET = _IOW(GPIB_CODE, 40, __s16), + IBPP2_GET = _IOR(GPIB_CODE, 41, __s16), + IBSELECT_DEVICE_PATH = _IOW(GPIB_CODE, 43, struct gpib_select_device_path_ioctl), // 44 was IBSELECT_SERIAL_NUMBER - IBRSV2 = _IOW(GPIB_CODE, 45, request_service2_t) + IBRSV2 = _IOW(GPIB_CODE, 45, struct gpib_request_service2) }; #endif /* _GPIB_IOCTL_H */ diff --git a/drivers/staging/gpib/uapi/gpib_user.h b/drivers/staging/gpib/uapi/gpib_user.h deleted file mode 100644 index 5ff4588686fd..000000000000 --- a/drivers/staging/gpib/uapi/gpib_user.h +++ /dev/null @@ -1,352 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -/*************************************************************************** - * copyright : (C) 2002 by Frank Mori Hess - ***************************************************************************/ - -#ifndef _GPIB_USER_H -#define _GPIB_USER_H - -#define GPIB_MAX_NUM_BOARDS 16 -#define GPIB_MAX_NUM_DESCRIPTORS 0x1000 - -enum ibsta_bit_numbers { - DCAS_NUM = 0, - DTAS_NUM = 1, - LACS_NUM = 2, - TACS_NUM = 3, - ATN_NUM = 4, - CIC_NUM = 5, - REM_NUM = 6, - LOK_NUM = 7, - CMPL_NUM = 8, - EVENT_NUM = 9, - SPOLL_NUM = 10, - RQS_NUM = 11, - SRQI_NUM = 12, - END_NUM = 13, - TIMO_NUM = 14, - ERR_NUM = 15 -}; - -/* IBSTA status bits (returned by all functions) */ -enum ibsta_bits { - DCAS = (1 << DCAS_NUM), /* device clear state */ - DTAS = (1 << DTAS_NUM), /* device trigger state */ - LACS = (1 << LACS_NUM), /* GPIB interface is addressed as Listener */ - TACS = (1 << TACS_NUM), /* GPIB interface is addressed as Talker */ - ATN = (1 << ATN_NUM), /* Attention is asserted */ - CIC = (1 << CIC_NUM), /* GPIB interface is Controller-in-Charge */ - REM = (1 << REM_NUM), /* remote state */ - LOK = (1 << LOK_NUM), /* lockout state */ - CMPL = (1 << CMPL_NUM), /* I/O is complete */ - EVENT = (1 << EVENT_NUM), /* DCAS, DTAS, or IFC has occurred */ - SPOLL = (1 << SPOLL_NUM), /* board serial polled by busmaster */ - RQS = (1 << RQS_NUM), /* Device requesting service */ - SRQI = (1 << SRQI_NUM), /* SRQ is asserted */ - END = (1 << END_NUM), /* EOI or EOS encountered */ - TIMO = (1 << TIMO_NUM), /* Time limit on I/O or wait function exceeded */ - ERR = (1 << ERR_NUM), /* Function call terminated on error */ - - device_status_mask = ERR | TIMO | END | CMPL | RQS, - board_status_mask = ERR | TIMO | END | CMPL | SPOLL | - EVENT | LOK | REM | CIC | ATN | TACS | LACS | DTAS | DCAS | SRQI, -}; - -/* IBERR error codes */ -enum iberr_code { - EDVR = 0, /* system error */ - ECIC = 1, /* not CIC */ - ENOL = 2, /* no listeners */ - EADR = 3, /* CIC and not addressed before I/O */ - EARG = 4, /* bad argument to function call */ - ESAC = 5, /* not SAC */ - EABO = 6, /* I/O operation was aborted */ - ENEB = 7, /* non-existent board (GPIB interface offline) */ - EDMA = 8, /* DMA hardware error detected */ - EOIP = 10, /* new I/O attempted with old I/O in progress */ - ECAP = 11, /* no capability for intended opeation */ - EFSO = 12, /* file system operation error */ - EBUS = 14, /* bus error */ - ESTB = 15, /* lost serial poll bytes */ - ESRQ = 16, /* SRQ stuck on */ - ETAB = 20 /* Table Overflow */ -}; - -/* Timeout values and meanings */ -enum gpib_timeout { - TNONE = 0, /* Infinite timeout (disabled) */ - T10us = 1, /* Timeout of 10 usec (ideal) */ - T30us = 2, /* Timeout of 30 usec (ideal) */ - T100us = 3, /* Timeout of 100 usec (ideal) */ - T300us = 4, /* Timeout of 300 usec (ideal) */ - T1ms = 5, /* Timeout of 1 msec (ideal) */ - T3ms = 6, /* Timeout of 3 msec (ideal) */ - T10ms = 7, /* Timeout of 10 msec (ideal) */ - T30ms = 8, /* Timeout of 30 msec (ideal) */ - T100ms = 9, /* Timeout of 100 msec (ideal) */ - T300ms = 10, /* Timeout of 300 msec (ideal) */ - T1s = 11, /* Timeout of 1 sec (ideal) */ - T3s = 12, /* Timeout of 3 sec (ideal) */ - T10s = 13, /* Timeout of 10 sec (ideal) */ - T30s = 14, /* Timeout of 30 sec (ideal) */ - T100s = 15, /* Timeout of 100 sec (ideal) */ - T300s = 16, /* Timeout of 300 sec (ideal) */ - T1000s = 17 /* Timeout of 1000 sec (maximum) */ -}; - -/* End-of-string (EOS) modes for use with ibeos */ - -enum eos_flags { - EOS_MASK = 0x1c00, - REOS = 0x0400, /* Terminate reads on EOS */ - XEOS = 0x800, /* assert EOI when EOS char is sent */ - BIN = 0x1000 /* Do 8-bit compare on EOS */ -}; - -/* GPIB Bus Control Lines bit vector */ -enum bus_control_line { - VALID_DAV = 0x01, - VALID_NDAC = 0x02, - VALID_NRFD = 0x04, - VALID_IFC = 0x08, - VALID_REN = 0x10, - VALID_SRQ = 0x20, - VALID_ATN = 0x40, - VALID_EOI = 0x80, - VALID_ALL = 0xff, - BUS_DAV = 0x0100, /* DAV line status bit */ - BUS_NDAC = 0x0200, /* NDAC line status bit */ - BUS_NRFD = 0x0400, /* NRFD line status bit */ - BUS_IFC = 0x0800, /* IFC line status bit */ - BUS_REN = 0x1000, /* REN line status bit */ - BUS_SRQ = 0x2000, /* SRQ line status bit */ - BUS_ATN = 0x4000, /* ATN line status bit */ - BUS_EOI = 0x8000 /* EOI line status bit */ -}; - -/* Possible GPIB command messages */ - -enum cmd_byte { - GTL = 0x1, /* go to local */ - SDC = 0x4, /* selected device clear */ - PPConfig = 0x5, -#ifndef PPC - PPC = PPConfig, /* parallel poll configure */ -#endif - GET = 0x8, /* group execute trigger */ - TCT = 0x9, /* take control */ - LLO = 0x11, /* local lockout */ - DCL = 0x14, /* device clear */ - PPU = 0x15, /* parallel poll unconfigure */ - SPE = 0x18, /* serial poll enable */ - SPD = 0x19, /* serial poll disable */ - CFE = 0x1f, /* configure enable */ - LAD = 0x20, /* value to be 'ored' in to obtain listen address */ - UNL = 0x3F, /* unlisten */ - TAD = 0x40, /* value to be 'ored' in to obtain talk address */ - UNT = 0x5F, /* untalk */ - SAD = 0x60, /* my secondary address (base) */ - PPE = 0x60, /* parallel poll enable (base) */ - PPD = 0x70 /* parallel poll disable */ -}; - -enum ppe_bits { - PPC_DISABLE = 0x10, - PPC_SENSE = 0x8, /* parallel poll sense bit */ - PPC_DIO_MASK = 0x7 -}; - -/* confine address to range 0 to 30. */ -static inline unsigned int gpib_address_restrict(unsigned int addr) -{ - addr &= 0x1f; - if (addr == 0x1f) - addr = 0; - return addr; -} - -static inline uint8_t MLA(unsigned int addr) -{ - return gpib_address_restrict(addr) | LAD; -} - -static inline uint8_t MTA(unsigned int addr) -{ - return gpib_address_restrict(addr) | TAD; -} - -static inline uint8_t MSA(unsigned int addr) -{ - return gpib_address_restrict(addr) | SAD; -} - -static inline uint8_t PPE_byte(unsigned int dio_line, int sense) -{ - uint8_t cmd; - - cmd = PPE; - if (sense) - cmd |= PPC_SENSE; - cmd |= (dio_line - 1) & 0x7; - return cmd; -} - -static inline uint8_t CFGn(unsigned int meters) -{ - return 0x6 | (meters & 0xf); -} - -/* mask of bits that actually matter in a command byte */ -enum { - gpib_command_mask = 0x7f, -}; - -static inline int is_PPE(uint8_t command) -{ - return (command & 0x70) == 0x60; -} - -static inline int is_PPD(uint8_t command) -{ - return (command & 0x70) == 0x70; -} - -static inline int in_addressed_command_group(uint8_t command) -{ - return (command & 0x70) == 0x0; -} - -static inline int in_universal_command_group(uint8_t command) -{ - return (command & 0x70) == 0x10; -} - -static inline int in_listen_address_group(uint8_t command) -{ - return (command & 0x60) == 0x20; -} - -static inline int in_talk_address_group(uint8_t command) -{ - return (command & 0x60) == 0x40; -} - -static inline int in_primary_command_group(uint8_t command) -{ - return in_addressed_command_group(command) || - in_universal_command_group(command) || - in_listen_address_group(command) || - in_talk_address_group(command); -} - -static inline int gpib_address_equal(unsigned int pad1, int sad1, unsigned int pad2, int sad2) -{ - if (pad1 == pad2) { - if (sad1 == sad2) - return 1; - if (sad1 < 0 && sad2 < 0) - return 1; - } - - return 0; -} - -enum ibask_option { - IbaPAD = 0x1, - IbaSAD = 0x2, - IbaTMO = 0x3, - IbaEOT = 0x4, - IbaPPC = 0x5, /* board only */ - IbaREADDR = 0x6, /* device only */ - IbaAUTOPOLL = 0x7, /* board only */ - IbaCICPROT = 0x8, /* board only */ - IbaIRQ = 0x9, /* board only */ - IbaSC = 0xa, /* board only */ - IbaSRE = 0xb, /* board only */ - IbaEOSrd = 0xc, - IbaEOSwrt = 0xd, - IbaEOScmp = 0xe, - IbaEOSchar = 0xf, - IbaPP2 = 0x10, /* board only */ - IbaTIMING = 0x11, /* board only */ - IbaDMA = 0x12, /* board only */ - IbaReadAdjust = 0x13, - IbaWriteAdjust = 0x14, - IbaEventQueue = 0x15, /* board only */ - IbaSPollBit = 0x16, /* board only */ - IbaSpollBit = 0x16, /* board only */ - IbaSendLLO = 0x17, /* board only */ - IbaSPollTime = 0x18, /* device only */ - IbaPPollTime = 0x19, /* board only */ - IbaEndBitIsNormal = 0x1a, - IbaUnAddr = 0x1b, /* device only */ - IbaHSCableLength = 0x1f, /* board only */ - IbaIst = 0x20, /* board only */ - IbaRsv = 0x21, /* board only */ - IbaBNA = 0x200, /* device only */ - /* linux-gpib extensions */ - Iba7BitEOS = 0x1000 /* board only. Returns 1 if board supports 7 bit eos compares*/ -}; - -enum ibconfig_option { - IbcPAD = 0x1, - IbcSAD = 0x2, - IbcTMO = 0x3, - IbcEOT = 0x4, - IbcPPC = 0x5, /* board only */ - IbcREADDR = 0x6, /* device only */ - IbcAUTOPOLL = 0x7, /* board only */ - IbcCICPROT = 0x8, /* board only */ - IbcIRQ = 0x9, /* board only */ - IbcSC = 0xa, /* board only */ - IbcSRE = 0xb, /* board only */ - IbcEOSrd = 0xc, - IbcEOSwrt = 0xd, - IbcEOScmp = 0xe, - IbcEOSchar = 0xf, - IbcPP2 = 0x10, /* board only */ - IbcTIMING = 0x11, /* board only */ - IbcDMA = 0x12, /* board only */ - IbcReadAdjust = 0x13, - IbcWriteAdjust = 0x14, - IbcEventQueue = 0x15, /* board only */ - IbcSPollBit = 0x16, /* board only */ - IbcSpollBit = 0x16, /* board only */ - IbcSendLLO = 0x17, /* board only */ - IbcSPollTime = 0x18, /* device only */ - IbcPPollTime = 0x19, /* board only */ - IbcEndBitIsNormal = 0x1a, - IbcUnAddr = 0x1b, /* device only */ - IbcHSCableLength = 0x1f, /* board only */ - IbcIst = 0x20, /* board only */ - IbcRsv = 0x21, /* board only */ - IbcBNA = 0x200 /* device only */ -}; - -enum t1_delays { - T1_DELAY_2000ns = 1, - T1_DELAY_500ns = 2, - T1_DELAY_350ns = 3 -}; - -enum { - request_service_bit = 0x40, -}; - -enum gpib_events { - EventNone = 0, - EventDevTrg = 1, - EventDevClr = 2, - EventIFC = 3 -}; - -enum gpib_stb { - IbStbRQS = 0x40, /* IEEE 488.1 & 2 */ - IbStbESB = 0x20, /* IEEE 488.2 only */ - IbStbMAV = 0x10 /* IEEE 488.2 only */ -}; - -#endif /* _GPIB_USER_H */ - -/* Check for errors */ diff --git a/drivers/staging/greybus/Documentation/firmware/firmware.c b/drivers/staging/greybus/Documentation/firmware/firmware.c index 765d69faa9cc..3b35ef6d4adb 100644 --- a/drivers/staging/greybus/Documentation/firmware/firmware.c +++ b/drivers/staging/greybus/Documentation/firmware/firmware.c @@ -47,12 +47,12 @@ static int update_intf_firmware(int fd) ret = ioctl(fd, FW_MGMT_IOC_GET_INTF_FW, &intf_fw_info); if (ret < 0) { printf("Failed to get interface firmware version: %s (%d)\n", - fwdev, ret); + fwdev, ret); return -1; } printf("Interface Firmware tag (%s), major (%d), minor (%d)\n", - intf_fw_info.firmware_tag, intf_fw_info.major, + intf_fw_info.firmware_tag, intf_fw_info.major, intf_fw_info.minor); /* Try Interface Firmware load over Unipro */ @@ -69,20 +69,20 @@ static int update_intf_firmware(int fd) ret = ioctl(fd, FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE, &intf_load); if (ret < 0) { printf("Failed to load interface firmware: %s (%d)\n", fwdev, - ret); + ret); return -1; } if (intf_load.status != GB_FW_U_LOAD_STATUS_VALIDATED && intf_load.status != GB_FW_U_LOAD_STATUS_UNVALIDATED) { printf("Load status says loading failed: %d\n", - intf_load.status); + intf_load.status); return -1; } printf("Interface Firmware (%s) Load done: major: %d, minor: %d, status: %d\n", - firmware_tag, intf_load.major, intf_load.minor, - intf_load.status); + firmware_tag, intf_load.major, intf_load.minor, + intf_load.status); /* Initiate Mode-switch to the newly loaded firmware */ printf("Initiate Mode switch\n"); @@ -108,21 +108,21 @@ retry_fw_version: ret = ioctl(fd, FW_MGMT_IOC_GET_BACKEND_FW, &backend_fw_info); if (ret < 0) { printf("Failed to get backend firmware version: %s (%d)\n", - fwdev, ret); + fwdev, ret); return -1; } printf("Backend Firmware tag (%s), major (%d), minor (%d), status (%d)\n", - backend_fw_info.firmware_tag, backend_fw_info.major, + backend_fw_info.firmware_tag, backend_fw_info.major, backend_fw_info.minor, backend_fw_info.status); if (backend_fw_info.status == GB_FW_U_BACKEND_VERSION_STATUS_RETRY) goto retry_fw_version; - if ((backend_fw_info.status != GB_FW_U_BACKEND_VERSION_STATUS_SUCCESS) - && (backend_fw_info.status != GB_FW_U_BACKEND_VERSION_STATUS_NOT_AVAILABLE)) { + if ((backend_fw_info.status != GB_FW_U_BACKEND_VERSION_STATUS_SUCCESS) && + (backend_fw_info.status != GB_FW_U_BACKEND_VERSION_STATUS_NOT_AVAILABLE)) { printf("Failed to get backend firmware version: %s (%d)\n", - fwdev, backend_fw_info.status); + fwdev, backend_fw_info.status); return -1; } @@ -148,10 +148,10 @@ retry_fw_update: if (backend_update.status != GB_FW_U_BACKEND_FW_STATUS_SUCCESS) { printf("Load status says loading failed: %d\n", - backend_update.status); + backend_update.status); } else { printf("Backend Firmware (%s) Load done: status: %d\n", - firmware_tag, backend_update.status); + firmware_tag, backend_update.status); } return 0; @@ -185,7 +185,7 @@ int main(int argc, char *argv[]) fw_timeout = strtoul(argv[4], &endptr, 10); printf("Trying Firmware update: fwdev: %s, type: %s, tag: %s, timeout: %u\n", - fwdev, fw_update_type == 0 ? "interface" : "backend", + fwdev, fw_update_type == 0 ? "interface" : "backend", firmware_tag, fw_timeout); printf("Opening %s firmware management device\n", fwdev); diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c index 5d80ace41d8e..5ac19c0055d9 100644 --- a/drivers/staging/greybus/camera.c +++ b/drivers/staging/greybus/camera.c @@ -1128,7 +1128,7 @@ done: static int gb_camera_debugfs_open(struct inode *inode, struct file *file) { - file->private_data = (void *)debugfs_get_aux(file); + file->private_data = debugfs_get_aux(file); return 0; } @@ -1165,8 +1165,8 @@ static int gb_camera_debugfs_init(struct gb_camera *gcam) gcam->debugfs.buffers[i].length = 0; debugfs_create_file_aux(entry->name, entry->mask, - gcam->debugfs.root, gcam, entry, - &gb_camera_debugfs_ops); + gcam->debugfs.root, gcam, entry, + &gb_camera_debugfs_ops); } return 0; diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c index a47385175582..152949c23d65 100644 --- a/drivers/staging/greybus/fw-management.c +++ b/drivers/staging/greybus/fw-management.c @@ -123,17 +123,11 @@ static int fw_mgmt_interface_fw_version_operation(struct fw_mgmt *fw_mgmt, fw_info->major = le16_to_cpu(response.major); fw_info->minor = le16_to_cpu(response.minor); - strscpy_pad(fw_info->firmware_tag, response.firmware_tag); - - /* - * The firmware-tag should be NULL terminated, otherwise throw error but - * don't fail. - */ - if (fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') { + ret = strscpy_pad(fw_info->firmware_tag, response.firmware_tag); + if (ret == -E2BIG) dev_err(fw_mgmt->parent, - "fw-version: firmware-tag is not NULL terminated\n"); - fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] = '\0'; - } + "fw-version: truncated firmware tag: %s\n", + fw_info->firmware_tag); return 0; } @@ -152,14 +146,12 @@ static int fw_mgmt_load_and_validate_operation(struct fw_mgmt *fw_mgmt, } request.load_method = load_method; - strscpy_pad(request.firmware_tag, tag); - /* - * The firmware-tag should be NULL terminated, otherwise throw error and - * fail. - */ - if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') { - dev_err(fw_mgmt->parent, "load-and-validate: firmware-tag is not NULL terminated\n"); + ret = strscpy_pad(request.firmware_tag, tag); + if (ret == -E2BIG) { + dev_err(fw_mgmt->parent, + "load-and-validate: truncated firmware tag: %s\n", + request.firmware_tag); return -EINVAL; } @@ -248,14 +240,11 @@ static int fw_mgmt_backend_fw_version_operation(struct fw_mgmt *fw_mgmt, struct gb_fw_mgmt_backend_fw_version_response response; int ret; - strscpy_pad(request.firmware_tag, fw_info->firmware_tag); - - /* - * The firmware-tag should be NULL terminated, otherwise throw error and - * fail. - */ - if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') { - dev_err(fw_mgmt->parent, "backend-version: firmware-tag is not NULL terminated\n"); + ret = strscpy_pad(request.firmware_tag, fw_info->firmware_tag); + if (ret == -E2BIG) { + dev_err(fw_mgmt->parent, + "backend-fw-version: truncated firmware tag: %s\n", + request.firmware_tag); return -EINVAL; } @@ -302,13 +291,10 @@ static int fw_mgmt_backend_fw_update_operation(struct fw_mgmt *fw_mgmt, int ret; ret = strscpy_pad(request.firmware_tag, tag); - - /* - * The firmware-tag should be NULL terminated, otherwise throw error and - * fail. - */ if (ret == -E2BIG) { - dev_err(fw_mgmt->parent, "backend-update: firmware-tag is not NULL terminated\n"); + dev_err(fw_mgmt->parent, + "backend-fw-update: truncated firmware tag: %s\n", + request.firmware_tag); return -EINVAL; } diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c index 6adcad286633..60cf09a302a7 100644 --- a/drivers/staging/greybus/gbphy.c +++ b/drivers/staging/greybus/gbphy.c @@ -102,8 +102,8 @@ static int gbphy_dev_uevent(const struct device *dev, struct kobj_uevent_env *en } static const struct gbphy_device_id * -gbphy_dev_match_id(struct gbphy_device *gbphy_dev, - struct gbphy_driver *gbphy_drv) +gbphy_dev_match_id(const struct gbphy_device *gbphy_dev, + const struct gbphy_driver *gbphy_drv) { const struct gbphy_device_id *id = gbphy_drv->id_table; @@ -119,7 +119,7 @@ gbphy_dev_match_id(struct gbphy_device *gbphy_dev, static int gbphy_dev_match(struct device *dev, const struct device_driver *drv) { - struct gbphy_driver *gbphy_drv = to_gbphy_driver(drv); + const struct gbphy_driver *gbphy_drv = to_gbphy_driver(drv); struct gbphy_device *gbphy_dev = to_gbphy_dev(dev); const struct gbphy_device_id *id; diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c index 16bcf7fc8158..ac62b932e6a4 100644 --- a/drivers/staging/greybus/gpio.c +++ b/drivers/staging/greybus/gpio.c @@ -185,29 +185,25 @@ static int gb_gpio_get_value_operation(struct gb_gpio_controller *ggc, return 0; } -static void gb_gpio_set_value_operation(struct gb_gpio_controller *ggc, - u8 which, bool value_high) +static int gb_gpio_set_value_operation(struct gb_gpio_controller *ggc, + u8 which, bool value_high) { struct device *dev = &ggc->gbphy_dev->dev; struct gb_gpio_set_value_request request; int ret; - if (ggc->lines[which].direction == 1) { - dev_warn(dev, "refusing to set value of input gpio %u\n", - which); - return; - } - request.which = which; request.value = value_high ? 1 : 0; ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_SET_VALUE, &request, sizeof(request), NULL, 0); if (ret) { dev_err(dev, "failed to set value of gpio %u\n", which); - return; + return ret; } ggc->lines[which].value = request.value; + + return 0; } static int gb_gpio_set_debounce_operation(struct gb_gpio_controller *ggc, @@ -457,11 +453,11 @@ static int gb_gpio_get(struct gpio_chip *chip, unsigned int offset) return ggc->lines[which].value; } -static void gb_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) +static int gb_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct gb_gpio_controller *ggc = gpiochip_get_data(chip); - gb_gpio_set_value_operation(ggc, (u8)offset, !!value); + return gb_gpio_set_value_operation(ggc, (u8)offset, !!value); } static int gb_gpio_set_config(struct gpio_chip *chip, unsigned int offset, diff --git a/drivers/staging/greybus/power_supply.c b/drivers/staging/greybus/power_supply.c index 2ef46822f676..a484c0ca058d 100644 --- a/drivers/staging/greybus/power_supply.c +++ b/drivers/staging/greybus/power_supply.c @@ -324,7 +324,7 @@ static struct gb_power_supply_prop *get_psy_prop(struct gb_power_supply *gbpsy, } static int is_psy_prop_writeable(struct gb_power_supply *gbpsy, - enum power_supply_property psp) + enum power_supply_property psp) { struct gb_power_supply_prop *prop; @@ -493,7 +493,7 @@ static int gb_power_supply_description_get(struct gb_power_supply *gbpsy) if (!gbpsy->model_name) return -ENOMEM; gbpsy->serial_number = kstrndup(resp.serial_number, PROP_MAX, - GFP_KERNEL); + GFP_KERNEL); if (!gbpsy->serial_number) return -ENOMEM; @@ -546,7 +546,7 @@ static int gb_power_supply_prop_descriptors_get(struct gb_power_supply *gbpsy) } gbpsy->props = kcalloc(gbpsy->properties_count, sizeof(*gbpsy->props), - GFP_KERNEL); + GFP_KERNEL); if (!gbpsy->props) { ret = -ENOMEM; goto out_put_operation; @@ -634,8 +634,8 @@ static int __gb_power_supply_property_get(struct gb_power_supply *gbpsy, } static int __gb_power_supply_property_strval_get(struct gb_power_supply *gbpsy, - enum power_supply_property psp, - union power_supply_propval *val) + enum power_supply_property psp, + union power_supply_propval *val) { switch (psp) { case POWER_SUPPLY_PROP_MODEL_NAME: @@ -943,8 +943,8 @@ static int gb_power_supplies_setup(struct gb_power_supplies *supplies) goto out; supplies->supply = kcalloc(supplies->supplies_count, - sizeof(struct gb_power_supply), - GFP_KERNEL); + sizeof(struct gb_power_supply), + GFP_KERNEL); if (!supplies->supply) { ret = -ENOMEM; diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 308ed1ca9947..10df5c37c83e 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -916,7 +916,6 @@ static void gb_uart_remove(struct gbphy_device *gbphy_dev) { struct gb_tty *gb_tty = gb_gbphy_get_data(gbphy_dev); struct gb_connection *connection = gb_tty->connection; - struct tty_struct *tty; int ret; ret = gbphy_runtime_get_sync(gbphy_dev); @@ -929,11 +928,7 @@ static void gb_uart_remove(struct gbphy_device *gbphy_dev) wake_up_all(&gb_tty->wioctl); mutex_unlock(&gb_tty->mutex); - tty = tty_port_tty_get(&gb_tty->port); - if (tty) { - tty_vhangup(tty); - tty_kref_put(tty); - } + tty_port_tty_vhangup(&gb_tty->port); gb_connection_disable_rx(connection); tty_unregister_device(gb_tty_driver, gb_tty->minor); diff --git a/drivers/staging/iio/accel/adis16203.c b/drivers/staging/iio/accel/adis16203.c index c1c73308800c..830ff38fda92 100644 --- a/drivers/staging/iio/accel/adis16203.c +++ b/drivers/staging/iio/accel/adis16203.c @@ -294,7 +294,7 @@ static int adis16203_probe(struct spi_device *spi) static const struct of_device_id adis16203_of_match[] = { { .compatible = "adi,adis16203" }, - { }, + { } }; MODULE_DEVICE_TABLE(of, adis16203_of_match); diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 081b17f49863..4774df778de9 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -431,7 +431,7 @@ static const struct spi_device_id ad7816_id[] = { { "ad7816", ID_AD7816 }, { "ad7817", ID_AD7817 }, { "ad7818", ID_AD7818 }, - {} + { } }; MODULE_DEVICE_TABLE(spi, ad7816_id); diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c index e6ad088636f6..f45968ef94ea 100644 --- a/drivers/staging/iio/addac/adt7316-i2c.c +++ b/drivers/staging/iio/addac/adt7316-i2c.c @@ -127,7 +127,7 @@ static const struct of_device_id adt7316_of_match[] = { { .compatible = "adi,adt7516" }, { .compatible = "adi,adt7517" }, { .compatible = "adi,adt7519" }, - { }, + { } }; MODULE_DEVICE_TABLE(of, adt7316_of_match); diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index f4260786d50a..16f30c4f1aa0 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -1794,7 +1794,7 @@ static int adt7316_setup_irq(struct iio_dev *indio_dev) struct adt7316_chip_info *chip = iio_priv(indio_dev); int irq_type, ret; - irq_type = irqd_get_trigger_type(irq_get_irq_data(chip->bus.irq)); + irq_type = irq_get_trigger_type(chip->bus.irq); switch (irq_type) { case IRQF_TRIGGER_HIGH: diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c index db42810c7664..49388da5a684 100644 --- a/drivers/staging/iio/frequency/ad9832.c +++ b/drivers/staging/iio/frequency/ad9832.c @@ -7,6 +7,8 @@ #include <asm/div64.h> +#include <linux/bitfield.h> +#include <linux/bits.h> #include <linux/clk.h> #include <linux/device.h> #include <linux/err.h> @@ -16,6 +18,7 @@ #include <linux/slab.h> #include <linux/spi/spi.h> #include <linux/sysfs.h> +#include <linux/unaligned.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -59,17 +62,17 @@ #define AD9832_CMD_SLEEPRESCLR 0xC #define AD9832_FREQ BIT(11) -#define AD9832_PHASE(x) (((x) & 3) << 9) +#define AD9832_PHASE_MASK GENMASK(10, 9) #define AD9832_SYNC BIT(13) #define AD9832_SELSRC BIT(12) #define AD9832_SLEEP BIT(13) #define AD9832_RESET BIT(12) #define AD9832_CLR BIT(11) -#define CMD_SHIFT 12 -#define ADD_SHIFT 8 #define AD9832_FREQ_BITS 32 #define AD9832_PHASE_BITS 12 -#define RES_MASK(bits) ((1 << (bits)) - 1) +#define AD9832_CMD_MSK GENMASK(15, 12) +#define AD9832_ADD_MSK GENMASK(11, 8) +#define AD9832_DAT_MSK GENMASK(7, 0) /** * struct ad9832_state - driver instance specific data @@ -127,6 +130,8 @@ static int ad9832_write_frequency(struct ad9832_state *st, { unsigned long clk_freq; unsigned long regval; + u8 regval_bytes[4]; + u16 freq_cmd; clk_freq = clk_get_rate(st->mclk); @@ -134,19 +139,15 @@ static int ad9832_write_frequency(struct ad9832_state *st, return -EINVAL; regval = ad9832_calc_freqreg(clk_freq, fout); + put_unaligned_be32(regval, regval_bytes); - st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | - (addr << ADD_SHIFT) | - ((regval >> 24) & 0xFF)); - st->freq_data[1] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | - ((addr - 1) << ADD_SHIFT) | - ((regval >> 16) & 0xFF)); - st->freq_data[2] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | - ((addr - 2) << ADD_SHIFT) | - ((regval >> 8) & 0xFF)); - st->freq_data[3] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | - ((addr - 3) << ADD_SHIFT) | - ((regval >> 0) & 0xFF)); + for (int i = 0; i < ARRAY_SIZE(regval_bytes); i++) { + freq_cmd = (i % 2 == 0) ? AD9832_CMD_FRE8BITSW : AD9832_CMD_FRE16BITSW; + + st->freq_data[i] = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, freq_cmd) | + FIELD_PREP(AD9832_ADD_MSK, addr - i) | + FIELD_PREP(AD9832_DAT_MSK, regval_bytes[i])); + } return spi_sync(st->spi, &st->freq_msg); } @@ -154,15 +155,21 @@ static int ad9832_write_frequency(struct ad9832_state *st, static int ad9832_write_phase(struct ad9832_state *st, unsigned long addr, unsigned long phase) { + u8 phase_bytes[2]; + u16 phase_cmd; + if (phase >= BIT(AD9832_PHASE_BITS)) return -EINVAL; - st->phase_data[0] = cpu_to_be16((AD9832_CMD_PHA8BITSW << CMD_SHIFT) | - (addr << ADD_SHIFT) | - ((phase >> 8) & 0xFF)); - st->phase_data[1] = cpu_to_be16((AD9832_CMD_PHA16BITSW << CMD_SHIFT) | - ((addr - 1) << ADD_SHIFT) | - (phase & 0xFF)); + put_unaligned_be16(phase, phase_bytes); + + for (int i = 0; i < ARRAY_SIZE(phase_bytes); i++) { + phase_cmd = (i % 2 == 0) ? AD9832_CMD_PHA8BITSW : AD9832_CMD_PHA16BITSW; + + st->phase_data[i] = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, phase_cmd) | + FIELD_PREP(AD9832_ADD_MSK, addr - i) | + FIELD_PREP(AD9832_DAT_MSK, phase_bytes[i])); + } return spi_sync(st->spi, &st->phase_msg); } @@ -193,25 +200,23 @@ static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, ret = ad9832_write_phase(st, this_attr->address, val); break; case AD9832_PINCTRL_EN: - if (val) - st->ctrl_ss &= ~AD9832_SELSRC; - else - st->ctrl_ss |= AD9832_SELSRC; - st->data = cpu_to_be16((AD9832_CMD_SYNCSELSRC << CMD_SHIFT) | - st->ctrl_ss); + st->ctrl_ss &= ~AD9832_SELSRC; + st->ctrl_ss |= FIELD_PREP(AD9832_SELSRC, val ? 0 : 1); + + st->data = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, AD9832_CMD_SYNCSELSRC) | + st->ctrl_ss); ret = spi_sync(st->spi, &st->msg); break; case AD9832_FREQ_SYM: - if (val == 1) { - st->ctrl_fp |= AD9832_FREQ; - } else if (val == 0) { + if (val == 1 || val == 0) { st->ctrl_fp &= ~AD9832_FREQ; + st->ctrl_fp |= FIELD_PREP(AD9832_FREQ, val ? 1 : 0); } else { ret = -EINVAL; break; } - st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | - st->ctrl_fp); + st->data = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, AD9832_CMD_FPSELECT) | + st->ctrl_fp); ret = spi_sync(st->spi, &st->msg); break; case AD9832_PHASE_SYM: @@ -220,22 +225,21 @@ static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, break; } - st->ctrl_fp &= ~AD9832_PHASE(3); - st->ctrl_fp |= AD9832_PHASE(val); + st->ctrl_fp &= ~AD9832_PHASE_MASK; + st->ctrl_fp |= FIELD_PREP(AD9832_PHASE_MASK, val); - st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | - st->ctrl_fp); + st->data = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, AD9832_CMD_FPSELECT) | + st->ctrl_fp); ret = spi_sync(st->spi, &st->msg); break; case AD9832_OUTPUT_EN: if (val) - st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | - AD9832_CLR); + st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | AD9832_CLR); else - st->ctrl_src |= AD9832_RESET; + st->ctrl_src |= FIELD_PREP(AD9832_RESET, 1); - st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) | - st->ctrl_src); + st->data = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, AD9832_CMD_SLEEPRESCLR) | + st->ctrl_src); ret = spi_sync(st->spi, &st->msg); break; default: @@ -367,8 +371,8 @@ static int ad9832_probe(struct spi_device *spi) spi_message_add_tail(&st->phase_xfer[1], &st->phase_msg); st->ctrl_src = AD9832_SLEEP | AD9832_RESET | AD9832_CLR; - st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) | - st->ctrl_src); + st->data = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, AD9832_CMD_SLEEPRESCLR) | + st->ctrl_src); ret = spi_sync(st->spi, &st->msg); if (ret) { dev_err(&spi->dev, "device init failed\n"); @@ -402,16 +406,24 @@ static int ad9832_probe(struct spi_device *spi) return devm_iio_device_register(&spi->dev, indio_dev); } +static const struct of_device_id ad9832_of_match[] = { + { .compatible = "adi,ad9832" }, + { .compatible = "adi,ad9835" }, + { } +}; +MODULE_DEVICE_TABLE(of, ad9832_of_match); + static const struct spi_device_id ad9832_id[] = { {"ad9832", 0}, {"ad9835", 0}, - {} + { } }; MODULE_DEVICE_TABLE(spi, ad9832_id); static struct spi_driver ad9832_driver = { .driver = { .name = "ad9832", + .of_match_table = ad9832_of_match, }, .probe = ad9832_probe, .id_table = ad9832_id, diff --git a/drivers/staging/iio/frequency/ad9832.h b/drivers/staging/iio/frequency/ad9832.h index 98dfbd9289ab..d0d840edb8d2 100644 --- a/drivers/staging/iio/frequency/ad9832.h +++ b/drivers/staging/iio/frequency/ad9832.h @@ -13,7 +13,6 @@ /** * struct ad9832_platform_data - platform specific information - * @mclk: master clock in Hz * @freq0: power up freq0 tuning word in Hz * @freq1: power up freq1 tuning word in Hz * @phase0: power up phase0 value [0..4095] correlates with 0..2PI diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 50413da2aa65..0038eb234d40 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -479,7 +479,7 @@ static const struct spi_device_id ad9834_id[] = { {"ad9834", ID_AD9834}, {"ad9837", ID_AD9837}, {"ad9838", ID_AD9838}, - {} + { } }; MODULE_DEVICE_TABLE(spi, ad9834_id); @@ -488,7 +488,7 @@ static const struct of_device_id ad9834_of_match[] = { {.compatible = "adi,ad9834"}, {.compatible = "adi,ad9837"}, {.compatible = "adi,ad9838"}, - {} + { } }; MODULE_DEVICE_TABLE(of, ad9834_of_match); diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index d5544fc2fe98..85a4223295cd 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -271,11 +271,12 @@ static ssize_t ad5933_show_frequency(struct device *dev, u8 d8[4]; } dat; - ret = iio_device_claim_direct_mode(indio_dev); - if (ret) - return ret; + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + ret = ad5933_i2c_read(st->client, this_attr->address, 3, &dat.d8[1]); - iio_device_release_direct_mode(indio_dev); + + iio_device_release_direct(indio_dev); if (ret < 0) return ret; @@ -305,11 +306,12 @@ static ssize_t ad5933_store_frequency(struct device *dev, if (val > AD5933_MAX_OUTPUT_FREQ_Hz) return -EINVAL; - ret = iio_device_claim_direct_mode(indio_dev); - if (ret) - return ret; + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + ret = ad5933_set_freq(st, this_attr->address, val); - iio_device_release_direct_mode(indio_dev); + + iio_device_release_direct(indio_dev); return ret ? ret : len; } @@ -384,9 +386,9 @@ static ssize_t ad5933_store(struct device *dev, return ret; } - ret = iio_device_claim_direct_mode(indio_dev); - if (ret) - return ret; + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + mutex_lock(&st->lock); switch ((u32)this_attr->address) { case AD5933_OUT_RANGE: @@ -411,7 +413,7 @@ static ssize_t ad5933_store(struct device *dev, ret = ad5933_cmd(st, 0); break; case AD5933_OUT_SETTLING_CYCLES: - val = clamp(val, (u16)0, (u16)0x7FF); + val = clamp(val, (u16)0, (u16)0x7FC); st->settling_cycles = val; /* 2x, 4x handling, see datasheet */ @@ -438,7 +440,8 @@ static ssize_t ad5933_store(struct device *dev, } mutex_unlock(&st->lock); - iio_device_release_direct_mode(indio_dev); + + iio_device_release_direct(indio_dev); return ret ? ret : len; } @@ -506,9 +509,9 @@ static int ad5933_read_raw(struct iio_dev *indio_dev, switch (m) { case IIO_CHAN_INFO_RAW: - ret = iio_device_claim_direct_mode(indio_dev); - if (ret) - return ret; + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + ret = ad5933_cmd(st, AD5933_CTRL_MEASURE_TEMP); if (ret < 0) goto out; @@ -521,7 +524,8 @@ static int ad5933_read_raw(struct iio_dev *indio_dev, 2, (u8 *)&dat); if (ret < 0) goto out; - iio_device_release_direct_mode(indio_dev); + + iio_device_release_direct(indio_dev); *val = sign_extend32(be16_to_cpu(dat), 13); return IIO_VAL_INT; @@ -533,7 +537,7 @@ static int ad5933_read_raw(struct iio_dev *indio_dev, return -EINVAL; out: - iio_device_release_direct_mode(indio_dev); + iio_device_release_direct(indio_dev); return ret; } @@ -724,7 +728,7 @@ static int ad5933_probe(struct i2c_client *client) static const struct i2c_device_id ad5933_id[] = { { "ad5933" }, { "ad5934" }, - {} + { } }; MODULE_DEVICE_TABLE(i2c, ad5933_id); @@ -732,7 +736,7 @@ MODULE_DEVICE_TABLE(i2c, ad5933_id); static const struct of_device_id ad5933_of_match[] = { { .compatible = "adi,ad5933" }, { .compatible = "adi,ad5934" }, - { }, + { } }; MODULE_DEVICE_TABLE(of, ad5933_of_match); diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index b44214854399..ab250c89cd4d 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -28,12 +28,12 @@ source "drivers/staging/media/imx/Kconfig" source "drivers/staging/media/ipu3/Kconfig" +source "drivers/staging/media/ipu7/Kconfig" + source "drivers/staging/media/max96712/Kconfig" source "drivers/staging/media/meson/vdec/Kconfig" -source "drivers/staging/media/rkvdec/Kconfig" - source "drivers/staging/media/starfive/Kconfig" source "drivers/staging/media/sunxi/Kconfig" diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index ad4e9619a9e0..4a073938b2b2 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -4,9 +4,9 @@ obj-$(CONFIG_INTEL_ATOMISP) += atomisp/ obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/ obj-$(CONFIG_VIDEO_MAX96712) += max96712/ obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/ -obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rkvdec/ obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive/ obj-$(CONFIG_VIDEO_SUNXI) += sunxi/ obj-$(CONFIG_VIDEO_TEGRA) += tegra-video/ obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/ +obj-$(CONFIG_VIDEO_INTEL_IPU7) += ipu7/ obj-$(CONFIG_DVB_AV7110) += av7110/ diff --git a/drivers/staging/media/atomisp/Kconfig b/drivers/staging/media/atomisp/Kconfig index 1265fc58a232..fbe507ae6ec6 100644 --- a/drivers/staging/media/atomisp/Kconfig +++ b/drivers/staging/media/atomisp/Kconfig @@ -12,6 +12,7 @@ menuconfig INTEL_ATOMISP config VIDEO_ATOMISP tristate "Intel Atom Image Signal Processor Driver" depends on VIDEO_DEV && INTEL_ATOMISP + depends on INTEL_SKL_INT3472 depends on IPU_BRIDGE depends on MEDIA_PCI_SUPPORT depends on PMIC_OPREGION diff --git a/drivers/staging/media/atomisp/Makefile b/drivers/staging/media/atomisp/Makefile index 43116c74781d..1d0fbe22036b 100644 --- a/drivers/staging/media/atomisp/Makefile +++ b/drivers/staging/media/atomisp/Makefile @@ -17,7 +17,6 @@ atomisp-objs += \ pci/atomisp_compat_css20.o \ pci/atomisp_csi2.o \ pci/atomisp_csi2_bridge.o \ - pci/atomisp_drvfs.o \ pci/atomisp_fops.o \ pci/atomisp_ioctl.o \ pci/atomisp_subdev.o \ diff --git a/drivers/staging/media/atomisp/TODO b/drivers/staging/media/atomisp/TODO index 27cbbde93b1e..82be275b4a0a 100644 --- a/drivers/staging/media/atomisp/TODO +++ b/drivers/staging/media/atomisp/TODO @@ -7,8 +7,6 @@ TODO * Remove/disable custom v4l2-ctrls -* Remove custom sysfs files created by atomisp_drvfs.c - * Remove unnecessary/unwanted module parameters * Remove abuse of priv field in various v4l2 userspace API structs diff --git a/drivers/staging/media/atomisp/i2c/Kconfig b/drivers/staging/media/atomisp/i2c/Kconfig index f5ab23592f29..ef2094c22347 100644 --- a/drivers/staging/media/atomisp/i2c/Kconfig +++ b/drivers/staging/media/atomisp/i2c/Kconfig @@ -27,22 +27,11 @@ config VIDEO_ATOMISP_GC2235 It currently only works with the atomisp driver. -config VIDEO_ATOMISP_MT9M114 - tristate "Aptina mt9m114 sensor support" - depends on ACPI - depends on I2C && VIDEO_DEV - help - This is a Video4Linux2 sensor-level driver for the Micron - mt9m114 1.3 Mpixel camera. - - mt9m114 is video camera sensor. - - It currently only works with the atomisp driver. - config VIDEO_ATOMISP_GC0310 tristate "GC0310 sensor support" depends on ACPI depends on I2C && VIDEO_DEV + select V4L2_CCI_I2C help This is a Video4Linux2 sensor-level driver for the Galaxycore GC0310 0.3MP sensor. diff --git a/drivers/staging/media/atomisp/i2c/Makefile b/drivers/staging/media/atomisp/i2c/Makefile index 021a7ea0a075..e1637417e5c5 100644 --- a/drivers/staging/media/atomisp/i2c/Makefile +++ b/drivers/staging/media/atomisp/i2c/Makefile @@ -3,7 +3,6 @@ # Makefile for sensor drivers # -obj-$(CONFIG_VIDEO_ATOMISP_MT9M114) += atomisp-mt9m114.o obj-$(CONFIG_VIDEO_ATOMISP_GC2235) += atomisp-gc2235.o obj-$(CONFIG_VIDEO_ATOMISP_OV2722) += atomisp-ov2722.o obj-$(CONFIG_VIDEO_ATOMISP_GC0310) += atomisp-gc0310.o diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c index d35394f1ddbb..7af4d66f42a0 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c @@ -3,7 +3,7 @@ * Support for GalaxyCore GC0310 VGA camera sensor. * * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - * Copyright (c) 2023 Hans de Goede <hdegoede@redhat.com> + * Copyright (c) 2023-2025 Hans de Goede <hansg@kernel.org> */ #include <linux/delay.h> @@ -13,77 +13,92 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/regmap.h> #include <linux/string.h> #include <linux/types.h> +#include <media/v4l2-cci.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> +#include <media/v4l2-fwnode.h> #define GC0310_NATIVE_WIDTH 656 #define GC0310_NATIVE_HEIGHT 496 +/* + * The actual PLL output rate is unknown, the datasheet + * says that the formula for the frame-time in pixels is: + * rowtime = win-width + hblank + sh-delay + 4 + * frametime = rowtime * (win-height + vblank) + * Filling this in and multiplying by 30 fps gives: + * pixelrate = (660 + 178 + 42 + 4) * (498 + 27) * 30 = 13923000 + */ +#define GC0310_PIXELRATE 13923000 +/* single lane, bus-format is 8 bpp, CSI-2 is double data rate */ +#define GC0310_LINK_FREQ (GC0310_PIXELRATE * 8 / 2) +#define GC0310_MCLK_FREQ 19200000 #define GC0310_FPS 30 #define GC0310_SKIP_FRAMES 3 -#define GC0310_FOCAL_LENGTH_NUM 278 /* 2.78mm */ - #define GC0310_ID 0xa310 -#define GC0310_RESET_RELATED 0xFE +#define GC0310_RESET_RELATED_REG CCI_REG8(0xfe) #define GC0310_REGISTER_PAGE_0 0x0 #define GC0310_REGISTER_PAGE_3 0x3 /* * GC0310 System control registers */ -#define GC0310_SW_STREAM 0x10 - -#define GC0310_SC_CMMN_CHIP_ID_H 0xf0 -#define GC0310_SC_CMMN_CHIP_ID_L 0xf1 - -#define GC0310_AEC_PK_EXPO_H 0x03 -#define GC0310_AEC_PK_EXPO_L 0x04 -#define GC0310_AGC_ADJ 0x48 -#define GC0310_DGC_ADJ 0x71 -#define GC0310_GROUP_ACCESS 0x3208 - -#define GC0310_H_CROP_START_H 0x09 -#define GC0310_H_CROP_START_L 0x0A -#define GC0310_V_CROP_START_H 0x0B -#define GC0310_V_CROP_START_L 0x0C -#define GC0310_H_OUTSIZE_H 0x0F -#define GC0310_H_OUTSIZE_L 0x10 -#define GC0310_V_OUTSIZE_H 0x0D -#define GC0310_V_OUTSIZE_L 0x0E -#define GC0310_H_BLANKING_H 0x05 -#define GC0310_H_BLANKING_L 0x06 -#define GC0310_V_BLANKING_H 0x07 -#define GC0310_V_BLANKING_L 0x08 -#define GC0310_SH_DELAY 0x11 +#define GC0310_SW_STREAM_REG CCI_REG8(0x10) #define GC0310_START_STREAMING 0x94 /* 8-bit enable */ #define GC0310_STOP_STREAMING 0x0 /* 8-bit disable */ +#define GC0310_SC_CMMN_CHIP_ID_REG CCI_REG16(0xf0) + +#define GC0310_AEC_PK_EXPO_REG CCI_REG16(0x03) +#define GC0310_AGC_ADJ_REG CCI_REG8(0x48) +#define GC0310_DGC_ADJ_REG CCI_REG8(0x71) + +#define GC0310_H_CROP_START_REG CCI_REG16(0x09) +#define GC0310_V_CROP_START_REG CCI_REG16(0x0b) +#define GC0310_H_OUTSIZE_REG CCI_REG16(0x0f) +#define GC0310_V_OUTSIZE_REG CCI_REG16(0x0d) + +#define GC0310_H_BLANKING_REG CCI_REG16(0x05) +/* Hblank-register + sh-delay + H-crop + 4 (from hw) */ +#define GC0310_H_BLANK_DEFAULT (178 + 42 + 4 + 4) + +#define GC0310_V_BLANKING_REG CCI_REG16(0x07) +/* Vblank needs an offset compensate for the small V-crop done */ +#define GC0310_V_BLANK_OFFSET 2 +/* Vsync start time + 1 row vsync + vsync end time + offset */ +#define GC0310_V_BLANK_MIN (9 + 1 + 4 + GC0310_V_BLANK_OFFSET) +#define GC0310_V_BLANK_DEFAULT (27 + GC0310_V_BLANK_OFFSET) +#define GC0310_V_BLANK_MAX (4095 - GC0310_NATIVE_HEIGHT) + +#define GC0310_SH_DELAY_REG CCI_REG8(0x11) +#define GC0310_VS_START_TIME_REG CCI_REG8(0x12) +#define GC0310_VS_END_TIME_REG CCI_REG8(0x13) + #define to_gc0310_sensor(x) container_of(x, struct gc0310_device, sd) struct gc0310_device { struct v4l2_subdev sd; struct media_pad pad; - /* Protect against concurrent changes to controls */ - struct mutex input_lock; - bool is_streaming; + struct regmap *regmap; struct gpio_desc *reset; struct gpio_desc *powerdown; - struct gc0310_mode { - struct v4l2_mbus_framefmt fmt; - } mode; - struct gc0310_ctrls { struct v4l2_ctrl_handler handler; struct v4l2_ctrl *exposure; struct v4l2_ctrl *gain; + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *hblank; } ctrls; }; @@ -92,7 +107,7 @@ struct gc0310_reg { u8 val; }; -static const struct gc0310_reg gc0310_reset_register[] = { +static const struct reg_sequence gc0310_reset_register[] = { /* System registers */ { 0xfe, 0xf0 }, { 0xfe, 0xf0 }, @@ -142,8 +157,7 @@ static const struct gc0310_reg gc0310_reset_register[] = { { 0x04, 0xc0 }, /* 0xe8 //58 */ { 0x05, 0x00 }, { 0x06, 0xb2 }, /* 0x0a //HB */ - { 0x07, 0x00 }, - { 0x08, 0x0c }, /* 0x89 //VB */ + /* Vblank (reg 0x07 + 0x08) gets set by the vblank ctrl */ { 0x09, 0x00 }, /* row start */ { 0x0a, 0x00 }, { 0x0b, 0x00 }, /* col start */ @@ -235,7 +249,7 @@ static const struct gc0310_reg gc0310_reset_register[] = { { 0xfe, 0x00 }, }; -static const struct gc0310_reg gc0310_VGA_30fps[] = { +static const struct reg_sequence gc0310_VGA_30fps[] = { { 0xfe, 0x00 }, { 0x0d, 0x01 }, /* height */ { 0x0e, 0xf2 }, /* 0xf7 //height */ @@ -259,41 +273,14 @@ static const struct gc0310_reg gc0310_VGA_30fps[] = { { 0xfe, 0x00 }, }; -/* - * gc0310_write_reg_array - Initializes a list of GC0310 registers - * @client: i2c driver client structure - * @reglist: list of registers to be written - * @count: number of register, value pairs in the list - */ -static int gc0310_write_reg_array(struct i2c_client *client, - const struct gc0310_reg *reglist, int count) -{ - int i, err; - - for (i = 0; i < count; i++) { - err = i2c_smbus_write_byte_data(client, reglist[i].reg, reglist[i].val); - if (err) { - dev_err(&client->dev, "write error: wrote 0x%x to offset 0x%x error %d", - reglist[i].val, reglist[i].reg, err); - return err; - } - } - - return 0; -} - -static int gc0310_exposure_set(struct gc0310_device *dev, u32 exp) -{ - struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); - - return i2c_smbus_write_word_swapped(client, GC0310_AEC_PK_EXPO_H, exp); -} +static const s64 link_freq_menu_items[] = { + GC0310_LINK_FREQ, +}; -static int gc0310_gain_set(struct gc0310_device *dev, u32 gain) +static int gc0310_gain_set(struct gc0310_device *sensor, u32 gain) { - struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); u8 again, dgain; - int ret; + int ret = 0; /* Taken from original driver, this never sets dgain lower then 32? */ @@ -308,36 +295,55 @@ static int gc0310_gain_set(struct gc0310_device *dev, u32 gain) dgain = gain / 2; } - ret = i2c_smbus_write_byte_data(client, GC0310_AGC_ADJ, again); - if (ret) - return ret; + cci_write(sensor->regmap, GC0310_AGC_ADJ_REG, again, &ret); + cci_write(sensor->regmap, GC0310_DGC_ADJ_REG, dgain, &ret); + return ret; +} + +static int gc0310_exposure_update_range(struct gc0310_device *sensor) +{ + int exp_max = GC0310_NATIVE_HEIGHT + sensor->ctrls.vblank->val; - return i2c_smbus_write_byte_data(client, GC0310_DGC_ADJ, dgain); + return __v4l2_ctrl_modify_range(sensor->ctrls.exposure, 0, exp_max, + 1, exp_max); } static int gc0310_s_ctrl(struct v4l2_ctrl *ctrl) { - struct gc0310_device *dev = + struct gc0310_device *sensor = container_of(ctrl->handler, struct gc0310_device, ctrls.handler); int ret; + /* Update exposure range on vblank changes */ + if (ctrl->id == V4L2_CID_VBLANK) { + ret = gc0310_exposure_update_range(sensor); + if (ret) + return ret; + } + /* Only apply changes to the controls if the device is powered up */ - if (!pm_runtime_get_if_in_use(dev->sd.dev)) + if (!pm_runtime_get_if_in_use(sensor->sd.dev)) return 0; switch (ctrl->id) { case V4L2_CID_EXPOSURE: - ret = gc0310_exposure_set(dev, ctrl->val); + ret = cci_write(sensor->regmap, GC0310_AEC_PK_EXPO_REG, + ctrl->val, NULL); break; - case V4L2_CID_GAIN: - ret = gc0310_gain_set(dev, ctrl->val); + case V4L2_CID_ANALOGUE_GAIN: + ret = gc0310_gain_set(sensor, ctrl->val); + break; + case V4L2_CID_VBLANK: + ret = cci_write(sensor->regmap, GC0310_V_BLANKING_REG, + ctrl->val - GC0310_V_BLANK_OFFSET, + NULL); break; default: ret = -EINVAL; break; } - pm_runtime_put(dev->sd.dev); + pm_runtime_put(sensor->sd.dev); return ret; } @@ -345,17 +351,6 @@ static const struct v4l2_ctrl_ops ctrl_ops = { .s_ctrl = gc0310_s_ctrl, }; -static struct v4l2_mbus_framefmt * -gc0310_get_pad_format(struct gc0310_device *dev, - struct v4l2_subdev_state *state, - unsigned int pad, enum v4l2_subdev_format_whence which) -{ - if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_state_get_format(state, pad); - - return &dev->mode.fmt; -} - /* The GC0310 currently only supports 1 fixed fmt */ static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt) { @@ -366,54 +361,72 @@ static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt) fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; } -static int gc0310_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) +static int gc0310_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) { - struct gc0310_device *dev = to_gc0310_sensor(sd); - struct v4l2_mbus_framefmt *fmt; + /* Only the single fixed 656x496 mode is supported, without croping */ + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_NATIVE_SIZE: + sel->r.top = 0; + sel->r.left = 0; + sel->r.width = GC0310_NATIVE_WIDTH; + sel->r.height = GC0310_NATIVE_HEIGHT; + break; + default: + return -EINVAL; + } + + return 0; +} - fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which); - gc0310_fill_format(fmt); +static int gc0310_power_off(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct gc0310_device *sensor = to_gc0310_sensor(sd); - format->format = *fmt; + gpiod_set_value_cansleep(sensor->powerdown, 1); + gpiod_set_value_cansleep(sensor->reset, 1); return 0; } -static int gc0310_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) +static int gc0310_power_on(struct device *dev) { - struct gc0310_device *dev = to_gc0310_sensor(sd); - struct v4l2_mbus_framefmt *fmt; + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct gc0310_device *sensor = to_gc0310_sensor(sd); + + fsleep(10 * USEC_PER_MSEC); + gpiod_set_value_cansleep(sensor->reset, 0); + fsleep(10 * USEC_PER_MSEC); + gpiod_set_value_cansleep(sensor->powerdown, 0); + fsleep(10 * USEC_PER_MSEC); - fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which); - format->format = *fmt; return 0; } -static int gc0310_detect(struct i2c_client *client) +static int gc0310_detect(struct gc0310_device *sensor) { - struct i2c_adapter *adapter = client->adapter; + struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd); + u64 val; int ret; - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; - ret = pm_runtime_get_sync(&client->dev); - if (ret >= 0) - ret = i2c_smbus_read_word_swapped(client, GC0310_SC_CMMN_CHIP_ID_H); - pm_runtime_put(&client->dev); + ret = cci_read(sensor->regmap, GC0310_SC_CMMN_CHIP_ID_REG, &val, NULL); if (ret < 0) { dev_err(&client->dev, "read sensor_id failed: %d\n", ret); return -ENODEV; } - dev_dbg(&client->dev, "sensor ID = 0x%x\n", ret); + dev_dbg(&client->dev, "sensor ID = 0x%llx\n", val); - if (ret != GC0310_ID) { - dev_err(&client->dev, "sensor ID error, read id = 0x%x, target id = 0x%x\n", - ret, GC0310_ID); + if (val != GC0310_ID) { + dev_err(&client->dev, "sensor ID error, read id = 0x%llx, target id = 0x%x\n", + val, GC0310_ID); return -ENODEV; } @@ -422,85 +435,67 @@ static int gc0310_detect(struct i2c_client *client) return 0; } -static int gc0310_s_stream(struct v4l2_subdev *sd, int enable) +static int gc0310_enable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + u32 pad, u64 streams_mask) { - struct gc0310_device *dev = to_gc0310_sensor(sd); + struct gc0310_device *sensor = to_gc0310_sensor(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret = 0; - - dev_dbg(&client->dev, "%s S enable=%d\n", __func__, enable); - mutex_lock(&dev->input_lock); - - if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) - goto error_power_down; - - msleep(100); - - ret = gc0310_write_reg_array(client, gc0310_reset_register, - ARRAY_SIZE(gc0310_reset_register)); - if (ret) - goto error_power_down; - - ret = gc0310_write_reg_array(client, gc0310_VGA_30fps, - ARRAY_SIZE(gc0310_VGA_30fps)); - if (ret) - goto error_power_down; - - /* restore value of all ctrls */ - ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler); - if (ret) - goto error_power_down; - - /* enable per frame MIPI and sensor ctrl reset */ - ret = i2c_smbus_write_byte_data(client, 0xFE, 0x30); - if (ret) - goto error_power_down; - } + int ret; - ret = i2c_smbus_write_byte_data(client, GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_3); + ret = pm_runtime_resume_and_get(&client->dev); if (ret) - goto error_power_down; + return ret; - ret = i2c_smbus_write_byte_data(client, GC0310_SW_STREAM, - enable ? GC0310_START_STREAMING : GC0310_STOP_STREAMING); + ret = regmap_multi_reg_write(sensor->regmap, + gc0310_reset_register, + ARRAY_SIZE(gc0310_reset_register)); if (ret) goto error_power_down; - ret = i2c_smbus_write_byte_data(client, GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_0); + ret = regmap_multi_reg_write(sensor->regmap, + gc0310_VGA_30fps, + ARRAY_SIZE(gc0310_VGA_30fps)); if (ret) goto error_power_down; - if (!enable) - pm_runtime_put(&client->dev); + /* restore value of all ctrls */ + ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); - dev->is_streaming = enable; - mutex_unlock(&dev->input_lock); - return 0; + /* enable per frame MIPI and sensor ctrl reset */ + cci_write(sensor->regmap, GC0310_RESET_RELATED_REG, 0x30, &ret); + + cci_write(sensor->regmap, GC0310_RESET_RELATED_REG, + GC0310_REGISTER_PAGE_3, &ret); + cci_write(sensor->regmap, GC0310_SW_STREAM_REG, + GC0310_START_STREAMING, &ret); + cci_write(sensor->regmap, GC0310_RESET_RELATED_REG, + GC0310_REGISTER_PAGE_0, &ret); error_power_down: - pm_runtime_put(&client->dev); - dev->is_streaming = false; - mutex_unlock(&dev->input_lock); + if (ret) + pm_runtime_put(&client->dev); + return ret; } -static int gc0310_get_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_interval *interval) +static int gc0310_disable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + u32 pad, u64 streams_mask) { - /* - * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2 - * subdev active state API. - */ - if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE) - return -EINVAL; + struct gc0310_device *sensor = to_gc0310_sensor(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret = 0; - interval->interval.numerator = 1; - interval->interval.denominator = GC0310_FPS; + cci_write(sensor->regmap, GC0310_RESET_RELATED_REG, + GC0310_REGISTER_PAGE_3, &ret); + cci_write(sensor->regmap, GC0310_SW_STREAM_REG, + GC0310_STOP_STREAMING, &ret); + cci_write(sensor->regmap, GC0310_RESET_RELATED_REG, + GC0310_REGISTER_PAGE_0, &ret); - return 0; + pm_runtime_put(&client->dev); + return ret; } static int gc0310_enum_mbus_code(struct v4l2_subdev *sd, @@ -531,164 +526,239 @@ static int gc0310_enum_frame_size(struct v4l2_subdev *sd, return 0; } -static int gc0310_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) -{ - *frames = GC0310_SKIP_FRAMES; - return 0; -} - -static const struct v4l2_subdev_sensor_ops gc0310_sensor_ops = { - .g_skip_frames = gc0310_g_skip_frames, -}; - static const struct v4l2_subdev_video_ops gc0310_video_ops = { - .s_stream = gc0310_s_stream, + .s_stream = v4l2_subdev_s_stream_helper, }; static const struct v4l2_subdev_pad_ops gc0310_pad_ops = { .enum_mbus_code = gc0310_enum_mbus_code, .enum_frame_size = gc0310_enum_frame_size, - .get_fmt = gc0310_get_fmt, - .set_fmt = gc0310_set_fmt, - .get_frame_interval = gc0310_get_frame_interval, + .get_fmt = v4l2_subdev_get_fmt, + .set_fmt = v4l2_subdev_get_fmt, /* Only 1 fixed mode supported */ + .get_selection = gc0310_get_selection, + .set_selection = gc0310_get_selection, + .enable_streams = gc0310_enable_streams, + .disable_streams = gc0310_disable_streams, }; static const struct v4l2_subdev_ops gc0310_ops = { .video = &gc0310_video_ops, .pad = &gc0310_pad_ops, - .sensor = &gc0310_sensor_ops, }; -static int gc0310_init_controls(struct gc0310_device *dev) +static int gc0310_init_state(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state) { - struct v4l2_ctrl_handler *hdl = &dev->ctrls.handler; + gc0310_fill_format(v4l2_subdev_state_get_format(sd_state, 0)); + return 0; +} - v4l2_ctrl_handler_init(hdl, 2); +static const struct v4l2_subdev_internal_ops gc0310_internal_ops = { + .init_state = gc0310_init_state, +}; + +static int gc0310_init_controls(struct gc0310_device *sensor) +{ + struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd); + struct v4l2_ctrl_handler *hdl = &sensor->ctrls.handler; + struct v4l2_fwnode_device_properties props; + int exp_max, ret; + + v4l2_ctrl_handler_init(hdl, 8); /* Use the same lock for controls as for everything else */ - hdl->lock = &dev->input_lock; - dev->sd.ctrl_handler = hdl; + sensor->sd.ctrl_handler = hdl; - dev->ctrls.exposure = - v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0, 4095, 1, 1023); + exp_max = GC0310_NATIVE_HEIGHT + GC0310_V_BLANK_DEFAULT; + sensor->ctrls.exposure = + v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0, + exp_max, 1, exp_max); /* 32 steps at base gain 1 + 64 half steps at base gain 2 */ - dev->ctrls.gain = - v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_GAIN, 0, 95, 1, 31); + sensor->ctrls.gain = + v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_ANALOGUE_GAIN, 0, 95, 1, 31); + + sensor->ctrls.link_freq = + v4l2_ctrl_new_int_menu(hdl, NULL, V4L2_CID_LINK_FREQ, + 0, 0, link_freq_menu_items); + sensor->ctrls.pixel_rate = + v4l2_ctrl_new_std(hdl, NULL, V4L2_CID_PIXEL_RATE, 0, + GC0310_PIXELRATE, 1, GC0310_PIXELRATE); + + sensor->ctrls.vblank = + v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_VBLANK, + GC0310_V_BLANK_MIN, + GC0310_V_BLANK_MAX, 1, + GC0310_V_BLANK_DEFAULT); + + sensor->ctrls.hblank = + v4l2_ctrl_new_std(hdl, NULL, V4L2_CID_HBLANK, + GC0310_H_BLANK_DEFAULT, + GC0310_H_BLANK_DEFAULT, 1, + GC0310_H_BLANK_DEFAULT); + + ret = v4l2_fwnode_device_parse(&client->dev, &props); + if (ret) + return ret; + + v4l2_ctrl_new_fwnode_properties(hdl, &ctrl_ops, &props); - return hdl->error; + if (hdl->error) + return hdl->error; + + sensor->ctrls.pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY; + sensor->ctrls.link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + sensor->ctrls.hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + return 0; } static void gc0310_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct gc0310_device *dev = to_gc0310_sensor(sd); - - dev_dbg(&client->dev, "gc0310_remove...\n"); + struct gc0310_device *sensor = to_gc0310_sensor(sd); v4l2_async_unregister_subdev(sd); - media_entity_cleanup(&dev->sd.entity); - v4l2_ctrl_handler_free(&dev->ctrls.handler); - mutex_destroy(&dev->input_lock); + v4l2_subdev_cleanup(sd); + media_entity_cleanup(&sensor->sd.entity); + v4l2_ctrl_handler_free(&sensor->ctrls.handler); pm_runtime_disable(&client->dev); + if (!pm_runtime_status_suspended(&client->dev)) { + gc0310_power_off(&client->dev); + pm_runtime_set_suspended(&client->dev); + } } -static int gc0310_probe(struct i2c_client *client) +static int gc0310_check_hwcfg(struct device *dev) { + struct v4l2_fwnode_endpoint bus_cfg = { + .bus_type = V4L2_MBUS_CSI2_DPHY, + }; struct fwnode_handle *ep_fwnode; - struct gc0310_device *dev; + unsigned long link_freq_bitmap; + u32 mclk; int ret; /* * Sometimes the fwnode graph is initialized by the bridge driver. * Bridge drivers doing this may also add GPIO mappings, wait for this. */ - ep_fwnode = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL); + ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0); if (!ep_fwnode) - return dev_err_probe(&client->dev, -EPROBE_DEFER, "waiting for fwnode graph endpoint\n"); + return dev_err_probe(dev, -EPROBE_DEFER, + "waiting for fwnode graph endpoint\n"); + + ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", + &mclk); + if (ret) { + fwnode_handle_put(ep_fwnode); + return dev_err_probe(dev, ret, + "reading clock-frequency property\n"); + } + + if (mclk != GC0310_MCLK_FREQ) { + fwnode_handle_put(ep_fwnode); + return dev_err_probe(dev, -EINVAL, + "external clock %u is not supported\n", + mclk); + } + ret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &bus_cfg); fwnode_handle_put(ep_fwnode); + if (ret) + return dev_err_probe(dev, ret, "parsing endpoint failed\n"); + + ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies, + bus_cfg.nr_of_link_frequencies, + link_freq_menu_items, + ARRAY_SIZE(link_freq_menu_items), + &link_freq_bitmap); + + if (ret == 0 && bus_cfg.bus.mipi_csi2.num_data_lanes != 1) + ret = dev_err_probe(dev, -EINVAL, + "number of CSI2 data lanes %u is not supported\n", + bus_cfg.bus.mipi_csi2.num_data_lanes); + + v4l2_fwnode_endpoint_free(&bus_cfg); + return ret; +} + +static int gc0310_probe(struct i2c_client *client) +{ + struct gc0310_device *sensor; + int ret; - dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) + ret = gc0310_check_hwcfg(&client->dev); + if (ret) + return ret; + + sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL); + if (!sensor) return -ENOMEM; - dev->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH); - if (IS_ERR(dev->reset)) { - return dev_err_probe(&client->dev, PTR_ERR(dev->reset), + sensor->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(sensor->reset)) { + return dev_err_probe(&client->dev, PTR_ERR(sensor->reset), "getting reset GPIO\n"); } - dev->powerdown = devm_gpiod_get(&client->dev, "powerdown", GPIOD_OUT_HIGH); - if (IS_ERR(dev->powerdown)) { - return dev_err_probe(&client->dev, PTR_ERR(dev->powerdown), + sensor->powerdown = devm_gpiod_get(&client->dev, "powerdown", GPIOD_OUT_HIGH); + if (IS_ERR(sensor->powerdown)) { + return dev_err_probe(&client->dev, PTR_ERR(sensor->powerdown), "getting powerdown GPIO\n"); } - mutex_init(&dev->input_lock); - v4l2_i2c_subdev_init(&dev->sd, client, &gc0310_ops); - gc0310_fill_format(&dev->mode.fmt); + v4l2_i2c_subdev_init(&sensor->sd, client, &gc0310_ops); - pm_runtime_set_suspended(&client->dev); - pm_runtime_enable(&client->dev); - pm_runtime_set_autosuspend_delay(&client->dev, 1000); - pm_runtime_use_autosuspend(&client->dev); + sensor->regmap = devm_cci_regmap_init_i2c(client, 8); + if (IS_ERR(sensor->regmap)) + return PTR_ERR(sensor->regmap); - ret = gc0310_detect(client); - if (ret) { - gc0310_remove(client); - return ret; - } + gc0310_power_on(&client->dev); - dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - dev->pad.flags = MEDIA_PAD_FL_SOURCE; - dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; - - ret = gc0310_init_controls(dev); - if (ret) { - gc0310_remove(client); - return ret; - } + pm_runtime_set_active(&client->dev); + pm_runtime_get_noresume(&client->dev); + pm_runtime_enable(&client->dev); - ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); - if (ret) { - gc0310_remove(client); - return ret; - } + ret = gc0310_detect(sensor); + if (ret) + goto err_power_down; - ret = v4l2_async_register_subdev_sensor(&dev->sd); - if (ret) { - gc0310_remove(client); - return ret; - } + sensor->sd.internal_ops = &gc0310_internal_ops; + sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + sensor->pad.flags = MEDIA_PAD_FL_SOURCE; + sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; - return 0; -} + ret = gc0310_init_controls(sensor); + if (ret) + goto err_power_down; -static int gc0310_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct gc0310_device *gc0310_dev = to_gc0310_sensor(sd); + ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad); + if (ret) + goto err_power_down; - gpiod_set_value_cansleep(gc0310_dev->powerdown, 1); - gpiod_set_value_cansleep(gc0310_dev->reset, 1); - return 0; -} + sensor->sd.state_lock = sensor->ctrls.handler.lock; + ret = v4l2_subdev_init_finalize(&sensor->sd); + if (ret) + goto err_power_down; -static int gc0310_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct gc0310_device *gc0310_dev = to_gc0310_sensor(sd); + ret = v4l2_async_register_subdev_sensor(&sensor->sd); + if (ret) + goto err_power_down; - usleep_range(10000, 15000); - gpiod_set_value_cansleep(gc0310_dev->reset, 0); - usleep_range(10000, 15000); - gpiod_set_value_cansleep(gc0310_dev->powerdown, 0); + pm_runtime_set_autosuspend_delay(&client->dev, 1000); + pm_runtime_use_autosuspend(&client->dev); + pm_runtime_put_autosuspend(&client->dev); return 0; + +err_power_down: + pm_runtime_put_noidle(&client->dev); + gc0310_remove(client); + return ret; } -static DEFINE_RUNTIME_DEV_PM_OPS(gc0310_pm_ops, gc0310_suspend, gc0310_resume, NULL); +static DEFINE_RUNTIME_DEV_PM_OPS(gc0310_pm_ops, + gc0310_power_off, gc0310_power_on, NULL); static const struct acpi_device_id gc0310_acpi_match[] = { {"INT0310"}, @@ -708,5 +778,6 @@ static struct i2c_driver gc0310_driver = { module_i2c_driver(gc0310_driver); MODULE_AUTHOR("Lai, Angie <angie.lai@intel.com>"); +MODULE_AUTHOR("Hans de Goede <hansg@kernel.org>"); MODULE_DESCRIPTION("A low-level driver for GalaxyCore GC0310 sensors"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c index 857d7175942c..6fc39ab95e46 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c @@ -779,8 +779,6 @@ static void gc2235_remove(struct i2c_client *client) struct v4l2_subdev *sd = i2c_get_clientdata(client); struct gc2235_device *dev = to_gc2235_sensor(sd); - dev_dbg(&client->dev, "gc2235_remove...\n"); - dev->platform_data->csi_cfg(sd, 0); v4l2_device_unregister_subdev(sd); diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c deleted file mode 100644 index 4658aeeb88fd..000000000000 --- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c +++ /dev/null @@ -1,1612 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Support for mt9m114 Camera Sensor. - * - * Copyright (c) 2010 Intel Corporation. All Rights Reserved. - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kmod.h> -#include <linux/device.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/i2c.h> -#include <linux/acpi.h> -#include <linux/mutex.h> -#include "../include/linux/atomisp_gmin_platform.h" -#include <media/v4l2-device.h> - -#include "mt9m114.h" - -#define to_mt9m114_sensor(s) container_of(s, struct mt9m114_device, sd) - -/* - * TODO: use debug parameter to actually define when debug messages should - * be printed. - */ -static int debug; -static int aaalock; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Debug level (0-1)"); - -static int mt9m114_t_vflip(struct v4l2_subdev *sd, int value); -static int mt9m114_t_hflip(struct v4l2_subdev *sd, int value); -static int mt9m114_wait_state(struct i2c_client *client, int timeout); - -static int -mt9m114_read_reg(struct i2c_client *client, u16 data_length, u32 reg, u32 *val) -{ - int err; - struct i2c_msg msg[2]; - unsigned char data[4]; - - if (!client->adapter) { - v4l2_err(client, "%s error, no client->adapter\n", __func__); - return -ENODEV; - } - - if (data_length != MISENSOR_8BIT && data_length != MISENSOR_16BIT - && data_length != MISENSOR_32BIT) { - v4l2_err(client, "%s error, invalid data length\n", __func__); - return -EINVAL; - } - - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = MSG_LEN_OFFSET; - msg[0].buf = data; - - /* high byte goes out first */ - data[0] = (u16)(reg >> 8); - data[1] = (u16)(reg & 0xff); - - msg[1].addr = client->addr; - msg[1].len = data_length; - msg[1].flags = I2C_M_RD; - msg[1].buf = data; - - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = 0; - /* high byte comes first */ - if (data_length == MISENSOR_8BIT) - *val = data[0]; - else if (data_length == MISENSOR_16BIT) - *val = data[1] + (data[0] << 8); - else - *val = data[3] + (data[2] << 8) + - (data[1] << 16) + (data[0] << 24); - - return 0; - } - - dev_err(&client->dev, "read from offset 0x%x error %d", reg, err); - return err; -} - -static int -mt9m114_write_reg(struct i2c_client *client, u16 data_length, u16 reg, u32 val) -{ - int num_msg; - struct i2c_msg msg; - unsigned char data[6] = {0}; - __be16 *wreg; - int retry = 0; - - if (!client->adapter) { - v4l2_err(client, "%s error, no client->adapter\n", __func__); - return -ENODEV; - } - - if (data_length != MISENSOR_8BIT && data_length != MISENSOR_16BIT - && data_length != MISENSOR_32BIT) { - v4l2_err(client, "%s error, invalid data_length\n", __func__); - return -EINVAL; - } - - memset(&msg, 0, sizeof(msg)); - -again: - msg.addr = client->addr; - msg.flags = 0; - msg.len = 2 + data_length; - msg.buf = data; - - /* high byte goes out first */ - wreg = (void *)data; - *wreg = cpu_to_be16(reg); - - if (data_length == MISENSOR_8BIT) { - data[2] = (u8)(val); - } else if (data_length == MISENSOR_16BIT) { - u16 *wdata = (void *)&data[2]; - - *wdata = be16_to_cpu(*(__be16 *)&data[2]); - } else { - /* MISENSOR_32BIT */ - u32 *wdata = (void *)&data[2]; - - *wdata = be32_to_cpu(*(__be32 *)&data[2]); - } - - num_msg = i2c_transfer(client->adapter, &msg, 1); - - /* - * HACK: Need some delay here for Rev 2 sensors otherwise some - * registers do not seem to load correctly. - */ - mdelay(1); - - if (num_msg >= 0) - return 0; - - dev_err(&client->dev, "write error: wrote 0x%x to offset 0x%x error %d", - val, reg, num_msg); - if (retry <= I2C_RETRY_COUNT) { - dev_dbg(&client->dev, "retrying... %d", retry); - retry++; - msleep(20); - goto again; - } - - return num_msg; -} - -/** - * misensor_rmw_reg - Read/Modify/Write a value to a register in the sensor - * device - * @client: i2c driver client structure - * @data_length: 8/16/32-bits length - * @reg: register address - * @mask: masked out bits - * @set: bits set - * - * Read/modify/write a value to a register in the sensor device. - * Returns zero if successful, or non-zero otherwise. - */ -static int -misensor_rmw_reg(struct i2c_client *client, u16 data_length, u16 reg, - u32 mask, u32 set) -{ - int err; - u32 val; - - /* Exit when no mask */ - if (mask == 0) - return 0; - - /* @mask must not exceed data length */ - switch (data_length) { - case MISENSOR_8BIT: - if (mask & ~0xff) - return -EINVAL; - break; - case MISENSOR_16BIT: - if (mask & ~0xffff) - return -EINVAL; - break; - case MISENSOR_32BIT: - break; - default: - /* Wrong @data_length */ - return -EINVAL; - } - - err = mt9m114_read_reg(client, data_length, reg, &val); - if (err) { - v4l2_err(client, "%s error exit, read failed\n", __func__); - return -EINVAL; - } - - val &= ~mask; - - /* - * Perform the OR function if the @set exists. - * Shift @set value to target bit location. @set should set only - * bits included in @mask. - * - * REVISIT: This function expects @set to be non-shifted. Its shift - * value is then defined to be equal to mask's LSB position. - * How about to inform values in their right offset position and avoid - * this unneeded shift operation? - */ - set <<= ffs(mask) - 1; - val |= set & mask; - - err = mt9m114_write_reg(client, data_length, reg, val); - if (err) { - v4l2_err(client, "%s error exit, write failed\n", __func__); - return -EINVAL; - } - - return 0; -} - -static int __mt9m114_flush_reg_array(struct i2c_client *client, - struct mt9m114_write_ctrl *ctrl) -{ - struct i2c_msg msg; - const int num_msg = 1; - int ret; - int retry = 0; - __be16 *data16 = (void *)&ctrl->buffer.addr; - - if (ctrl->index == 0) - return 0; - -again: - msg.addr = client->addr; - msg.flags = 0; - msg.len = 2 + ctrl->index; - *data16 = cpu_to_be16(ctrl->buffer.addr); - msg.buf = (u8 *)&ctrl->buffer; - - ret = i2c_transfer(client->adapter, &msg, num_msg); - if (ret != num_msg) { - if (++retry <= I2C_RETRY_COUNT) { - dev_dbg(&client->dev, "retrying... %d\n", retry); - msleep(20); - goto again; - } - dev_err(&client->dev, "%s: i2c transfer error\n", __func__); - return -EIO; - } - - ctrl->index = 0; - - /* - * REVISIT: Previously we had a delay after writing data to sensor. - * But it was removed as our tests have shown it is not necessary - * anymore. - */ - - return 0; -} - -static int __mt9m114_buf_reg_array(struct i2c_client *client, - struct mt9m114_write_ctrl *ctrl, - const struct misensor_reg *next) -{ - __be16 *data16; - __be32 *data32; - int err; - - /* Insufficient buffer? Let's flush and get more free space. */ - if (ctrl->index + next->length >= MT9M114_MAX_WRITE_BUF_SIZE) { - err = __mt9m114_flush_reg_array(client, ctrl); - if (err) - return err; - } - - switch (next->length) { - case MISENSOR_8BIT: - ctrl->buffer.data[ctrl->index] = (u8)next->val; - break; - case MISENSOR_16BIT: - data16 = (__be16 *)&ctrl->buffer.data[ctrl->index]; - *data16 = cpu_to_be16((u16)next->val); - break; - case MISENSOR_32BIT: - data32 = (__be32 *)&ctrl->buffer.data[ctrl->index]; - *data32 = cpu_to_be32(next->val); - break; - default: - return -EINVAL; - } - - /* When first item is added, we need to store its starting address */ - if (ctrl->index == 0) - ctrl->buffer.addr = next->reg; - - ctrl->index += next->length; - - return 0; -} - -static int -__mt9m114_write_reg_is_consecutive(struct i2c_client *client, - struct mt9m114_write_ctrl *ctrl, - const struct misensor_reg *next) -{ - if (ctrl->index == 0) - return 1; - - return ctrl->buffer.addr + ctrl->index == next->reg; -} - -/* - * mt9m114_write_reg_array - Initializes a list of mt9m114 registers - * @client: i2c driver client structure - * @reglist: list of registers to be written - * @poll: completion polling requirement - * This function initializes a list of registers. When consecutive addresses - * are found in a row on the list, this function creates a buffer and sends - * consecutive data in a single i2c_transfer(). - * - * __mt9m114_flush_reg_array, __mt9m114_buf_reg_array() and - * __mt9m114_write_reg_is_consecutive() are internal functions to - * mt9m114_write_reg_array() and should be not used anywhere else. - * - */ -static int mt9m114_write_reg_array(struct i2c_client *client, - const struct misensor_reg *reglist, - int poll) -{ - const struct misensor_reg *next = reglist; - struct mt9m114_write_ctrl ctrl; - int err; - - if (poll == PRE_POLLING) { - err = mt9m114_wait_state(client, MT9M114_WAIT_STAT_TIMEOUT); - if (err) - return err; - } - - ctrl.index = 0; - for (; next->length != MISENSOR_TOK_TERM; next++) { - switch (next->length & MISENSOR_TOK_MASK) { - case MISENSOR_TOK_DELAY: - err = __mt9m114_flush_reg_array(client, &ctrl); - if (err) - return err; - msleep(next->val); - break; - case MISENSOR_TOK_RMW: - err = __mt9m114_flush_reg_array(client, &ctrl); - err |= misensor_rmw_reg(client, - next->length & - ~MISENSOR_TOK_RMW, - next->reg, next->val, - next->val2); - if (err) { - dev_err(&client->dev, "%s read err. aborted\n", - __func__); - return -EINVAL; - } - break; - default: - /* - * If next address is not consecutive, data needs to be - * flushed before proceed. - */ - if (!__mt9m114_write_reg_is_consecutive(client, &ctrl, - next)) { - err = __mt9m114_flush_reg_array(client, &ctrl); - if (err) - return err; - } - err = __mt9m114_buf_reg_array(client, &ctrl, next); - if (err) { - v4l2_err(client, "%s: write error, aborted\n", - __func__); - return err; - } - break; - } - } - - err = __mt9m114_flush_reg_array(client, &ctrl); - if (err) - return err; - - if (poll == POST_POLLING) - return mt9m114_wait_state(client, MT9M114_WAIT_STAT_TIMEOUT); - - return 0; -} - -static int mt9m114_wait_state(struct i2c_client *client, int timeout) -{ - int ret; - unsigned int val; - - while (timeout-- > 0) { - ret = mt9m114_read_reg(client, MISENSOR_16BIT, 0x0080, &val); - if (ret) - return ret; - if ((val & 0x2) == 0) - return 0; - msleep(20); - } - - return -EINVAL; -} - -static int mt9m114_set_suspend(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return mt9m114_write_reg_array(client, - mt9m114_standby_reg, POST_POLLING); -} - -static int mt9m114_init_common(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return mt9m114_write_reg_array(client, mt9m114_common, PRE_POLLING); -} - -static int power_ctrl(struct v4l2_subdev *sd, bool flag) -{ - int ret; - struct mt9m114_device *dev = to_mt9m114_sensor(sd); - - if (!dev || !dev->platform_data) - return -ENODEV; - - if (flag) { - ret = dev->platform_data->v2p8_ctrl(sd, 1); - if (ret == 0) { - ret = dev->platform_data->v1p8_ctrl(sd, 1); - if (ret) - ret = dev->platform_data->v2p8_ctrl(sd, 0); - } - } else { - ret = dev->platform_data->v2p8_ctrl(sd, 0); - ret = dev->platform_data->v1p8_ctrl(sd, 0); - } - return ret; -} - -static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) -{ - int ret; - struct mt9m114_device *dev = to_mt9m114_sensor(sd); - - if (!dev || !dev->platform_data) - return -ENODEV; - - /* - * Note: current modules wire only one GPIO signal (RESET#), - * but the schematic wires up two to the connector. BIOS - * versions have been unfortunately inconsistent with which - * ACPI index RESET# is on, so hit both - */ - - if (flag) { - ret = dev->platform_data->gpio0_ctrl(sd, 0); - ret = dev->platform_data->gpio1_ctrl(sd, 0); - msleep(60); - ret |= dev->platform_data->gpio0_ctrl(sd, 1); - ret |= dev->platform_data->gpio1_ctrl(sd, 1); - } else { - ret = dev->platform_data->gpio0_ctrl(sd, 0); - ret = dev->platform_data->gpio1_ctrl(sd, 0); - } - return ret; -} - -static int power_up(struct v4l2_subdev *sd) -{ - struct mt9m114_device *dev = to_mt9m114_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - if (!dev->platform_data) { - dev_err(&client->dev, "no camera_sensor_platform_data"); - return -ENODEV; - } - - /* power control */ - ret = power_ctrl(sd, 1); - if (ret) - goto fail_power; - - /* flis clock control */ - ret = dev->platform_data->flisclk_ctrl(sd, 1); - if (ret) - goto fail_clk; - - /* gpio ctrl */ - ret = gpio_ctrl(sd, 1); - if (ret) - dev_err(&client->dev, "gpio failed 1\n"); - /* - * according to DS, 44ms is needed between power up and first i2c - * commend - */ - msleep(50); - - return 0; - -fail_clk: - dev->platform_data->flisclk_ctrl(sd, 0); -fail_power: - power_ctrl(sd, 0); - dev_err(&client->dev, "sensor power-up failed\n"); - - return ret; -} - -static int power_down(struct v4l2_subdev *sd) -{ - struct mt9m114_device *dev = to_mt9m114_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - if (!dev->platform_data) { - dev_err(&client->dev, "no camera_sensor_platform_data"); - return -ENODEV; - } - - ret = dev->platform_data->flisclk_ctrl(sd, 0); - if (ret) - dev_err(&client->dev, "flisclk failed\n"); - - /* gpio ctrl */ - ret = gpio_ctrl(sd, 0); - if (ret) - dev_err(&client->dev, "gpio failed 1\n"); - - /* power control */ - ret = power_ctrl(sd, 0); - if (ret) - dev_err(&client->dev, "vprog failed.\n"); - - /* according to DS, 20ms is needed after power down */ - msleep(20); - - return ret; -} - -static int mt9m114_s_power(struct v4l2_subdev *sd, int power) -{ - if (power == 0) - return power_down(sd); - - if (power_up(sd)) - return -EINVAL; - - return mt9m114_init_common(sd); -} - -static int mt9m114_res2size(struct v4l2_subdev *sd, int *h_size, int *v_size) -{ - struct mt9m114_device *dev = to_mt9m114_sensor(sd); - unsigned short hsize; - unsigned short vsize; - - switch (dev->res) { - case MT9M114_RES_736P: - hsize = MT9M114_RES_736P_SIZE_H; - vsize = MT9M114_RES_736P_SIZE_V; - break; - case MT9M114_RES_864P: - hsize = MT9M114_RES_864P_SIZE_H; - vsize = MT9M114_RES_864P_SIZE_V; - break; - case MT9M114_RES_960P: - hsize = MT9M114_RES_960P_SIZE_H; - vsize = MT9M114_RES_960P_SIZE_V; - break; - default: - v4l2_err(sd, "%s: Resolution 0x%08x unknown\n", __func__, - dev->res); - return -EINVAL; - } - - if (h_size) - *h_size = hsize; - if (v_size) - *v_size = vsize; - - return 0; -} - -static int mt9m114_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) -{ - struct v4l2_mbus_framefmt *fmt = &format->format; - int width, height; - int ret; - - if (format->pad) - return -EINVAL; - fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; - - ret = mt9m114_res2size(sd, &width, &height); - if (ret) - return ret; - fmt->width = width; - fmt->height = height; - - return 0; -} - -static int mt9m114_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) -{ - struct v4l2_mbus_framefmt *fmt = &format->format; - struct i2c_client *c = v4l2_get_subdevdata(sd); - struct mt9m114_device *dev = to_mt9m114_sensor(sd); - struct mt9m114_res_struct *res; - u32 width = fmt->width; - u32 height = fmt->height; - struct camera_mipi_info *mt9m114_info = NULL; - - int ret; - - if (format->pad) - return -EINVAL; - dev->streamon = 0; - dev->first_exp = MT9M114_DEFAULT_FIRST_EXP; - - mt9m114_info = v4l2_get_subdev_hostdata(sd); - if (!mt9m114_info) - return -EINVAL; - - res = v4l2_find_nearest_size(mt9m114_res, - ARRAY_SIZE(mt9m114_res), width, - height, fmt->width, fmt->height); - if (!res) - res = &mt9m114_res[N_RES - 1]; - - fmt->width = res->width; - fmt->height = res->height; - fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; - - if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_state_get_format(sd_state, 0) = *fmt; - return 0; - } - - switch (res->res) { - case MT9M114_RES_736P: - ret = mt9m114_write_reg_array(c, mt9m114_736P_init, NO_POLLING); - ret += misensor_rmw_reg(c, MISENSOR_16BIT, MISENSOR_READ_MODE, - MISENSOR_R_MODE_MASK, MISENSOR_NORMAL_SET); - break; - case MT9M114_RES_864P: - ret = mt9m114_write_reg_array(c, mt9m114_864P_init, NO_POLLING); - ret += misensor_rmw_reg(c, MISENSOR_16BIT, MISENSOR_READ_MODE, - MISENSOR_R_MODE_MASK, MISENSOR_NORMAL_SET); - break; - case MT9M114_RES_960P: - ret = mt9m114_write_reg_array(c, mt9m114_976P_init, NO_POLLING); - /* set sensor read_mode to Normal */ - ret += misensor_rmw_reg(c, MISENSOR_16BIT, MISENSOR_READ_MODE, - MISENSOR_R_MODE_MASK, MISENSOR_NORMAL_SET); - break; - default: - v4l2_err(sd, "set resolution: %d failed!\n", res->res); - return -EINVAL; - } - - if (ret) - return -EINVAL; - - ret = mt9m114_write_reg_array(c, mt9m114_chgstat_reg, POST_POLLING); - if (ret < 0) - return ret; - - if (mt9m114_set_suspend(sd)) - return -EINVAL; - - if (dev->res != res->res) { - int index; - - /* Switch to different size */ - if (width <= 640) { - dev->nctx = 0x00; /* Set for context A */ - } else { - /* - * Context B is used for resolutions larger than 640x480 - * Using YUV for Context B. - */ - dev->nctx = 0x01; /* set for context B */ - } - - /* - * Marked current sensor res as being "used" - * - * REVISIT: We don't need to use an "used" field on each mode - * list entry to know which mode is selected. If this - * information is really necessary, how about to use a single - * variable on sensor dev struct? - */ - for (index = 0; index < N_RES; index++) { - if ((width == mt9m114_res[index].width) && - (height == mt9m114_res[index].height)) { - mt9m114_res[index].used = true; - continue; - } - mt9m114_res[index].used = false; - } - } - /* - * mt9m114 - we don't poll for context switch - * because it does not happen with streaming disabled. - */ - dev->res = res->res; - - fmt->width = width; - fmt->height = height; - fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; - return 0; -} - -/* Horizontal flip the image. */ -static int mt9m114_g_hflip(struct v4l2_subdev *sd, s32 *val) -{ - struct i2c_client *c = v4l2_get_subdevdata(sd); - int ret; - u32 data; - - ret = mt9m114_read_reg(c, MISENSOR_16BIT, - (u32)MISENSOR_READ_MODE, &data); - if (ret) - return ret; - *val = !!(data & MISENSOR_HFLIP_MASK); - - return 0; -} - -static int mt9m114_g_vflip(struct v4l2_subdev *sd, s32 *val) -{ - struct i2c_client *c = v4l2_get_subdevdata(sd); - int ret; - u32 data; - - ret = mt9m114_read_reg(c, MISENSOR_16BIT, - (u32)MISENSOR_READ_MODE, &data); - if (ret) - return ret; - *val = !!(data & MISENSOR_VFLIP_MASK); - - return 0; -} - -static long mt9m114_s_exposure(struct v4l2_subdev *sd, - struct atomisp_exposure *exposure) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct mt9m114_device *dev = to_mt9m114_sensor(sd); - int ret = 0; - unsigned int coarse_integration = 0; - unsigned int f_lines = 0; - unsigned int frame_len_lines = 0; /* ExposureTime.FrameLengthLines; */ - unsigned int analog_gain, digital_gain; - u32 analog_gain_to_write = 0; - - dev_dbg(&client->dev, "%s(0x%X 0x%X 0x%X)\n", __func__, - exposure->integration_time[0], exposure->gain[0], - exposure->gain[1]); - - coarse_integration = exposure->integration_time[0]; - /* - * fine_integration = ExposureTime.FineIntegrationTime; - * frame_len_lines = ExposureTime.FrameLengthLines; - */ - f_lines = mt9m114_res[dev->res].lines_per_frame; - analog_gain = exposure->gain[0]; - digital_gain = exposure->gain[1]; - if (!dev->streamon) { - /*Save the first exposure values while stream is off*/ - dev->first_exp = coarse_integration; - dev->first_gain = analog_gain; - dev->first_diggain = digital_gain; - } - /* digital_gain = 0x400 * (((u16) digital_gain) >> 8) + */ - /* ((unsigned int)(0x400 * (((u16) digital_gain) & 0xFF)) >>8); */ - - /* set frame length */ - if (f_lines < coarse_integration + 6) - f_lines = coarse_integration + 6; - if (f_lines < frame_len_lines) - f_lines = frame_len_lines; - ret = mt9m114_write_reg(client, MISENSOR_16BIT, 0x300A, f_lines); - if (ret) { - v4l2_err(client, "%s: fail to set f_lines\n", __func__); - return -EINVAL; - } - - /* set coarse integration */ - /* - * 3A provide real exposure time. - * should not translate to any value here. - */ - ret = mt9m114_write_reg(client, MISENSOR_16BIT, - REG_EXPO_COARSE, (u16)(coarse_integration)); - if (ret) { - v4l2_err(client, "%s: fail to set exposure time\n", __func__); - return -EINVAL; - } - - /* - * set analog/digital gain - switch(analog_gain) - { - case 0: - analog_gain_to_write = 0x0; - break; - case 1: - analog_gain_to_write = 0x20; - break; - case 2: - analog_gain_to_write = 0x60; - break; - case 4: - analog_gain_to_write = 0xA0; - break; - case 8: - analog_gain_to_write = 0xE0; - break; - default: - analog_gain_to_write = 0x20; - break; - } - */ - if (digital_gain >= 16 || digital_gain <= 1) - digital_gain = 1; - /* - * analog_gain_to_write = (u16)((digital_gain << 12) - * | analog_gain_to_write); - */ - analog_gain_to_write = (u16)((digital_gain << 12) | (u16)analog_gain); - ret = mt9m114_write_reg(client, MISENSOR_16BIT, - REG_GAIN, analog_gain_to_write); - if (ret) { - v4l2_err(client, "%s: fail to set analog_gain_to_write\n", - __func__); - return -EINVAL; - } - - return ret; -} - -static long mt9m114_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - switch (cmd) { - case ATOMISP_IOC_S_EXPOSURE: - return mt9m114_s_exposure(sd, arg); - default: - return -EINVAL; - } - - return 0; -} - -/* - * This returns the exposure time being used. This should only be used - * for filling in EXIF data, not for actual image processing. - */ -static int mt9m114_g_exposure(struct v4l2_subdev *sd, s32 *value) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - u32 coarse; - int ret; - - /* the fine integration time is currently not calculated */ - ret = mt9m114_read_reg(client, MISENSOR_16BIT, - REG_EXPO_COARSE, &coarse); - if (ret) - return ret; - - *value = coarse; - return 0; -} - -/* - * This function will return the sensor supported max exposure zone number. - * the sensor which supports max exposure zone number is 1. - */ -static int mt9m114_g_exposure_zone_num(struct v4l2_subdev *sd, s32 *val) -{ - *val = 1; - - return 0; -} - -/* - * set exposure metering, average/center_weighted/spot/matrix. - */ -static int mt9m114_s_exposure_metering(struct v4l2_subdev *sd, s32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - switch (val) { - case V4L2_EXPOSURE_METERING_SPOT: - ret = mt9m114_write_reg_array(client, mt9m114_exp_average, - NO_POLLING); - if (ret) { - dev_err(&client->dev, "write exp_average reg err.\n"); - return ret; - } - break; - case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED: - default: - ret = mt9m114_write_reg_array(client, mt9m114_exp_center, - NO_POLLING); - if (ret) { - dev_err(&client->dev, "write exp_default reg err"); - return ret; - } - } - - return 0; -} - -/* - * This function is for touch exposure feature. - */ -static int mt9m114_s_exposure_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_selection *sel) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct misensor_reg exp_reg; - int width, height; - int grid_width, grid_height; - int grid_left, grid_top, grid_right, grid_bottom; - int win_left, win_top, win_right, win_bottom; - int i, j; - int ret; - - if (sel->which != V4L2_SUBDEV_FORMAT_TRY && - sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) - return -EINVAL; - - grid_left = sel->r.left; - grid_top = sel->r.top; - grid_right = sel->r.left + sel->r.width - 1; - grid_bottom = sel->r.top + sel->r.height - 1; - - ret = mt9m114_res2size(sd, &width, &height); - if (ret) - return ret; - - grid_width = width / 5; - grid_height = height / 5; - - if (grid_width && grid_height) { - win_left = grid_left / grid_width; - win_top = grid_top / grid_height; - win_right = grid_right / grid_width; - win_bottom = grid_bottom / grid_height; - } else { - dev_err(&client->dev, "Incorrect exp grid.\n"); - return -EINVAL; - } - - win_left = clamp_t(int, win_left, 0, 4); - win_top = clamp_t(int, win_top, 0, 4); - win_right = clamp_t(int, win_right, 0, 4); - win_bottom = clamp_t(int, win_bottom, 0, 4); - - ret = mt9m114_write_reg_array(client, mt9m114_exp_average, NO_POLLING); - if (ret) { - dev_err(&client->dev, "write exp_average reg err.\n"); - return ret; - } - - for (i = win_top; i <= win_bottom; i++) { - for (j = win_left; j <= win_right; j++) { - exp_reg = mt9m114_exp_win[i][j]; - - ret = mt9m114_write_reg(client, exp_reg.length, - exp_reg.reg, exp_reg.val); - if (ret) { - dev_err(&client->dev, "write exp_reg err.\n"); - return ret; - } - } - } - - return 0; -} - -static int mt9m114_s_ev(struct v4l2_subdev *sd, s32 val) -{ - struct i2c_client *c = v4l2_get_subdevdata(sd); - s32 luma = 0x37; - int err; - - /* - * EV value only support -2 to 2 - * 0: 0x37, 1:0x47, 2:0x57, -1:0x27, -2:0x17 - */ - if (val < -2 || val > 2) - return -EINVAL; - luma += 0x10 * val; - dev_dbg(&c->dev, "%s val:%d luma:0x%x\n", __func__, val, luma); - err = mt9m114_write_reg(c, MISENSOR_16BIT, 0x098E, 0xC87A); - if (err) { - dev_err(&c->dev, "%s logic addr access error\n", __func__); - return err; - } - err = mt9m114_write_reg(c, MISENSOR_8BIT, 0xC87A, (u32)luma); - if (err) { - dev_err(&c->dev, "%s write target_average_luma failed\n", - __func__); - return err; - } - udelay(10); - - return 0; -} - -static int mt9m114_g_ev(struct v4l2_subdev *sd, s32 *val) -{ - struct i2c_client *c = v4l2_get_subdevdata(sd); - int err; - u32 luma; - - err = mt9m114_write_reg(c, MISENSOR_16BIT, 0x098E, 0xC87A); - if (err) { - dev_err(&c->dev, "%s logic addr access error\n", __func__); - return err; - } - err = mt9m114_read_reg(c, MISENSOR_8BIT, 0xC87A, &luma); - if (err) { - dev_err(&c->dev, "%s read target_average_luma failed\n", - __func__); - return err; - } - luma -= 0x17; - luma /= 0x10; - *val = (s32)luma - 2; - dev_dbg(&c->dev, "%s val:%d\n", __func__, *val); - - return 0; -} - -/* - * Fake interface - * mt9m114 now can not support 3a_lock - */ -static int mt9m114_s_3a_lock(struct v4l2_subdev *sd, s32 val) -{ - aaalock = val; - return 0; -} - -static int mt9m114_g_3a_lock(struct v4l2_subdev *sd, s32 *val) -{ - if (aaalock) - return V4L2_LOCK_EXPOSURE | V4L2_LOCK_WHITE_BALANCE - | V4L2_LOCK_FOCUS; - return 0; -} - -static int mt9m114_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct mt9m114_device *dev = - container_of(ctrl->handler, struct mt9m114_device, ctrl_handler); - struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_VFLIP: - dev_dbg(&client->dev, "%s: CID_VFLIP:%d.\n", - __func__, ctrl->val); - ret = mt9m114_t_vflip(&dev->sd, ctrl->val); - break; - case V4L2_CID_HFLIP: - dev_dbg(&client->dev, "%s: CID_HFLIP:%d.\n", - __func__, ctrl->val); - ret = mt9m114_t_hflip(&dev->sd, ctrl->val); - break; - case V4L2_CID_EXPOSURE_METERING: - ret = mt9m114_s_exposure_metering(&dev->sd, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - ret = mt9m114_s_ev(&dev->sd, ctrl->val); - break; - case V4L2_CID_3A_LOCK: - ret = mt9m114_s_3a_lock(&dev->sd, ctrl->val); - break; - default: - ret = -EINVAL; - } - return ret; -} - -static int mt9m114_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct mt9m114_device *dev = - container_of(ctrl->handler, struct mt9m114_device, ctrl_handler); - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_VFLIP: - ret = mt9m114_g_vflip(&dev->sd, &ctrl->val); - break; - case V4L2_CID_HFLIP: - ret = mt9m114_g_hflip(&dev->sd, &ctrl->val); - break; - case V4L2_CID_EXPOSURE_ABSOLUTE: - ret = mt9m114_g_exposure(&dev->sd, &ctrl->val); - break; - case V4L2_CID_EXPOSURE_ZONE_NUM: - ret = mt9m114_g_exposure_zone_num(&dev->sd, &ctrl->val); - break; - case V4L2_CID_EXPOSURE: - ret = mt9m114_g_ev(&dev->sd, &ctrl->val); - break; - case V4L2_CID_3A_LOCK: - ret = mt9m114_g_3a_lock(&dev->sd, &ctrl->val); - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static const struct v4l2_ctrl_ops ctrl_ops = { - .s_ctrl = mt9m114_s_ctrl, - .g_volatile_ctrl = mt9m114_g_volatile_ctrl -}; - -static struct v4l2_ctrl_config mt9m114_controls[] = { - { - .ops = &ctrl_ops, - .id = V4L2_CID_VFLIP, - .name = "Image v-Flip", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .max = 1, - .step = 1, - .def = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_HFLIP, - .name = "Image h-Flip", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .max = 1, - .step = 1, - .def = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_EXPOSURE_ABSOLUTE, - .name = "exposure", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .max = 0xffff, - .step = 1, - .def = 0, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_EXPOSURE_ZONE_NUM, - .name = "one-time exposure zone number", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .max = 0xffff, - .step = 1, - .def = 0, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_EXPOSURE_METERING, - .name = "metering", - .type = V4L2_CTRL_TYPE_MENU, - .min = 0, - .max = 3, - .step = 0, - .def = 1, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_EXPOSURE, - .name = "exposure biasx", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = -2, - .max = 2, - .step = 1, - .def = 0, - .flags = 0, - }, -#if 0 /* Causes v4l2_ctrl_new_custom() to fail with -ERANGE, disable for now */ - { - .ops = &ctrl_ops, - .id = V4L2_CID_3A_LOCK, - .name = "3a lock", - .type = V4L2_CTRL_TYPE_BITMASK, - .min = 0, - .max = V4L2_LOCK_EXPOSURE | V4L2_LOCK_WHITE_BALANCE | V4L2_LOCK_FOCUS, - .step = 1, - .def = 0, - .flags = 0, - }, -#endif -}; - -static int mt9m114_detect(struct mt9m114_device *dev, struct i2c_client *client) -{ - struct i2c_adapter *adapter = client->adapter; - u32 model; - int ret; - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "%s: i2c error", __func__); - return -ENODEV; - } - ret = mt9m114_read_reg(client, MISENSOR_16BIT, MT9M114_PID, &model); - if (ret) - return ret; - dev->real_model_id = model; - - if (model != MT9M114_MOD_ID) { - dev_err(&client->dev, "%s: failed: client->addr = %x\n", - __func__, client->addr); - return -ENODEV; - } - - return 0; -} - -static int -mt9m114_s_config(struct v4l2_subdev *sd, int irq, void *platform_data) -{ - struct mt9m114_device *dev = to_mt9m114_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - if (!platform_data) - return -ENODEV; - - dev->platform_data = - (struct camera_sensor_platform_data *)platform_data; - - ret = power_up(sd); - if (ret) { - v4l2_err(client, "mt9m114 power-up err"); - return ret; - } - - /* config & detect sensor */ - ret = mt9m114_detect(dev, client); - if (ret) { - v4l2_err(client, "mt9m114_detect err s_config.\n"); - goto fail_detect; - } - - ret = dev->platform_data->csi_cfg(sd, 1); - if (ret) - goto fail_csi_cfg; - - ret = mt9m114_set_suspend(sd); - if (ret) { - v4l2_err(client, "mt9m114 suspend err"); - return ret; - } - - ret = power_down(sd); - if (ret) { - v4l2_err(client, "mt9m114 power down err"); - return ret; - } - - return ret; - -fail_csi_cfg: - dev->platform_data->csi_cfg(sd, 0); -fail_detect: - power_down(sd); - dev_err(&client->dev, "sensor power-gating failed\n"); - return ret; -} - -/* Horizontal flip the image. */ -static int mt9m114_t_hflip(struct v4l2_subdev *sd, int value) -{ - struct i2c_client *c = v4l2_get_subdevdata(sd); - struct mt9m114_device *dev = to_mt9m114_sensor(sd); - int err; - /* set for direct mode */ - err = mt9m114_write_reg(c, MISENSOR_16BIT, 0x098E, 0xC850); - if (value) { - /* enable H flip ctx A */ - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC850, 0x01, 0x01); - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC851, 0x01, 0x01); - /* ctx B */ - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC888, 0x01, 0x01); - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC889, 0x01, 0x01); - - err += misensor_rmw_reg(c, MISENSOR_16BIT, MISENSOR_READ_MODE, - MISENSOR_HFLIP_MASK, MISENSOR_FLIP_EN); - - dev->bpat = MT9M114_BPAT_GRGRBGBG; - } else { - /* disable H flip ctx A */ - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC850, 0x01, 0x00); - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC851, 0x01, 0x00); - /* ctx B */ - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC888, 0x01, 0x00); - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC889, 0x01, 0x00); - - err += misensor_rmw_reg(c, MISENSOR_16BIT, MISENSOR_READ_MODE, - MISENSOR_HFLIP_MASK, MISENSOR_FLIP_DIS); - - dev->bpat = MT9M114_BPAT_BGBGGRGR; - } - - err += mt9m114_write_reg(c, MISENSOR_8BIT, 0x8404, 0x06); - udelay(10); - - return !!err; -} - -/* Vertically flip the image */ -static int mt9m114_t_vflip(struct v4l2_subdev *sd, int value) -{ - struct i2c_client *c = v4l2_get_subdevdata(sd); - int err; - /* set for direct mode */ - err = mt9m114_write_reg(c, MISENSOR_16BIT, 0x098E, 0xC850); - if (value >= 1) { - /* enable H flip - ctx A */ - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC850, 0x02, 0x01); - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC851, 0x02, 0x01); - /* ctx B */ - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC888, 0x02, 0x01); - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC889, 0x02, 0x01); - - err += misensor_rmw_reg(c, MISENSOR_16BIT, MISENSOR_READ_MODE, - MISENSOR_VFLIP_MASK, MISENSOR_FLIP_EN); - } else { - /* disable H flip - ctx A */ - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC850, 0x02, 0x00); - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC851, 0x02, 0x00); - /* ctx B */ - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC888, 0x02, 0x00); - err += misensor_rmw_reg(c, MISENSOR_8BIT, 0xC889, 0x02, 0x00); - - err += misensor_rmw_reg(c, MISENSOR_16BIT, MISENSOR_READ_MODE, - MISENSOR_VFLIP_MASK, MISENSOR_FLIP_DIS); - } - - err += mt9m114_write_reg(c, MISENSOR_8BIT, 0x8404, 0x06); - udelay(10); - - return !!err; -} - -static int mt9m114_get_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_interval *interval) -{ - struct mt9m114_device *dev = to_mt9m114_sensor(sd); - - /* - * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2 - * subdev active state API. - */ - if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE) - return -EINVAL; - - interval->interval.numerator = 1; - interval->interval.denominator = mt9m114_res[dev->res].fps; - - return 0; -} - -static int mt9m114_s_stream(struct v4l2_subdev *sd, int enable) -{ - int ret; - struct i2c_client *c = v4l2_get_subdevdata(sd); - struct mt9m114_device *dev = to_mt9m114_sensor(sd); - struct atomisp_exposure exposure; - - if (enable) { - ret = mt9m114_write_reg_array(c, mt9m114_chgstat_reg, - POST_POLLING); - if (ret < 0) - return ret; - - if (dev->first_exp > MT9M114_MAX_FIRST_EXP) { - exposure.integration_time[0] = dev->first_exp; - exposure.gain[0] = dev->first_gain; - exposure.gain[1] = dev->first_diggain; - mt9m114_s_exposure(sd, &exposure); - } - dev->streamon = 1; - - } else { - dev->streamon = 0; - ret = mt9m114_set_suspend(sd); - } - - return ret; -} - -static int mt9m114_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_mbus_code_enum *code) -{ - if (code->index) - return -EINVAL; - code->code = MEDIA_BUS_FMT_SGRBG10_1X10; - - return 0; -} - -static int mt9m114_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_size_enum *fse) -{ - unsigned int index = fse->index; - - if (index >= N_RES) - return -EINVAL; - - fse->min_width = mt9m114_res[index].width; - fse->min_height = mt9m114_res[index].height; - fse->max_width = mt9m114_res[index].width; - fse->max_height = mt9m114_res[index].height; - - return 0; -} - -static int mt9m114_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) -{ - int index; - struct mt9m114_device *snr = to_mt9m114_sensor(sd); - - if (!frames) - return -EINVAL; - - for (index = 0; index < N_RES; index++) { - if (mt9m114_res[index].res == snr->res) - break; - } - - if (index >= N_RES) - return -EINVAL; - - *frames = mt9m114_res[index].skip_frames; - - return 0; -} - -static const struct v4l2_subdev_video_ops mt9m114_video_ops = { - .s_stream = mt9m114_s_stream, -}; - -static const struct v4l2_subdev_sensor_ops mt9m114_sensor_ops = { - .g_skip_frames = mt9m114_g_skip_frames, -}; - -static const struct v4l2_subdev_core_ops mt9m114_core_ops = { - .s_power = mt9m114_s_power, - .ioctl = mt9m114_ioctl, -}; - -/* REVISIT: Do we need pad operations? */ -static const struct v4l2_subdev_pad_ops mt9m114_pad_ops = { - .enum_mbus_code = mt9m114_enum_mbus_code, - .enum_frame_size = mt9m114_enum_frame_size, - .get_fmt = mt9m114_get_fmt, - .set_fmt = mt9m114_set_fmt, - .set_selection = mt9m114_s_exposure_selection, - .get_frame_interval = mt9m114_get_frame_interval, -}; - -static const struct v4l2_subdev_ops mt9m114_ops = { - .core = &mt9m114_core_ops, - .video = &mt9m114_video_ops, - .pad = &mt9m114_pad_ops, - .sensor = &mt9m114_sensor_ops, -}; - -static void mt9m114_remove(struct i2c_client *client) -{ - struct mt9m114_device *dev; - struct v4l2_subdev *sd = i2c_get_clientdata(client); - - dev = container_of(sd, struct mt9m114_device, sd); - dev->platform_data->csi_cfg(sd, 0); - v4l2_device_unregister_subdev(sd); - media_entity_cleanup(&dev->sd.entity); - v4l2_ctrl_handler_free(&dev->ctrl_handler); -} - -static int mt9m114_probe(struct i2c_client *client) -{ - struct mt9m114_device *dev; - int ret = 0; - unsigned int i; - void *pdata; - - /* Setup sensor configuration structure */ - dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - ret = devm_mutex_init(&client->dev, &dev->input_lock); - if (ret) - return ret; - - v4l2_i2c_subdev_init(&dev->sd, client, &mt9m114_ops); - pdata = gmin_camera_platform_data(&dev->sd, - ATOMISP_INPUT_FORMAT_RAW_10, - atomisp_bayer_order_grbg); - if (pdata) - ret = mt9m114_s_config(&dev->sd, client->irq, pdata); - if (!pdata || ret) { - v4l2_device_unregister_subdev(&dev->sd); - return ret; - } - - ret = atomisp_register_i2c_module(&dev->sd, pdata); - if (ret) { - v4l2_device_unregister_subdev(&dev->sd); - /* Coverity CID 298095 - return on error */ - return ret; - } - - /* TODO add format code here */ - dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - dev->pad.flags = MEDIA_PAD_FL_SOURCE; - dev->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; - dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; - - ret = - v4l2_ctrl_handler_init(&dev->ctrl_handler, - ARRAY_SIZE(mt9m114_controls)); - if (ret) { - mt9m114_remove(client); - return ret; - } - - for (i = 0; i < ARRAY_SIZE(mt9m114_controls); i++) - v4l2_ctrl_new_custom(&dev->ctrl_handler, &mt9m114_controls[i], - NULL); - - if (dev->ctrl_handler.error) { - mt9m114_remove(client); - return dev->ctrl_handler.error; - } - - /* Use same lock for controls as for everything else. */ - dev->ctrl_handler.lock = &dev->input_lock; - dev->sd.ctrl_handler = &dev->ctrl_handler; - - /* REVISIT: Do we need media controller? */ - ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); - if (ret) { - mt9m114_remove(client); - return ret; - } - return 0; -} - -static const struct acpi_device_id mt9m114_acpi_match[] = { - { "INT33F0" }, - { "CRMT1040" }, - {}, -}; -MODULE_DEVICE_TABLE(acpi, mt9m114_acpi_match); - -static struct i2c_driver mt9m114_driver = { - .driver = { - .name = "mt9m114", - .acpi_match_table = mt9m114_acpi_match, - }, - .probe = mt9m114_probe, - .remove = mt9m114_remove, -}; -module_i2c_driver(mt9m114_driver); - -MODULE_AUTHOR("Shuguang Gong <Shuguang.gong@intel.com>"); -MODULE_DESCRIPTION("Aptina mt9m114 sensor support module"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h index 6c743a17f198..7dd9a676fb98 100644 --- a/drivers/staging/media/atomisp/i2c/gc2235.h +++ b/drivers/staging/media/atomisp/i2c/gc2235.h @@ -179,21 +179,21 @@ struct gc2235_write_ctrl { struct gc2235_write_buffer buffer; }; -static struct gc2235_reg const gc2235_stream_on[] = { +static const struct gc2235_reg gc2235_stream_on[] = { { GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */ { GC2235_8BIT, 0x10, 0x91}, /* start mipi */ { GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */ { GC2235_TOK_TERM, 0, 0 } }; -static struct gc2235_reg const gc2235_stream_off[] = { +static const struct gc2235_reg gc2235_stream_off[] = { { GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */ { GC2235_8BIT, 0x10, 0x01}, /* stop mipi */ { GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */ { GC2235_TOK_TERM, 0, 0 } }; -static struct gc2235_reg const gc2235_init_settings[] = { +static const struct gc2235_reg gc2235_init_settings[] = { /* System */ { GC2235_8BIT, 0xfe, 0x80 }, { GC2235_8BIT, 0xfe, 0x80 }, @@ -268,7 +268,7 @@ static struct gc2235_reg const gc2235_init_settings[] = { * Register settings for various resolution */ #if ENABLE_NON_PREVIEW -static struct gc2235_reg const gc2235_1296_736_30fps[] = { +static const struct gc2235_reg gc2235_1296_736_30fps[] = { { GC2235_8BIT, 0x8b, 0xa0 }, { GC2235_8BIT, 0x8c, 0x02 }, @@ -321,7 +321,7 @@ static struct gc2235_reg const gc2235_1296_736_30fps[] = { { GC2235_TOK_TERM, 0, 0 } }; -static struct gc2235_reg const gc2235_960_640_30fps[] = { +static const struct gc2235_reg gc2235_960_640_30fps[] = { { GC2235_8BIT, 0x8b, 0xa0 }, { GC2235_8BIT, 0x8c, 0x02 }, @@ -373,7 +373,7 @@ static struct gc2235_reg const gc2235_960_640_30fps[] = { }; #endif -static struct gc2235_reg const gc2235_1600_900_30fps[] = { +static const struct gc2235_reg gc2235_1600_900_30fps[] = { { GC2235_8BIT, 0x8b, 0xa0 }, { GC2235_8BIT, 0x8c, 0x02 }, @@ -418,7 +418,7 @@ static struct gc2235_reg const gc2235_1600_900_30fps[] = { { GC2235_TOK_TERM, 0, 0 } }; -static struct gc2235_reg const gc2235_1616_1082_30fps[] = { +static const struct gc2235_reg gc2235_1616_1082_30fps[] = { { GC2235_8BIT, 0x8b, 0xa0 }, { GC2235_8BIT, 0x8c, 0x02 }, @@ -463,7 +463,7 @@ static struct gc2235_reg const gc2235_1616_1082_30fps[] = { { GC2235_TOK_TERM, 0, 0 } }; -static struct gc2235_reg const gc2235_1616_1216_30fps[] = { +static const struct gc2235_reg gc2235_1616_1216_30fps[] = { { GC2235_8BIT, 0x8b, 0xa0 }, { GC2235_8BIT, 0x8c, 0x02 }, diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.h b/drivers/staging/media/atomisp/i2c/mt9m114.h deleted file mode 100644 index 97820db90827..000000000000 --- a/drivers/staging/media/atomisp/i2c/mt9m114.h +++ /dev/null @@ -1,1768 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Support for mt9m114 Camera Sensor. - * - * Copyright (c) 2010 Intel Corporation. All Rights Reserved. - */ - -#ifndef __A1040_H__ -#define __A1040_H__ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/i2c.h> -#include <linux/delay.h> -#include <linux/videodev2.h> -#include <linux/spinlock.h> -#include <media/v4l2-subdev.h> -#include <media/v4l2-device.h> -#include <media/v4l2-ctrls.h> -#include <linux/v4l2-mediabus.h> -#include <media/media-entity.h> -#include "../include/linux/atomisp_platform.h" -#include "../include/linux/atomisp.h" - -#define V4L2_IDENT_MT9M114 8245 - -#define MT9P111_REV3 -#define FULLINISUPPORT - -/* #defines for register writes and register array processing */ -#define MISENSOR_8BIT 1 -#define MISENSOR_16BIT 2 -#define MISENSOR_32BIT 4 - -#define MISENSOR_FWBURST0 0x80 -#define MISENSOR_FWBURST1 0x81 -#define MISENSOR_FWBURST4 0x84 -#define MISENSOR_FWBURST 0x88 - -#define MISENSOR_TOK_TERM 0xf000 /* terminating token for reg list */ -#define MISENSOR_TOK_DELAY 0xfe00 /* delay token for reg list */ -#define MISENSOR_TOK_FWLOAD 0xfd00 /* token indicating load FW */ -#define MISENSOR_TOK_POLL 0xfc00 /* token indicating poll instruction */ -#define MISENSOR_TOK_RMW 0x0010 /* RMW operation */ -#define MISENSOR_TOK_MASK 0xfff0 -#define MISENSOR_AWB_STEADY BIT(0) /* awb steady */ -#define MISENSOR_AE_READY BIT(3) /* ae status ready */ - -/* mask to set sensor read_mode via misensor_rmw_reg */ -#define MISENSOR_R_MODE_MASK 0x0330 -/* mask to set sensor vert_flip and horz_mirror */ -#define MISENSOR_VFLIP_MASK 0x0002 -#define MISENSOR_HFLIP_MASK 0x0001 -#define MISENSOR_FLIP_EN 1 -#define MISENSOR_FLIP_DIS 0 - -/* bits set to set sensor read_mode via misensor_rmw_reg */ -#define MISENSOR_SKIPPING_SET 0x0011 -#define MISENSOR_SUMMING_SET 0x0033 -#define MISENSOR_NORMAL_SET 0x0000 - -/* sensor register that control sensor read-mode and mirror */ -#define MISENSOR_READ_MODE 0xC834 -/* sensor ae-track status register */ -#define MISENSOR_AE_TRACK_STATUS 0xA800 -/* sensor awb status register */ -#define MISENSOR_AWB_STATUS 0xAC00 -/* sensor coarse integration time register */ -#define MISENSOR_COARSE_INTEGRATION_TIME 0xC83C - -/* registers */ -#define REG_SW_RESET 0x301A -#define REG_SW_STREAM 0xDC00 -#define REG_SCCB_CTRL 0x3100 -#define REG_SC_CMMN_CHIP_ID 0x0000 -#define REG_V_START 0xc800 /* 16bits */ -#define REG_H_START 0xc802 /* 16bits */ -#define REG_V_END 0xc804 /* 16bits */ -#define REG_H_END 0xc806 /* 16bits */ -#define REG_PIXEL_CLK 0xc808 /* 32bits */ -#define REG_TIMING_VTS 0xc812 /* 16bits */ -#define REG_TIMING_HTS 0xc814 /* 16bits */ -#define REG_WIDTH 0xC868 /* 16bits */ -#define REG_HEIGHT 0xC86A /* 16bits */ -#define REG_EXPO_COARSE 0x3012 /* 16bits */ -#define REG_EXPO_FINE 0x3014 /* 16bits */ -#define REG_GAIN 0x305E -#define REG_ANALOGGAIN 0x305F -#define REG_ADDR_ACESSS 0x098E /* logical_address_access */ -#define REG_COMM_Register 0x0080 /* command_register */ - -#define SENSOR_DETECTED 1 -#define SENSOR_NOT_DETECTED 0 - -#define I2C_RETRY_COUNT 5 -#define MSG_LEN_OFFSET 2 - -#ifndef MIPI_CONTROL -#define MIPI_CONTROL 0x3400 /* MIPI_Control */ -#endif - -/* GPIO pin on Moorestown */ -#define GPIO_SCLK_25 44 -#define GPIO_STB_PIN 47 - -#define GPIO_STDBY_PIN 49 /* ab:new */ -#define GPIO_RESET_PIN 50 - -/* System control register for Aptina A-1040SOC*/ -#define MT9M114_PID 0x0 - -/* MT9P111_DEVICE_ID */ -#define MT9M114_MOD_ID 0x2481 - -#define MT9M114_FINE_INTG_TIME_MIN 0 -#define MT9M114_FINE_INTG_TIME_MAX_MARGIN 0 -#define MT9M114_COARSE_INTG_TIME_MIN 1 -#define MT9M114_COARSE_INTG_TIME_MAX_MARGIN 6 - -/* ulBPat; */ - -#define MT9M114_BPAT_RGRGGBGB BIT(0) -#define MT9M114_BPAT_GRGRBGBG BIT(1) -#define MT9M114_BPAT_GBGBRGRG BIT(2) -#define MT9M114_BPAT_BGBGGRGR BIT(3) - -#define MT9M114_FOCAL_LENGTH_NUM 208 /*2.08mm*/ -#define MT9M114_WAIT_STAT_TIMEOUT 100 -#define MT9M114_FLICKER_MODE_50HZ 1 -#define MT9M114_FLICKER_MODE_60HZ 2 -/* - * focal length bits definition: - * bits 31-16: numerator, bits 15-0: denominator - */ -#define MT9M114_FOCAL_LENGTH_DEFAULT 0xD00064 - -/* - * current f-number bits definition: - * bits 31-16: numerator, bits 15-0: denominator - */ -#define MT9M114_F_NUMBER_DEFAULT 0x18000a - -/* - * f-number range bits definition: - * bits 31-24: max f-number numerator - * bits 23-16: max f-number denominator - * bits 15-8: min f-number numerator - * bits 7-0: min f-number denominator - */ -#define MT9M114_F_NUMBER_RANGE 0x180a180a - -/* Supported resolutions */ -enum { - MT9M114_RES_736P, - MT9M114_RES_864P, - MT9M114_RES_960P, -}; - -#define MT9M114_RES_960P_SIZE_H 1296 -#define MT9M114_RES_960P_SIZE_V 976 -#define MT9M114_RES_720P_SIZE_H 1280 -#define MT9M114_RES_720P_SIZE_V 720 -#define MT9M114_RES_576P_SIZE_H 1024 -#define MT9M114_RES_576P_SIZE_V 576 -#define MT9M114_RES_480P_SIZE_H 768 -#define MT9M114_RES_480P_SIZE_V 480 -#define MT9M114_RES_VGA_SIZE_H 640 -#define MT9M114_RES_VGA_SIZE_V 480 -#define MT9M114_RES_QVGA_SIZE_H 320 -#define MT9M114_RES_QVGA_SIZE_V 240 -#define MT9M114_RES_QCIF_SIZE_H 176 -#define MT9M114_RES_QCIF_SIZE_V 144 - -#define MT9M114_RES_720_480p_768_SIZE_H 736 -#define MT9M114_RES_720_480p_768_SIZE_V 496 -#define MT9M114_RES_736P_SIZE_H 1296 -#define MT9M114_RES_736P_SIZE_V 736 -#define MT9M114_RES_864P_SIZE_H 1296 -#define MT9M114_RES_864P_SIZE_V 864 -#define MT9M114_RES_976P_SIZE_H 1296 -#define MT9M114_RES_976P_SIZE_V 976 - -#define MT9M114_BIN_FACTOR_MAX 3 - -#define MT9M114_DEFAULT_FIRST_EXP 0x10 -#define MT9M114_MAX_FIRST_EXP 0x302 - -/* completion status polling requirements, usage based on Aptina .INI Rev2 */ -enum poll_reg { - NO_POLLING, - PRE_POLLING, - POST_POLLING, -}; - -/* - * struct misensor_reg - MI sensor register format - * @length: length of the register - * @reg: 16-bit offset to register - * @val: 8/16/32-bit register value - * Define a structure for sensor register initialization values - */ -struct misensor_reg { - u32 length; - u32 reg; - u32 val; /* value or for read/mod/write, AND mask */ - u32 val2; /* optional; for rmw, OR mask */ -}; - -/* - * struct misensor_fwreg - Firmware burst command - * @type: FW burst or 8/16 bit register - * @addr: 16-bit offset to register or other values depending on type - * @valx: data value for burst (or other commands) - * - * Define a structure for sensor register initialization values - */ -struct misensor_fwreg { - u32 type; /* type of value, register or FW burst string */ - u32 addr; /* target address */ - u32 val0; - u32 val1; - u32 val2; - u32 val3; - u32 val4; - u32 val5; - u32 val6; - u32 val7; -}; - -struct regval_list { - u16 reg_num; - u8 value; -}; - -struct mt9m114_device { - struct v4l2_subdev sd; - struct media_pad pad; - struct v4l2_mbus_framefmt format; - - struct camera_sensor_platform_data *platform_data; - struct mutex input_lock; /* serialize sensor's ioctl */ - struct v4l2_ctrl_handler ctrl_handler; - int real_model_id; - int nctx; - int power; - - unsigned int bus_width; - unsigned int mode; - unsigned int field_inv; - unsigned int field_sel; - unsigned int ycseq; - unsigned int conv422; - unsigned int bpat; - unsigned int hpol; - unsigned int vpol; - unsigned int edge; - unsigned int bls; - unsigned int gamma; - unsigned int cconv; - unsigned int res; - unsigned int dwn_sz; - unsigned int blc; - unsigned int agc; - unsigned int awb; - unsigned int aec; - /* extension SENSOR version 2 */ - unsigned int cie_profile; - - /* extension SENSOR version 3 */ - unsigned int flicker_freq; - - /* extension SENSOR version 4 */ - unsigned int smia_mode; - unsigned int mipi_mode; - - /* Add name here to load shared library */ - unsigned int type; - - /*Number of MIPI lanes*/ - unsigned int mipi_lanes; - /*WA for low light AE*/ - unsigned int first_exp; - unsigned int first_gain; - unsigned int first_diggain; - char name[32]; - - u8 lightfreq; - u8 streamon; -}; - -struct mt9m114_format_struct { - u8 *desc; - u32 pixelformat; - struct regval_list *regs; -}; - -struct mt9m114_res_struct { - u8 *desc; - int res; - int width; - int height; - int fps; - int skip_frames; - bool used; - struct regval_list *regs; - u16 pixels_per_line; - u16 lines_per_frame; -}; - -/* 2 bytes used for address: 256 bytes total */ -#define MT9M114_MAX_WRITE_BUF_SIZE 254 -struct mt9m114_write_buffer { - u16 addr; - u8 data[MT9M114_MAX_WRITE_BUF_SIZE]; -}; - -struct mt9m114_write_ctrl { - int index; - struct mt9m114_write_buffer buffer; -}; - -/* - * Modes supported by the mt9m114 driver. - * Please, keep them in ascending order. - */ -static struct mt9m114_res_struct mt9m114_res[] = { - { - .desc = "720P", - .res = MT9M114_RES_736P, - .width = 1296, - .height = 736, - .fps = 30, - .used = false, - .regs = NULL, - .skip_frames = 1, - - .pixels_per_line = 0x0640, - .lines_per_frame = 0x0307, - }, - { - .desc = "848P", - .res = MT9M114_RES_864P, - .width = 1296, - .height = 864, - .fps = 30, - .used = false, - .regs = NULL, - .skip_frames = 1, - - .pixels_per_line = 0x0640, - .lines_per_frame = 0x03E8, - }, - { - .desc = "960P", - .res = MT9M114_RES_960P, - .width = 1296, - .height = 976, - .fps = 30, - .used = false, - .regs = NULL, - .skip_frames = 1, - - .pixels_per_line = 0x0644, /* consistent with regs arrays */ - .lines_per_frame = 0x03E5, /* consistent with regs arrays */ - }, -}; - -#define N_RES (ARRAY_SIZE(mt9m114_res)) - -#if 0 /* Currently unused */ -static struct misensor_reg const mt9m114_exitstandby[] = { - {MISENSOR_16BIT, 0x098E, 0xDC00}, - /* exit-standby */ - {MISENSOR_8BIT, 0xDC00, 0x54}, - {MISENSOR_16BIT, 0x0080, 0x8002}, - {MISENSOR_TOK_TERM, 0, 0} -}; -#endif - -static struct misensor_reg const mt9m114_exp_win[5][5] = { - { - {MISENSOR_8BIT, 0xA407, 0x64}, - {MISENSOR_8BIT, 0xA408, 0x64}, - {MISENSOR_8BIT, 0xA409, 0x64}, - {MISENSOR_8BIT, 0xA40A, 0x64}, - {MISENSOR_8BIT, 0xA40B, 0x64}, - }, - { - {MISENSOR_8BIT, 0xA40C, 0x64}, - {MISENSOR_8BIT, 0xA40D, 0x64}, - {MISENSOR_8BIT, 0xA40E, 0x64}, - {MISENSOR_8BIT, 0xA40F, 0x64}, - {MISENSOR_8BIT, 0xA410, 0x64}, - }, - { - {MISENSOR_8BIT, 0xA411, 0x64}, - {MISENSOR_8BIT, 0xA412, 0x64}, - {MISENSOR_8BIT, 0xA413, 0x64}, - {MISENSOR_8BIT, 0xA414, 0x64}, - {MISENSOR_8BIT, 0xA415, 0x64}, - }, - { - {MISENSOR_8BIT, 0xA416, 0x64}, - {MISENSOR_8BIT, 0xA417, 0x64}, - {MISENSOR_8BIT, 0xA418, 0x64}, - {MISENSOR_8BIT, 0xA419, 0x64}, - {MISENSOR_8BIT, 0xA41A, 0x64}, - }, - { - {MISENSOR_8BIT, 0xA41B, 0x64}, - {MISENSOR_8BIT, 0xA41C, 0x64}, - {MISENSOR_8BIT, 0xA41D, 0x64}, - {MISENSOR_8BIT, 0xA41E, 0x64}, - {MISENSOR_8BIT, 0xA41F, 0x64}, - }, -}; - -static struct misensor_reg const mt9m114_exp_average[] = { - {MISENSOR_8BIT, 0xA407, 0x00}, - {MISENSOR_8BIT, 0xA408, 0x00}, - {MISENSOR_8BIT, 0xA409, 0x00}, - {MISENSOR_8BIT, 0xA40A, 0x00}, - {MISENSOR_8BIT, 0xA40B, 0x00}, - {MISENSOR_8BIT, 0xA40C, 0x00}, - {MISENSOR_8BIT, 0xA40D, 0x00}, - {MISENSOR_8BIT, 0xA40E, 0x00}, - {MISENSOR_8BIT, 0xA40F, 0x00}, - {MISENSOR_8BIT, 0xA410, 0x00}, - {MISENSOR_8BIT, 0xA411, 0x00}, - {MISENSOR_8BIT, 0xA412, 0x00}, - {MISENSOR_8BIT, 0xA413, 0x00}, - {MISENSOR_8BIT, 0xA414, 0x00}, - {MISENSOR_8BIT, 0xA415, 0x00}, - {MISENSOR_8BIT, 0xA416, 0x00}, - {MISENSOR_8BIT, 0xA417, 0x00}, - {MISENSOR_8BIT, 0xA418, 0x00}, - {MISENSOR_8BIT, 0xA419, 0x00}, - {MISENSOR_8BIT, 0xA41A, 0x00}, - {MISENSOR_8BIT, 0xA41B, 0x00}, - {MISENSOR_8BIT, 0xA41C, 0x00}, - {MISENSOR_8BIT, 0xA41D, 0x00}, - {MISENSOR_8BIT, 0xA41E, 0x00}, - {MISENSOR_8BIT, 0xA41F, 0x00}, - {MISENSOR_TOK_TERM, 0, 0} -}; - -static struct misensor_reg const mt9m114_exp_center[] = { - {MISENSOR_8BIT, 0xA407, 0x19}, - {MISENSOR_8BIT, 0xA408, 0x19}, - {MISENSOR_8BIT, 0xA409, 0x19}, - {MISENSOR_8BIT, 0xA40A, 0x19}, - {MISENSOR_8BIT, 0xA40B, 0x19}, - {MISENSOR_8BIT, 0xA40C, 0x19}, - {MISENSOR_8BIT, 0xA40D, 0x4B}, - {MISENSOR_8BIT, 0xA40E, 0x4B}, - {MISENSOR_8BIT, 0xA40F, 0x4B}, - {MISENSOR_8BIT, 0xA410, 0x19}, - {MISENSOR_8BIT, 0xA411, 0x19}, - {MISENSOR_8BIT, 0xA412, 0x4B}, - {MISENSOR_8BIT, 0xA413, 0x64}, - {MISENSOR_8BIT, 0xA414, 0x4B}, - {MISENSOR_8BIT, 0xA415, 0x19}, - {MISENSOR_8BIT, 0xA416, 0x19}, - {MISENSOR_8BIT, 0xA417, 0x4B}, - {MISENSOR_8BIT, 0xA418, 0x4B}, - {MISENSOR_8BIT, 0xA419, 0x4B}, - {MISENSOR_8BIT, 0xA41A, 0x19}, - {MISENSOR_8BIT, 0xA41B, 0x19}, - {MISENSOR_8BIT, 0xA41C, 0x19}, - {MISENSOR_8BIT, 0xA41D, 0x19}, - {MISENSOR_8BIT, 0xA41E, 0x19}, - {MISENSOR_8BIT, 0xA41F, 0x19}, - {MISENSOR_TOK_TERM, 0, 0} -}; - -#if 0 /* Currently unused */ -static struct misensor_reg const mt9m114_suspend[] = { - {MISENSOR_16BIT, 0x098E, 0xDC00}, - {MISENSOR_8BIT, 0xDC00, 0x40}, - {MISENSOR_16BIT, 0x0080, 0x8002}, - {MISENSOR_TOK_TERM, 0, 0} -}; - -static struct misensor_reg const mt9m114_streaming[] = { - {MISENSOR_16BIT, 0x098E, 0xDC00}, - {MISENSOR_8BIT, 0xDC00, 0x34}, - {MISENSOR_16BIT, 0x0080, 0x8002}, - {MISENSOR_TOK_TERM, 0, 0} -}; -#endif - -static struct misensor_reg const mt9m114_standby_reg[] = { - {MISENSOR_16BIT, 0x098E, 0xDC00}, - {MISENSOR_8BIT, 0xDC00, 0x50}, - {MISENSOR_16BIT, 0x0080, 0x8002}, - {MISENSOR_TOK_TERM, 0, 0} -}; - -#if 0 /* Currently unused */ -static struct misensor_reg const mt9m114_wakeup_reg[] = { - {MISENSOR_16BIT, 0x098E, 0xDC00}, - {MISENSOR_8BIT, 0xDC00, 0x54}, - {MISENSOR_16BIT, 0x0080, 0x8002}, - {MISENSOR_TOK_TERM, 0, 0} -}; -#endif - -static struct misensor_reg const mt9m114_chgstat_reg[] = { - {MISENSOR_16BIT, 0x098E, 0xDC00}, - {MISENSOR_8BIT, 0xDC00, 0x28}, - {MISENSOR_16BIT, 0x0080, 0x8002}, - {MISENSOR_TOK_TERM, 0, 0} -}; - -/* [1296x976_30fps] - Intel */ -#if 0 -static struct misensor_reg const mt9m114_960P_init[] = { - {MISENSOR_16BIT, 0x098E, 0x1000}, - {MISENSOR_8BIT, 0xC97E, 0x01}, /* cam_sysctl_pll_enable = 1 */ - {MISENSOR_16BIT, 0xC980, 0x0128}, /* cam_sysctl_pll_divider_m_n = 276 */ - {MISENSOR_16BIT, 0xC982, 0x0700}, /* cam_sysctl_pll_divider_p = 1792 */ - {MISENSOR_16BIT, 0xC800, 0x0000}, /* cam_sensor_cfg_y_addr_start = 0 */ - {MISENSOR_16BIT, 0xC802, 0x0000}, /* cam_sensor_cfg_x_addr_start = 0 */ - {MISENSOR_16BIT, 0xC804, 0x03CF}, /* cam_sensor_cfg_y_addr_end = 971 */ - {MISENSOR_16BIT, 0xC806, 0x050F}, /* cam_sensor_cfg_x_addr_end = 1291 */ - {MISENSOR_16BIT, 0xC808, 0x02DC}, /* cam_sensor_cfg_pixclk = 48000000 */ - {MISENSOR_16BIT, 0xC80A, 0x6C00}, - {MISENSOR_16BIT, 0xC80C, 0x0001}, /* cam_sensor_cfg_row_speed = 1 */ - /* cam_sensor_cfg_fine_integ_time_min = 219 */ - {MISENSOR_16BIT, 0xC80E, 0x00DB}, - /* cam_sensor_cfg_fine_integ_time_max = 1459 */ - {MISENSOR_16BIT, 0xC810, 0x05B3}, - /* cam_sensor_cfg_frame_length_lines = 1006 */ - {MISENSOR_16BIT, 0xC812, 0x03F6}, - /* cam_sensor_cfg_line_length_pck = 1590 */ - {MISENSOR_16BIT, 0xC814, 0x063E}, - /* cam_sensor_cfg_fine_correction = 96 */ - {MISENSOR_16BIT, 0xC816, 0x0060}, - /* cam_sensor_cfg_cpipe_last_row = 963 */ - {MISENSOR_16BIT, 0xC818, 0x03C3}, - {MISENSOR_16BIT, 0xC826, 0x0020}, /* cam_sensor_cfg_reg_0_data = 32 */ - {MISENSOR_16BIT, 0xC834, 0x0000}, /* cam_sensor_control_read_mode = 0 */ - {MISENSOR_16BIT, 0xC854, 0x0000}, /* cam_crop_window_xoffset = 0 */ - {MISENSOR_16BIT, 0xC856, 0x0000}, /* cam_crop_window_yoffset = 0 */ - {MISENSOR_16BIT, 0xC858, 0x0508}, /* cam_crop_window_width = 1280 */ - {MISENSOR_16BIT, 0xC85A, 0x03C8}, /* cam_crop_window_height = 960 */ - {MISENSOR_8BIT, 0xC85C, 0x03}, /* cam_crop_cropmode = 3 */ - {MISENSOR_16BIT, 0xC868, 0x0508}, /* cam_output_width = 1280 */ - {MISENSOR_16BIT, 0xC86A, 0x03C8}, /* cam_output_height = 960 */ - {MISENSOR_TOK_TERM, 0, 0}, -}; -#endif - -/* [1296x976_30fps_768Mbps] */ -static struct misensor_reg const mt9m114_976P_init[] = { - {MISENSOR_16BIT, 0x98E, 0x1000}, - {MISENSOR_8BIT, 0xC97E, 0x01}, /* cam_sysctl_pll_enable = 1 */ - {MISENSOR_16BIT, 0xC980, 0x0128}, /* cam_sysctl_pll_divider_m_n = 276 */ - {MISENSOR_16BIT, 0xC982, 0x0700}, /* cam_sysctl_pll_divider_p = 1792 */ - {MISENSOR_16BIT, 0xC800, 0x0000}, /* cam_sensor_cfg_y_addr_start = 0 */ - {MISENSOR_16BIT, 0xC802, 0x0000}, /* cam_sensor_cfg_x_addr_start = 0 */ - {MISENSOR_16BIT, 0xC804, 0x03CF}, /* cam_sensor_cfg_y_addr_end = 975 */ - {MISENSOR_16BIT, 0xC806, 0x050F}, /* cam_sensor_cfg_x_addr_end = 1295 */ - {MISENSOR_32BIT, 0xC808, 0x2DC6C00},/* cam_sensor_cfg_pixclk = 480000*/ - {MISENSOR_16BIT, 0xC80C, 0x0001}, /* cam_sensor_cfg_row_speed = 1 */ - /* cam_sensor_cfg_fine_integ_time_min = 219 */ - {MISENSOR_16BIT, 0xC80E, 0x00DB}, - /* 0x062E //cam_sensor_cfg_fine_integ_time_max = 1459 */ - {MISENSOR_16BIT, 0xC810, 0x05B3}, - /* 0x074C //cam_sensor_cfg_frame_length_lines = 1006 */ - {MISENSOR_16BIT, 0xC812, 0x03E5}, - /* 0x06B1 /cam_sensor_cfg_line_length_pck = 1590 */ - {MISENSOR_16BIT, 0xC814, 0x0644}, - /* cam_sensor_cfg_fine_correction = 96 */ - {MISENSOR_16BIT, 0xC816, 0x0060}, - /* cam_sensor_cfg_cpipe_last_row = 963 */ - {MISENSOR_16BIT, 0xC818, 0x03C3}, - {MISENSOR_16BIT, 0xC826, 0x0020}, /* cam_sensor_cfg_reg_0_data = 32 */ - {MISENSOR_16BIT, 0xC834, 0x0000}, /* cam_sensor_control_read_mode = 0 */ - {MISENSOR_16BIT, 0xC854, 0x0000}, /* cam_crop_window_xoffset = 0 */ - {MISENSOR_16BIT, 0xC856, 0x0000}, /* cam_crop_window_yoffset = 0 */ - {MISENSOR_16BIT, 0xC858, 0x0508}, /* cam_crop_window_width = 1288 */ - {MISENSOR_16BIT, 0xC85A, 0x03C8}, /* cam_crop_window_height = 968 */ - {MISENSOR_8BIT, 0xC85C, 0x03}, /* cam_crop_cropmode = 3 */ - {MISENSOR_16BIT, 0xC868, 0x0508}, /* cam_output_width = 1288 */ - {MISENSOR_16BIT, 0xC86A, 0x03C8}, /* cam_output_height = 968 */ - {MISENSOR_8BIT, 0xC878, 0x00}, /* 0x0E //cam_aet_aemode = 0 */ - {MISENSOR_TOK_TERM, 0, 0} -}; - -/* [1296x864_30fps] */ -static struct misensor_reg const mt9m114_864P_init[] = { - {MISENSOR_16BIT, 0x98E, 0x1000}, - {MISENSOR_8BIT, 0xC97E, 0x01}, /* cam_sysctl_pll_enable = 1 */ - {MISENSOR_16BIT, 0xC980, 0x0128}, /* cam_sysctl_pll_divider_m_n = 276 */ - {MISENSOR_16BIT, 0xC982, 0x0700}, /* cam_sysctl_pll_divider_p = 1792 */ - {MISENSOR_16BIT, 0xC800, 0x0038}, /* cam_sensor_cfg_y_addr_start = 56 */ - {MISENSOR_16BIT, 0xC802, 0x0000}, /* cam_sensor_cfg_x_addr_start = 0 */ - {MISENSOR_16BIT, 0xC804, 0x0397}, /* cam_sensor_cfg_y_addr_end = 919 */ - {MISENSOR_16BIT, 0xC806, 0x050F}, /* cam_sensor_cfg_x_addr_end = 1295 */ - /* cam_sensor_cfg_pixclk = 48000000 */ - {MISENSOR_32BIT, 0xC808, 0x2DC6C00}, - {MISENSOR_16BIT, 0xC80C, 0x0001}, /* cam_sensor_cfg_row_speed = 1 */ - /* cam_sensor_cfg_fine_integ_time_min = 219 */ - {MISENSOR_16BIT, 0xC80E, 0x00DB}, - /* cam_sensor_cfg_fine_integ_time_max = 1469 */ - {MISENSOR_16BIT, 0xC810, 0x05BD}, - /* cam_sensor_cfg_frame_length_lines = 1000 */ - {MISENSOR_16BIT, 0xC812, 0x03E8}, - /* cam_sensor_cfg_line_length_pck = 1600 */ - {MISENSOR_16BIT, 0xC814, 0x0640}, - /* cam_sensor_cfg_fine_correction = 96 */ - {MISENSOR_16BIT, 0xC816, 0x0060}, - /* cam_sensor_cfg_cpipe_last_row = 859 */ - {MISENSOR_16BIT, 0xC818, 0x035B}, - {MISENSOR_16BIT, 0xC826, 0x0020}, /* cam_sensor_cfg_reg_0_data = 32 */ - {MISENSOR_16BIT, 0xC834, 0x0000}, /* cam_sensor_control_read_mode = 0 */ - {MISENSOR_16BIT, 0xC854, 0x0000}, /* cam_crop_window_xoffset = 0 */ - {MISENSOR_16BIT, 0xC856, 0x0000}, /* cam_crop_window_yoffset = 0 */ - {MISENSOR_16BIT, 0xC858, 0x0508}, /* cam_crop_window_width = 1288 */ - {MISENSOR_16BIT, 0xC85A, 0x0358}, /* cam_crop_window_height = 856 */ - {MISENSOR_8BIT, 0xC85C, 0x03}, /* cam_crop_cropmode = 3 */ - {MISENSOR_16BIT, 0xC868, 0x0508}, /* cam_output_width = 1288 */ - {MISENSOR_16BIT, 0xC86A, 0x0358}, /* cam_output_height = 856 */ - {MISENSOR_8BIT, 0xC878, 0x00}, /* 0x0E //cam_aet_aemode = 0 */ - {MISENSOR_TOK_TERM, 0, 0} -}; - -/* [1296x736_30fps] */ -static struct misensor_reg const mt9m114_736P_init[] = { - {MISENSOR_16BIT, 0x98E, 0x1000}, - {MISENSOR_8BIT, 0xC97E, 0x01}, /* cam_sysctl_pll_enable = 1 */ - {MISENSOR_16BIT, 0xC980, 0x011F}, /* cam_sysctl_pll_divider_m_n = 287 */ - {MISENSOR_16BIT, 0xC982, 0x0700}, /* cam_sysctl_pll_divider_p = 1792 */ - {MISENSOR_16BIT, 0xC800, 0x0078}, /* cam_sensor_cfg_y_addr_start = 120*/ - {MISENSOR_16BIT, 0xC802, 0x0000}, /* cam_sensor_cfg_x_addr_start = 0 */ - {MISENSOR_16BIT, 0xC804, 0x0357}, /* cam_sensor_cfg_y_addr_end = 855 */ - {MISENSOR_16BIT, 0xC806, 0x050F}, /* cam_sensor_cfg_x_addr_end = 1295 */ - {MISENSOR_32BIT, 0xC808, 0x237A07F}, /* cam_sensor_cfg_pixclk=37199999*/ - {MISENSOR_16BIT, 0xC80C, 0x0001}, /* cam_sensor_cfg_row_speed = 1 */ - /* cam_sensor_cfg_fine_integ_time_min = 219 */ - {MISENSOR_16BIT, 0xC80E, 0x00DB}, - /* 0x062E //cam_sensor_cfg_fine_integ_time_max = 1469 */ - {MISENSOR_16BIT, 0xC810, 0x05BD}, - /* 0x074C //cam_sensor_cfg_frame_length_lines = 775 */ - {MISENSOR_16BIT, 0xC812, 0x0307}, - /* 0x06B1 /cam_sensor_cfg_line_length_pck = 1600 */ - {MISENSOR_16BIT, 0xC814, 0x0640}, - /* cam_sensor_cfg_fine_correction = 96 */ - {MISENSOR_16BIT, 0xC816, 0x0060}, - /* cam_sensor_cfg_cpipe_last_row = 731 */ - {MISENSOR_16BIT, 0xC818, 0x02DB}, - {MISENSOR_16BIT, 0xC826, 0x0020}, /* cam_sensor_cfg_reg_0_data = 32 */ - {MISENSOR_16BIT, 0xC834, 0x0000}, /* cam_sensor_control_read_mode = 0 */ - {MISENSOR_16BIT, 0xC854, 0x0000}, /* cam_crop_window_xoffset = 0 */ - {MISENSOR_16BIT, 0xC856, 0x0000}, /* cam_crop_window_yoffset = 0 */ - {MISENSOR_16BIT, 0xC858, 0x0508}, /* cam_crop_window_width = 1288 */ - {MISENSOR_16BIT, 0xC85A, 0x02D8}, /* cam_crop_window_height = 728 */ - {MISENSOR_8BIT, 0xC85C, 0x03}, /* cam_crop_cropmode = 3 */ - {MISENSOR_16BIT, 0xC868, 0x0508}, /* cam_output_width = 1288 */ - {MISENSOR_16BIT, 0xC86A, 0x02D8}, /* cam_output_height = 728 */ - {MISENSOR_8BIT, 0xC878, 0x00}, /* 0x0E //cam_aet_aemode = 0 */ - {MISENSOR_TOK_TERM, 0, 0} -}; - -/* [736x496_30fps_768Mbps] */ -#if 0 /* Currently unused */ -static struct misensor_reg const mt9m114_720_480P_init[] = { - {MISENSOR_16BIT, 0x98E, 0x1000}, - {MISENSOR_8BIT, 0xC97E, 0x01}, /* cam_sysctl_pll_enable = 1 */ - {MISENSOR_16BIT, 0xC980, 0x0128}, /* cam_sysctl_pll_divider_m_n = 276 */ - {MISENSOR_16BIT, 0xC982, 0x0700}, /* cam_sysctl_pll_divider_p = 1792 */ - {MISENSOR_16BIT, 0xC800, 0x00F0}, /* cam_sensor_cfg_y_addr_start = 240*/ - {MISENSOR_16BIT, 0xC802, 0x0118}, /* cam_sensor_cfg_x_addr_start = 280*/ - {MISENSOR_16BIT, 0xC804, 0x02DF}, /* cam_sensor_cfg_y_addr_end = 735 */ - {MISENSOR_16BIT, 0xC806, 0x03F7}, /* cam_sensor_cfg_x_addr_end = 1015 */ - /* cam_sensor_cfg_pixclk = 48000000 */ - {MISENSOR_32BIT, 0xC808, 0x2DC6C00}, - {MISENSOR_16BIT, 0xC80C, 0x0001}, /* cam_sensor_cfg_row_speed = 1 */ - /* cam_sensor_cfg_fine_integ_time_min = 219 */ - {MISENSOR_16BIT, 0xC80E, 0x00DB}, - /* 0x062E //cam_sensor_cfg_fine_integ_time_max = 1459 */ - {MISENSOR_16BIT, 0xC810, 0x05B3}, - /* 0x074C //cam_sensor_cfg_frame_length_lines = 997 */ - {MISENSOR_16BIT, 0xC812, 0x03E5}, - /* 0x06B1 /cam_sensor_cfg_line_length_pck = 1604 */ - {MISENSOR_16BIT, 0xC814, 0x0644}, - /* cam_sensor_cfg_fine_correction = 96 */ - {MISENSOR_16BIT, 0xC816, 0x0060}, - {MISENSOR_16BIT, 0xC818, 0x03C3}, /* cam_sensor_cfg_cpipe_last_row=963*/ - {MISENSOR_16BIT, 0xC826, 0x0020}, /* cam_sensor_cfg_reg_0_data = 32 */ - {MISENSOR_16BIT, 0xC834, 0x0000}, /* cam_sensor_control_read_mode = 0*/ - {MISENSOR_16BIT, 0xC854, 0x0000}, /* cam_crop_window_xoffset = 0 */ - {MISENSOR_16BIT, 0xC856, 0x0000}, /* cam_crop_window_yoffset = 0 */ - {MISENSOR_16BIT, 0xC858, 0x02D8}, /* cam_crop_window_width = 728 */ - {MISENSOR_16BIT, 0xC85A, 0x01E8}, /* cam_crop_window_height = 488 */ - {MISENSOR_8BIT, 0xC85C, 0x03}, /* cam_crop_cropmode = 3 */ - {MISENSOR_16BIT, 0xC868, 0x02D8}, /* cam_output_width = 728 */ - {MISENSOR_16BIT, 0xC86A, 0x01E8}, /* cam_output_height = 488 */ - {MISENSOR_8BIT, 0xC878, 0x00}, /* 0x0E //cam_aet_aemode = 0 */ - {MISENSOR_TOK_TERM, 0, 0} -}; -#endif - -static struct misensor_reg const mt9m114_common[] = { - /* reset */ - {MISENSOR_16BIT, 0x301A, 0x0234}, - /* LOAD = Step2-PLL_Timing //PLL and Timing */ - {MISENSOR_16BIT, 0x098E, 0x1000}, /* LOGICAL_ADDRESS_ACCESS */ - {MISENSOR_8BIT, 0xC97E, 0x01}, /* cam_sysctl_pll_enable = 1 */ - {MISENSOR_16BIT, 0xC980, 0x0128}, /* cam_sysctl_pll_divider_m_n = 276 */ - {MISENSOR_16BIT, 0xC982, 0x0700}, /* cam_sysctl_pll_divider_p = 1792 */ - {MISENSOR_16BIT, 0xC800, 0x0000}, /* cam_sensor_cfg_y_addr_start = 216*/ - {MISENSOR_16BIT, 0xC802, 0x0000}, /* cam_sensor_cfg_x_addr_start = 168*/ - {MISENSOR_16BIT, 0xC804, 0x03CD}, /* cam_sensor_cfg_y_addr_end = 761 */ - {MISENSOR_16BIT, 0xC806, 0x050D}, /* cam_sensor_cfg_x_addr_end = 1127 */ - {MISENSOR_16BIT, 0xC808, 0x02DC}, /* cam_sensor_cfg_pixclk = 24000000 */ - {MISENSOR_16BIT, 0xC80A, 0x6C00}, - {MISENSOR_16BIT, 0xC80C, 0x0001}, /* cam_sensor_cfg_row_speed = 1 */ - /* cam_sensor_cfg_fine_integ_time_min = 219 */ - {MISENSOR_16BIT, 0xC80E, 0x01C3}, - /* cam_sensor_cfg_fine_integ_time_max = 1149 */ - {MISENSOR_16BIT, 0xC810, 0x03F7}, - /* cam_sensor_cfg_frame_length_lines = 625 */ - {MISENSOR_16BIT, 0xC812, 0x0500}, - /* cam_sensor_cfg_line_length_pck = 1280 */ - {MISENSOR_16BIT, 0xC814, 0x04E2}, - /* cam_sensor_cfg_fine_correction = 96 */ - {MISENSOR_16BIT, 0xC816, 0x00E0}, - /* cam_sensor_cfg_cpipe_last_row = 541 */ - {MISENSOR_16BIT, 0xC818, 0x01E3}, - {MISENSOR_16BIT, 0xC826, 0x0020}, /* cam_sensor_cfg_reg_0_data = 32 */ - {MISENSOR_16BIT, 0xC834, 0x0330}, /* cam_sensor_control_read_mode = 0 */ - {MISENSOR_16BIT, 0xC854, 0x0000}, /* cam_crop_window_xoffset = 0 */ - {MISENSOR_16BIT, 0xC856, 0x0000}, /* cam_crop_window_yoffset = 0 */ - {MISENSOR_16BIT, 0xC858, 0x0280}, /* cam_crop_window_width = 952 */ - {MISENSOR_16BIT, 0xC85A, 0x01E0}, /* cam_crop_window_height = 538 */ - {MISENSOR_8BIT, 0xC85C, 0x03}, /* cam_crop_cropmode = 3 */ - {MISENSOR_16BIT, 0xC868, 0x0280}, /* cam_output_width = 952 */ - {MISENSOR_16BIT, 0xC86A, 0x01E0}, /* cam_output_height = 538 */ - /* - * LOAD = Step3-Recommended - * Patch, Errata and Sensor optimization Setting - */ - {MISENSOR_16BIT, 0x316A, 0x8270}, /* DAC_TXLO_ROW */ - {MISENSOR_16BIT, 0x316C, 0x8270}, /* DAC_TXLO */ - {MISENSOR_16BIT, 0x3ED0, 0x2305}, /* DAC_LD_4_5 */ - {MISENSOR_16BIT, 0x3ED2, 0x77CF}, /* DAC_LD_6_7 */ - {MISENSOR_16BIT, 0x316E, 0x8202}, /* DAC_ECL */ - {MISENSOR_16BIT, 0x3180, 0x87FF}, /* DELTA_DK_CONTROL */ - {MISENSOR_16BIT, 0x30D4, 0x6080}, /* COLUMN_CORRECTION */ - {MISENSOR_16BIT, 0xA802, 0x0008}, /* AE_TRACK_MODE */ - {MISENSOR_16BIT, 0x3E14, 0xFF39}, /* SAMP_COL_PUP2 */ - {MISENSOR_16BIT, 0x31E0, 0x0003}, /* PIX_DEF_ID */ - /* LOAD = Step8-Features //Ports, special features, etc. */ - {MISENSOR_16BIT, 0x098E, 0x0000}, /* LOGICAL_ADDRESS_ACCESS */ - {MISENSOR_16BIT, 0x001E, 0x0777}, /* PAD_SLEW */ - {MISENSOR_16BIT, 0x098E, 0x0000}, /* LOGICAL_ADDRESS_ACCESS */ - {MISENSOR_16BIT, 0xC984, 0x8001}, /* CAM_PORT_OUTPUT_CONTROL */ - {MISENSOR_16BIT, 0xC988, 0x0F00}, /* CAM_PORT_MIPI_TIMING_T_HS_ZERO */ - /* CAM_PORT_MIPI_TIMING_T_HS_EXIT_HS_TRAIL */ - {MISENSOR_16BIT, 0xC98A, 0x0B07}, - /* CAM_PORT_MIPI_TIMING_T_CLK_POST_CLK_PRE */ - {MISENSOR_16BIT, 0xC98C, 0x0D01}, - /* CAM_PORT_MIPI_TIMING_T_CLK_TRAIL_CLK_ZERO */ - {MISENSOR_16BIT, 0xC98E, 0x071D}, - {MISENSOR_16BIT, 0xC990, 0x0006}, /* CAM_PORT_MIPI_TIMING_T_LPX */ - {MISENSOR_16BIT, 0xC992, 0x0A0C}, /* CAM_PORT_MIPI_TIMING_INIT_TIMING */ - {MISENSOR_16BIT, 0x3C5A, 0x0009}, /* MIPI_DELAY_TRIM */ - {MISENSOR_16BIT, 0xC86C, 0x0210}, /* CAM_OUTPUT_FORMAT */ - {MISENSOR_16BIT, 0xA804, 0x0000}, /* AE_TRACK_ALGO */ - /* default exposure */ - {MISENSOR_16BIT, 0x3012, 0x0110}, /* COMMAND_REGISTER */ - {MISENSOR_TOK_TERM, 0, 0}, - -}; - -#if 0 /* Currently unused */ -static struct misensor_reg const mt9m114_antiflicker_50hz[] = { - {MISENSOR_16BIT, 0x098E, 0xC88B}, - {MISENSOR_8BIT, 0xC88B, 0x32}, - {MISENSOR_8BIT, 0xDC00, 0x28}, - {MISENSOR_16BIT, 0x0080, 0x8002}, - {MISENSOR_TOK_TERM, 0, 0} -}; - -static struct misensor_reg const mt9m114_antiflicker_60hz[] = { - {MISENSOR_16BIT, 0x098E, 0xC88B}, - {MISENSOR_8BIT, 0xC88B, 0x3C}, - {MISENSOR_8BIT, 0xDC00, 0x28}, - {MISENSOR_16BIT, 0x0080, 0x8002}, - {MISENSOR_TOK_TERM, 0, 0} -}; - -static struct misensor_reg const mt9m114_iq[] = { - /* [Step3-Recommended] [Sensor optimization] */ - {MISENSOR_16BIT, 0x316A, 0x8270}, - {MISENSOR_16BIT, 0x316C, 0x8270}, - {MISENSOR_16BIT, 0x3ED0, 0x2305}, - {MISENSOR_16BIT, 0x3ED2, 0x77CF}, - {MISENSOR_16BIT, 0x316E, 0x8202}, - {MISENSOR_16BIT, 0x3180, 0x87FF}, - {MISENSOR_16BIT, 0x30D4, 0x6080}, - {MISENSOR_16BIT, 0xA802, 0x0008}, - - /* This register is from vender to avoid low light color noise */ - {MISENSOR_16BIT, 0x31E0, 0x0001}, - - /* LOAD=Errata item 1 */ - {MISENSOR_16BIT, 0x3E14, 0xFF39}, - - /* LOAD=Errata item 2 */ - {MISENSOR_16BIT, 0x301A, 0x8234}, - - /* - * LOAD=Errata item 3 - * LOAD=Patch 0202; - * Feature Recommended; Black level correction fix - */ - {MISENSOR_16BIT, 0x0982, 0x0001}, - {MISENSOR_16BIT, 0x098A, 0x5000}, - {MISENSOR_16BIT, 0xD000, 0x70CF}, - {MISENSOR_16BIT, 0xD002, 0xFFFF}, - {MISENSOR_16BIT, 0xD004, 0xC5D4}, - {MISENSOR_16BIT, 0xD006, 0x903A}, - {MISENSOR_16BIT, 0xD008, 0x2144}, - {MISENSOR_16BIT, 0xD00A, 0x0C00}, - {MISENSOR_16BIT, 0xD00C, 0x2186}, - {MISENSOR_16BIT, 0xD00E, 0x0FF3}, - {MISENSOR_16BIT, 0xD010, 0xB844}, - {MISENSOR_16BIT, 0xD012, 0xB948}, - {MISENSOR_16BIT, 0xD014, 0xE082}, - {MISENSOR_16BIT, 0xD016, 0x20CC}, - {MISENSOR_16BIT, 0xD018, 0x80E2}, - {MISENSOR_16BIT, 0xD01A, 0x21CC}, - {MISENSOR_16BIT, 0xD01C, 0x80A2}, - {MISENSOR_16BIT, 0xD01E, 0x21CC}, - {MISENSOR_16BIT, 0xD020, 0x80E2}, - {MISENSOR_16BIT, 0xD022, 0xF404}, - {MISENSOR_16BIT, 0xD024, 0xD801}, - {MISENSOR_16BIT, 0xD026, 0xF003}, - {MISENSOR_16BIT, 0xD028, 0xD800}, - {MISENSOR_16BIT, 0xD02A, 0x7EE0}, - {MISENSOR_16BIT, 0xD02C, 0xC0F1}, - {MISENSOR_16BIT, 0xD02E, 0x08BA}, - - {MISENSOR_16BIT, 0xD030, 0x0600}, - {MISENSOR_16BIT, 0xD032, 0xC1A1}, - {MISENSOR_16BIT, 0xD034, 0x76CF}, - {MISENSOR_16BIT, 0xD036, 0xFFFF}, - {MISENSOR_16BIT, 0xD038, 0xC130}, - {MISENSOR_16BIT, 0xD03A, 0x6E04}, - {MISENSOR_16BIT, 0xD03C, 0xC040}, - {MISENSOR_16BIT, 0xD03E, 0x71CF}, - {MISENSOR_16BIT, 0xD040, 0xFFFF}, - {MISENSOR_16BIT, 0xD042, 0xC790}, - {MISENSOR_16BIT, 0xD044, 0x8103}, - {MISENSOR_16BIT, 0xD046, 0x77CF}, - {MISENSOR_16BIT, 0xD048, 0xFFFF}, - {MISENSOR_16BIT, 0xD04A, 0xC7C0}, - {MISENSOR_16BIT, 0xD04C, 0xE001}, - {MISENSOR_16BIT, 0xD04E, 0xA103}, - {MISENSOR_16BIT, 0xD050, 0xD800}, - {MISENSOR_16BIT, 0xD052, 0x0C6A}, - {MISENSOR_16BIT, 0xD054, 0x04E0}, - {MISENSOR_16BIT, 0xD056, 0xB89E}, - {MISENSOR_16BIT, 0xD058, 0x7508}, - {MISENSOR_16BIT, 0xD05A, 0x8E1C}, - {MISENSOR_16BIT, 0xD05C, 0x0809}, - {MISENSOR_16BIT, 0xD05E, 0x0191}, - - {MISENSOR_16BIT, 0xD060, 0xD801}, - {MISENSOR_16BIT, 0xD062, 0xAE1D}, - {MISENSOR_16BIT, 0xD064, 0xE580}, - {MISENSOR_16BIT, 0xD066, 0x20CA}, - {MISENSOR_16BIT, 0xD068, 0x0022}, - {MISENSOR_16BIT, 0xD06A, 0x20CF}, - {MISENSOR_16BIT, 0xD06C, 0x0522}, - {MISENSOR_16BIT, 0xD06E, 0x0C5C}, - {MISENSOR_16BIT, 0xD070, 0x04E2}, - {MISENSOR_16BIT, 0xD072, 0x21CA}, - {MISENSOR_16BIT, 0xD074, 0x0062}, - {MISENSOR_16BIT, 0xD076, 0xE580}, - {MISENSOR_16BIT, 0xD078, 0xD901}, - {MISENSOR_16BIT, 0xD07A, 0x79C0}, - {MISENSOR_16BIT, 0xD07C, 0xD800}, - {MISENSOR_16BIT, 0xD07E, 0x0BE6}, - {MISENSOR_16BIT, 0xD080, 0x04E0}, - {MISENSOR_16BIT, 0xD082, 0xB89E}, - {MISENSOR_16BIT, 0xD084, 0x70CF}, - {MISENSOR_16BIT, 0xD086, 0xFFFF}, - {MISENSOR_16BIT, 0xD088, 0xC8D4}, - {MISENSOR_16BIT, 0xD08A, 0x9002}, - {MISENSOR_16BIT, 0xD08C, 0x0857}, - {MISENSOR_16BIT, 0xD08E, 0x025E}, - - {MISENSOR_16BIT, 0xD090, 0xFFDC}, - {MISENSOR_16BIT, 0xD092, 0xE080}, - {MISENSOR_16BIT, 0xD094, 0x25CC}, - {MISENSOR_16BIT, 0xD096, 0x9022}, - {MISENSOR_16BIT, 0xD098, 0xF225}, - {MISENSOR_16BIT, 0xD09A, 0x1700}, - {MISENSOR_16BIT, 0xD09C, 0x108A}, - {MISENSOR_16BIT, 0xD09E, 0x73CF}, - {MISENSOR_16BIT, 0xD0A0, 0xFF00}, - {MISENSOR_16BIT, 0xD0A2, 0x3174}, - {MISENSOR_16BIT, 0xD0A4, 0x9307}, - {MISENSOR_16BIT, 0xD0A6, 0x2A04}, - {MISENSOR_16BIT, 0xD0A8, 0x103E}, - {MISENSOR_16BIT, 0xD0AA, 0x9328}, - {MISENSOR_16BIT, 0xD0AC, 0x2942}, - {MISENSOR_16BIT, 0xD0AE, 0x7140}, - {MISENSOR_16BIT, 0xD0B0, 0x2A04}, - {MISENSOR_16BIT, 0xD0B2, 0x107E}, - {MISENSOR_16BIT, 0xD0B4, 0x9349}, - {MISENSOR_16BIT, 0xD0B6, 0x2942}, - {MISENSOR_16BIT, 0xD0B8, 0x7141}, - {MISENSOR_16BIT, 0xD0BA, 0x2A04}, - {MISENSOR_16BIT, 0xD0BC, 0x10BE}, - {MISENSOR_16BIT, 0xD0BE, 0x934A}, - - {MISENSOR_16BIT, 0xD0C0, 0x2942}, - {MISENSOR_16BIT, 0xD0C2, 0x714B}, - {MISENSOR_16BIT, 0xD0C4, 0x2A04}, - {MISENSOR_16BIT, 0xD0C6, 0x10BE}, - {MISENSOR_16BIT, 0xD0C8, 0x130C}, - {MISENSOR_16BIT, 0xD0CA, 0x010A}, - {MISENSOR_16BIT, 0xD0CC, 0x2942}, - {MISENSOR_16BIT, 0xD0CE, 0x7142}, - {MISENSOR_16BIT, 0xD0D0, 0x2250}, - {MISENSOR_16BIT, 0xD0D2, 0x13CA}, - {MISENSOR_16BIT, 0xD0D4, 0x1B0C}, - {MISENSOR_16BIT, 0xD0D6, 0x0284}, - {MISENSOR_16BIT, 0xD0D8, 0xB307}, - {MISENSOR_16BIT, 0xD0DA, 0xB328}, - {MISENSOR_16BIT, 0xD0DC, 0x1B12}, - {MISENSOR_16BIT, 0xD0DE, 0x02C4}, - {MISENSOR_16BIT, 0xD0E0, 0xB34A}, - {MISENSOR_16BIT, 0xD0E2, 0xED88}, - {MISENSOR_16BIT, 0xD0E4, 0x71CF}, - {MISENSOR_16BIT, 0xD0E6, 0xFF00}, - {MISENSOR_16BIT, 0xD0E8, 0x3174}, - {MISENSOR_16BIT, 0xD0EA, 0x9106}, - {MISENSOR_16BIT, 0xD0EC, 0xB88F}, - {MISENSOR_16BIT, 0xD0EE, 0xB106}, - - {MISENSOR_16BIT, 0xD0F0, 0x210A}, - {MISENSOR_16BIT, 0xD0F2, 0x8340}, - {MISENSOR_16BIT, 0xD0F4, 0xC000}, - {MISENSOR_16BIT, 0xD0F6, 0x21CA}, - {MISENSOR_16BIT, 0xD0F8, 0x0062}, - {MISENSOR_16BIT, 0xD0FA, 0x20F0}, - {MISENSOR_16BIT, 0xD0FC, 0x0040}, - {MISENSOR_16BIT, 0xD0FE, 0x0B02}, - {MISENSOR_16BIT, 0xD100, 0x0320}, - {MISENSOR_16BIT, 0xD102, 0xD901}, - {MISENSOR_16BIT, 0xD104, 0x07F1}, - {MISENSOR_16BIT, 0xD106, 0x05E0}, - {MISENSOR_16BIT, 0xD108, 0xC0A1}, - {MISENSOR_16BIT, 0xD10A, 0x78E0}, - {MISENSOR_16BIT, 0xD10C, 0xC0F1}, - {MISENSOR_16BIT, 0xD10E, 0x71CF}, - {MISENSOR_16BIT, 0xD110, 0xFFFF}, - {MISENSOR_16BIT, 0xD112, 0xC7C0}, - {MISENSOR_16BIT, 0xD114, 0xD840}, - {MISENSOR_16BIT, 0xD116, 0xA900}, - {MISENSOR_16BIT, 0xD118, 0x71CF}, - {MISENSOR_16BIT, 0xD11A, 0xFFFF}, - {MISENSOR_16BIT, 0xD11C, 0xD02C}, - {MISENSOR_16BIT, 0xD11E, 0xD81E}, - - {MISENSOR_16BIT, 0xD120, 0x0A5A}, - {MISENSOR_16BIT, 0xD122, 0x04E0}, - {MISENSOR_16BIT, 0xD124, 0xDA00}, - {MISENSOR_16BIT, 0xD126, 0xD800}, - {MISENSOR_16BIT, 0xD128, 0xC0D1}, - {MISENSOR_16BIT, 0xD12A, 0x7EE0}, - - {MISENSOR_16BIT, 0x098E, 0x0000}, - {MISENSOR_16BIT, 0xE000, 0x010C}, - {MISENSOR_16BIT, 0xE002, 0x0202}, - {MISENSOR_16BIT, 0xE004, 0x4103}, - {MISENSOR_16BIT, 0xE006, 0x0202}, - {MISENSOR_16BIT, 0x0080, 0xFFF0}, - {MISENSOR_16BIT, 0x0080, 0xFFF1}, - - /* LOAD=Patch 0302; Feature Recommended; Adaptive Sensitivity */ - {MISENSOR_16BIT, 0x0982, 0x0001}, - {MISENSOR_16BIT, 0x098A, 0x512C}, - {MISENSOR_16BIT, 0xD12C, 0x70CF}, - {MISENSOR_16BIT, 0xD12E, 0xFFFF}, - {MISENSOR_16BIT, 0xD130, 0xC5D4}, - {MISENSOR_16BIT, 0xD132, 0x903A}, - {MISENSOR_16BIT, 0xD134, 0x2144}, - {MISENSOR_16BIT, 0xD136, 0x0C00}, - {MISENSOR_16BIT, 0xD138, 0x2186}, - {MISENSOR_16BIT, 0xD13A, 0x0FF3}, - {MISENSOR_16BIT, 0xD13C, 0xB844}, - {MISENSOR_16BIT, 0xD13E, 0x262F}, - {MISENSOR_16BIT, 0xD140, 0xF008}, - {MISENSOR_16BIT, 0xD142, 0xB948}, - {MISENSOR_16BIT, 0xD144, 0x21CC}, - {MISENSOR_16BIT, 0xD146, 0x8021}, - {MISENSOR_16BIT, 0xD148, 0xD801}, - {MISENSOR_16BIT, 0xD14A, 0xF203}, - {MISENSOR_16BIT, 0xD14C, 0xD800}, - {MISENSOR_16BIT, 0xD14E, 0x7EE0}, - {MISENSOR_16BIT, 0xD150, 0xC0F1}, - {MISENSOR_16BIT, 0xD152, 0x71CF}, - {MISENSOR_16BIT, 0xD154, 0xFFFF}, - {MISENSOR_16BIT, 0xD156, 0xC610}, - {MISENSOR_16BIT, 0xD158, 0x910E}, - {MISENSOR_16BIT, 0xD15A, 0x208C}, - {MISENSOR_16BIT, 0xD15C, 0x8014}, - {MISENSOR_16BIT, 0xD15E, 0xF418}, - {MISENSOR_16BIT, 0xD160, 0x910F}, - {MISENSOR_16BIT, 0xD162, 0x208C}, - {MISENSOR_16BIT, 0xD164, 0x800F}, - {MISENSOR_16BIT, 0xD166, 0xF414}, - {MISENSOR_16BIT, 0xD168, 0x9116}, - {MISENSOR_16BIT, 0xD16A, 0x208C}, - {MISENSOR_16BIT, 0xD16C, 0x800A}, - {MISENSOR_16BIT, 0xD16E, 0xF410}, - {MISENSOR_16BIT, 0xD170, 0x9117}, - {MISENSOR_16BIT, 0xD172, 0x208C}, - {MISENSOR_16BIT, 0xD174, 0x8807}, - {MISENSOR_16BIT, 0xD176, 0xF40C}, - {MISENSOR_16BIT, 0xD178, 0x9118}, - {MISENSOR_16BIT, 0xD17A, 0x2086}, - {MISENSOR_16BIT, 0xD17C, 0x0FF3}, - {MISENSOR_16BIT, 0xD17E, 0xB848}, - {MISENSOR_16BIT, 0xD180, 0x080D}, - {MISENSOR_16BIT, 0xD182, 0x0090}, - {MISENSOR_16BIT, 0xD184, 0xFFEA}, - {MISENSOR_16BIT, 0xD186, 0xE081}, - {MISENSOR_16BIT, 0xD188, 0xD801}, - {MISENSOR_16BIT, 0xD18A, 0xF203}, - {MISENSOR_16BIT, 0xD18C, 0xD800}, - {MISENSOR_16BIT, 0xD18E, 0xC0D1}, - {MISENSOR_16BIT, 0xD190, 0x7EE0}, - {MISENSOR_16BIT, 0xD192, 0x78E0}, - {MISENSOR_16BIT, 0xD194, 0xC0F1}, - {MISENSOR_16BIT, 0xD196, 0x71CF}, - {MISENSOR_16BIT, 0xD198, 0xFFFF}, - {MISENSOR_16BIT, 0xD19A, 0xC610}, - {MISENSOR_16BIT, 0xD19C, 0x910E}, - {MISENSOR_16BIT, 0xD19E, 0x208C}, - {MISENSOR_16BIT, 0xD1A0, 0x800A}, - {MISENSOR_16BIT, 0xD1A2, 0xF418}, - {MISENSOR_16BIT, 0xD1A4, 0x910F}, - {MISENSOR_16BIT, 0xD1A6, 0x208C}, - {MISENSOR_16BIT, 0xD1A8, 0x8807}, - {MISENSOR_16BIT, 0xD1AA, 0xF414}, - {MISENSOR_16BIT, 0xD1AC, 0x9116}, - {MISENSOR_16BIT, 0xD1AE, 0x208C}, - {MISENSOR_16BIT, 0xD1B0, 0x800A}, - {MISENSOR_16BIT, 0xD1B2, 0xF410}, - {MISENSOR_16BIT, 0xD1B4, 0x9117}, - {MISENSOR_16BIT, 0xD1B6, 0x208C}, - {MISENSOR_16BIT, 0xD1B8, 0x8807}, - {MISENSOR_16BIT, 0xD1BA, 0xF40C}, - {MISENSOR_16BIT, 0xD1BC, 0x9118}, - {MISENSOR_16BIT, 0xD1BE, 0x2086}, - {MISENSOR_16BIT, 0xD1C0, 0x0FF3}, - {MISENSOR_16BIT, 0xD1C2, 0xB848}, - {MISENSOR_16BIT, 0xD1C4, 0x080D}, - {MISENSOR_16BIT, 0xD1C6, 0x0090}, - {MISENSOR_16BIT, 0xD1C8, 0xFFD9}, - {MISENSOR_16BIT, 0xD1CA, 0xE080}, - {MISENSOR_16BIT, 0xD1CC, 0xD801}, - {MISENSOR_16BIT, 0xD1CE, 0xF203}, - {MISENSOR_16BIT, 0xD1D0, 0xD800}, - {MISENSOR_16BIT, 0xD1D2, 0xF1DF}, - {MISENSOR_16BIT, 0xD1D4, 0x9040}, - {MISENSOR_16BIT, 0xD1D6, 0x71CF}, - {MISENSOR_16BIT, 0xD1D8, 0xFFFF}, - {MISENSOR_16BIT, 0xD1DA, 0xC5D4}, - {MISENSOR_16BIT, 0xD1DC, 0xB15A}, - {MISENSOR_16BIT, 0xD1DE, 0x9041}, - {MISENSOR_16BIT, 0xD1E0, 0x73CF}, - {MISENSOR_16BIT, 0xD1E2, 0xFFFF}, - {MISENSOR_16BIT, 0xD1E4, 0xC7D0}, - {MISENSOR_16BIT, 0xD1E6, 0xB140}, - {MISENSOR_16BIT, 0xD1E8, 0x9042}, - {MISENSOR_16BIT, 0xD1EA, 0xB141}, - {MISENSOR_16BIT, 0xD1EC, 0x9043}, - {MISENSOR_16BIT, 0xD1EE, 0xB142}, - {MISENSOR_16BIT, 0xD1F0, 0x9044}, - {MISENSOR_16BIT, 0xD1F2, 0xB143}, - {MISENSOR_16BIT, 0xD1F4, 0x9045}, - {MISENSOR_16BIT, 0xD1F6, 0xB147}, - {MISENSOR_16BIT, 0xD1F8, 0x9046}, - {MISENSOR_16BIT, 0xD1FA, 0xB148}, - {MISENSOR_16BIT, 0xD1FC, 0x9047}, - {MISENSOR_16BIT, 0xD1FE, 0xB14B}, - {MISENSOR_16BIT, 0xD200, 0x9048}, - {MISENSOR_16BIT, 0xD202, 0xB14C}, - {MISENSOR_16BIT, 0xD204, 0x9049}, - {MISENSOR_16BIT, 0xD206, 0x1958}, - {MISENSOR_16BIT, 0xD208, 0x0084}, - {MISENSOR_16BIT, 0xD20A, 0x904A}, - {MISENSOR_16BIT, 0xD20C, 0x195A}, - {MISENSOR_16BIT, 0xD20E, 0x0084}, - {MISENSOR_16BIT, 0xD210, 0x8856}, - {MISENSOR_16BIT, 0xD212, 0x1B36}, - {MISENSOR_16BIT, 0xD214, 0x8082}, - {MISENSOR_16BIT, 0xD216, 0x8857}, - {MISENSOR_16BIT, 0xD218, 0x1B37}, - {MISENSOR_16BIT, 0xD21A, 0x8082}, - {MISENSOR_16BIT, 0xD21C, 0x904C}, - {MISENSOR_16BIT, 0xD21E, 0x19A7}, - {MISENSOR_16BIT, 0xD220, 0x009C}, - {MISENSOR_16BIT, 0xD222, 0x881A}, - {MISENSOR_16BIT, 0xD224, 0x7FE0}, - {MISENSOR_16BIT, 0xD226, 0x1B54}, - {MISENSOR_16BIT, 0xD228, 0x8002}, - {MISENSOR_16BIT, 0xD22A, 0x78E0}, - {MISENSOR_16BIT, 0xD22C, 0x71CF}, - {MISENSOR_16BIT, 0xD22E, 0xFFFF}, - {MISENSOR_16BIT, 0xD230, 0xC350}, - {MISENSOR_16BIT, 0xD232, 0xD828}, - {MISENSOR_16BIT, 0xD234, 0xA90B}, - {MISENSOR_16BIT, 0xD236, 0x8100}, - {MISENSOR_16BIT, 0xD238, 0x01C5}, - {MISENSOR_16BIT, 0xD23A, 0x0320}, - {MISENSOR_16BIT, 0xD23C, 0xD900}, - {MISENSOR_16BIT, 0xD23E, 0x78E0}, - {MISENSOR_16BIT, 0xD240, 0x220A}, - {MISENSOR_16BIT, 0xD242, 0x1F80}, - {MISENSOR_16BIT, 0xD244, 0xFFFF}, - {MISENSOR_16BIT, 0xD246, 0xD4E0}, - {MISENSOR_16BIT, 0xD248, 0xC0F1}, - {MISENSOR_16BIT, 0xD24A, 0x0811}, - {MISENSOR_16BIT, 0xD24C, 0x0051}, - {MISENSOR_16BIT, 0xD24E, 0x2240}, - {MISENSOR_16BIT, 0xD250, 0x1200}, - {MISENSOR_16BIT, 0xD252, 0xFFE1}, - {MISENSOR_16BIT, 0xD254, 0xD801}, - {MISENSOR_16BIT, 0xD256, 0xF006}, - {MISENSOR_16BIT, 0xD258, 0x2240}, - {MISENSOR_16BIT, 0xD25A, 0x1900}, - {MISENSOR_16BIT, 0xD25C, 0xFFDE}, - {MISENSOR_16BIT, 0xD25E, 0xD802}, - {MISENSOR_16BIT, 0xD260, 0x1A05}, - {MISENSOR_16BIT, 0xD262, 0x1002}, - {MISENSOR_16BIT, 0xD264, 0xFFF2}, - {MISENSOR_16BIT, 0xD266, 0xF195}, - {MISENSOR_16BIT, 0xD268, 0xC0F1}, - {MISENSOR_16BIT, 0xD26A, 0x0E7E}, - {MISENSOR_16BIT, 0xD26C, 0x05C0}, - {MISENSOR_16BIT, 0xD26E, 0x75CF}, - {MISENSOR_16BIT, 0xD270, 0xFFFF}, - {MISENSOR_16BIT, 0xD272, 0xC84C}, - {MISENSOR_16BIT, 0xD274, 0x9502}, - {MISENSOR_16BIT, 0xD276, 0x77CF}, - {MISENSOR_16BIT, 0xD278, 0xFFFF}, - {MISENSOR_16BIT, 0xD27A, 0xC344}, - {MISENSOR_16BIT, 0xD27C, 0x2044}, - {MISENSOR_16BIT, 0xD27E, 0x008E}, - {MISENSOR_16BIT, 0xD280, 0xB8A1}, - {MISENSOR_16BIT, 0xD282, 0x0926}, - {MISENSOR_16BIT, 0xD284, 0x03E0}, - {MISENSOR_16BIT, 0xD286, 0xB502}, - {MISENSOR_16BIT, 0xD288, 0x9502}, - {MISENSOR_16BIT, 0xD28A, 0x952E}, - {MISENSOR_16BIT, 0xD28C, 0x7E05}, - {MISENSOR_16BIT, 0xD28E, 0xB5C2}, - {MISENSOR_16BIT, 0xD290, 0x70CF}, - {MISENSOR_16BIT, 0xD292, 0xFFFF}, - {MISENSOR_16BIT, 0xD294, 0xC610}, - {MISENSOR_16BIT, 0xD296, 0x099A}, - {MISENSOR_16BIT, 0xD298, 0x04A0}, - {MISENSOR_16BIT, 0xD29A, 0xB026}, - {MISENSOR_16BIT, 0xD29C, 0x0E02}, - {MISENSOR_16BIT, 0xD29E, 0x0560}, - {MISENSOR_16BIT, 0xD2A0, 0xDE00}, - {MISENSOR_16BIT, 0xD2A2, 0x0A12}, - {MISENSOR_16BIT, 0xD2A4, 0x0320}, - {MISENSOR_16BIT, 0xD2A6, 0xB7C4}, - {MISENSOR_16BIT, 0xD2A8, 0x0B36}, - {MISENSOR_16BIT, 0xD2AA, 0x03A0}, - {MISENSOR_16BIT, 0xD2AC, 0x70C9}, - {MISENSOR_16BIT, 0xD2AE, 0x9502}, - {MISENSOR_16BIT, 0xD2B0, 0x7608}, - {MISENSOR_16BIT, 0xD2B2, 0xB8A8}, - {MISENSOR_16BIT, 0xD2B4, 0xB502}, - {MISENSOR_16BIT, 0xD2B6, 0x70CF}, - {MISENSOR_16BIT, 0xD2B8, 0x0000}, - {MISENSOR_16BIT, 0xD2BA, 0x5536}, - {MISENSOR_16BIT, 0xD2BC, 0x7860}, - {MISENSOR_16BIT, 0xD2BE, 0x2686}, - {MISENSOR_16BIT, 0xD2C0, 0x1FFB}, - {MISENSOR_16BIT, 0xD2C2, 0x9502}, - {MISENSOR_16BIT, 0xD2C4, 0x78C5}, - {MISENSOR_16BIT, 0xD2C6, 0x0631}, - {MISENSOR_16BIT, 0xD2C8, 0x05E0}, - {MISENSOR_16BIT, 0xD2CA, 0xB502}, - {MISENSOR_16BIT, 0xD2CC, 0x72CF}, - {MISENSOR_16BIT, 0xD2CE, 0xFFFF}, - {MISENSOR_16BIT, 0xD2D0, 0xC5D4}, - {MISENSOR_16BIT, 0xD2D2, 0x923A}, - {MISENSOR_16BIT, 0xD2D4, 0x73CF}, - {MISENSOR_16BIT, 0xD2D6, 0xFFFF}, - {MISENSOR_16BIT, 0xD2D8, 0xC7D0}, - {MISENSOR_16BIT, 0xD2DA, 0xB020}, - {MISENSOR_16BIT, 0xD2DC, 0x9220}, - {MISENSOR_16BIT, 0xD2DE, 0xB021}, - {MISENSOR_16BIT, 0xD2E0, 0x9221}, - {MISENSOR_16BIT, 0xD2E2, 0xB022}, - {MISENSOR_16BIT, 0xD2E4, 0x9222}, - {MISENSOR_16BIT, 0xD2E6, 0xB023}, - {MISENSOR_16BIT, 0xD2E8, 0x9223}, - {MISENSOR_16BIT, 0xD2EA, 0xB024}, - {MISENSOR_16BIT, 0xD2EC, 0x9227}, - {MISENSOR_16BIT, 0xD2EE, 0xB025}, - {MISENSOR_16BIT, 0xD2F0, 0x9228}, - {MISENSOR_16BIT, 0xD2F2, 0xB026}, - {MISENSOR_16BIT, 0xD2F4, 0x922B}, - {MISENSOR_16BIT, 0xD2F6, 0xB027}, - {MISENSOR_16BIT, 0xD2F8, 0x922C}, - {MISENSOR_16BIT, 0xD2FA, 0xB028}, - {MISENSOR_16BIT, 0xD2FC, 0x1258}, - {MISENSOR_16BIT, 0xD2FE, 0x0101}, - {MISENSOR_16BIT, 0xD300, 0xB029}, - {MISENSOR_16BIT, 0xD302, 0x125A}, - {MISENSOR_16BIT, 0xD304, 0x0101}, - {MISENSOR_16BIT, 0xD306, 0xB02A}, - {MISENSOR_16BIT, 0xD308, 0x1336}, - {MISENSOR_16BIT, 0xD30A, 0x8081}, - {MISENSOR_16BIT, 0xD30C, 0xA836}, - {MISENSOR_16BIT, 0xD30E, 0x1337}, - {MISENSOR_16BIT, 0xD310, 0x8081}, - {MISENSOR_16BIT, 0xD312, 0xA837}, - {MISENSOR_16BIT, 0xD314, 0x12A7}, - {MISENSOR_16BIT, 0xD316, 0x0701}, - {MISENSOR_16BIT, 0xD318, 0xB02C}, - {MISENSOR_16BIT, 0xD31A, 0x1354}, - {MISENSOR_16BIT, 0xD31C, 0x8081}, - {MISENSOR_16BIT, 0xD31E, 0x7FE0}, - {MISENSOR_16BIT, 0xD320, 0xA83A}, - {MISENSOR_16BIT, 0xD322, 0x78E0}, - {MISENSOR_16BIT, 0xD324, 0xC0F1}, - {MISENSOR_16BIT, 0xD326, 0x0DC2}, - {MISENSOR_16BIT, 0xD328, 0x05C0}, - {MISENSOR_16BIT, 0xD32A, 0x7608}, - {MISENSOR_16BIT, 0xD32C, 0x09BB}, - {MISENSOR_16BIT, 0xD32E, 0x0010}, - {MISENSOR_16BIT, 0xD330, 0x75CF}, - {MISENSOR_16BIT, 0xD332, 0xFFFF}, - {MISENSOR_16BIT, 0xD334, 0xD4E0}, - {MISENSOR_16BIT, 0xD336, 0x8D21}, - {MISENSOR_16BIT, 0xD338, 0x8D00}, - {MISENSOR_16BIT, 0xD33A, 0x2153}, - {MISENSOR_16BIT, 0xD33C, 0x0003}, - {MISENSOR_16BIT, 0xD33E, 0xB8C0}, - {MISENSOR_16BIT, 0xD340, 0x8D45}, - {MISENSOR_16BIT, 0xD342, 0x0B23}, - {MISENSOR_16BIT, 0xD344, 0x0000}, - {MISENSOR_16BIT, 0xD346, 0xEA8F}, - {MISENSOR_16BIT, 0xD348, 0x0915}, - {MISENSOR_16BIT, 0xD34A, 0x001E}, - {MISENSOR_16BIT, 0xD34C, 0xFF81}, - {MISENSOR_16BIT, 0xD34E, 0xE808}, - {MISENSOR_16BIT, 0xD350, 0x2540}, - {MISENSOR_16BIT, 0xD352, 0x1900}, - {MISENSOR_16BIT, 0xD354, 0xFFDE}, - {MISENSOR_16BIT, 0xD356, 0x8D00}, - {MISENSOR_16BIT, 0xD358, 0xB880}, - {MISENSOR_16BIT, 0xD35A, 0xF004}, - {MISENSOR_16BIT, 0xD35C, 0x8D00}, - {MISENSOR_16BIT, 0xD35E, 0xB8A0}, - {MISENSOR_16BIT, 0xD360, 0xAD00}, - {MISENSOR_16BIT, 0xD362, 0x8D05}, - {MISENSOR_16BIT, 0xD364, 0xE081}, - {MISENSOR_16BIT, 0xD366, 0x20CC}, - {MISENSOR_16BIT, 0xD368, 0x80A2}, - {MISENSOR_16BIT, 0xD36A, 0xDF00}, - {MISENSOR_16BIT, 0xD36C, 0xF40A}, - {MISENSOR_16BIT, 0xD36E, 0x71CF}, - {MISENSOR_16BIT, 0xD370, 0xFFFF}, - {MISENSOR_16BIT, 0xD372, 0xC84C}, - {MISENSOR_16BIT, 0xD374, 0x9102}, - {MISENSOR_16BIT, 0xD376, 0x7708}, - {MISENSOR_16BIT, 0xD378, 0xB8A6}, - {MISENSOR_16BIT, 0xD37A, 0x2786}, - {MISENSOR_16BIT, 0xD37C, 0x1FFE}, - {MISENSOR_16BIT, 0xD37E, 0xB102}, - {MISENSOR_16BIT, 0xD380, 0x0B42}, - {MISENSOR_16BIT, 0xD382, 0x0180}, - {MISENSOR_16BIT, 0xD384, 0x0E3E}, - {MISENSOR_16BIT, 0xD386, 0x0180}, - {MISENSOR_16BIT, 0xD388, 0x0F4A}, - {MISENSOR_16BIT, 0xD38A, 0x0160}, - {MISENSOR_16BIT, 0xD38C, 0x70C9}, - {MISENSOR_16BIT, 0xD38E, 0x8D05}, - {MISENSOR_16BIT, 0xD390, 0xE081}, - {MISENSOR_16BIT, 0xD392, 0x20CC}, - {MISENSOR_16BIT, 0xD394, 0x80A2}, - {MISENSOR_16BIT, 0xD396, 0xF429}, - {MISENSOR_16BIT, 0xD398, 0x76CF}, - {MISENSOR_16BIT, 0xD39A, 0xFFFF}, - {MISENSOR_16BIT, 0xD39C, 0xC84C}, - {MISENSOR_16BIT, 0xD39E, 0x082D}, - {MISENSOR_16BIT, 0xD3A0, 0x0051}, - {MISENSOR_16BIT, 0xD3A2, 0x70CF}, - {MISENSOR_16BIT, 0xD3A4, 0xFFFF}, - {MISENSOR_16BIT, 0xD3A6, 0xC90C}, - {MISENSOR_16BIT, 0xD3A8, 0x8805}, - {MISENSOR_16BIT, 0xD3AA, 0x09B6}, - {MISENSOR_16BIT, 0xD3AC, 0x0360}, - {MISENSOR_16BIT, 0xD3AE, 0xD908}, - {MISENSOR_16BIT, 0xD3B0, 0x2099}, - {MISENSOR_16BIT, 0xD3B2, 0x0802}, - {MISENSOR_16BIT, 0xD3B4, 0x9634}, - {MISENSOR_16BIT, 0xD3B6, 0xB503}, - {MISENSOR_16BIT, 0xD3B8, 0x7902}, - {MISENSOR_16BIT, 0xD3BA, 0x1523}, - {MISENSOR_16BIT, 0xD3BC, 0x1080}, - {MISENSOR_16BIT, 0xD3BE, 0xB634}, - {MISENSOR_16BIT, 0xD3C0, 0xE001}, - {MISENSOR_16BIT, 0xD3C2, 0x1D23}, - {MISENSOR_16BIT, 0xD3C4, 0x1002}, - {MISENSOR_16BIT, 0xD3C6, 0xF00B}, - {MISENSOR_16BIT, 0xD3C8, 0x9634}, - {MISENSOR_16BIT, 0xD3CA, 0x9503}, - {MISENSOR_16BIT, 0xD3CC, 0x6038}, - {MISENSOR_16BIT, 0xD3CE, 0xB614}, - {MISENSOR_16BIT, 0xD3D0, 0x153F}, - {MISENSOR_16BIT, 0xD3D2, 0x1080}, - {MISENSOR_16BIT, 0xD3D4, 0xE001}, - {MISENSOR_16BIT, 0xD3D6, 0x1D3F}, - {MISENSOR_16BIT, 0xD3D8, 0x1002}, - {MISENSOR_16BIT, 0xD3DA, 0xFFA4}, - {MISENSOR_16BIT, 0xD3DC, 0x9602}, - {MISENSOR_16BIT, 0xD3DE, 0x7F05}, - {MISENSOR_16BIT, 0xD3E0, 0xD800}, - {MISENSOR_16BIT, 0xD3E2, 0xB6E2}, - {MISENSOR_16BIT, 0xD3E4, 0xAD05}, - {MISENSOR_16BIT, 0xD3E6, 0x0511}, - {MISENSOR_16BIT, 0xD3E8, 0x05E0}, - {MISENSOR_16BIT, 0xD3EA, 0xD800}, - {MISENSOR_16BIT, 0xD3EC, 0xC0F1}, - {MISENSOR_16BIT, 0xD3EE, 0x0CFE}, - {MISENSOR_16BIT, 0xD3F0, 0x05C0}, - {MISENSOR_16BIT, 0xD3F2, 0x0A96}, - {MISENSOR_16BIT, 0xD3F4, 0x05A0}, - {MISENSOR_16BIT, 0xD3F6, 0x7608}, - {MISENSOR_16BIT, 0xD3F8, 0x0C22}, - {MISENSOR_16BIT, 0xD3FA, 0x0240}, - {MISENSOR_16BIT, 0xD3FC, 0xE080}, - {MISENSOR_16BIT, 0xD3FE, 0x20CA}, - {MISENSOR_16BIT, 0xD400, 0x0F82}, - {MISENSOR_16BIT, 0xD402, 0x0000}, - {MISENSOR_16BIT, 0xD404, 0x190B}, - {MISENSOR_16BIT, 0xD406, 0x0C60}, - {MISENSOR_16BIT, 0xD408, 0x05A2}, - {MISENSOR_16BIT, 0xD40A, 0x21CA}, - {MISENSOR_16BIT, 0xD40C, 0x0022}, - {MISENSOR_16BIT, 0xD40E, 0x0C56}, - {MISENSOR_16BIT, 0xD410, 0x0240}, - {MISENSOR_16BIT, 0xD412, 0xE806}, - {MISENSOR_16BIT, 0xD414, 0x0E0E}, - {MISENSOR_16BIT, 0xD416, 0x0220}, - {MISENSOR_16BIT, 0xD418, 0x70C9}, - {MISENSOR_16BIT, 0xD41A, 0xF048}, - {MISENSOR_16BIT, 0xD41C, 0x0896}, - {MISENSOR_16BIT, 0xD41E, 0x0440}, - {MISENSOR_16BIT, 0xD420, 0x0E96}, - {MISENSOR_16BIT, 0xD422, 0x0400}, - {MISENSOR_16BIT, 0xD424, 0x0966}, - {MISENSOR_16BIT, 0xD426, 0x0380}, - {MISENSOR_16BIT, 0xD428, 0x75CF}, - {MISENSOR_16BIT, 0xD42A, 0xFFFF}, - {MISENSOR_16BIT, 0xD42C, 0xD4E0}, - {MISENSOR_16BIT, 0xD42E, 0x8D00}, - {MISENSOR_16BIT, 0xD430, 0x084D}, - {MISENSOR_16BIT, 0xD432, 0x001E}, - {MISENSOR_16BIT, 0xD434, 0xFF47}, - {MISENSOR_16BIT, 0xD436, 0x080D}, - {MISENSOR_16BIT, 0xD438, 0x0050}, - {MISENSOR_16BIT, 0xD43A, 0xFF57}, - {MISENSOR_16BIT, 0xD43C, 0x0841}, - {MISENSOR_16BIT, 0xD43E, 0x0051}, - {MISENSOR_16BIT, 0xD440, 0x8D04}, - {MISENSOR_16BIT, 0xD442, 0x9521}, - {MISENSOR_16BIT, 0xD444, 0xE064}, - {MISENSOR_16BIT, 0xD446, 0x790C}, - {MISENSOR_16BIT, 0xD448, 0x702F}, - {MISENSOR_16BIT, 0xD44A, 0x0CE2}, - {MISENSOR_16BIT, 0xD44C, 0x05E0}, - {MISENSOR_16BIT, 0xD44E, 0xD964}, - {MISENSOR_16BIT, 0xD450, 0x72CF}, - {MISENSOR_16BIT, 0xD452, 0xFFFF}, - {MISENSOR_16BIT, 0xD454, 0xC700}, - {MISENSOR_16BIT, 0xD456, 0x9235}, - {MISENSOR_16BIT, 0xD458, 0x0811}, - {MISENSOR_16BIT, 0xD45A, 0x0043}, - {MISENSOR_16BIT, 0xD45C, 0xFF3D}, - {MISENSOR_16BIT, 0xD45E, 0x080D}, - {MISENSOR_16BIT, 0xD460, 0x0051}, - {MISENSOR_16BIT, 0xD462, 0xD801}, - {MISENSOR_16BIT, 0xD464, 0xFF77}, - {MISENSOR_16BIT, 0xD466, 0xF025}, - {MISENSOR_16BIT, 0xD468, 0x9501}, - {MISENSOR_16BIT, 0xD46A, 0x9235}, - {MISENSOR_16BIT, 0xD46C, 0x0911}, - {MISENSOR_16BIT, 0xD46E, 0x0003}, - {MISENSOR_16BIT, 0xD470, 0xFF49}, - {MISENSOR_16BIT, 0xD472, 0x080D}, - {MISENSOR_16BIT, 0xD474, 0x0051}, - {MISENSOR_16BIT, 0xD476, 0xD800}, - {MISENSOR_16BIT, 0xD478, 0xFF72}, - {MISENSOR_16BIT, 0xD47A, 0xF01B}, - {MISENSOR_16BIT, 0xD47C, 0x0886}, - {MISENSOR_16BIT, 0xD47E, 0x03E0}, - {MISENSOR_16BIT, 0xD480, 0xD801}, - {MISENSOR_16BIT, 0xD482, 0x0EF6}, - {MISENSOR_16BIT, 0xD484, 0x03C0}, - {MISENSOR_16BIT, 0xD486, 0x0F52}, - {MISENSOR_16BIT, 0xD488, 0x0340}, - {MISENSOR_16BIT, 0xD48A, 0x0DBA}, - {MISENSOR_16BIT, 0xD48C, 0x0200}, - {MISENSOR_16BIT, 0xD48E, 0x0AF6}, - {MISENSOR_16BIT, 0xD490, 0x0440}, - {MISENSOR_16BIT, 0xD492, 0x0C22}, - {MISENSOR_16BIT, 0xD494, 0x0400}, - {MISENSOR_16BIT, 0xD496, 0x0D72}, - {MISENSOR_16BIT, 0xD498, 0x0440}, - {MISENSOR_16BIT, 0xD49A, 0x0DC2}, - {MISENSOR_16BIT, 0xD49C, 0x0200}, - {MISENSOR_16BIT, 0xD49E, 0x0972}, - {MISENSOR_16BIT, 0xD4A0, 0x0440}, - {MISENSOR_16BIT, 0xD4A2, 0x0D3A}, - {MISENSOR_16BIT, 0xD4A4, 0x0220}, - {MISENSOR_16BIT, 0xD4A6, 0xD820}, - {MISENSOR_16BIT, 0xD4A8, 0x0BFA}, - {MISENSOR_16BIT, 0xD4AA, 0x0260}, - {MISENSOR_16BIT, 0xD4AC, 0x70C9}, - {MISENSOR_16BIT, 0xD4AE, 0x0451}, - {MISENSOR_16BIT, 0xD4B0, 0x05C0}, - {MISENSOR_16BIT, 0xD4B2, 0x78E0}, - {MISENSOR_16BIT, 0xD4B4, 0xD900}, - {MISENSOR_16BIT, 0xD4B6, 0xF00A}, - {MISENSOR_16BIT, 0xD4B8, 0x70CF}, - {MISENSOR_16BIT, 0xD4BA, 0xFFFF}, - {MISENSOR_16BIT, 0xD4BC, 0xD520}, - {MISENSOR_16BIT, 0xD4BE, 0x7835}, - {MISENSOR_16BIT, 0xD4C0, 0x8041}, - {MISENSOR_16BIT, 0xD4C2, 0x8000}, - {MISENSOR_16BIT, 0xD4C4, 0xE102}, - {MISENSOR_16BIT, 0xD4C6, 0xA040}, - {MISENSOR_16BIT, 0xD4C8, 0x09F1}, - {MISENSOR_16BIT, 0xD4CA, 0x8114}, - {MISENSOR_16BIT, 0xD4CC, 0x71CF}, - {MISENSOR_16BIT, 0xD4CE, 0xFFFF}, - {MISENSOR_16BIT, 0xD4D0, 0xD4E0}, - {MISENSOR_16BIT, 0xD4D2, 0x70CF}, - {MISENSOR_16BIT, 0xD4D4, 0xFFFF}, - {MISENSOR_16BIT, 0xD4D6, 0xC594}, - {MISENSOR_16BIT, 0xD4D8, 0xB03A}, - {MISENSOR_16BIT, 0xD4DA, 0x7FE0}, - {MISENSOR_16BIT, 0xD4DC, 0xD800}, - {MISENSOR_16BIT, 0xD4DE, 0x0000}, - {MISENSOR_16BIT, 0xD4E0, 0x0000}, - {MISENSOR_16BIT, 0xD4E2, 0x0500}, - {MISENSOR_16BIT, 0xD4E4, 0x0500}, - {MISENSOR_16BIT, 0xD4E6, 0x0200}, - {MISENSOR_16BIT, 0xD4E8, 0x0330}, - {MISENSOR_16BIT, 0xD4EA, 0x0000}, - {MISENSOR_16BIT, 0xD4EC, 0x0000}, - {MISENSOR_16BIT, 0xD4EE, 0x03CD}, - {MISENSOR_16BIT, 0xD4F0, 0x050D}, - {MISENSOR_16BIT, 0xD4F2, 0x01C5}, - {MISENSOR_16BIT, 0xD4F4, 0x03B3}, - {MISENSOR_16BIT, 0xD4F6, 0x00E0}, - {MISENSOR_16BIT, 0xD4F8, 0x01E3}, - {MISENSOR_16BIT, 0xD4FA, 0x0280}, - {MISENSOR_16BIT, 0xD4FC, 0x01E0}, - {MISENSOR_16BIT, 0xD4FE, 0x0109}, - {MISENSOR_16BIT, 0xD500, 0x0080}, - {MISENSOR_16BIT, 0xD502, 0x0500}, - {MISENSOR_16BIT, 0xD504, 0x0000}, - {MISENSOR_16BIT, 0xD506, 0x0000}, - {MISENSOR_16BIT, 0xD508, 0x0000}, - {MISENSOR_16BIT, 0xD50A, 0x0000}, - {MISENSOR_16BIT, 0xD50C, 0x0000}, - {MISENSOR_16BIT, 0xD50E, 0x0000}, - {MISENSOR_16BIT, 0xD510, 0x0000}, - {MISENSOR_16BIT, 0xD512, 0x0000}, - {MISENSOR_16BIT, 0xD514, 0x0000}, - {MISENSOR_16BIT, 0xD516, 0x0000}, - {MISENSOR_16BIT, 0xD518, 0x0000}, - {MISENSOR_16BIT, 0xD51A, 0x0000}, - {MISENSOR_16BIT, 0xD51C, 0x0000}, - {MISENSOR_16BIT, 0xD51E, 0x0000}, - {MISENSOR_16BIT, 0xD520, 0xFFFF}, - {MISENSOR_16BIT, 0xD522, 0xC9B4}, - {MISENSOR_16BIT, 0xD524, 0xFFFF}, - {MISENSOR_16BIT, 0xD526, 0xD324}, - {MISENSOR_16BIT, 0xD528, 0xFFFF}, - {MISENSOR_16BIT, 0xD52A, 0xCA34}, - {MISENSOR_16BIT, 0xD52C, 0xFFFF}, - {MISENSOR_16BIT, 0xD52E, 0xD3EC}, - {MISENSOR_16BIT, 0x098E, 0x0000}, - {MISENSOR_16BIT, 0xE000, 0x04B4}, - {MISENSOR_16BIT, 0xE002, 0x0302}, - {MISENSOR_16BIT, 0xE004, 0x4103}, - {MISENSOR_16BIT, 0xE006, 0x0202}, - {MISENSOR_16BIT, 0x0080, 0xFFF0}, - {MISENSOR_16BIT, 0x0080, 0xFFF1}, - - /* PGA parameter and APGA - * [Step4-APGA] [TP101_MT9M114_APGA] - */ - {MISENSOR_16BIT, 0x098E, 0x495E}, - {MISENSOR_16BIT, 0xC95E, 0x0000}, - {MISENSOR_16BIT, 0x3640, 0x02B0}, - {MISENSOR_16BIT, 0x3642, 0x8063}, - {MISENSOR_16BIT, 0x3644, 0x78D0}, - {MISENSOR_16BIT, 0x3646, 0x50CC}, - {MISENSOR_16BIT, 0x3648, 0x3511}, - {MISENSOR_16BIT, 0x364A, 0x0110}, - {MISENSOR_16BIT, 0x364C, 0xBD8A}, - {MISENSOR_16BIT, 0x364E, 0x0CD1}, - {MISENSOR_16BIT, 0x3650, 0x24ED}, - {MISENSOR_16BIT, 0x3652, 0x7C11}, - {MISENSOR_16BIT, 0x3654, 0x0150}, - {MISENSOR_16BIT, 0x3656, 0x124C}, - {MISENSOR_16BIT, 0x3658, 0x3130}, - {MISENSOR_16BIT, 0x365A, 0x508C}, - {MISENSOR_16BIT, 0x365C, 0x21F1}, - {MISENSOR_16BIT, 0x365E, 0x0090}, - {MISENSOR_16BIT, 0x3660, 0xBFCA}, - {MISENSOR_16BIT, 0x3662, 0x0A11}, - {MISENSOR_16BIT, 0x3664, 0x4F4B}, - {MISENSOR_16BIT, 0x3666, 0x28B1}, - {MISENSOR_16BIT, 0x3680, 0x50A9}, - {MISENSOR_16BIT, 0x3682, 0xA04B}, - {MISENSOR_16BIT, 0x3684, 0x0E2D}, - {MISENSOR_16BIT, 0x3686, 0x73EC}, - {MISENSOR_16BIT, 0x3688, 0x164F}, - {MISENSOR_16BIT, 0x368A, 0xF829}, - {MISENSOR_16BIT, 0x368C, 0xC1A8}, - {MISENSOR_16BIT, 0x368E, 0xB0EC}, - {MISENSOR_16BIT, 0x3690, 0xE76A}, - {MISENSOR_16BIT, 0x3692, 0x69AF}, - {MISENSOR_16BIT, 0x3694, 0x378C}, - {MISENSOR_16BIT, 0x3696, 0xA70D}, - {MISENSOR_16BIT, 0x3698, 0x884F}, - {MISENSOR_16BIT, 0x369A, 0xEE8B}, - {MISENSOR_16BIT, 0x369C, 0x5DEF}, - {MISENSOR_16BIT, 0x369E, 0x27CC}, - {MISENSOR_16BIT, 0x36A0, 0xCAAC}, - {MISENSOR_16BIT, 0x36A2, 0x840E}, - {MISENSOR_16BIT, 0x36A4, 0xDAA9}, - {MISENSOR_16BIT, 0x36A6, 0xF00C}, - {MISENSOR_16BIT, 0x36C0, 0x1371}, - {MISENSOR_16BIT, 0x36C2, 0x272F}, - {MISENSOR_16BIT, 0x36C4, 0x2293}, - {MISENSOR_16BIT, 0x36C6, 0xE6D0}, - {MISENSOR_16BIT, 0x36C8, 0xEC32}, - {MISENSOR_16BIT, 0x36CA, 0x11B1}, - {MISENSOR_16BIT, 0x36CC, 0x7BAF}, - {MISENSOR_16BIT, 0x36CE, 0x5813}, - {MISENSOR_16BIT, 0x36D0, 0xB871}, - {MISENSOR_16BIT, 0x36D2, 0x8913}, - {MISENSOR_16BIT, 0x36D4, 0x4610}, - {MISENSOR_16BIT, 0x36D6, 0x7EEE}, - {MISENSOR_16BIT, 0x36D8, 0x0DF3}, - {MISENSOR_16BIT, 0x36DA, 0xB84F}, - {MISENSOR_16BIT, 0x36DC, 0xB532}, - {MISENSOR_16BIT, 0x36DE, 0x1171}, - {MISENSOR_16BIT, 0x36E0, 0x13CF}, - {MISENSOR_16BIT, 0x36E2, 0x22F3}, - {MISENSOR_16BIT, 0x36E4, 0xE090}, - {MISENSOR_16BIT, 0x36E6, 0x8133}, - {MISENSOR_16BIT, 0x3700, 0x88AE}, - {MISENSOR_16BIT, 0x3702, 0x00EA}, - {MISENSOR_16BIT, 0x3704, 0x344F}, - {MISENSOR_16BIT, 0x3706, 0xEC88}, - {MISENSOR_16BIT, 0x3708, 0x3E91}, - {MISENSOR_16BIT, 0x370A, 0xF12D}, - {MISENSOR_16BIT, 0x370C, 0xB0EF}, - {MISENSOR_16BIT, 0x370E, 0x77CD}, - {MISENSOR_16BIT, 0x3710, 0x7930}, - {MISENSOR_16BIT, 0x3712, 0x5C12}, - {MISENSOR_16BIT, 0x3714, 0x500C}, - {MISENSOR_16BIT, 0x3716, 0x22CE}, - {MISENSOR_16BIT, 0x3718, 0x2370}, - {MISENSOR_16BIT, 0x371A, 0x258F}, - {MISENSOR_16BIT, 0x371C, 0x3D30}, - {MISENSOR_16BIT, 0x371E, 0x370C}, - {MISENSOR_16BIT, 0x3720, 0x03ED}, - {MISENSOR_16BIT, 0x3722, 0x9AD0}, - {MISENSOR_16BIT, 0x3724, 0x7ECF}, - {MISENSOR_16BIT, 0x3726, 0x1093}, - {MISENSOR_16BIT, 0x3740, 0x2391}, - {MISENSOR_16BIT, 0x3742, 0xAAD0}, - {MISENSOR_16BIT, 0x3744, 0x28F2}, - {MISENSOR_16BIT, 0x3746, 0xBA4F}, - {MISENSOR_16BIT, 0x3748, 0xC536}, - {MISENSOR_16BIT, 0x374A, 0x1472}, - {MISENSOR_16BIT, 0x374C, 0xD110}, - {MISENSOR_16BIT, 0x374E, 0x2933}, - {MISENSOR_16BIT, 0x3750, 0xD0D1}, - {MISENSOR_16BIT, 0x3752, 0x9F37}, - {MISENSOR_16BIT, 0x3754, 0x34D1}, - {MISENSOR_16BIT, 0x3756, 0x1C6C}, - {MISENSOR_16BIT, 0x3758, 0x3FD2}, - {MISENSOR_16BIT, 0x375A, 0xCB72}, - {MISENSOR_16BIT, 0x375C, 0xBA96}, - {MISENSOR_16BIT, 0x375E, 0x1551}, - {MISENSOR_16BIT, 0x3760, 0xB74F}, - {MISENSOR_16BIT, 0x3762, 0x1672}, - {MISENSOR_16BIT, 0x3764, 0x84F1}, - {MISENSOR_16BIT, 0x3766, 0xC2D6}, - {MISENSOR_16BIT, 0x3782, 0x01E0}, - {MISENSOR_16BIT, 0x3784, 0x0280}, - {MISENSOR_16BIT, 0x37C0, 0xA6EA}, - {MISENSOR_16BIT, 0x37C2, 0x874B}, - {MISENSOR_16BIT, 0x37C4, 0x85CB}, - {MISENSOR_16BIT, 0x37C6, 0x968A}, - {MISENSOR_16BIT, 0x098E, 0x0000}, - {MISENSOR_16BIT, 0xC960, 0x0AF0}, - {MISENSOR_16BIT, 0xC962, 0x79E2}, - {MISENSOR_16BIT, 0xC964, 0x5EC8}, - {MISENSOR_16BIT, 0xC966, 0x791F}, - {MISENSOR_16BIT, 0xC968, 0x76EE}, - {MISENSOR_16BIT, 0xC96A, 0x0FA0}, - {MISENSOR_16BIT, 0xC96C, 0x7DFA}, - {MISENSOR_16BIT, 0xC96E, 0x7DAF}, - {MISENSOR_16BIT, 0xC970, 0x7E02}, - {MISENSOR_16BIT, 0xC972, 0x7E0A}, - {MISENSOR_16BIT, 0xC974, 0x1964}, - {MISENSOR_16BIT, 0xC976, 0x7CDC}, - {MISENSOR_16BIT, 0xC978, 0x7838}, - {MISENSOR_16BIT, 0xC97A, 0x7C2F}, - {MISENSOR_16BIT, 0xC97C, 0x7792}, - {MISENSOR_16BIT, 0xC95E, 0x0003}, - - /* [Step4-APGA] */ - {MISENSOR_16BIT, 0x098E, 0x0000}, - {MISENSOR_16BIT, 0xC95E, 0x0003}, - - /* [Step5-AWB_CCM]1: LOAD=CCM */ - {MISENSOR_16BIT, 0xC892, 0x0267}, - {MISENSOR_16BIT, 0xC894, 0xFF1A}, - {MISENSOR_16BIT, 0xC896, 0xFFB3}, - {MISENSOR_16BIT, 0xC898, 0xFF80}, - {MISENSOR_16BIT, 0xC89A, 0x0166}, - {MISENSOR_16BIT, 0xC89C, 0x0003}, - {MISENSOR_16BIT, 0xC89E, 0xFF9A}, - {MISENSOR_16BIT, 0xC8A0, 0xFEB4}, - {MISENSOR_16BIT, 0xC8A2, 0x024D}, - {MISENSOR_16BIT, 0xC8A4, 0x01BF}, - {MISENSOR_16BIT, 0xC8A6, 0xFF01}, - {MISENSOR_16BIT, 0xC8A8, 0xFFF3}, - {MISENSOR_16BIT, 0xC8AA, 0xFF75}, - {MISENSOR_16BIT, 0xC8AC, 0x0198}, - {MISENSOR_16BIT, 0xC8AE, 0xFFFD}, - {MISENSOR_16BIT, 0xC8B0, 0xFF9A}, - {MISENSOR_16BIT, 0xC8B2, 0xFEE7}, - {MISENSOR_16BIT, 0xC8B4, 0x02A8}, - {MISENSOR_16BIT, 0xC8B6, 0x01D9}, - {MISENSOR_16BIT, 0xC8B8, 0xFF26}, - {MISENSOR_16BIT, 0xC8BA, 0xFFF3}, - {MISENSOR_16BIT, 0xC8BC, 0xFFB3}, - {MISENSOR_16BIT, 0xC8BE, 0x0132}, - {MISENSOR_16BIT, 0xC8C0, 0xFFE8}, - {MISENSOR_16BIT, 0xC8C2, 0xFFDA}, - {MISENSOR_16BIT, 0xC8C4, 0xFECD}, - {MISENSOR_16BIT, 0xC8C6, 0x02C2}, - {MISENSOR_16BIT, 0xC8C8, 0x0075}, - {MISENSOR_16BIT, 0xC8CA, 0x011C}, - {MISENSOR_16BIT, 0xC8CC, 0x009A}, - {MISENSOR_16BIT, 0xC8CE, 0x0105}, - {MISENSOR_16BIT, 0xC8D0, 0x00A4}, - {MISENSOR_16BIT, 0xC8D2, 0x00AC}, - {MISENSOR_16BIT, 0xC8D4, 0x0A8C}, - {MISENSOR_16BIT, 0xC8D6, 0x0F0A}, - {MISENSOR_16BIT, 0xC8D8, 0x1964}, - - /* LOAD=AWB */ - {MISENSOR_16BIT, 0xC914, 0x0000}, - {MISENSOR_16BIT, 0xC916, 0x0000}, - {MISENSOR_16BIT, 0xC918, 0x04FF}, - {MISENSOR_16BIT, 0xC91A, 0x02CF}, - {MISENSOR_16BIT, 0xC904, 0x0033}, - {MISENSOR_16BIT, 0xC906, 0x0040}, - {MISENSOR_8BIT, 0xC8F2, 0x03}, - {MISENSOR_8BIT, 0xC8F3, 0x02}, - {MISENSOR_16BIT, 0xC906, 0x003C}, - {MISENSOR_16BIT, 0xC8F4, 0x0000}, - {MISENSOR_16BIT, 0xC8F6, 0x0000}, - {MISENSOR_16BIT, 0xC8F8, 0x0000}, - {MISENSOR_16BIT, 0xC8FA, 0xE724}, - {MISENSOR_16BIT, 0xC8FC, 0x1583}, - {MISENSOR_16BIT, 0xC8FE, 0x2045}, - {MISENSOR_16BIT, 0xC900, 0x05DC}, - {MISENSOR_16BIT, 0xC902, 0x007C}, - {MISENSOR_8BIT, 0xC90C, 0x80}, - {MISENSOR_8BIT, 0xC90D, 0x80}, - {MISENSOR_8BIT, 0xC90E, 0x80}, - {MISENSOR_8BIT, 0xC90F, 0x88}, - {MISENSOR_8BIT, 0xC910, 0x80}, - {MISENSOR_8BIT, 0xC911, 0x80}, - - /* LOAD=Step7-CPIPE_Preference */ - {MISENSOR_16BIT, 0xC926, 0x0020}, - {MISENSOR_16BIT, 0xC928, 0x009A}, - {MISENSOR_16BIT, 0xC946, 0x0070}, - {MISENSOR_16BIT, 0xC948, 0x00F3}, - {MISENSOR_16BIT, 0xC952, 0x0020}, - {MISENSOR_16BIT, 0xC954, 0x009A}, - {MISENSOR_8BIT, 0xC92A, 0x80}, - {MISENSOR_8BIT, 0xC92B, 0x4B}, - {MISENSOR_8BIT, 0xC92C, 0x00}, - {MISENSOR_8BIT, 0xC92D, 0xFF}, - {MISENSOR_8BIT, 0xC92E, 0x3C}, - {MISENSOR_8BIT, 0xC92F, 0x02}, - {MISENSOR_8BIT, 0xC930, 0x06}, - {MISENSOR_8BIT, 0xC931, 0x64}, - {MISENSOR_8BIT, 0xC932, 0x01}, - {MISENSOR_8BIT, 0xC933, 0x0C}, - {MISENSOR_8BIT, 0xC934, 0x3C}, - {MISENSOR_8BIT, 0xC935, 0x3C}, - {MISENSOR_8BIT, 0xC936, 0x3C}, - {MISENSOR_8BIT, 0xC937, 0x0F}, - {MISENSOR_8BIT, 0xC938, 0x64}, - {MISENSOR_8BIT, 0xC939, 0x64}, - {MISENSOR_8BIT, 0xC93A, 0x64}, - {MISENSOR_8BIT, 0xC93B, 0x32}, - {MISENSOR_16BIT, 0xC93C, 0x0020}, - {MISENSOR_16BIT, 0xC93E, 0x009A}, - {MISENSOR_16BIT, 0xC940, 0x00DC}, - {MISENSOR_8BIT, 0xC942, 0x38}, - {MISENSOR_8BIT, 0xC943, 0x30}, - {MISENSOR_8BIT, 0xC944, 0x50}, - {MISENSOR_8BIT, 0xC945, 0x19}, - {MISENSOR_16BIT, 0xC94A, 0x0230}, - {MISENSOR_16BIT, 0xC94C, 0x0010}, - {MISENSOR_16BIT, 0xC94E, 0x01CD}, - {MISENSOR_8BIT, 0xC950, 0x05}, - {MISENSOR_8BIT, 0xC951, 0x40}, - {MISENSOR_8BIT, 0xC87B, 0x1B}, - {MISENSOR_8BIT, 0xC878, 0x0E}, - {MISENSOR_16BIT, 0xC890, 0x0080}, - {MISENSOR_16BIT, 0xC886, 0x0100}, - {MISENSOR_16BIT, 0xC87C, 0x005A}, - {MISENSOR_8BIT, 0xB42A, 0x05}, - {MISENSOR_8BIT, 0xA80A, 0x20}, - - /* Speed up AE/AWB */ - {MISENSOR_16BIT, 0x098E, 0x2802}, - {MISENSOR_16BIT, 0xA802, 0x0008}, - {MISENSOR_8BIT, 0xC908, 0x01}, - {MISENSOR_8BIT, 0xC879, 0x01}, - {MISENSOR_8BIT, 0xC909, 0x02}, - {MISENSOR_8BIT, 0xA80A, 0x18}, - {MISENSOR_8BIT, 0xA80B, 0x18}, - {MISENSOR_8BIT, 0xAC16, 0x18}, - {MISENSOR_8BIT, 0xC878, 0x0E}, - - {MISENSOR_TOK_TERM, 0, 0} -}; - -#endif -#endif diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h index bc36133f3722..00317d105305 100644 --- a/drivers/staging/media/atomisp/i2c/ov2722.h +++ b/drivers/staging/media/atomisp/i2c/ov2722.h @@ -236,7 +236,7 @@ struct ov2722_write_ctrl { * Register settings for various resolution */ #if 0 -static struct ov2722_reg const ov2722_QVGA_30fps[] = { +static const struct ov2722_reg ov2722_QVGA_30fps[] = { {OV2722_8BIT, 0x3718, 0x10}, {OV2722_8BIT, 0x3702, 0x0c}, {OV2722_8BIT, 0x373a, 0x1c}, @@ -346,7 +346,7 @@ static struct ov2722_reg const ov2722_QVGA_30fps[] = { }; -static struct ov2722_reg const ov2722_480P_30fps[] = { +static const struct ov2722_reg ov2722_480P_30fps[] = { {OV2722_8BIT, 0x3718, 0x10}, {OV2722_8BIT, 0x3702, 0x18}, {OV2722_8BIT, 0x373a, 0x3c}, @@ -455,7 +455,7 @@ static struct ov2722_reg const ov2722_480P_30fps[] = { {OV2722_TOK_TERM, 0, 0}, }; -static struct ov2722_reg const ov2722_VGA_30fps[] = { +static const struct ov2722_reg ov2722_VGA_30fps[] = { {OV2722_8BIT, 0x3718, 0x10}, {OV2722_8BIT, 0x3702, 0x18}, {OV2722_8BIT, 0x373a, 0x3c}, @@ -565,7 +565,7 @@ static struct ov2722_reg const ov2722_VGA_30fps[] = { }; #endif -static struct ov2722_reg const ov2722_1632_1092_30fps[] = { +static const struct ov2722_reg ov2722_1632_1092_30fps[] = { {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for a whole frame complete.(vblank) */ {OV2722_8BIT, 0x3718, 0x10}, @@ -667,7 +667,7 @@ static struct ov2722_reg const ov2722_1632_1092_30fps[] = { {OV2722_TOK_TERM, 0, 0} }; -static struct ov2722_reg const ov2722_1452_1092_30fps[] = { +static const struct ov2722_reg ov2722_1452_1092_30fps[] = { {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for a whole frame complete.(vblank) */ {OV2722_8BIT, 0x3718, 0x10}, @@ -769,7 +769,7 @@ static struct ov2722_reg const ov2722_1452_1092_30fps[] = { }; #if 0 -static struct ov2722_reg const ov2722_1M3_30fps[] = { +static const struct ov2722_reg ov2722_1M3_30fps[] = { {OV2722_8BIT, 0x3718, 0x10}, {OV2722_8BIT, 0x3702, 0x24}, {OV2722_8BIT, 0x373a, 0x60}, @@ -877,7 +877,7 @@ static struct ov2722_reg const ov2722_1M3_30fps[] = { }; #endif -static struct ov2722_reg const ov2722_1080p_30fps[] = { +static const struct ov2722_reg ov2722_1080p_30fps[] = { {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for a whole frame complete.(vblank) */ {OV2722_8BIT, 0x3718, 0x10}, @@ -983,7 +983,7 @@ static struct ov2722_reg const ov2722_1080p_30fps[] = { }; #if 0 /* Currently unused */ -static struct ov2722_reg const ov2722_720p_30fps[] = { +static const struct ov2722_reg ov2722_720p_30fps[] = { {OV2722_8BIT, 0x3021, 0x03}, {OV2722_8BIT, 0x3718, 0x10}, {OV2722_8BIT, 0x3702, 0x24}, diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c index 02ccf80e6559..3a4eb4f6d3be 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -87,7 +87,7 @@ static unsigned short atomisp_get_sensor_fps(struct atomisp_sub_device *asd) unsigned short fps = 0; int ret; - ret = v4l2_subdev_call_state_active(isp->inputs[asd->input_curr].camera, + ret = v4l2_subdev_call_state_active(isp->inputs[asd->input_curr].sensor, pad, get_frame_interval, &fi); if (!ret && fi.interval.numerator) @@ -881,7 +881,8 @@ void atomisp_assert_recovery_work(struct work_struct *work) spin_unlock_irqrestore(&isp->lock, flags); /* stream off sensor */ - ret = v4l2_subdev_call(isp->inputs[isp->asd.input_curr].camera, video, s_stream, 0); + ret = v4l2_subdev_call(isp->inputs[isp->asd.input_curr].csi_remote_source, + video, s_stream, 0); if (ret) dev_warn(isp->dev, "Stopping sensor stream failed: %d\n", ret); @@ -936,7 +937,8 @@ void atomisp_assert_recovery_work(struct work_struct *work) /* Requeue unprocessed per-frame parameters. */ atomisp_recover_params_queue(&isp->asd.video_out); - ret = v4l2_subdev_call(isp->inputs[isp->asd.input_curr].camera, video, s_stream, 1); + ret = v4l2_subdev_call(isp->inputs[isp->asd.input_curr].csi_remote_source, + video, s_stream, 1); if (ret) dev_err(isp->dev, "Starting sensor stream failed: %d\n", ret); @@ -3124,7 +3126,7 @@ int atomisp_color_effect(struct atomisp_sub_device *asd, int flag, control.id = V4L2_CID_COLORFX; control.value = *effect; ret = - v4l2_s_ctrl(NULL, isp->inputs[asd->input_curr].camera->ctrl_handler, + v4l2_s_ctrl(NULL, isp->inputs[asd->input_curr].sensor->ctrl_handler, &control); /* * if set color effect to sensor successfully, return @@ -3620,16 +3622,16 @@ int atomisp_s_sensor_power(struct atomisp_device *isp, unsigned int input, bool { int ret; - if (isp->inputs[input].camera_on == on) + if (isp->inputs[input].sensor_on == on) return 0; - ret = v4l2_subdev_call(isp->inputs[input].camera, core, s_power, on); + ret = v4l2_subdev_call(isp->inputs[input].sensor, core, s_power, on); if (ret && ret != -ENOIOCTLCMD) { dev_err(isp->dev, "Error setting sensor power %d: %d\n", on, ret); return ret; } - isp->inputs[input].camera_on = on; + isp->inputs[input].sensor_on = on; return 0; } @@ -3677,7 +3679,7 @@ void atomisp_setup_input_links(struct atomisp_device *isp) * will end up calling atomisp_link_setup() which calls this * function again leading to endless recursion. */ - if (isp->sensor_subdevs[i] == isp->inputs[isp->asd.input_curr].camera) + if (isp->sensor_subdevs[i] == isp->inputs[isp->asd.input_curr].csi_remote_source) link->flags |= MEDIA_LNK_FL_ENABLED; else link->flags &= ~MEDIA_LNK_FL_ENABLED; @@ -3704,7 +3706,7 @@ static int atomisp_set_sensor_crop_and_fmt(struct atomisp_device *isp, struct v4l2_subdev_state *sd_state; int ret = 0; - if (!input->camera) + if (!input->sensor) return -EINVAL; /* @@ -3719,7 +3721,7 @@ static int atomisp_set_sensor_crop_and_fmt(struct atomisp_device *isp, } sd_state = (which == V4L2_SUBDEV_FORMAT_TRY) ? input->try_sd_state : - input->camera->active_state; + input->sensor->active_state; if (sd_state) v4l2_subdev_lock_state(sd_state); @@ -3740,20 +3742,44 @@ static int atomisp_set_sensor_crop_and_fmt(struct atomisp_device *isp, sel.r.left = ((input->native_rect.width - sel.r.width) / 2) & ~1; sel.r.top = ((input->native_rect.height - sel.r.height) / 2) & ~1; - ret = v4l2_subdev_call(input->camera, pad, set_selection, sd_state, &sel); + ret = v4l2_subdev_call(input->sensor, pad, set_selection, sd_state, &sel); if (ret) - dev_err(isp->dev, "Error setting crop to %ux%u @%ux%u: %d\n", - sel.r.width, sel.r.height, sel.r.left, sel.r.top, ret); + dev_err(isp->dev, "Error setting crop to (%d,%d)/%ux%u: %d\n", + sel.r.left, sel.r.top, sel.r.width, sel.r.height, ret); set_fmt: - if (ret == 0) - ret = v4l2_subdev_call(input->camera, pad, set_fmt, sd_state, &format); + if (ret == 0) { + ret = v4l2_subdev_call(input->sensor, pad, set_fmt, sd_state, &format); + dev_dbg(isp->dev, "Set sensor format ret: %d size %dx%d\n", + ret, format.format.width, format.format.height); + } if (sd_state) v4l2_subdev_unlock_state(sd_state); + /* Propagate new fmt to sensor ISP */ + if (ret == 0 && which == V4L2_SUBDEV_FORMAT_ACTIVE && input->sensor_isp) { + sd_state = v4l2_subdev_lock_and_get_active_state(input->sensor_isp); + + format.pad = SENSOR_ISP_PAD_SINK; + ret = v4l2_subdev_call(input->sensor_isp, pad, set_fmt, sd_state, &format); + dev_dbg(isp->dev, "Set sensor ISP sink format ret: %d size %dx%d\n", + ret, format.format.width, format.format.height); + + if (ret == 0) { + format.pad = SENSOR_ISP_PAD_SOURCE; + ret = v4l2_subdev_call(input->sensor_isp, pad, set_fmt, sd_state, &format); + dev_dbg(isp->dev, "Set sensor ISP source format ret: %d size %dx%d\n", + ret, format.format.width, format.format.height); + } + + if (sd_state) + v4l2_subdev_unlock_state(sd_state); + } + /* Propagate new fmt to CSI port */ - if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { + if (ret == 0 && which == V4L2_SUBDEV_FORMAT_ACTIVE) { + format.pad = CSI2_PAD_SINK; ret = v4l2_subdev_call(input->csi_port, pad, set_fmt, NULL, &format); if (ret) return ret; @@ -3784,9 +3810,14 @@ int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f, return -EINVAL; } - /* The preview pipeline does not support width > 1920 */ - if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) - f->width = min_t(u32, f->width, 1920); + /* + * The preview pipeline does not support width > 1920. Also limit height + * to avoid sensor drivers still picking a too wide resolution. + */ + if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) { + f->width = min(f->width, 1920U); + f->height = min(f->height, 1440U); + } /* * atomisp_set_fmt() will set the sensor resolution to the requested @@ -3875,7 +3906,7 @@ static inline int atomisp_set_sensor_mipi_to_isp( u32 mipi_port, metadata_width = 0, metadata_height = 0; ctrl.id = V4L2_CID_LINK_FREQ; - if (v4l2_g_ctrl(input->camera->ctrl_handler, &ctrl) == 0) + if (v4l2_g_ctrl(input->sensor->ctrl_handler, &ctrl) == 0) mipi_freq = ctrl.value; if (asd->stream_env[stream_id].isys_configs == 1) { @@ -4038,7 +4069,7 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, if (!format) return -EINVAL; - mipi_info = atomisp_to_sensor_mipi_info(input->camera); + mipi_info = atomisp_to_sensor_mipi_info(input->sensor); if (atomisp_set_sensor_mipi_to_isp(asd, ATOMISP_INPUT_STREAM_GENERAL, mipi_info)) diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c index 2eb44bccff0e..be5f37f4a6fd 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c @@ -387,7 +387,7 @@ static int __destroy_stream(struct atomisp_sub_device *asd, } if (stream_env->stream_state == CSS_STREAM_STARTED) { - timeout = jiffies + msecs_to_jiffies(40); + timeout = jiffies + msecs_to_jiffies(200); while (1) { if (ia_css_stream_has_stopped(stream_env->stream)) break; @@ -1845,7 +1845,7 @@ static enum ia_css_pipe_mode __pipe_id_to_pipe_mode( { struct atomisp_device *isp = asd->isp; struct camera_mipi_info *mipi_info = atomisp_to_sensor_mipi_info( - isp->inputs[asd->input_curr].camera); + isp->inputs[asd->input_curr].sensor); switch (pipe_id) { case IA_CSS_PIPE_ID_COPY: diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.h b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.h deleted file mode 100644 index 23d798f3085c..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.h +++ /dev/null @@ -1,244 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Support for Intel Camera Imaging ISP subsystem. - * - * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - */ -#ifndef __ATOMISP_COMPAT_IOCTL32_H__ -#define __ATOMISP_COMPAT_IOCTL32_H__ - -#include <linux/compat.h> -#include <linux/videodev2.h> - -#include "atomisp_compat.h" - -struct atomisp_histogram32 { - unsigned int num_elements; - compat_uptr_t data; -}; - -struct atomisp_dvs2_stat_types32 { - compat_uptr_t odd_real; /** real part of the odd statistics*/ - compat_uptr_t odd_imag; /** imaginary part of the odd statistics*/ - compat_uptr_t even_real;/** real part of the even statistics*/ - compat_uptr_t even_imag;/** imaginary part of the even statistics*/ -}; - -struct atomisp_dvs2_coef_types32 { - compat_uptr_t odd_real; /** real part of the odd coefficients*/ - compat_uptr_t odd_imag; /** imaginary part of the odd coefficients*/ - compat_uptr_t even_real;/** real part of the even coefficients*/ - compat_uptr_t even_imag;/** imaginary part of the even coefficients*/ -}; - -struct atomisp_dvs2_statistics32 { - struct atomisp_dvs_grid_info grid_info; - struct atomisp_dvs2_stat_types32 hor_prod; - struct atomisp_dvs2_stat_types32 ver_prod; -}; - -struct atomisp_dis_statistics32 { - struct atomisp_dvs2_statistics32 dvs2_stat; - u32 exp_id; -}; - -struct atomisp_dis_coefficients32 { - struct atomisp_dvs_grid_info grid_info; - struct atomisp_dvs2_coef_types32 hor_coefs; - struct atomisp_dvs2_coef_types32 ver_coefs; -}; - -struct atomisp_3a_statistics32 { - struct atomisp_grid_info grid_info; - compat_uptr_t data; - compat_uptr_t rgby_data; - u32 exp_id; - u32 isp_config_id; -}; - -struct atomisp_morph_table32 { - unsigned int enabled; - unsigned int height; - unsigned int width; /* number of valid elements per line */ - compat_uptr_t coordinates_x[ATOMISP_MORPH_TABLE_NUM_PLANES]; - compat_uptr_t coordinates_y[ATOMISP_MORPH_TABLE_NUM_PLANES]; -}; - -struct v4l2_framebuffer32 { - __u32 capability; - __u32 flags; - compat_uptr_t base; - struct v4l2_pix_format fmt; -}; - -struct atomisp_overlay32 { - /* the frame containing the overlay data The overlay frame width should - * be the multiples of 2*ISP_VEC_NELEMS. The overlay frame height - * should be the multiples of 2. - */ - compat_uptr_t frame; - /* Y value of overlay background */ - unsigned char bg_y; - /* U value of overlay background */ - char bg_u; - /* V value of overlay background */ - char bg_v; - /* the blending percent of input data for Y subpixels */ - unsigned char blend_input_perc_y; - /* the blending percent of input data for U subpixels */ - unsigned char blend_input_perc_u; - /* the blending percent of input data for V subpixels */ - unsigned char blend_input_perc_v; - /* the blending percent of overlay data for Y subpixels */ - unsigned char blend_overlay_perc_y; - /* the blending percent of overlay data for U subpixels */ - unsigned char blend_overlay_perc_u; - /* the blending percent of overlay data for V subpixels */ - unsigned char blend_overlay_perc_v; - /* the overlay start x pixel position on output frame It should be the - multiples of 2*ISP_VEC_NELEMS. */ - unsigned int overlay_start_x; - /* the overlay start y pixel position on output frame It should be the - multiples of 2. */ - unsigned int overlay_start_y; -}; - -struct atomisp_shading_table32 { - __u32 enable; - __u32 sensor_width; - __u32 sensor_height; - __u32 width; - __u32 height; - __u32 fraction_bits; - - compat_uptr_t data[ATOMISP_NUM_SC_COLORS]; -}; - -struct atomisp_parameters32 { - compat_uptr_t wb_config; /* White Balance config */ - compat_uptr_t cc_config; /* Color Correction config */ - compat_uptr_t tnr_config; /* Temporal Noise Reduction */ - compat_uptr_t ecd_config; /* Eigen Color Demosaicing */ - compat_uptr_t ynr_config; /* Y(Luma) Noise Reduction */ - compat_uptr_t fc_config; /* Fringe Control */ - compat_uptr_t formats_config; /* Formats Control */ - compat_uptr_t cnr_config; /* Chroma Noise Reduction */ - compat_uptr_t macc_config; /* MACC */ - compat_uptr_t ctc_config; /* Chroma Tone Control */ - compat_uptr_t aa_config; /* Anti-Aliasing */ - compat_uptr_t baa_config; /* Anti-Aliasing */ - compat_uptr_t ce_config; - compat_uptr_t dvs_6axis_config; - compat_uptr_t ob_config; /* Objective Black config */ - compat_uptr_t dp_config; /* Dead Pixel config */ - compat_uptr_t nr_config; /* Noise Reduction config */ - compat_uptr_t ee_config; /* Edge Enhancement config */ - compat_uptr_t de_config; /* Demosaic config */ - compat_uptr_t gc_config; /* Gamma Correction config */ - compat_uptr_t anr_config; /* Advanced Noise Reduction */ - compat_uptr_t a3a_config; /* 3A Statistics config */ - compat_uptr_t xnr_config; /* eXtra Noise Reduction */ - compat_uptr_t dz_config; /* Digital Zoom */ - compat_uptr_t yuv2rgb_cc_config; /* Color - Correction config */ - compat_uptr_t rgb2yuv_cc_config; /* Color - Correction config */ - compat_uptr_t macc_table; - compat_uptr_t gamma_table; - compat_uptr_t ctc_table; - compat_uptr_t xnr_table; - compat_uptr_t r_gamma_table; - compat_uptr_t g_gamma_table; - compat_uptr_t b_gamma_table; - compat_uptr_t motion_vector; /* For 2-axis DVS */ - compat_uptr_t shading_table; - compat_uptr_t morph_table; - compat_uptr_t dvs_coefs; /* DVS 1.0 coefficients */ - compat_uptr_t dvs2_coefs; /* DVS 2.0 coefficients */ - compat_uptr_t capture_config; - compat_uptr_t anr_thres; - - compat_uptr_t lin_2500_config; /* Skylake: Linearization config */ - compat_uptr_t obgrid_2500_config; /* Skylake: OBGRID config */ - compat_uptr_t bnr_2500_config; /* Skylake: bayer denoise config */ - compat_uptr_t shd_2500_config; /* Skylake: shading config */ - compat_uptr_t dm_2500_config; /* Skylake: demosaic config */ - compat_uptr_t rgbpp_2500_config; /* Skylake: RGBPP config */ - compat_uptr_t dvs_stat_2500_config; /* Skylake: DVS STAT config */ - compat_uptr_t lace_stat_2500_config; /* Skylake: LACE STAT config */ - compat_uptr_t yuvp1_2500_config; /* Skylake: yuvp1 config */ - compat_uptr_t yuvp2_2500_config; /* Skylake: yuvp2 config */ - compat_uptr_t tnr_2500_config; /* Skylake: TNR config */ - compat_uptr_t dpc_2500_config; /* Skylake: DPC config */ - compat_uptr_t awb_2500_config; /* Skylake: auto white balance config */ - compat_uptr_t - awb_fr_2500_config; /* Skylake: auto white balance filter response config */ - compat_uptr_t anr_2500_config; /* Skylake: ANR config */ - compat_uptr_t af_2500_config; /* Skylake: auto focus config */ - compat_uptr_t ae_2500_config; /* Skylake: auto exposure config */ - compat_uptr_t bds_2500_config; /* Skylake: bayer downscaler config */ - compat_uptr_t - dvs_2500_config; /* Skylake: digital video stabilization config */ - compat_uptr_t res_mgr_2500_config; - - /* - * Output frame pointer the config is to be applied to (optional), - * set to NULL to make this config is applied as global. - */ - compat_uptr_t output_frame; - /* - * Unique ID to track which config was actually applied to a particular - * frame, driver will send this id back with output frame together. - */ - u32 isp_config_id; - u32 per_frame_setting; -}; - -struct atomisp_dvs_6axis_config32 { - u32 exp_id; - u32 width_y; - u32 height_y; - u32 width_uv; - u32 height_uv; - compat_uptr_t xcoords_y; - compat_uptr_t ycoords_y; - compat_uptr_t xcoords_uv; - compat_uptr_t ycoords_uv; -}; - -#define ATOMISP_IOC_G_HISTOGRAM32 \ - _IOWR('v', BASE_VIDIOC_PRIVATE + 3, struct atomisp_histogram32) -#define ATOMISP_IOC_S_HISTOGRAM32 \ - _IOW('v', BASE_VIDIOC_PRIVATE + 3, struct atomisp_histogram32) - -#define ATOMISP_IOC_G_DIS_STAT32 \ - _IOWR('v', BASE_VIDIOC_PRIVATE + 6, struct atomisp_dis_statistics32) -#define ATOMISP_IOC_S_DIS_COEFS32 \ - _IOW('v', BASE_VIDIOC_PRIVATE + 6, struct atomisp_dis_coefficients32) - -#define ATOMISP_IOC_S_DIS_VECTOR32 \ - _IOW('v', BASE_VIDIOC_PRIVATE + 6, struct atomisp_dvs_6axis_config32) - -#define ATOMISP_IOC_G_3A_STAT32 \ - _IOWR('v', BASE_VIDIOC_PRIVATE + 7, struct atomisp_3a_statistics32) - -#define ATOMISP_IOC_G_ISP_GDC_TAB32 \ - _IOR('v', BASE_VIDIOC_PRIVATE + 10, struct atomisp_morph_table32) -#define ATOMISP_IOC_S_ISP_GDC_TAB32 \ - _IOW('v', BASE_VIDIOC_PRIVATE + 10, struct atomisp_morph_table32) - -#define ATOMISP_IOC_S_ISP_FPN_TABLE32 \ - _IOW('v', BASE_VIDIOC_PRIVATE + 17, struct v4l2_framebuffer32) - -#define ATOMISP_IOC_G_ISP_OVERLAY32 \ - _IOWR('v', BASE_VIDIOC_PRIVATE + 18, struct atomisp_overlay32) -#define ATOMISP_IOC_S_ISP_OVERLAY32 \ - _IOW('v', BASE_VIDIOC_PRIVATE + 18, struct atomisp_overlay32) - -#define ATOMISP_IOC_S_ISP_SHD_TAB32 \ - _IOWR('v', BASE_VIDIOC_PRIVATE + 27, struct atomisp_shading_table32) - -#define ATOMISP_IOC_S_PARAMETERS32 \ - _IOW('v', BASE_VIDIOC_PRIVATE + 32, struct atomisp_parameters32) - -#endif /* __ATOMISP_COMPAT_IOCTL32_H__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2.c b/drivers/staging/media/atomisp/pci/atomisp_csi2.c index 28afc0bfc43b..95b9113d75e9 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.c @@ -298,7 +298,7 @@ static void atomisp_csi2_configure_isp2401(struct atomisp_sub_device *asd) ctrl.id = V4L2_CID_LINK_FREQ; if (v4l2_g_ctrl - (isp->inputs[asd->input_curr].camera->ctrl_handler, &ctrl) == 0) + (isp->inputs[asd->input_curr].sensor->ctrl_handler, &ctrl) == 0) mipi_freq = ctrl.value; clk_termen = atomisp_csi2_configure_calc(coeff_clk_termen, mipi_freq, diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2.h b/drivers/staging/media/atomisp/pci/atomisp_csi2.h index bb998c82a438..ec762f8fb922 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2.h +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.h @@ -19,28 +19,11 @@ #define CSI2_PAD_SOURCE 1 #define CSI2_PADS_NUM 2 -#define CSI2_MAX_ACPI_GPIOS 2u - -struct acpi_device; struct v4l2_device; struct atomisp_device; struct atomisp_sub_device; -struct atomisp_csi2_acpi_gpio_map { - struct acpi_gpio_params params[CSI2_MAX_ACPI_GPIOS]; - struct acpi_gpio_mapping mapping[CSI2_MAX_ACPI_GPIOS + 1]; -}; - -struct atomisp_csi2_acpi_gpio_parsing_data { - struct acpi_device *adev; - struct atomisp_csi2_acpi_gpio_map *map; - u32 settings[CSI2_MAX_ACPI_GPIOS]; - unsigned int settings_count; - unsigned int res_count; - unsigned int map_count; -}; - struct atomisp_mipi_csi2_device { struct v4l2_subdev subdev; struct media_pad pads[CSI2_PADS_NUM]; diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c b/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c index 6abda358a72f..2a90f86e515f 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c @@ -13,6 +13,7 @@ #include <linux/clk.h> #include <linux/device.h> #include <linux/dmi.h> +#include <linux/platform_data/x86/int3472.h> #include <linux/property.h> #include <media/ipu-bridge.h> @@ -25,39 +26,6 @@ #define PMC_CLK_RATE_19_2MHZ 19200000 /* - * 79234640-9e10-4fea-a5c1-b5aa8b19756f - * This _DSM GUID returns information about the GPIO lines mapped to a sensor. - * Function number 1 returns a count of the GPIO lines that are mapped. - * Subsequent functions return 32 bit ints encoding information about the GPIO. - */ -static const guid_t intel_sensor_gpio_info_guid = - GUID_INIT(0x79234640, 0x9e10, 0x4fea, - 0xa5, 0xc1, 0xb5, 0xaa, 0x8b, 0x19, 0x75, 0x6f); - -#define INTEL_GPIO_DSM_TYPE_SHIFT 0 -#define INTEL_GPIO_DSM_TYPE_MASK GENMASK(7, 0) -#define INTEL_GPIO_DSM_PIN_SHIFT 8 -#define INTEL_GPIO_DSM_PIN_MASK GENMASK(15, 8) -#define INTEL_GPIO_DSM_SENSOR_ON_VAL_SHIFT 24 -#define INTEL_GPIO_DSM_SENSOR_ON_VAL_MASK GENMASK(31, 24) - -#define INTEL_GPIO_DSM_TYPE(x) \ - (((x) & INTEL_GPIO_DSM_TYPE_MASK) >> INTEL_GPIO_DSM_TYPE_SHIFT) -#define INTEL_GPIO_DSM_PIN(x) \ - (((x) & INTEL_GPIO_DSM_PIN_MASK) >> INTEL_GPIO_DSM_PIN_SHIFT) -#define INTEL_GPIO_DSM_SENSOR_ON_VAL(x) \ - (((x) & INTEL_GPIO_DSM_SENSOR_ON_VAL_MASK) >> INTEL_GPIO_DSM_SENSOR_ON_VAL_SHIFT) - -/* - * 822ace8f-2814-4174-a56b-5f029fe079ee - * This _DSM GUID returns a string from the sensor device, which acts as a - * module identifier. - */ -static const guid_t intel_sensor_module_guid = - GUID_INIT(0x822ace8f, 0x2814, 0x4174, - 0xa5, 0x6b, 0x5f, 0x02, 0x9f, 0xe0, 0x79, 0xee); - -/* * dc2f6c4f-045b-4f1d-97b9-882a6860a4be * This _DSM GUID returns a package with n*2 strings, with each set of 2 strings * forming a key, value pair for settings like e.g. "CsiLanes" = "1". @@ -323,196 +291,45 @@ static int atomisp_csi2_get_port(struct acpi_device *adev, int clock_num) return gmin_cfg_get_int(adev, "CsiPort", port); } -/* Note this always returns 1 to continue looping so that res_count is accurate */ -static int atomisp_csi2_handle_acpi_gpio_res(struct acpi_resource *ares, void *_data) -{ - struct atomisp_csi2_acpi_gpio_parsing_data *data = _data; - struct acpi_resource_gpio *agpio; - const char *name; - bool active_low; - unsigned int i; - u32 settings = 0; - u16 pin; - - if (!acpi_gpio_get_io_resource(ares, &agpio)) - return 1; /* Not a GPIO, continue the loop */ - - data->res_count++; - - pin = agpio->pin_table[0]; - for (i = 0; i < data->settings_count; i++) { - if (INTEL_GPIO_DSM_PIN(data->settings[i]) == pin) { - settings = data->settings[i]; - break; - } - } - - if (i == data->settings_count) { - acpi_handle_warn(data->adev->handle, - "%s: Could not find DSM GPIO settings for pin %u\n", - dev_name(&data->adev->dev), pin); - return 1; - } - - switch (INTEL_GPIO_DSM_TYPE(settings)) { - case 0: - name = "reset-gpios"; - break; - case 1: - name = "powerdown-gpios"; - break; - default: - acpi_handle_warn(data->adev->handle, "%s: Unknown GPIO type 0x%02lx for pin %u\n", - dev_name(&data->adev->dev), - INTEL_GPIO_DSM_TYPE(settings), pin); - return 1; - } - - /* - * Both reset and power-down need to be logical false when the sensor - * is on (sensor should not be in reset and not be powered-down). So - * when the sensor-on-value (which is the physical pin value) is high, - * then the signal is active-low. - */ - active_low = INTEL_GPIO_DSM_SENSOR_ON_VAL(settings); - - i = data->map_count; - if (i == CSI2_MAX_ACPI_GPIOS) - return 1; - - /* res_count is already incremented */ - data->map->params[i].crs_entry_index = data->res_count - 1; - data->map->params[i].active_low = active_low; - data->map->mapping[i].name = name; - data->map->mapping[i].data = &data->map->params[i]; - data->map->mapping[i].size = 1; - data->map_count++; - - acpi_handle_info(data->adev->handle, "%s: %s crs %d %s pin %u active-%s\n", - dev_name(&data->adev->dev), name, - data->res_count - 1, agpio->resource_source.string_ptr, - pin, active_low ? "low" : "high"); - - return 1; -} - /* - * Helper function to create an ACPI GPIO lookup table for sensor reset and - * powerdown signals on Intel Bay Trail (BYT) and Cherry Trail (CHT) devices, - * including setting the correct polarity for the GPIO. - * - * This uses the "79234640-9e10-4fea-a5c1-b5aa8b19756f" DSM method directly - * on the sensor device's ACPI node. This is different from later Intel - * hardware which has a separate INT3472 acpi_device with this info. - * - * This function must be called before creating the sw-noded describing - * the fwnode graph endpoint. And sensor drivers used on these devices - * must return -EPROBE_DEFER when there is no endpoint description yet. - * Together this guarantees that the GPIO lookups are in place before - * the sensor driver tries to get GPIOs with gpiod_get(). + * Alloc and fill an int3472_discrete_device struct so that we can re-use + * the INT3472 sensor GPIO mapping code. * - * Note this code uses the same DSM GUID as the int3472_gpio_guid in - * the INT3472 discrete.c code and there is some overlap, but there are - * enough differences that it is difficult to share the code. + * This gets called from ipu_bridge_init() which runs only once per boot, + * the created faux int3472 device is leaked on purpose to keep the created + * GPIO mappings around permanently. */ static int atomisp_csi2_add_gpio_mappings(struct acpi_device *adev) { - struct atomisp_csi2_acpi_gpio_parsing_data data = { }; - LIST_HEAD(resource_list); - union acpi_object *obj; - unsigned int i, j; + struct int3472_discrete_device *int3472; int ret; - obj = acpi_evaluate_dsm_typed(adev->handle, &intel_sensor_module_guid, - 0x00, 1, NULL, ACPI_TYPE_STRING); - if (obj) { - acpi_handle_info(adev->handle, "%s: Sensor module id: '%s'\n", - dev_name(&adev->dev), obj->string.pointer); - ACPI_FREE(obj); - } + /* Max num GPIOs we've seen plus a terminator */ + int3472 = kzalloc(struct_size(int3472, gpios.table, INT3472_MAX_SENSOR_GPIOS + 1), + GFP_KERNEL); + if (!int3472) + return -ENOMEM; /* - * First get the GPIO-settings count and then get count GPIO-settings - * values. Note the order of these may differ from the order in which - * the GPIOs are listed on the ACPI resources! So we first store them all - * and then enumerate the ACPI resources and match them up by pin number. + * On atomisp the _DSM to get the GPIO type must be made on the sensor + * adev, rather than on a separate INT3472 adev. */ - obj = acpi_evaluate_dsm_typed(adev->handle, - &intel_sensor_gpio_info_guid, 0x00, 1, - NULL, ACPI_TYPE_INTEGER); - if (!obj) { - acpi_handle_err(adev->handle, "%s: No _DSM entry for GPIO pin count\n", - dev_name(&adev->dev)); - return -EIO; - } - - data.settings_count = obj->integer.value; - ACPI_FREE(obj); + int3472->adev = adev; + int3472->dev = &adev->dev; + int3472->sensor = adev; - if (data.settings_count > CSI2_MAX_ACPI_GPIOS) { - acpi_handle_err(adev->handle, "%s: Too many GPIOs %u > %u\n", - dev_name(&adev->dev), data.settings_count, - CSI2_MAX_ACPI_GPIOS); - return -EOVERFLOW; + int3472->sensor_name = kasprintf(GFP_KERNEL, I2C_DEV_NAME_FORMAT, acpi_dev_name(adev)); + if (!int3472->sensor_name) { + kfree(int3472); + return -ENOMEM; } - for (i = 0; i < data.settings_count; i++) { - /* - * i + 2 because the index of this _DSM function is 1-based - * and the first function is just a count. - */ - obj = acpi_evaluate_dsm_typed(adev->handle, - &intel_sensor_gpio_info_guid, - 0x00, i + 2, - NULL, ACPI_TYPE_INTEGER); - if (!obj) { - acpi_handle_err(adev->handle, "%s: No _DSM entry for pin %u\n", - dev_name(&adev->dev), i); - return -EIO; - } - - data.settings[i] = obj->integer.value; - ACPI_FREE(obj); + ret = int3472_discrete_parse_crs(int3472); + if (ret) { + int3472_discrete_cleanup(int3472); + kfree(int3472); } - /* Since we match up by pin-number the pin-numbers must be unique */ - for (i = 0; i < data.settings_count; i++) { - for (j = i + 1; j < data.settings_count; j++) { - if (INTEL_GPIO_DSM_PIN(data.settings[i]) != - INTEL_GPIO_DSM_PIN(data.settings[j])) - continue; - - acpi_handle_err(adev->handle, "%s: Duplicate pin number %lu\n", - dev_name(&adev->dev), - INTEL_GPIO_DSM_PIN(data.settings[i])); - return -EIO; - } - } - - data.map = kzalloc(sizeof(*data.map), GFP_KERNEL); - if (!data.map) - return -ENOMEM; - - /* Now parse the ACPI resources and build the lookup table */ - data.adev = adev; - ret = acpi_dev_get_resources(adev, &resource_list, - atomisp_csi2_handle_acpi_gpio_res, &data); - if (ret < 0) - return ret; - - acpi_dev_free_resource_list(&resource_list); - - if (data.map_count != data.settings_count || - data.res_count != data.settings_count) - acpi_handle_warn(adev->handle, "%s: ACPI GPIO resources vs DSM GPIO-info count mismatch (dsm: %d res: %d map %d\n", - dev_name(&adev->dev), data.settings_count, - data.res_count, data.map_count); - - ret = acpi_dev_add_driver_gpios(adev, data.map->mapping); - if (ret) - acpi_handle_err(adev->handle, "%s: Error adding driver GPIOs: %d\n", - dev_name(&adev->dev), ret); - return ret; } diff --git a/drivers/staging/media/atomisp/pci/atomisp_drvfs.c b/drivers/staging/media/atomisp/pci/atomisp_drvfs.c deleted file mode 100644 index 31c82c3c0d33..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp_drvfs.c +++ /dev/null @@ -1,155 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Support for atomisp driver sysfs interface - * - * Copyright (c) 2014 Intel Corporation. All Rights Reserved. - */ - -#include <linux/device.h> -#include <linux/err.h> -#include <linux/kernel.h> - -#include "atomisp_compat.h" -#include "atomisp_internal.h" -#include "atomisp_ioctl.h" -#include "atomisp_drvfs.h" -#include "hmm/hmm.h" -#include "ia_css_debug.h" - -#define OPTION_BIN_LIST BIT(0) -#define OPTION_BIN_RUN BIT(1) -#define OPTION_VALID (OPTION_BIN_LIST | OPTION_BIN_RUN) - -/* - * dbgopt: iunit debug option: - * bit 0: binary list - * bit 1: running binary - * bit 2: memory statistic - */ -static unsigned int dbgopt = OPTION_BIN_LIST; - -static inline int iunit_dump_dbgopt(struct atomisp_device *isp, - unsigned int opt) -{ - int ret = 0; - - if (opt & OPTION_VALID) { - if (opt & OPTION_BIN_LIST) { - ret = atomisp_css_dump_blob_infor(isp); - if (ret) { - dev_err(isp->dev, "%s dump blob infor err[ret:%d]\n", - __func__, ret); - goto opt_err; - } - } - - if (opt & OPTION_BIN_RUN) { - if (isp->asd.streaming) { - atomisp_css_dump_sp_raw_copy_linecount(true); - atomisp_css_debug_dump_isp_binary(); - } else { - ret = -EPERM; - dev_err(isp->dev, "%s dump running bin err[ret:%d]\n", - __func__, ret); - goto opt_err; - } - } - } else { - ret = -EINVAL; - dev_err(isp->dev, "%s dump nothing[ret=%d]\n", __func__, ret); - } - -opt_err: - return ret; -} - -static ssize_t dbglvl_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - unsigned int dbglvl = ia_css_debug_get_dtrace_level(); - - return sysfs_emit(buf, "dtrace level:%u\n", dbglvl); -} - -static ssize_t dbglvl_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) -{ - unsigned int dbglvl; - int ret; - - ret = kstrtouint(buf, 10, &dbglvl); - if (ret) - return ret; - - if (dbglvl < 1 || dbglvl > 9) - return -ERANGE; - - ia_css_debug_set_dtrace_level(dbglvl); - return size; -} -static DEVICE_ATTR_RW(dbglvl); - -static ssize_t dbgfun_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - unsigned int dbgfun = atomisp_get_css_dbgfunc(); - - return sysfs_emit(buf, "dbgfun opt:%u\n", dbgfun); -} - -static ssize_t dbgfun_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) -{ - struct atomisp_device *isp = dev_get_drvdata(dev); - unsigned int opt; - int ret; - - ret = kstrtouint(buf, 10, &opt); - if (ret) - return ret; - - return atomisp_set_css_dbgfunc(isp, opt); -} -static DEVICE_ATTR_RW(dbgfun); - -static ssize_t dbgopt_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "option:0x%x\n", dbgopt); -} - -static ssize_t dbgopt_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) -{ - struct atomisp_device *isp = dev_get_drvdata(dev); - unsigned int opt; - int ret; - - ret = kstrtouint(buf, 10, &opt); - if (ret) - return ret; - - dbgopt = opt; - ret = iunit_dump_dbgopt(isp, dbgopt); - if (ret) - return ret; - - return size; -} -static DEVICE_ATTR_RW(dbgopt); - -static struct attribute *dbg_attrs[] = { - &dev_attr_dbglvl.attr, - &dev_attr_dbgfun.attr, - &dev_attr_dbgopt.attr, - NULL -}; - -static const struct attribute_group dbg_attr_group = { - .attrs = dbg_attrs, -}; - -const struct attribute_group *dbg_attr_groups[] = { - &dbg_attr_group, - NULL -}; diff --git a/drivers/staging/media/atomisp/pci/atomisp_drvfs.h b/drivers/staging/media/atomisp/pci/atomisp_drvfs.h deleted file mode 100644 index 46ad59b8df28..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp_drvfs.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Support for atomisp driver sysfs interface. - * - * Copyright (c) 2014 Intel Corporation. All Rights Reserved. - */ - -#ifndef __ATOMISP_DRVFS_H__ -#define __ATOMISP_DRVFS_H__ - -#include <linux/sysfs.h> - -extern const struct attribute_group *dbg_attr_groups[]; - -#endif /* __ATOMISP_DRVFS_H__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c index 57da7ddb1503..c7aef066f209 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c @@ -234,9 +234,6 @@ static int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd, if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM)) return -EINVAL; - if (pipe->stopping) - return -EINVAL; - space = ATOMISP_CSS_Q_DEPTH - atomisp_buffers_in_css(pipe); while (space--) { struct ia_css_frame *frame; @@ -367,7 +364,7 @@ static void atomisp_buf_queue(struct vb2_buffer *vb) mutex_lock(&asd->isp->mutex); ret = atomisp_pipe_check(pipe, false); - if (ret || pipe->stopping) { + if (ret) { spin_lock_irqsave(&pipe->irq_lock, irqflags); atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR); spin_unlock_irqrestore(&pipe->irq_lock, irqflags); diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c index e176483df301..964cc3bcc0ac 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c +++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c @@ -85,9 +85,6 @@ struct gmin_subdev { bool v2p8_on; bool v1p2_on; - int v1p8_gpio; - int v2p8_gpio; - u8 pwm_i2c_addr; /* For PMIC AXP */ @@ -225,16 +222,6 @@ static struct gmin_cfg_var ffrd8_vars[] = { {}, }; -/* Cribbed from MCG defaults in the mt9m114 driver, not actually verified - * vs. T100 hardware - */ -static struct gmin_cfg_var t100_vars[] = { - { "INT33F0:00_CsiPort", "0" }, - { "INT33F0:00_CsiLanes", "1" }, - { "INT33F0:00_CamClk", "1" }, - {}, -}; - static struct gmin_cfg_var mrd7_vars[] = { {"INT33F8:00_CamType", "1"}, {"INT33F8:00_CsiPort", "1"}, @@ -252,22 +239,6 @@ static struct gmin_cfg_var mrd7_vars[] = { {}, }; -static struct gmin_cfg_var ecs7_vars[] = { - {"INT33BE:00_CsiPort", "1"}, - {"INT33BE:00_CsiLanes", "2"}, - {"INT33BE:00_CsiFmt", "13"}, - {"INT33BE:00_CsiBayer", "2"}, - {"INT33BE:00_CamClk", "0"}, - - {"INT33F0:00_CsiPort", "0"}, - {"INT33F0:00_CsiLanes", "1"}, - {"INT33F0:00_CsiFmt", "13"}, - {"INT33F0:00_CsiBayer", "0"}, - {"INT33F0:00_CamClk", "1"}, - {"gmin_V2P8GPIO", "402"}, - {}, -}; - static struct gmin_cfg_var i8880_vars[] = { {"XXOV2680:00_CsiPort", "1"}, {"XXOV2680:00_CsiLanes", "1"}, @@ -310,13 +281,6 @@ static const struct dmi_system_id gmin_vars[] = { .driver_data = ffrd8_vars, }, { - .ident = "T100TA", - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "T100TA"), - }, - .driver_data = t100_vars, - }, - { .ident = "MRD7", .matches = { DMI_MATCH(DMI_BOARD_NAME, "TABLET"), @@ -325,13 +289,6 @@ static const struct dmi_system_id gmin_vars[] = { .driver_data = mrd7_vars, }, { - .ident = "ST70408", - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "ST70408"), - }, - .driver_data = ecs7_vars, - }, - { .ident = "VTA0803", .matches = { DMI_MATCH(DMI_BOARD_NAME, "VTA0803"), @@ -516,9 +473,9 @@ static int gmin_subdev_add(struct gmin_subdev *gs) dev_info(dev, "%s: ACPI path is %pfw\n", __func__, dev_fwnode(dev)); - /*WA:CHT requires XTAL clock as PLL is not stable.*/ + /* WA:CHT requires XTAL clock as PLL is not stable. */ gs->clock_src = gmin_get_var_int(dev, false, "ClkSrc", - VLV2_CLK_PLL_19P2MHZ); + VLV2_CLK_PLL_19P2MHZ); /* * Get ACPI _PR0 derived clock here already because it is used @@ -549,23 +506,6 @@ static int gmin_subdev_add(struct gmin_subdev *gs) dev_info(dev, "will handle gpio1 via ACPI\n"); /* - * Those are used only when there is an external regulator apart - * from the PMIC that would be providing power supply, like on the - * two cases below: - * - * The ECS E7 board drives camera 2.8v from an external regulator - * instead of the PMIC. There's a gmin_CamV2P8 config variable - * that specifies the GPIO to handle this particular case, - * but this needs a broader architecture for handling camera power. - * - * The CHT RVP board drives camera 1.8v from an* external regulator - * instead of the PMIC just like ECS E7 board. - */ - - gs->v1p8_gpio = gmin_get_var_int(dev, true, "V1P8GPIO", -1); - gs->v2p8_gpio = gmin_get_var_int(dev, true, "V2P8GPIO", -1); - - /* * FIXME: * * The ACPI handling code checks for the _PR? tables in order to @@ -837,16 +777,6 @@ static int gmin_v1p8_ctrl(struct v4l2_subdev *subdev, int on) if (!gs || gs->v1p8_on == on) return 0; - if (gs->v1p8_gpio >= 0) { - pr_info("atomisp_gmin_platform: 1.8v power on GPIO %d\n", - gs->v1p8_gpio); - ret = gpio_request(gs->v1p8_gpio, "camera_v1p8_en"); - if (!ret) - ret = gpio_direction_output(gs->v1p8_gpio, 0); - if (ret) - pr_err("V1P8 GPIO initialization failed\n"); - } - gs->v1p8_on = on; ret = 0; @@ -861,9 +791,6 @@ static int gmin_v1p8_ctrl(struct v4l2_subdev *subdev, int on) goto out; /* Still needed */ } - if (gs->v1p8_gpio >= 0) - gpio_set_value(gs->v1p8_gpio, on); - if (gs->v1p8_reg) { regulator_set_voltage(gs->v1p8_reg, 1800000, 1800000); if (on) @@ -918,16 +845,6 @@ static int gmin_v2p8_ctrl(struct v4l2_subdev *subdev, int on) if (WARN_ON(!gs)) return -ENODEV; - if (gs->v2p8_gpio >= 0) { - pr_info("atomisp_gmin_platform: 2.8v power on GPIO %d\n", - gs->v2p8_gpio); - ret = gpio_request(gs->v2p8_gpio, "camera_v2p8"); - if (!ret) - ret = gpio_direction_output(gs->v2p8_gpio, 0); - if (ret) - pr_err("V2P8 GPIO initialization failed\n"); - } - if (gs->v2p8_on == on) return 0; gs->v2p8_on = on; @@ -944,9 +861,6 @@ static int gmin_v2p8_ctrl(struct v4l2_subdev *subdev, int on) goto out; /* Still needed */ } - if (gs->v2p8_gpio >= 0) - gpio_set_value(gs->v2p8_gpio, on); - if (gs->v2p8_reg) { regulator_set_voltage(gs->v2p8_reg, 2900000, 2900000); if (on) @@ -1292,7 +1206,7 @@ static int gmin_get_config_dsm_var(struct device *dev, * if it founds something different than string, letting it * to fall back to the old code. */ - if (cur && cur->type != ACPI_TYPE_STRING) { + if (cur->type != ACPI_TYPE_STRING) { dev_info(dev, "found non-string _DSM entry for '%s'\n", var); ACPI_FREE(obj); return -EINVAL; @@ -1358,14 +1272,15 @@ static int gmin_get_config_var(struct device *maindev, if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) status = efi.get_variable(var16, &GMIN_CFG_VAR_EFI_GUID, NULL, (unsigned long *)out_len, out); - if (status == EFI_SUCCESS) + if (status == EFI_SUCCESS) { dev_info(maindev, "found EFI entry for '%s'\n", var8); - else if (is_gmin) + return 0; + } + if (is_gmin) dev_info(maindev, "Failed to find EFI gmin variable %s\n", var8); else dev_info(maindev, "Failed to find EFI variable %s\n", var8); - - return ret; + return -ENOENT; } int gmin_get_var_int(struct device *dev, bool is_gmin, const char *var, int def) diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h index 775506757471..5a69580b8251 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h @@ -109,14 +109,20 @@ #define DIV_NEAREST_STEP(n, d, step) \ round_down((2 * (n) + (d) * (step)) / (2 * (d)), (step)) +#define SENSOR_ISP_PAD_SINK 0 +#define SENSOR_ISP_PAD_SOURCE 1 +#define SENSOR_ISP_PADS_NUM 2 + struct atomisp_input_subdev { enum atomisp_camera_port port; u32 code; /* MEDIA_BUS_FMT_* */ bool binning_support; bool crop_support; - bool camera_on; - struct v4l2_subdev *camera; + bool sensor_on; + struct v4l2_subdev *sensor; + struct v4l2_subdev *sensor_isp; struct v4l2_subdev *csi_port; + struct v4l2_subdev *csi_remote_source; /* Sensor rects for sensors which support crop */ struct v4l2_rect native_rect; struct v4l2_rect active_rect; diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c index 1fb2ba819de3..bb8b2f2213b0 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c @@ -386,11 +386,11 @@ static int atomisp_enum_input(struct file *file, void *fh, if (index >= isp->input_cnt) return -EINVAL; - if (!isp->inputs[index].camera) + if (!isp->inputs[index].sensor) return -EINVAL; memset(input, 0, sizeof(struct v4l2_input)); - strscpy(input->name, isp->inputs[index].camera->name, + strscpy(input->name, isp->inputs[index].sensor->name, sizeof(input->name)); input->type = V4L2_INPUT_TYPE_CAMERA; @@ -433,7 +433,7 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input) if (input >= isp->input_cnt) return -EINVAL; - if (!isp->inputs[input].camera) + if (!isp->inputs[input].sensor) return -EINVAL; ret = atomisp_pipe_check(pipe, true); @@ -539,14 +539,14 @@ static int atomisp_enum_framesizes(struct file *file, void *priv, struct v4l2_subdev_state *act_sd_state; int ret; - if (!input->camera) + if (!input->sensor) return -EINVAL; if (input->crop_support) return atomisp_enum_framesizes_crop(isp, fsize); - act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); - ret = v4l2_subdev_call(input->camera, pad, enum_frame_size, + act_sd_state = v4l2_subdev_lock_and_get_active_state(input->sensor); + ret = v4l2_subdev_call(input->sensor, pad, enum_frame_size, act_sd_state, &fse); if (act_sd_state) v4l2_subdev_unlock_state(act_sd_state); @@ -577,11 +577,11 @@ static int atomisp_enum_frameintervals(struct file *file, void *priv, struct v4l2_subdev_state *act_sd_state; int ret; - if (!input->camera) + if (!input->sensor) return -EINVAL; - act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); - ret = v4l2_subdev_call(input->camera, pad, enum_frame_interval, + act_sd_state = v4l2_subdev_lock_and_get_active_state(input->sensor); + ret = v4l2_subdev_call(input->sensor, pad, enum_frame_interval, act_sd_state, &fie); if (act_sd_state) v4l2_subdev_unlock_state(act_sd_state); @@ -609,11 +609,11 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh, unsigned int i, fi = 0; int ret; - if (!input->camera) + if (!input->sensor) return -EINVAL; - act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); - ret = v4l2_subdev_call(input->camera, pad, enum_mbus_code, + act_sd_state = v4l2_subdev_lock_and_get_active_state(input->sensor); + ret = v4l2_subdev_call(input->sensor, pad, enum_mbus_code, act_sd_state, &code); if (act_sd_state) v4l2_subdev_unlock_state(act_sd_state); @@ -856,6 +856,62 @@ static void atomisp_dma_burst_len_cfg(struct atomisp_sub_device *asd) atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x00); } +static void atomisp_stop_stream(struct atomisp_video_pipe *pipe, + bool stop_sensor, enum vb2_buffer_state state) +{ + struct atomisp_sub_device *asd = pipe->asd; + struct atomisp_device *isp = asd->isp; + struct pci_dev *pdev = to_pci_dev(isp->dev); + unsigned long flags; + int ret; + + spin_lock_irqsave(&isp->lock, flags); + asd->streaming = false; + spin_unlock_irqrestore(&isp->lock, flags); + + atomisp_clear_css_buffer_counters(asd); + atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false); + + atomisp_css_stop(asd, false); + + atomisp_subdev_cleanup_pending_events(asd); + + if (stop_sensor) { + ret = v4l2_subdev_call(isp->inputs[asd->input_curr].csi_remote_source, + video, s_stream, 0); + if (ret) + dev_warn(isp->dev, "Stopping sensor stream failed: %d\n", ret); + } + + /* Disable the CSI interface on ANN B0/K0 */ + if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << + ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { + pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL, + isp->saved_regs.csi_control & ~MRFLD_PCI_CSI_CONTROL_CSI_READY); + } + + if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false)) + dev_warn(isp->dev, "DFS failed.\n"); + + /* + * ISP work around, need to reset ISP to allow next stream on to work. + * Streams have already been destroyed by atomisp_css_stop(). + * Disable PUNIT/ISP acknowledge/handshake - SRSE=3 and then reset. + */ + pci_write_config_dword(pdev, PCI_I_CONTROL, + isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK); + atomisp_reset(isp); + + atomisp_flush_video_pipe(pipe, state, false); + + /* Streams were destroyed by atomisp_css_stop(), recreate them. */ + ret = atomisp_create_pipes_stream(&isp->asd); + if (ret) + dev_warn(isp->dev, "Recreating streams failed: %d\n", ret); + + media_pipeline_stop(&asd->video_out.vdev.entity.pads[0]); +} + int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) { struct atomisp_video_pipe *pipe = vq_to_pipe(vq); @@ -910,6 +966,7 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) ret = atomisp_css_start(asd); if (ret) { atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_QUEUED, true); + media_pipeline_stop(&asd->video_out.vdev.entity.pads[0]); goto out_unlock; } @@ -945,15 +1002,11 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) } /* stream on the sensor */ - ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, + ret = v4l2_subdev_call(isp->inputs[asd->input_curr].csi_remote_source, video, s_stream, 1); if (ret) { dev_err(isp->dev, "Starting sensor stream failed: %d\n", ret); - spin_lock_irqsave(&isp->lock, irqflags); - asd->streaming = false; - spin_unlock_irqrestore(&isp->lock, irqflags); - ret = -EINVAL; - goto out_unlock; + atomisp_stop_stream(pipe, false, VB2_BUF_STATE_QUEUED); } out_unlock: @@ -964,74 +1017,12 @@ out_unlock: void atomisp_stop_streaming(struct vb2_queue *vq) { struct atomisp_video_pipe *pipe = vq_to_pipe(vq); - struct atomisp_sub_device *asd = pipe->asd; - struct atomisp_device *isp = asd->isp; - struct pci_dev *pdev = to_pci_dev(isp->dev); - unsigned long flags; - int ret; + struct atomisp_device *isp = pipe->asd->isp; dev_dbg(isp->dev, "Stop stream\n"); mutex_lock(&isp->mutex); - /* - * There is no guarantee that the buffers queued to / owned by the ISP - * will properly be returned to the queue when stopping. Set a flag to - * avoid new buffers getting queued and then wait for all the current - * buffers to finish. - */ - pipe->stopping = true; - mutex_unlock(&isp->mutex); - /* wait max 1 second */ - ret = wait_event_timeout(pipe->vb_queue.done_wq, - atomisp_buffers_in_css(pipe) == 0, HZ); - mutex_lock(&isp->mutex); - pipe->stopping = false; - if (ret == 0) - dev_warn(isp->dev, "Warning timeout waiting for CSS to return buffers\n"); - - spin_lock_irqsave(&isp->lock, flags); - asd->streaming = false; - spin_unlock_irqrestore(&isp->lock, flags); - - atomisp_clear_css_buffer_counters(asd); - atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false); - - atomisp_css_stop(asd, false); - - atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_ERROR, true); - - atomisp_subdev_cleanup_pending_events(asd); - - ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, - video, s_stream, 0); - if (ret) - dev_warn(isp->dev, "Stopping sensor stream failed: %d\n", ret); - - /* Disable the CSI interface on ANN B0/K0 */ - if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << - ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { - pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL, - isp->saved_regs.csi_control & ~MRFLD_PCI_CSI_CONTROL_CSI_READY); - } - - if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false)) - dev_warn(isp->dev, "DFS failed.\n"); - - /* - * ISP work around, need to reset ISP to allow next stream on to work. - * Streams have already been destroyed by atomisp_css_stop(). - * Disable PUNIT/ISP acknowledge/handshake - SRSE=3 and then reset. - */ - pci_write_config_dword(pdev, PCI_I_CONTROL, - isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK); - atomisp_reset(isp); - - /* Streams were destroyed by atomisp_css_stop(), recreate them. */ - ret = atomisp_create_pipes_stream(&isp->asd); - if (ret) - dev_warn(isp->dev, "Recreating streams failed: %d\n", ret); - - media_pipeline_stop(&asd->video_out.vdev.entity.pads[0]); + atomisp_stop_stream(pipe, true, VB2_BUF_STATE_ERROR); mutex_unlock(&isp->mutex); } @@ -1332,7 +1323,7 @@ static int atomisp_s_parm(struct file *file, void *fh, fi.interval = parm->parm.capture.timeperframe; - rval = v4l2_subdev_call_state_active(isp->inputs[asd->input_curr].camera, + rval = v4l2_subdev_call_state_active(isp->inputs[asd->input_curr].csi_remote_source, pad, set_frame_interval, &fi); if (!rval) parm->parm.capture.timeperframe = fi.interval; diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.h b/drivers/staging/media/atomisp/pci/atomisp_ioctl.h index 4feaa0338cb4..57f608f9db56 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.h +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.h @@ -33,8 +33,4 @@ void atomisp_stop_streaming(struct vb2_queue *vq); extern const struct v4l2_ioctl_ops atomisp_ioctl_ops; -/* compat_ioctl for 32bit userland app and 64bit kernel */ -long atomisp_compat_ioctl32(struct file *file, - unsigned int cmd, unsigned long arg); - #endif /* __ATOMISP_IOCTL_H__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.h b/drivers/staging/media/atomisp/pci/atomisp_subdev.h index bd1a198cda30..e1d0168cb91d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.h +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.h @@ -57,9 +57,6 @@ struct atomisp_video_pipe { /* Filled through atomisp_get_css_frame_info() on queue setup */ struct ia_css_frame_info frame_info; - /* Set from streamoff to disallow queuing further buffers in CSS */ - bool stopping; - /* * irq_lock is used to protect video buffer state change operations and * also to make activeq and capq operations atomic. diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 2841824cd0ca..900a67552d6a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -29,7 +29,6 @@ #include "atomisp_internal.h" #include "atomisp-regs.h" #include "atomisp_dfs_tables.h" -#include "atomisp_drvfs.h" #include "hmm/hmm.h" #include "atomisp_trace_event.h" @@ -895,24 +894,25 @@ static void atomisp_init_sensor(struct atomisp_input_subdev *input) * it emulates a normal v4l2 device there, passing through try_fmt / * set_fmt to the sensor. */ - try_sd_state = __v4l2_subdev_state_alloc(input->camera, - "atomisp:try_sd_state->lock", &try_sd_state_key); + try_sd_state = __v4l2_subdev_state_alloc(input->sensor, + "atomisp:try_sd_state->lock", + &try_sd_state_key); if (IS_ERR(try_sd_state)) return; input->try_sd_state = try_sd_state; - act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); + act_sd_state = v4l2_subdev_lock_and_get_active_state(input->sensor); mbus_code_enum.which = V4L2_SUBDEV_FORMAT_ACTIVE; - err = v4l2_subdev_call(input->camera, pad, enum_mbus_code, + err = v4l2_subdev_call(input->sensor, pad, enum_mbus_code, act_sd_state, &mbus_code_enum); if (!err) input->code = mbus_code_enum.code; sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; sel.target = V4L2_SEL_TGT_NATIVE_SIZE; - err = v4l2_subdev_call(input->camera, pad, get_selection, + err = v4l2_subdev_call(input->sensor, pad, get_selection, act_sd_state, &sel); if (err) goto unlock_act_sd_state; @@ -921,7 +921,7 @@ static void atomisp_init_sensor(struct atomisp_input_subdev *input) sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; sel.target = V4L2_SEL_TGT_CROP_DEFAULT; - err = v4l2_subdev_call(input->camera, pad, get_selection, + err = v4l2_subdev_call(input->sensor, pad, get_selection, act_sd_state, &sel); if (err) goto unlock_act_sd_state; @@ -939,7 +939,7 @@ static void atomisp_init_sensor(struct atomisp_input_subdev *input) fse.code = input->code; fse.which = V4L2_SUBDEV_FORMAT_ACTIVE; - err = v4l2_subdev_call(input->camera, pad, enum_frame_size, + err = v4l2_subdev_call(input->sensor, pad, enum_frame_size, act_sd_state, &fse); if (err) break; @@ -962,22 +962,29 @@ static void atomisp_init_sensor(struct atomisp_input_subdev *input) sel.which = V4L2_SUBDEV_FORMAT_TRY; sel.target = V4L2_SEL_TGT_CROP; sel.r = input->native_rect; - v4l2_subdev_lock_state(input->try_sd_state); - err = v4l2_subdev_call(input->camera, pad, set_selection, + + /* Don't lock try_sd_state if the lock is shared with the active state */ + if (!input->sensor->state_lock) + v4l2_subdev_lock_state(input->try_sd_state); + + err = v4l2_subdev_call(input->sensor, pad, set_selection, input->try_sd_state, &sel); - v4l2_subdev_unlock_state(input->try_sd_state); + + if (!input->sensor->state_lock) + v4l2_subdev_unlock_state(input->try_sd_state); + if (err) goto unlock_act_sd_state; sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; sel.target = V4L2_SEL_TGT_CROP; sel.r = input->native_rect; - err = v4l2_subdev_call(input->camera, pad, set_selection, + err = v4l2_subdev_call(input->sensor, pad, set_selection, act_sd_state, &sel); if (err) goto unlock_act_sd_state; - dev_info(input->camera->dev, "Supports crop native %dx%d active %dx%d binning %d\n", + dev_info(input->sensor->dev, "Supports crop native %dx%d active %dx%d binning %d\n", input->native_rect.width, input->native_rect.height, input->active_rect.width, input->active_rect.height, input->binning_support); @@ -991,8 +998,9 @@ unlock_act_sd_state: int atomisp_register_device_nodes(struct atomisp_device *isp) { + struct media_pad *sensor_isp_sink, *sensor_src; struct atomisp_input_subdev *input; - int i, err; + int i, err, source_pad; for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) { err = media_create_pad_link(&isp->csi2_port[i].subdev.entity, @@ -1007,12 +1015,33 @@ int atomisp_register_device_nodes(struct atomisp_device *isp) input = &isp->inputs[isp->input_cnt]; input->port = i; - input->camera = isp->sensor_subdevs[i]; input->csi_port = &isp->csi2_port[i].subdev; + input->csi_remote_source = isp->sensor_subdevs[i]; + + /* + * Special case for sensors with a ISP in the sensor modelled + * as a separate v4l2-subdev, like the mt9m114. + */ + if (isp->sensor_subdevs[i]->entity.function == MEDIA_ENT_F_PROC_VIDEO_ISP) { + input->sensor_isp = isp->sensor_subdevs[i]; + source_pad = SENSOR_ISP_PAD_SOURCE; + + sensor_isp_sink = &input->sensor_isp->entity.pads[SENSOR_ISP_PAD_SINK]; + sensor_src = media_pad_remote_pad_first(sensor_isp_sink); + if (!sensor_src) { + dev_err(isp->dev, "Error could not find remote pad for sensor ISP sink\n"); + return -ENOENT; + } + + input->sensor = media_entity_to_v4l2_subdev(sensor_src->entity); + } else { + input->sensor = isp->sensor_subdevs[i]; + source_pad = 0; + } atomisp_init_sensor(input); - err = media_create_pad_link(&input->camera->entity, 0, + err = media_create_pad_link(&isp->sensor_subdevs[i]->entity, source_pad, &isp->csi2_port[i].subdev.entity, CSI2_PAD_SINK, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); @@ -1467,9 +1496,6 @@ static const struct pci_device_id atomisp_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, atomisp_pci_tbl); static struct pci_driver atomisp_pci_driver = { - .driver = { - .dev_groups = dbg_attr_groups, - }, .name = "atomisp-isp2", .id_table = atomisp_pci_tbl, .probe = atomisp_pci_probe, @@ -1483,3 +1509,4 @@ MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Intel ATOM Platform ISP Driver"); MODULE_IMPORT_NS("INTEL_IPU_BRIDGE"); +MODULE_IMPORT_NS("INTEL_INT3472_DISCRETE"); diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h index 2c47e7820bd7..69e68ecd6bc3 100644 --- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h +++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h @@ -18,7 +18,7 @@ #endif /* The IRQ is not mapped uniformly on its related interfaces */ -#define IRQ_SW_CHANNEL_OFFSET hrt_isp_css_irq_sw_pin_0 +#define IRQ_SW_CHANNEL_OFFSET HIVE_GP_DEV_IRQ_SW_PIN_0_BIT_ID typedef enum { IRQ_SW_CHANNEL0_ID = hrt_isp_css_irq_sw_pin_0 - IRQ_SW_CHANNEL_OFFSET, diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h index 6d45d0d8d060..2cb5c986790a 100644 --- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h +++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h @@ -10,14 +10,9 @@ /* Override the definition of max/min from Linux kernel */ #include <linux/minmax.h> -/* force a value to a lower even value */ -#define EVEN_FLOOR(x) ((x) & ~1) - #define CEIL_DIV(a, b) (((b) != 0) ? ((a) + (b) - 1) / (b) : 0) #define CEIL_MUL(a, b) (CEIL_DIV(a, b) * (b)) -#define CEIL_MUL2(a, b) (((a) + (b) - 1) & ~((b) - 1)) #define CEIL_SHIFT(a, b) (((a) + (1 << (b)) - 1) >> (b)) -#define CEIL_SHIFT_MUL(a, b) (CEIL_SHIFT(a, b) << (b)) /* * For SP and ISP, SDK provides the definition of OP_std_modadd. diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm.c b/drivers/staging/media/atomisp/pci/hmm/hmm.c index 84102c3aaf97..f998b57f90c4 100644 --- a/drivers/staging/media/atomisp/pci/hmm/hmm.c +++ b/drivers/staging/media/atomisp/pci/hmm/hmm.c @@ -28,88 +28,6 @@ struct hmm_bo_device bo_device; static ia_css_ptr dummy_ptr = mmgr_EXCEPTION; static bool hmm_initialized; -/* - * p: private - * v: vmalloc - */ -static const char hmm_bo_type_string[] = "pv"; - -static ssize_t bo_show(struct device *dev, struct device_attribute *attr, - char *buf, struct list_head *bo_list, bool active) -{ - ssize_t ret = 0; - struct hmm_buffer_object *bo; - unsigned long flags; - int i; - long total[HMM_BO_LAST] = { 0 }; - long count[HMM_BO_LAST] = { 0 }; - int index1 = 0; - int index2 = 0; - - ret = scnprintf(buf, PAGE_SIZE, "type pgnr\n"); - if (ret <= 0) - return 0; - - index1 += ret; - - spin_lock_irqsave(&bo_device.list_lock, flags); - list_for_each_entry(bo, bo_list, list) { - if ((active && (bo->status & HMM_BO_ALLOCED)) || - (!active && !(bo->status & HMM_BO_ALLOCED))) { - ret = scnprintf(buf + index1, PAGE_SIZE - index1, - "%c %d\n", - hmm_bo_type_string[bo->type], bo->pgnr); - - total[bo->type] += bo->pgnr; - count[bo->type]++; - if (ret > 0) - index1 += ret; - } - } - spin_unlock_irqrestore(&bo_device.list_lock, flags); - - for (i = 0; i < HMM_BO_LAST; i++) { - if (count[i]) { - ret = scnprintf(buf + index1 + index2, - PAGE_SIZE - index1 - index2, - "%ld %c buffer objects: %ld KB\n", - count[i], hmm_bo_type_string[i], - total[i] * 4); - if (ret > 0) - index2 += ret; - } - } - - /* Add trailing zero, not included by scnprintf */ - return index1 + index2 + 1; -} - -static ssize_t active_bo_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return bo_show(dev, attr, buf, &bo_device.entire_bo_list, true); -} - -static ssize_t free_bo_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return bo_show(dev, attr, buf, &bo_device.entire_bo_list, false); -} - - -static DEVICE_ATTR_RO(active_bo); -static DEVICE_ATTR_RO(free_bo); - -static struct attribute *sysfs_attrs_ctrl[] = { - &dev_attr_active_bo.attr, - &dev_attr_free_bo.attr, - NULL -}; - -static struct attribute_group atomisp_attribute_group[] = { - {.attrs = sysfs_attrs_ctrl }, -}; - int hmm_init(void) { int ret; @@ -130,14 +48,6 @@ int hmm_init(void) */ dummy_ptr = hmm_alloc(1); - if (!ret) { - ret = sysfs_create_group(&atomisp_dev->kobj, - atomisp_attribute_group); - if (ret) - dev_err(atomisp_dev, - "%s Failed to create sysfs\n", __func__); - } - return ret; } @@ -145,7 +55,6 @@ void hmm_cleanup(void) { if (dummy_ptr == mmgr_EXCEPTION) return; - sysfs_remove_group(&atomisp_dev->kobj, atomisp_attribute_group); /* free dummy memory first */ hmm_free(dummy_ptr); diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c b/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c index 224ca8d42721..5d0cd5260d3a 100644 --- a/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c +++ b/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c @@ -37,8 +37,6 @@ static int __bo_init(struct hmm_bo_device *bdev, struct hmm_buffer_object *bo, unsigned int pgnr) { check_bodev_null_return(bdev, -EINVAL); - var_equal_return(hmm_bo_device_inited(bdev), 0, -EINVAL, - "hmm_bo_device not inited yet.\n"); /* prevent zero size buffer object */ if (pgnr == 0) { dev_err(atomisp_dev, "0 size buffer is not allowed.\n"); @@ -341,7 +339,6 @@ int hmm_bo_device_init(struct hmm_bo_device *bdev, spin_lock_init(&bdev->list_lock); mutex_init(&bdev->rbtree_mutex); - bdev->flag = HMM_BO_DEVICE_INITED; INIT_LIST_HEAD(&bdev->entire_bo_list); bdev->allocated_rbtree = RB_ROOT; @@ -376,6 +373,8 @@ int hmm_bo_device_init(struct hmm_bo_device *bdev, __bo_insert_to_free_rbtree(&bdev->free_rbtree, bo); + bdev->flag = HMM_BO_DEVICE_INITED; + return 0; } diff --git a/drivers/staging/media/atomisp/pci/ia_css_pipe.h b/drivers/staging/media/atomisp/pci/ia_css_pipe.h index c97d2ae356fd..77072694eb42 100644 --- a/drivers/staging/media/atomisp/pci/ia_css_pipe.h +++ b/drivers/staging/media/atomisp/pci/ia_css_pipe.h @@ -102,8 +102,6 @@ struct ia_css_yuvpp_settings { struct osys_object; struct ia_css_pipe { - /* TODO: Remove stop_requested and use stop_requested in the pipeline */ - bool stop_requested; struct ia_css_pipe_config config; struct ia_css_pipe_extra_config extra_config; struct ia_css_pipe_info info; diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_types.h index 6e573ceaa9ea..bc2a78dff004 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_types.h +++ b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_types.h @@ -11,9 +11,11 @@ * CSS-API header file for Advanced Noise Reduction kernel v1 */ +#include <linux/math.h> + /* Application specific DMA settings */ #define ANR_BPP 10 -#define ANR_ELEMENT_BITS ((CEIL_DIV(ANR_BPP, 8)) * 8) +#define ANR_ELEMENT_BITS round_up(ANR_BPP, 8) /* Advanced Noise Reduction configuration. * This is also known as Low-Light. diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_param.h index 099f32b8de1a..b1bbc283e367 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_param.h +++ b/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_param.h @@ -7,6 +7,8 @@ #ifndef __IA_CSS_DPC2_PARAM_H #define __IA_CSS_DPC2_PARAM_H +#include <linux/math.h> + #include "type_support.h" #include "vmem.h" /* for VMEM_ARRAY*/ @@ -19,12 +21,12 @@ /* 3 lines state per color plane input_line_state */ #define DPC2_STATE_INPUT_BUFFER_HEIGHT (3 * NUM_PLANES) /* Each plane has width equal to half frame line */ -#define DPC2_STATE_INPUT_BUFFER_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define DPC2_STATE_INPUT_BUFFER_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) /* 1 line state per color plane for local deviation state*/ #define DPC2_STATE_LOCAL_DEVIATION_BUFFER_HEIGHT (1 * NUM_PLANES) /* Each plane has width equal to half frame line */ -#define DPC2_STATE_LOCAL_DEVIATION_BUFFER_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define DPC2_STATE_LOCAL_DEVIATION_BUFFER_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) /* MINMAX state buffer stores 1 full input line (GR-R color line) */ #define DPC2_STATE_SECOND_MINMAX_BUFFER_HEIGHT 1 diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c index 30c84639d7e8..e9d6dd0bbfe2 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c +++ b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c @@ -141,10 +141,10 @@ convert_coords_to_ispparams( /* similar to topleft_y calculation, but round up if ymax * has any fraction bits */ - bottom_y = CEIL_DIV(ymax, 1 << DVS_COORD_FRAC_BITS); + bottom_y = DIV_ROUND_UP(ymax, BIT(DVS_COORD_FRAC_BITS)); s.in_block_height = bottom_y - topleft_y + dvs_interp_envelope; - bottom_x = CEIL_DIV(xmax, 1 << DVS_COORD_FRAC_BITS); + bottom_x = DIV_ROUND_UP(xmax, BIT(DVS_COORD_FRAC_BITS)); s.in_block_width = bottom_x - topleft_x + dvs_interp_envelope; topleft_x_frac = topleft_x << (DVS_COORD_FRAC_BITS); diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h index df87770446dd..a24eef965f16 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h +++ b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h @@ -7,6 +7,8 @@ #ifndef __IA_CSS_EED1_8_PARAM_H #define __IA_CSS_EED1_8_PARAM_H +#include <linux/math.h> + #include "type_support.h" #include "vmem.h" /* needed for VMEM_ARRAY */ @@ -35,35 +37,35 @@ #define EED1_8_STATE_INPUT_BUFFER_HEIGHT (5 * NUM_PLANES) /* Each plane has width equal to half frame line */ -#define EED1_8_STATE_INPUT_BUFFER_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define EED1_8_STATE_INPUT_BUFFER_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) /* 1 line state per color plane LD_H state */ #define EED1_8_STATE_LD_H_HEIGHT (1 * NUM_PLANES) -#define EED1_8_STATE_LD_H_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define EED1_8_STATE_LD_H_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) /* 1 line state per color plane LD_V state */ #define EED1_8_STATE_LD_V_HEIGHT (1 * NUM_PLANES) -#define EED1_8_STATE_LD_V_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define EED1_8_STATE_LD_V_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) /* 1 line (single plane) state for D_Hr state */ #define EED1_8_STATE_D_HR_HEIGHT 1 -#define EED1_8_STATE_D_HR_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define EED1_8_STATE_D_HR_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) /* 1 line (single plane) state for D_Hb state */ #define EED1_8_STATE_D_HB_HEIGHT 1 -#define EED1_8_STATE_D_HB_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define EED1_8_STATE_D_HB_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) /* 2 lines (single plane) state for D_Vr state */ #define EED1_8_STATE_D_VR_HEIGHT 2 -#define EED1_8_STATE_D_VR_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define EED1_8_STATE_D_VR_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) /* 2 line (single plane) state for D_Vb state */ #define EED1_8_STATE_D_VB_HEIGHT 2 -#define EED1_8_STATE_D_VB_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define EED1_8_STATE_D_VB_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) /* 2 lines state for R and B (= 2 planes) rb_zipped_state */ #define EED1_8_STATE_RB_ZIPPED_HEIGHT (2 * 2) -#define EED1_8_STATE_RB_ZIPPED_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define EED1_8_STATE_RB_ZIPPED_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) #if EED1_8_FC_ENABLE_MEDIAN /* 1 full input line (GR-R color line) for Yc state */ @@ -72,11 +74,11 @@ /* 1 line state per color plane Cg_state */ #define EED1_8_STATE_CG_HEIGHT (1 * NUM_PLANES) -#define EED1_8_STATE_CG_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define EED1_8_STATE_CG_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) /* 1 line state per color plane Co_state */ #define EED1_8_STATE_CO_HEIGHT (1 * NUM_PLANES) -#define EED1_8_STATE_CO_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2) +#define EED1_8_STATE_CO_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2) /* 1 full input line (GR-R color line) for AbsK state */ #define EED1_8_STATE_ABSK_HEIGHT 1 diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c index b34feba5340b..e701b7e41ef4 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c +++ b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c @@ -4,6 +4,8 @@ * Copyright (c) 2015, Intel Corporation. */ +#include <linux/math.h> + #include <assert_support.h> #include <ia_css_frame_public.h> #include <ia_css_frame.h> @@ -71,9 +73,9 @@ int ia_css_fpn_configure(const struct ia_css_binary *binary, &my_info }; - my_info.res.width = CEIL_DIV(info->res.width, 2); /* Packed by 2x */ + my_info.res.width = DIV_ROUND_UP(info->res.width, 2); /* Packed by 2x */ my_info.res.height = info->res.height; - my_info.padded_width = CEIL_DIV(info->padded_width, 2); /* Packed by 2x */ + my_info.padded_width = DIV_ROUND_UP(info->padded_width, 2); /* Packed by 2x */ my_info.format = info->format; my_info.raw_bit_depth = FPN_BITS_PER_PIXEL; my_info.raw_bayer_order = info->raw_bayer_order; diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_param.h index 61e9c04d2515..b49761ad39ca 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_param.h +++ b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_param.h @@ -22,7 +22,7 @@ struct sh_css_isp_sc_params { * vec_slice is used for 2 adjacent vectors of shading gains. * The number of shift times by vec_slice is 8. * Max grid cell bqs to support the shading table centerting: N = 32 - * CEIL_DIV(N-1, ISP_SLICE_NELEMS) = CEIL_DIV(31, 4) = 8 + * DIV_ROUND_UP(N-1, ISP_SLICE_NELEMS) = DIV_ROUND_UP(31, 4) = 8 */ #define SH_CSS_SC_INTERPED_GAIN_HOR_SLICE_TIMES 8 diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2_types.h index f37802878528..2bed08435755 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2_types.h +++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2_types.h @@ -19,7 +19,7 @@ #endif /* DVS 2.0 Coefficient types. This structure contains 4 pointers to - * arrays that contain the coeffients for each type. + * arrays that contain the coefficients for each type. */ struct ia_css_dvs2_coef_types { s16 *odd_real; /** real part of the odd coefficients*/ diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c index ece5e3da34ee..3c675063c4a7 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c +++ b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c @@ -91,8 +91,7 @@ configure_kernel( unsigned int vf_log_ds = 0; /* First compute value */ - if (vf_info) - { + if (vf_info) { err = sh_css_vf_downscale_log2(out_info, vf_info, &vf_log_ds); if (err) return err; @@ -114,7 +113,7 @@ configure_dma( } int ia_css_vf_configure(const struct ia_css_binary *binary, - const struct ia_css_frame_info *out_info, + const struct ia_css_frame_info *out_info, struct ia_css_frame_info *vf_info, unsigned int *downscale_log2) { diff --git a/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h b/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h index c7ade6ce6c68..6a0257359e69 100644 --- a/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h +++ b/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h @@ -8,9 +8,10 @@ Copyright (c) 2010 - 2015, Intel Corporation. #ifndef _INPUT_BUF_ISP_H_ #define _INPUT_BUF_ISP_H_ +#include <linux/math.h> + /* Temporary include, since IA_CSS_BINARY_MODE_COPY is still needed */ #include "sh_css_defs.h" -#include "isp_const.h" /* MAX_VECTORS_PER_INPUT_LINE */ #define INPUT_BUF_HEIGHT 2 /* double buffer */ #define INPUT_BUF_LINES 2 @@ -22,7 +23,8 @@ Copyright (c) 2010 - 2015, Intel Corporation. /* In continuous mode, the input buffer must be a fixed size for all binaries * and at a fixed address since it will be used by the SP. */ #define EXTRA_INPUT_VECTORS 2 /* For left padding */ -#define MAX_VECTORS_PER_INPUT_LINE_CONT (CEIL_DIV(SH_CSS_MAX_SENSOR_WIDTH, ISP_NWAY) + EXTRA_INPUT_VECTORS) +#define MAX_VECTORS_PER_INPUT_LINE_CONT \ + (DIV_ROUND_UP(SH_CSS_MAX_SENSOR_WIDTH, ISP_NWAY) + EXTRA_INPUT_VECTORS) /* The input buffer should be on a fixed address in vmem, for continuous capture */ #define INPUT_BUF_ADDR 0x0 diff --git a/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h b/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h deleted file mode 100644 index b767b0d35bb4..000000000000 --- a/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h +++ /dev/null @@ -1,157 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/** -Support for Intel Camera Imaging ISP subsystem. -Copyright (c) 2010 - 2015, Intel Corporation. - -*/ - -#ifndef _COMMON_ISP_CONST_H_ -#define _COMMON_ISP_CONST_H_ - -/*#include "isp.h"*/ /* ISP_VEC_NELEMS */ - -/* Binary independent constants */ - -#ifndef NO_HOIST -# define NO_HOIST HIVE_ATTRIBUTE((no_hoist)) -#endif - -#define NO_HOIST_CSE HIVE_ATTRIBUTE((no_hoist, no_cse)) - -#define UNION struct /* Union constructors not allowed in C++ */ - -#define XMEM_WIDTH_BITS HIVE_ISP_DDR_WORD_BITS -#define XMEM_SHORTS_PER_WORD (HIVE_ISP_DDR_WORD_BITS / 16) -#define XMEM_INTS_PER_WORD (HIVE_ISP_DDR_WORD_BITS / 32) -#define XMEM_POW2_BYTES_PER_WORD HIVE_ISP_DDR_WORD_BYTES - -#define BITS8_ELEMENTS_PER_XMEM_ADDR CEIL_DIV(XMEM_WIDTH_BITS, 8) -#define BITS16_ELEMENTS_PER_XMEM_ADDR CEIL_DIV(XMEM_WIDTH_BITS, 16) - -#define ISP_NWAY_LOG2 6 - -/* ***************************** - * ISP input/output buffer sizes - * ****************************/ -/* input image */ -#define INPUT_BUF_DMA_HEIGHT 2 -#define INPUT_BUF_HEIGHT 2 /* double buffer */ -#define OUTPUT_BUF_DMA_HEIGHT 2 -#define OUTPUT_BUF_HEIGHT 2 /* double buffer */ -#define OUTPUT_NUM_TRANSFERS 4 - -/* GDC accelerator: Up/Down Scaling */ -/* These should be moved to the gdc_defs.h in the device */ -#define UDS_SCALING_N HRT_GDC_N -/* AB: This should cover the zooming up to 16MP */ -#define UDS_MAX_OXDIM 5000 -/* We support maximally 2 planes with different parameters - - luma and chroma (YUV420) */ -#define UDS_MAX_PLANES 2 -#define UDS_BLI_BLOCK_HEIGHT 2 -#define UDS_BCI_BLOCK_HEIGHT 4 -#define UDS_BLI_INTERP_ENVELOPE 1 -#define UDS_BCI_INTERP_ENVELOPE 3 -#define UDS_MAX_ZOOM_FAC 64 -/* Make it always one FPGA vector. - Four FPGA vectors are required and - four of them fit in one ASIC vector.*/ -#define UDS_MAX_CHUNKS 16 - -#define ISP_LEFT_PADDING _ISP_LEFT_CROP_EXTRA(ISP_LEFT_CROPPING) -#define ISP_LEFT_PADDING_VECS CEIL_DIV(ISP_LEFT_PADDING, ISP_VEC_NELEMS) -/* in case of continuous the croppong of the current binary doesn't matter for the buffer calculation, but the cropping of the sp copy should be used */ -#define ISP_LEFT_PADDING_CONT _ISP_LEFT_CROP_EXTRA(SH_CSS_MAX_LEFT_CROPPING) -#define ISP_LEFT_PADDING_VECS_CONT CEIL_DIV(ISP_LEFT_PADDING_CONT, ISP_VEC_NELEMS) - -#define CEIL_ROUND_DIV_STRIPE(width, stripe, padding) \ - CEIL_MUL(padding + CEIL_DIV(width - padding, stripe), ((ENABLE_RAW_BINNING || ENABLE_FIXED_BAYER_DS) ? 4 : 2)) - -/* output (Y,U,V) image, 4:2:0 */ -#define MAX_VECTORS_PER_LINE \ - CEIL_ROUND_DIV_STRIPE(CEIL_DIV(ISP_MAX_INTERNAL_WIDTH, ISP_VEC_NELEMS), \ - ISP_NUM_STRIPES, \ - ISP_LEFT_PADDING_VECS) - -/* - * ITERATOR_VECTOR_INCREMENT' explanation: - * when striping an even number of iterations, one of the stripes is - * one iteration wider than the other to account for overlap - * so the calc for the output buffer vmem size is: - * ((width[vectors]/num_of_stripes) + 2[vectors]) - */ -#define MAX_VECTORS_PER_OUTPUT_LINE \ - CEIL_DIV(CEIL_DIV(ISP_MAX_OUTPUT_WIDTH, ISP_NUM_STRIPES) + ISP_LEFT_PADDING, ISP_VEC_NELEMS) - -/* Must be even due to interlaced bayer input */ -#define MAX_VECTORS_PER_INPUT_LINE CEIL_MUL((CEIL_DIV(ISP_MAX_INPUT_WIDTH, ISP_VEC_NELEMS) + ISP_LEFT_PADDING_VECS), 2) -#define MAX_VECTORS_PER_INPUT_STRIPE CEIL_ROUND_DIV_STRIPE(MAX_VECTORS_PER_INPUT_LINE, \ - ISP_NUM_STRIPES, \ - ISP_LEFT_PADDING_VECS) - -/* Add 2 for left croppping */ -#define MAX_SP_RAW_COPY_VECTORS_PER_INPUT_LINE (CEIL_DIV(ISP_MAX_INPUT_WIDTH, ISP_VEC_NELEMS) + 2) - -#define MAX_VECTORS_PER_BUF_LINE \ - (MAX_VECTORS_PER_LINE + DUMMY_BUF_VECTORS) -#define MAX_VECTORS_PER_BUF_INPUT_LINE \ - (MAX_VECTORS_PER_INPUT_STRIPE + DUMMY_BUF_VECTORS) -#define MAX_OUTPUT_Y_FRAME_WIDTH \ - (MAX_VECTORS_PER_LINE * ISP_VEC_NELEMS) -#define MAX_OUTPUT_Y_FRAME_SIMDWIDTH \ - MAX_VECTORS_PER_LINE -#define MAX_OUTPUT_C_FRAME_WIDTH \ - (MAX_OUTPUT_Y_FRAME_WIDTH / 2) -#define MAX_OUTPUT_C_FRAME_SIMDWIDTH \ - CEIL_DIV(MAX_OUTPUT_C_FRAME_WIDTH, ISP_VEC_NELEMS) - -/* should be even */ -#define NO_CHUNKING (OUTPUT_NUM_CHUNKS == 1) - -#define MAX_VECTORS_PER_CHUNK \ - (NO_CHUNKING ? MAX_VECTORS_PER_LINE \ - : 2 * CEIL_DIV(MAX_VECTORS_PER_LINE, \ - 2 * OUTPUT_NUM_CHUNKS)) - -#define MAX_C_VECTORS_PER_CHUNK \ - (MAX_VECTORS_PER_CHUNK / 2) - -/* should be even */ -#define MAX_VECTORS_PER_OUTPUT_CHUNK \ - (NO_CHUNKING ? MAX_VECTORS_PER_OUTPUT_LINE \ - : 2 * CEIL_DIV(MAX_VECTORS_PER_OUTPUT_LINE, \ - 2 * OUTPUT_NUM_CHUNKS)) - -#define MAX_C_VECTORS_PER_OUTPUT_CHUNK \ - (MAX_VECTORS_PER_OUTPUT_CHUNK / 2) - -/* should be even */ -#define MAX_VECTORS_PER_INPUT_CHUNK \ - (INPUT_NUM_CHUNKS == 1 ? MAX_VECTORS_PER_INPUT_STRIPE \ - : 2 * CEIL_DIV(MAX_VECTORS_PER_INPUT_STRIPE, \ - 2 * OUTPUT_NUM_CHUNKS)) - -#define DEFAULT_C_SUBSAMPLING 2 - -/****** DMA buffer properties */ - -#define RAW_BUF_LINES ((ENABLE_RAW_BINNING || ENABLE_FIXED_BAYER_DS) ? 4 : 2) - -/* [isp vmem] table size[vectors] per line per color (GR,R,B,GB), - multiples of NWAY */ -#define ISP2400_SCTBL_VECTORS_PER_LINE_PER_COLOR \ - CEIL_DIV(SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS) -#define ISP2401_SCTBL_VECTORS_PER_LINE_PER_COLOR \ - CEIL_DIV(SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS) -/* [isp vmem] table size[vectors] per line for 4colors (GR,R,B,GB), - multiples of NWAY */ -#define SCTBL_VECTORS_PER_LINE \ - (SCTBL_VECTORS_PER_LINE_PER_COLOR * IA_CSS_SC_NUM_COLORS) - -/*************/ - -/* Format for fixed primaries */ - -#define ISP_FIXED_PRIMARY_FORMAT IA_CSS_FRAME_FORMAT_NV12 - -#endif /* _COMMON_ISP_CONST_H_ */ diff --git a/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c b/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c index 9818771a35e5..b411ca2f415e 100644 --- a/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c +++ b/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c @@ -51,7 +51,6 @@ #include "sp.h" #include "isp.h" #include "type_support.h" -#include "math_support.h" /* CEIL_DIV */ #include "input_system.h" /* input_formatter_reg_load */ #include "ia_css_tagger_common.h" @@ -121,7 +120,8 @@ static const char *const pipe_id_to_str[] = { /* [IA_CSS_PIPE_ID_YUVPP] =*/ "yuvpp", }; -static char dot_id_input_bin[SH_CSS_MAX_BINARY_NAME + 10]; +/* 27 is combined length of _stage%d(pipe%d)\0. */ +static char dot_id_input_bin[SH_CSS_MAX_BINARY_NAME + 27]; static char ring_buffer[200]; void ia_css_debug_dtrace(unsigned int level, const char *fmt, ...) diff --git a/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c b/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c index 4f610f57e6c1..2cb96f9a6030 100644 --- a/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c +++ b/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c @@ -4,15 +4,16 @@ * Copyright (c) 2015, Intel Corporation. */ -#include "hmm.h" +#include <linux/bitops.h> +#include <linux/math.h> -#include "ia_css_frame.h" -#include <math_support.h> #include "assert_support.h" +#include "atomisp_internal.h" +#include "hmm.h" #include "ia_css_debug.h" +#include "ia_css_frame.h" #include "isp.h" #include "sh_css_internal.h" -#include "atomisp_internal.h" #define NV12_TILEY_TILE_WIDTH 128 #define NV12_TILEY_TILE_HEIGHT 32 @@ -459,15 +460,16 @@ static void frame_init_single_plane(struct ia_css_frame *frame, unsigned int stride; stride = subpixels_per_line * bytes_per_pixel; - /* Frame height needs to be even number - needed by hw ISYS2401 - In case of odd number, round up to even. - Images won't be impacted by this round up, - only needed by jpeg/embedded data. - As long as buffer allocation and release are using data_bytes, - there won't be memory leak. */ - frame->data_bytes = stride * CEIL_MUL2(height, 2); + /* + * Frame height needs to be even number - needed by hw ISYS2401. + * In case of odd number, round up to even. + * Images won't be impacted by this round up, + * only needed by jpeg/embedded data. + * As long as buffer allocation and release are using data_bytes, + * there won't be memory leak. + */ + frame->data_bytes = stride * round_up(height, 2); frame_init_plane(plane, subpixels_per_line, stride, height, 0); - return; } static void frame_init_raw_single_plane( @@ -486,7 +488,6 @@ static void frame_init_raw_single_plane( HIVE_ISP_DDR_WORD_BITS / bits_per_pixel); frame->data_bytes = stride * height; frame_init_plane(plane, subpixels_per_line, stride, height, 0); - return; } static void frame_init_nv_planes(struct ia_css_frame *frame, @@ -690,7 +691,7 @@ ia_css_elems_bytes_from_info(const struct ia_css_frame_info *info) if (info->format == IA_CSS_FRAME_FORMAT_RAW || (info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED)) { if (info->raw_bit_depth) - return CEIL_DIV(info->raw_bit_depth, 8); + return BITS_TO_BYTES(info->raw_bit_depth); else return 2; /* bytes per pixel */ } diff --git a/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c b/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c index d57ffb335fc0..50b0b31d734a 100644 --- a/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c +++ b/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c @@ -4,9 +4,9 @@ * Copyright (c) 2010 - 2015, Intel Corporation. */ -#include "system_global.h" -#include <linux/kernel.h> +#include <linux/math.h> +#include "system_global.h" #include "ia_css_ifmtr.h" #include <math_support.h> @@ -149,10 +149,9 @@ int ia_css_ifmtr_configure(struct ia_css_stream_config *config, left_padding = 2 * ISP_VEC_NELEMS - config->left_padding; if (left_padding) { - num_vectors = CEIL_DIV(cropped_width + left_padding, - ISP_VEC_NELEMS); + num_vectors = DIV_ROUND_UP(cropped_width + left_padding, ISP_VEC_NELEMS); } else { - num_vectors = CEIL_DIV(cropped_width, ISP_VEC_NELEMS); + num_vectors = DIV_ROUND_UP(cropped_width, ISP_VEC_NELEMS); num_vectors *= buffer_height; /* todo: in case of left padding, num_vectors is vectors per line, @@ -305,7 +304,7 @@ int ia_css_ifmtr_configure(struct ia_css_stream_config *config, if ((!binary) || config->continuous) /* !binary -> sp raw copy pipe */ buffer_height *= 2; - vectors_per_line = CEIL_DIV(cropped_width, ISP_VEC_NELEMS); + vectors_per_line = DIV_ROUND_UP(cropped_width, ISP_VEC_NELEMS); vectors_per_line = CEIL_MUL(vectors_per_line, deinterleaving); break; case ATOMISP_INPUT_FORMAT_RAW_14: diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c index b5395aea89fc..e6c11d5f77b4 100644 --- a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c +++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c @@ -808,7 +808,7 @@ static bool calculate_isys2401_dma_port_cfg( cfg->elements = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel; cfg->cropping = 0; - cfg->width = CEIL_DIV(cfg->stride, HIVE_ISP_DDR_WORD_BYTES); + cfg->width = DIV_ROUND_UP(cfg->stride, HIVE_ISP_DDR_WORD_BYTES); return true; } diff --git a/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h b/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h index 316eaa2070ea..8b7cbf31a1a2 100644 --- a/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h +++ b/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h @@ -34,7 +34,6 @@ struct ia_css_pipeline_stage { struct ia_css_pipeline { enum ia_css_pipe_id pipe_id; u8 pipe_num; - bool stop_requested; struct ia_css_pipeline_stage *stages; struct ia_css_pipeline_stage *current_stage; unsigned int num_stages; diff --git a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c index aabebe61ec77..cb8d652227a7 100644 --- a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c +++ b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c @@ -198,7 +198,6 @@ int ia_css_pipeline_request_stop(struct ia_css_pipeline *pipeline) ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipeline_request_stop() enter: pipeline=%p\n", pipeline); - pipeline->stop_requested = true; /* Send stop event to the sp*/ /* This needs improvement, stop on all the pipes available @@ -663,7 +662,6 @@ static void pipeline_init_defaults( pipeline->pipe_id = pipe_id; pipeline->stages = NULL; - pipeline->stop_requested = false; pipeline->current_stage = NULL; memcpy(&pipeline->in_frame, &ia_css_default_frame, diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index 5a8e8e67aa13..73bd87f43a8c 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -2002,10 +2002,6 @@ ia_css_uninit(void) sh_css_params_free_default_gdc_lut(); - /* TODO: JB: implement decent check and handling of freeing mipi frames */ - if (!mipi_is_free()) - dev_warn(atomisp_dev, "mipi frames are not freed.\n"); - /* cleanup generic data */ sh_css_params_uninit(); ia_css_refcount_uninit(); @@ -3743,23 +3739,6 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe, case IA_CSS_BUFFER_TYPE_INPUT_FRAME: case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME: case IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME: - if (pipe && pipe->stop_requested) { - if (!IS_ISP2401) { - /* - * free mipi frames only for old input - * system for 2401 it is done in - * ia_css_stream_destroy call - */ - return_err = free_mipi_frames(pipe); - if (return_err) { - IA_CSS_LOG("free_mipi_frames() failed"); - IA_CSS_LEAVE_ERR(return_err); - return return_err; - } - } - pipe->stop_requested = false; - } - fallthrough; case IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME: case IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME: frame = (struct ia_css_frame *)HOST_ADDRESS(ddr_buffer.kernel_ptr); @@ -4095,8 +4074,6 @@ sh_css_pipe_start(struct ia_css_stream *stream) return err; } - pipe->stop_requested = false; - switch (pipe_id) { case IA_CSS_PIPE_ID_PREVIEW: err = preview_start(pipe); @@ -4120,19 +4097,15 @@ sh_css_pipe_start(struct ia_css_stream *stream) for (i = 1; i < stream->num_pipes && 0 == err ; i++) { switch (stream->pipes[i]->mode) { case IA_CSS_PIPE_ID_PREVIEW: - stream->pipes[i]->stop_requested = false; err = preview_start(stream->pipes[i]); break; case IA_CSS_PIPE_ID_VIDEO: - stream->pipes[i]->stop_requested = false; err = video_start(stream->pipes[i]); break; case IA_CSS_PIPE_ID_CAPTURE: - stream->pipes[i]->stop_requested = false; err = capture_start(stream->pipes[i]); break; case IA_CSS_PIPE_ID_YUVPP: - stream->pipes[i]->stop_requested = false; err = yuvpp_start(stream->pipes[i]); break; default: diff --git a/drivers/staging/media/atomisp/pci/sh_css_defs.h b/drivers/staging/media/atomisp/pci/sh_css_defs.h index 51491dfe05cc..7bfeeb8cf053 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_defs.h +++ b/drivers/staging/media/atomisp/pci/sh_css_defs.h @@ -7,12 +7,12 @@ #ifndef _SH_CSS_DEFS_H_ #define _SH_CSS_DEFS_H_ +#include <linux/math.h> + #include "isp.h" /*#include "vamem.h"*/ /* Cannot include for VAMEM properties this file is visible on ISP -> pipeline generator */ -#include "math_support.h" /* max(), min, etc etc */ - /* ID's for refcount */ #define IA_CSS_REFCOUNT_PARAM_SET_POOL 0xCAFE0001 #define IA_CSS_REFCOUNT_PARAM_BUFFER 0xCAFE0002 @@ -182,7 +182,7 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191] The ISP firmware needs these rules to be applied at pre-processor time, that's why these are macros, not functions. */ #define _ISP_BQS(num) ((num) / 2) -#define _ISP_VECS(width) CEIL_DIV(width, ISP_VEC_NELEMS) +#define _ISP_VECS(width) DIV_ROUND_UP(width, ISP_VEC_NELEMS) #define ISP_BQ_GRID_WIDTH(elements_per_line, deci_factor_log2) \ CEIL_SHIFT(elements_per_line / 2, deci_factor_log2) @@ -194,9 +194,9 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191] /* The morphing table is similar to the shading table in the sense that we have 1 more value than we have cells in the grid. */ #define _ISP_MORPH_TABLE_WIDTH(int_width) \ - (CEIL_DIV(int_width, SH_CSS_MORPH_TABLE_GRID) + 1) + (DIV_ROUND_UP(int_width, SH_CSS_MORPH_TABLE_GRID) + 1) #define _ISP_MORPH_TABLE_HEIGHT(int_height) \ - (CEIL_DIV(int_height, SH_CSS_MORPH_TABLE_GRID) + 1) + (DIV_ROUND_UP(int_height, SH_CSS_MORPH_TABLE_GRID) + 1) #define _ISP_MORPH_TABLE_ALIGNED_WIDTH(width) \ CEIL_MUL(_ISP_MORPH_TABLE_WIDTH(width), \ SH_CSS_MORPH_TABLE_ELEMS_PER_DDR_WORD) @@ -298,7 +298,7 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191] c_subsampling, \ num_chunks, \ pipelining) \ - CEIL_MUL2(CEIL_MUL2(MAX(__ISP_PADDED_OUTPUT_WIDTH(out_width, \ + round_up(round_up(MAX(__ISP_PADDED_OUTPUT_WIDTH(out_width, \ dvs_env_width, \ left_crop), \ __ISP_MIN_INTERNAL_WIDTH(num_chunks, \ diff --git a/drivers/staging/media/atomisp/pci/sh_css_internal.h b/drivers/staging/media/atomisp/pci/sh_css_internal.h index 7b3483585748..9155a83fcc03 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_internal.h +++ b/drivers/staging/media/atomisp/pci/sh_css_internal.h @@ -8,6 +8,7 @@ #define _SH_CSS_INTERNAL_H_ #include <linux/build_bug.h> +#include <linux/math.h> #include <linux/stdarg.h> #include <system_global.h> @@ -95,7 +96,6 @@ * the SIZE_OF_XXX macro of the corresponding struct. If they are not * equal, functionality will break. */ -#define CALC_ALIGNMENT_MEMBER(x, y) (CEIL_MUL(x, y) - x) #define SIZE_OF_HRT_VADDRESS sizeof(hive_uint32) /* Number of SP's */ @@ -704,13 +704,11 @@ struct sh_css_hmm_buffer { /* Do not use sizeof(uint64_t) since that does not exist of SP */ #define SIZE_OF_SH_CSS_HMM_BUFFER_STRUCT \ - (SIZE_OF_PAYLOAD_UNION + \ - CALC_ALIGNMENT_MEMBER(SIZE_OF_PAYLOAD_UNION, 8) + \ + (round_up(SIZE_OF_PAYLOAD_UNION, 8) + \ 8 + \ 8 + \ SIZE_OF_IA_CSS_TIME_MEAS_STRUCT + \ - SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT + \ - CALC_ALIGNMENT_MEMBER(SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT, 8)) + round_up(SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT, 8)) static_assert(sizeof(struct sh_css_hmm_buffer) == SIZE_OF_SH_CSS_HMM_BUFFER_STRUCT); diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.c b/drivers/staging/media/atomisp/pci/sh_css_mipi.c index 42f14ed853e1..971b685cdb58 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_mipi.c +++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.c @@ -185,17 +185,6 @@ mipi_init(void) ref_count_mipi_allocation[i] = 0; } -bool mipi_is_free(void) -{ - unsigned int i; - - for (i = 0; i < N_CSI_PORTS; i++) - if (ref_count_mipi_allocation[i]) - return false; - - return true; -} - /* * @brief Calculate the required MIPI buffer sizes. * Based on the stream configuration, calculate the diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.h b/drivers/staging/media/atomisp/pci/sh_css_mipi.h index 6f7389f44baa..b3887ee3c75a 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_mipi.h +++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.h @@ -14,8 +14,6 @@ void mipi_init(void); -bool mipi_is_free(void); - int allocate_mipi_frames(struct ia_css_pipe *pipe, struct ia_css_stream_info *info); diff --git a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.h b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.h index b7057887adea..b31a0d4e8acb 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.h +++ b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.h @@ -7,6 +7,8 @@ #ifndef _SH_CSS_PARAMS_DVS_H_ #define _SH_CSS_PARAMS_DVS_H_ +#include <linux/math.h> + #include <math_support.h> #include <ia_css_types.h> #include "gdc_global.h" /* gdc_warp_param_mem_t */ @@ -20,22 +22,20 @@ /* ISP2400 */ /* horizontal 64x64 blocks round up to DVS_BLOCKDIM_X, make even */ -#define DVS_NUM_BLOCKS_X(X) (CEIL_MUL(CEIL_DIV((X), DVS_BLOCKDIM_X), 2)) +#define DVS_NUM_BLOCKS_X(X) round_up(DIV_ROUND_UP((X), DVS_BLOCKDIM_X), 2) +#define DVS_NUM_BLOCKS_X_CHROMA(X) DIV_ROUND_UP((X), DVS_BLOCKDIM_X) /* ISP2400 */ /* vertical 64x64 blocks round up to DVS_BLOCKDIM_Y */ -#define DVS_NUM_BLOCKS_Y(X) (CEIL_DIV((X), DVS_BLOCKDIM_Y_LUMA)) -#define DVS_NUM_BLOCKS_X_CHROMA(X) (CEIL_DIV((X), DVS_BLOCKDIM_X)) -#define DVS_NUM_BLOCKS_Y_CHROMA(X) (CEIL_DIV((X), DVS_BLOCKDIM_Y_CHROMA)) +#define DVS_NUM_BLOCKS_Y(X) DIV_ROUND_UP((X), DVS_BLOCKDIM_Y_LUMA) +#define DVS_NUM_BLOCKS_Y_CHROMA(X) DIV_ROUND_UP((X), DVS_BLOCKDIM_Y_CHROMA) -#define DVS_TABLE_IN_BLOCKDIM_X_LUMA(X) (DVS_NUM_BLOCKS_X(X) + 1) /* N blocks have N + 1 set of coords */ -#define DVS_TABLE_IN_BLOCKDIM_X_CHROMA(X) (DVS_NUM_BLOCKS_X_CHROMA(X) + 1) +/* N blocks have N + 1 set of coords */ +#define DVS_TABLE_IN_BLOCKDIM_X_LUMA(X) (DVS_NUM_BLOCKS_X(X) + 1) +#define DVS_TABLE_IN_BLOCKDIM_X_CHROMA(X) (DVS_NUM_BLOCKS_X_CHROMA(X) + 1) #define DVS_TABLE_IN_BLOCKDIM_Y_LUMA(X) (DVS_NUM_BLOCKS_Y(X) + 1) #define DVS_TABLE_IN_BLOCKDIM_Y_CHROMA(X) (DVS_NUM_BLOCKS_Y_CHROMA(X) + 1) -#define DVS_ENVELOPE_X(X) (((X) == 0) ? (DVS_ENV_MIN_X) : (X)) -#define DVS_ENVELOPE_Y(X) (((X) == 0) ? (DVS_ENV_MIN_Y) : (X)) - #define DVS_COORD_FRAC_BITS (10) /* ISP2400 */ @@ -43,8 +43,8 @@ #define XMEM_ALIGN_LOG2 (5) -#define DVS_6AXIS_COORDS_ELEMS CEIL_MUL(sizeof(gdc_warp_param_mem_t) \ - , HIVE_ISP_DDR_WORD_BYTES) +#define DVS_6AXIS_COORDS_ELEMS \ + round_up(sizeof(gdc_warp_param_mem_t), HIVE_ISP_DDR_WORD_BYTES) /* currently we only support two output with the same resolution, output 0 is th default one. */ #define DVS_6AXIS_BYTES(binary) \ diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c index 0d4a936ad80f..11d62313c908 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_params.c +++ b/drivers/staging/media/atomisp/pci/sh_css_params.c @@ -4,6 +4,8 @@ * Copyright (c) 2015, Intel Corporation. */ +#include <linux/math.h> + #include "gdc_device.h" /* gdc_lut_store(), ... */ #include "isp.h" /* ISP_VEC_ELEMBITS */ #include "vamem.h" @@ -21,8 +23,6 @@ #include "platform_support.h" #include "assert_support.h" -#include "misc_support.h" /* NOT_USED */ -#include "math_support.h" /* max(), min() EVEN_FLOOR()*/ #include "ia_css_stream.h" #include "sh_css_params_internal.h" @@ -4042,10 +4042,10 @@ sh_css_update_uds_and_crop_info( } /* Must enforce that the crop position is even */ - crop_x = EVEN_FLOOR(crop_x); - crop_y = EVEN_FLOOR(crop_y); - uds_xc = EVEN_FLOOR(uds_xc); - uds_yc = EVEN_FLOOR(uds_yc); + crop_x = round_down(crop_x, 2); + crop_y = round_down(crop_y, 2); + uds_xc = round_down(uds_xc, 2); + uds_yc = round_down(uds_yc, 2); uds->xc = (uint16_t)uds_xc; uds->yc = (uint16_t)uds_yc; diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index 2855ba2296ac..77360bfe081a 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -295,7 +295,7 @@ static irqreturn_t prp_nfb4eof_interrupt(int irq, void *dev_id) */ static void prp_eof_timeout(struct timer_list *t) { - struct prp_priv *priv = from_timer(priv, t, eof_timeout_timer); + struct prp_priv *priv = timer_container_of(priv, t, eof_timeout_timer); struct imx_media_video_dev *vdev = priv->vdev; struct imx_ic_priv *ic_priv = priv->ic_priv; diff --git a/drivers/staging/media/imx/imx-media-csc-scaler.c b/drivers/staging/media/imx/imx-media-csc-scaler.c index e5e08c6f79f2..19fd31cb9bb0 100644 --- a/drivers/staging/media/imx/imx-media-csc-scaler.c +++ b/drivers/staging/media/imx/imx-media-csc-scaler.c @@ -912,7 +912,7 @@ imx_media_csc_scaler_device_init(struct imx_media_dev *md) return &priv->vdev; err_m2m: - video_set_drvdata(vfd, NULL); + video_device_release(vfd); err_vfd: kfree(priv); return ERR_PTR(ret); diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index f1d7fce8c020..a7cd3ef95fc3 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -356,7 +356,7 @@ static irqreturn_t csi_idmac_nfb4eof_interrupt(int irq, void *dev_id) */ static void csi_idmac_eof_timeout(struct timer_list *t) { - struct csi_priv *priv = from_timer(priv, t, eof_timeout_timer); + struct csi_priv *priv = timer_container_of(priv, t, eof_timeout_timer); struct imx_media_video_dev *vdev = priv->vdev; v4l2_err(&priv->sd, "EOF timeout\n"); diff --git a/drivers/staging/media/ipu7/Kconfig b/drivers/staging/media/ipu7/Kconfig new file mode 100644 index 000000000000..7d831ba7501d --- /dev/null +++ b/drivers/staging/media/ipu7/Kconfig @@ -0,0 +1,19 @@ +config VIDEO_INTEL_IPU7 + tristate "Intel IPU7 driver" + depends on ACPI || COMPILE_TEST + depends on VIDEO_DEV + depends on X86 && HAS_DMA + depends on IPU_BRIDGE || !IPU_BRIDGE + depends on PCI + select AUXILIARY_BUS + select IOMMU_IOVA + select VIDEO_V4L2_SUBDEV_API + select MEDIA_CONTROLLER + select VIDEOBUF2_DMA_SG + select V4L2_FWNODE + help + This is the 7th Gen Intel Image Processing Unit, found in Intel SoCs + and used for capturing images and video from camera sensors. + + To compile this driver, say Y here! It contains 2 modules - + intel_ipu7 and intel_ipu7_isys. diff --git a/drivers/staging/media/ipu7/Makefile b/drivers/staging/media/ipu7/Makefile new file mode 100644 index 000000000000..6d2aec219e65 --- /dev/null +++ b/drivers/staging/media/ipu7/Makefile @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2017 - 2025 Intel Corporation. + +intel-ipu7-objs += ipu7.o \ + ipu7-bus.o \ + ipu7-dma.o \ + ipu7-mmu.o \ + ipu7-buttress.o \ + ipu7-cpd.o \ + ipu7-syscom.o \ + ipu7-boot.o + +obj-$(CONFIG_VIDEO_INTEL_IPU7) += intel-ipu7.o + +intel-ipu7-isys-objs += ipu7-isys.o \ + ipu7-isys-csi2.o \ + ipu7-isys-csi-phy.o \ + ipu7-fw-isys.o \ + ipu7-isys-video.o \ + ipu7-isys-queue.o \ + ipu7-isys-subdev.o + +obj-$(CONFIG_VIDEO_INTEL_IPU7) += intel-ipu7-isys.o diff --git a/drivers/staging/media/ipu7/TODO b/drivers/staging/media/ipu7/TODO new file mode 100644 index 000000000000..7fbc37059adf --- /dev/null +++ b/drivers/staging/media/ipu7/TODO @@ -0,0 +1,28 @@ +This is a list of things that need to be done to get this driver out of the +staging directory. + +- ABI headers cleanup + Cleanup the firmware ABI headers + +- Add metadata capture support + The IPU7 hardware should support metadata capture, but it is not + fully verified with IPU7 firmware ABI so far, need to add the metadata + capture support. + +- Refine CSI2 PHY code + Refine the ipu7-isys-csi2-phy.c, move the hardware specific variant + into structure, clarify and explain the PHY registers to make it more + readable. + +- Work with the common IPU module + Sakari commented much of the driver code is the same than the IPU6 driver. + IPU7 driver is expected to work with the common IPU module in future. + +- Register definition cleanup + Cleanup the register definitions - remove some unnecessary definitions + remove 'U' suffix for hexadecimal and decimal values and add IPU7 prefix + for IPU7 specific registers. + Some ISYS IO sub-blocks register definitions are offset values from + specific sub-block base, but it is not clear and well suited for driver + to use, need to update the register definitions to make it more clear + and readable. diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h new file mode 100644 index 000000000000..a1519c4fe661 --- /dev/null +++ b/drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 - 2025 Intel Corporation + */ + +#ifndef IPU7_FW_BOOT_ABI_H +#define IPU7_FW_BOOT_ABI_H + +#include "ipu7_fw_common_abi.h" +#include "ipu7_fw_syscom_abi.h" + +#define IA_GOFO_FWLOG_SEVERITY_CRIT (0U) +#define IA_GOFO_FWLOG_SEVERITY_ERROR (1U) +#define IA_GOFO_FWLOG_SEVERITY_WARNING (2U) +#define IA_GOFO_FWLOG_SEVERITY_INFO (3U) +#define IA_GOFO_FWLOG_SEVERITY_DEBUG (4U) +#define IA_GOFO_FWLOG_SEVERITY_VERBOSE (5U) +#define IA_GOFO_FWLOG_MAX_LOGGER_SOURCES (64U) + +#define LOGGER_CONFIG_CHANNEL_ENABLE_HWPRINTF_BITMASK BIT(0) +#define LOGGER_CONFIG_CHANNEL_ENABLE_SYSCOM_BITMASK BIT(1) +#define LOGGER_CONFIG_CHANNEL_ENABLE_ALL_BITMASK \ + (LOGGER_CONFIG_CHANNEL_ENABLE_HWPRINTF_BITMASK | \ + LOGGER_CONFIG_CHANNEL_ENABLE_SYSCOM_BITMASK) + +struct ia_gofo_logger_config { + u8 use_source_severity; + u8 source_severity[IA_GOFO_FWLOG_MAX_LOGGER_SOURCES]; + u8 use_channels_enable_bitmask; + u8 channels_enable_bitmask; + u8 padding[1]; + ia_gofo_addr_t hw_printf_buffer_base_addr; + u32 hw_printf_buffer_size_bytes; +}; + +#pragma pack(push, 1) + +#define IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP \ + ((u32)IA_GOFO_FW_BOOT_ID_MAX) +#define IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_IS_OFFSET (0U) +#define IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_PS_OFFSET \ + ((IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_IS_OFFSET) + \ + (u32)(IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP)) +#define IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_PRIMARY_OFFSET (0U) +#define IA_GOFO_CCG_IPU_BUTTRESS_FW_BOOT_PARAMS_SECONDARY_OFFSET (0x3000U / 4U) +#define IA_GOFO_HKR_IPU_BUTTRESS_FW_BOOT_PARAMS_SECONDARY_OFFSET \ + (IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP * 2U) +#define IA_GOFO_HKR_HIF_BUTTRESS_FW_BOOT_PARAMS_SECONDARY_OFFSET \ + (IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP) +#define IA_GOFO_CCG_IPU_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX \ + (IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP * 4U) +#define IA_GOFO_HKR_IPU_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX \ + (IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP * 4U) + +#define IA_GOFO_BOOT_RESERVED_SIZE (58U) +#define IA_GOFO_BOOT_SECONDARY_RESERVED_SIZE (IA_GOFO_BOOT_RESERVED_SIZE) +#define IA_GOFO_BOOT_SECONDARY_RESERVED_FIELDS \ + (sizeof(ia_gofo_addr_t) + sizeof(ia_gofo_addr_t) + sizeof(u32)) + +enum ia_gofo_buttress_reg_id { + IA_GOFO_FW_BOOT_CONFIG_ID = 0, + IA_GOFO_FW_BOOT_STATE_ID = 1, + IA_GOFO_FW_BOOT_RESERVED1_ID = IA_GOFO_FW_BOOT_STATE_ID, + IA_GOFO_FW_BOOT_SYSCOM_QUEUE_INDICES_BASE_ID = 2, + IA_GOFO_FW_BOOT_UNTRUSTED_ADDR_MIN_ID = 3, + IA_GOFO_FW_BOOT_RESERVED0_ID = IA_GOFO_FW_BOOT_UNTRUSTED_ADDR_MIN_ID, + IA_GOFO_FW_BOOT_MESSAGING_VERSION_ID = 4, + IA_GOFO_FW_BOOT_ID_MAX +}; + +enum ia_gofo_boot_uc_tile_frequency_units { + IA_GOFO_FW_BOOT_UC_FREQUENCY_UNITS_MHZ = 0, + IA_GOFO_FW_BOOT_UC_FREQUENCY_UNITS_HZ = 1, + IA_GOFO_FW_BOOT_UC_FREQUENCY_UNITS_N +}; + +#define IA_GOFO_FW_BOOT_STATE_IS_CRITICAL(boot_state) \ + (0xdead0000U == ((boot_state) & 0xffff0000U)) + +struct ia_gofo_boot_config { + u32 length; + struct ia_gofo_version_s config_version; + struct ia_gofo_msg_version_list client_version_support; + ia_gofo_addr_t pkg_dir; + ia_gofo_addr_t subsys_config; + u32 uc_tile_frequency; + u16 checksum; + u8 uc_tile_frequency_units; + u8 padding[1]; + u32 reserved[IA_GOFO_BOOT_RESERVED_SIZE]; + struct syscom_config_s syscom_context_config; +}; + +struct ia_gofo_secondary_boot_config { + u32 length; + struct ia_gofo_version_s config_version; + struct ia_gofo_msg_version_list client_version_support; + u8 reserved1[IA_GOFO_BOOT_SECONDARY_RESERVED_FIELDS]; + u16 checksum; + u8 padding[2]; + u32 reserved2[IA_GOFO_BOOT_SECONDARY_RESERVED_SIZE]; + struct syscom_config_s syscom_context_config; +}; + +#pragma pack(pop) + +#define IA_GOFO_WDT_TIMEOUT_ERR 0xdead0401U +#define IA_GOFO_MEM_FATAL_DME_ERR 0xdead0801U +#define IA_GOFO_MEM_UNCORRECTABLE_LOCAL_ERR 0xdead0802U +#define IA_GOFO_MEM_UNCORRECTABLE_DIRTY_ERR 0xdead0803U +#define IA_GOFO_MEM_UNCORRECTABLE_DTAG_ERR 0xdead0804U +#define IA_GOFO_MEM_UNCORRECTABLE_CACHE_ERR 0xdead0805U +#define IA_GOFO_DOUBLE_EXCEPTION_ERR 0xdead0806U +#define IA_GOFO_BIST_DMEM_FAULT_DETECTION_ERR 0xdead1000U +#define IA_GOFO_BIST_DATA_INTEGRITY_FAILURE 0xdead1010U + +enum ia_gofo_boot_state { + IA_GOFO_FW_BOOT_STATE_SECONDARY_BOOT_CONFIG_READY = 0x57a7b000U, + IA_GOFO_FW_BOOT_STATE_UNINIT = 0x57a7e000U, + IA_GOFO_FW_BOOT_STATE_STARTING_0 = 0x57a7d000U, + IA_GOFO_FW_BOOT_STATE_CACHE_INIT_DONE = 0x57a7d010U, + IA_GOFO_FW_BOOT_STATE_MEM_INIT_DONE = 0x57a7d020U, + IA_GOFO_FW_BOOT_STATE_STACK_INIT_DONE = 0x57a7d030U, + IA_GOFO_FW_BOOT_STATE_EARLY_BOOT_DONE = 0x57a7d100U, + IA_GOFO_FW_BOOT_STATE_BOOT_CONFIG_START = 0x57a7d200U, + IA_GOFO_FW_BOOT_STATE_QUEUE_INIT_DONE = 0x57a7d300U, + IA_GOFO_FW_BOOT_STATE_READY = 0x57a7e100U, + IA_GOFO_FW_BOOT_STATE_CRIT_UNSPECIFIED = 0xdead0001U, + IA_GOFO_FW_BOOT_STATE_CRIT_CFG_PTR = 0xdead0101U, + IA_GOFO_FW_BOOT_STATE_CRIT_CFG_VERSION = 0xdead0201U, + IA_GOFO_FW_BOOT_STATE_CRIT_MSG_VERSION = 0xdead0301U, + IA_GOFO_FW_BOOT_STATE_CRIT_WDT_TIMEOUT = IA_GOFO_WDT_TIMEOUT_ERR, + IA_GOFO_FW_BOOT_STATE_WRONG_DATA_SECTION_UNPACKING = 0xdead0501U, + IA_GOFO_FW_BOOT_STATE_WRONG_RO_DATA_SECTION_UNPACKING = 0xdead0601U, + IA_GOFO_FW_BOOT_STATE_INVALID_UNTRUSTED_ADDR_MIN = 0xdead0701U, + IA_GOFO_FW_BOOT_STATE_CRIT_MEM_FATAL_DME = IA_GOFO_MEM_FATAL_DME_ERR, + IA_GOFO_FW_BOOT_STATE_CRIT_MEM_UNCORRECTABLE_LOCAL = + IA_GOFO_MEM_UNCORRECTABLE_LOCAL_ERR, + IA_GOFO_FW_BOOT_STATE_CRIT_MEM_UNCORRECTABLE_DIRTY = + IA_GOFO_MEM_UNCORRECTABLE_DIRTY_ERR, + IA_GOFO_FW_BOOT_STATE_CRIT_MEM_UNCORRECTABLE_DTAG = + IA_GOFO_MEM_UNCORRECTABLE_DTAG_ERR, + IA_GOFO_FW_BOOT_STATE_CRIT_MEM_UNCORRECTABLE_CACHE = + IA_GOFO_MEM_UNCORRECTABLE_CACHE_ERR, + IA_GOFO_FW_BOOT_STATE_CRIT_DOUBLE_EXCEPTION = + IA_GOFO_DOUBLE_EXCEPTION_ERR, + IA_GOFO_FW_BOOT_STATE_CRIT_BIST_DMEM_FAULT_DETECTION_ERR = + IA_GOFO_BIST_DMEM_FAULT_DETECTION_ERR, + IA_GOFO_FW_BOOT_STATE_CRIT_DATA_INTEGRITY_FAILURE = 0xdead1010U, + IA_GOFO_FW_BOOT_STATE_CRIT_STACK_CHK_FAILURE = 0xdead1011U, + IA_GOFO_FW_BOOT_STATE_CRIT_SYSCOM_CONTEXT_INTEGRITY_FAILURE = + 0xdead1012U, + IA_GOFO_FW_BOOT_STATE_CRIT_MPU_CONFIG_FAILURE = 0xdead1013U, + IA_GOFO_FW_BOOT_STATE_CRIT_SHARED_BUFFER_FAILURE = 0xdead1014U, + IA_GOFO_FW_BOOT_STATE_CRIT_CMEM_FAILURE = 0xdead1015U, + IA_GOFO_FW_BOOT_STATE_SHUTDOWN_CMD = 0x57a7f001U, + IA_GOFO_FW_BOOT_STATE_SHUTDOWN_START = 0x57a7e200U, + IA_GOFO_FW_BOOT_STATE_INACTIVE = 0x57a7e300U, + IA_GOFO_FW_BOOT_HW_CMD_ACK_TIMEOUT = 0x57a7e400U, + IA_GOFO_FW_BOOT_SYSTEM_CYCLES_ERROR = 0x57a7e500U +}; + +#endif diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_common_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_common_abi.h new file mode 100644 index 000000000000..7bb6fac585a3 --- /dev/null +++ b/drivers/staging/media/ipu7/abi/ipu7_fw_common_abi.h @@ -0,0 +1,175 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 - 2025 Intel Corporation + */ + +#ifndef IPU7_FW_COMMOM_ABI_H +#define IPU7_FW_COMMOM_ABI_H + +#include <linux/types.h> + +#pragma pack(push, 1) +typedef u32 ia_gofo_addr_t; + +#define IA_GOFO_ADDR_NULL (0U) + +struct ia_gofo_version_s { + u8 patch; + u8 subminor; + u8 minor; + u8 major; +}; + +#define IA_GOFO_MSG_VERSION_INIT(major_val, minor_val, subminor_val, patch_val)\ + {.major = (major_val), .minor = (minor_val), .subminor = \ + (subminor_val), .patch = (patch_val)} + +#define IA_GOFO_MSG_VERSION_LIST_MAX_ENTRIES (3U) +#define IA_GOFO_MSG_RESERVED_SIZE (3U) + +struct ia_gofo_msg_version_list { + u8 num_versions; + u8 reserved[IA_GOFO_MSG_RESERVED_SIZE]; + struct ia_gofo_version_s versions[IA_GOFO_MSG_VERSION_LIST_MAX_ENTRIES]; +}; + +#pragma pack(pop) + +#define TLV_TYPE_PADDING (0U) + +#pragma pack(push, 1) + +#define IA_GOFO_ABI_BITS_PER_BYTE (8U) + +struct ia_gofo_tlv_header { + u16 tlv_type; + u16 tlv_len32; +}; + +struct ia_gofo_tlv_list { + u16 num_elems; + u16 head_offset; +}; + +#define TLV_ITEM_ALIGNMENT ((u32)sizeof(u32)) +#define TLV_MSG_ALIGNMENT ((u32)sizeof(u64)) +#define TLV_LIST_ALIGNMENT TLV_ITEM_ALIGNMENT +#pragma pack(pop) + +#define IA_GOFO_MODULO(dividend, divisor) ((dividend) % (divisor)) + +#define IA_GOFO_MSG_ERR_MAX_DETAILS (4U) +#define IA_GOFO_MSG_ERR_OK (0U) +#define IA_GOFO_MSG_ERR_UNSPECIFED (0xffffffffU) +#define IA_GOFO_MSG_ERR_GROUP_UNSPECIFIED (0U) +#define IA_GOFO_MSG_ERR_IS_OK(err) (IA_GOFO_MSG_ERR_OK == (err).err_code) + +#pragma pack(push, 1) +struct ia_gofo_msg_err { + u32 err_group; + u32 err_code; + u32 err_detail[IA_GOFO_MSG_ERR_MAX_DETAILS]; +}; + +#pragma pack(pop) + +#define IA_GOFO_MSG_ERR_GROUP_APP_EXT_START (16U) +#define IA_GOFO_MSG_ERR_GROUP_MAX (31U) +#define IA_GOFO_MSG_ERR_GROUP_INTERNAL_START (IA_GOFO_MSG_ERR_GROUP_MAX + 1U) +#define IA_GOFO_MSG_ERR_GROUP_RESERVED IA_GOFO_MSG_ERR_GROUP_UNSPECIFIED +#define IA_GOFO_MSG_ERR_GROUP_GENERAL 1 + +enum ia_gofo_msg_err_general { + IA_GOFO_MSG_ERR_GENERAL_OK = IA_GOFO_MSG_ERR_OK, + IA_GOFO_MSG_ERR_GENERAL_MSG_TOO_SMALL = 1, + IA_GOFO_MSG_ERR_GENERAL_MSG_TOO_LARGE = 2, + IA_GOFO_MSG_ERR_GENERAL_DEVICE_STATE = 3, + IA_GOFO_MSG_ERR_GENERAL_ALIGNMENT = 4, + IA_GOFO_MSG_ERR_GENERAL_INDIRECT_REF_PTR_INVALID = 5, + IA_GOFO_MSG_ERR_GENERAL_INVALID_MSG_TYPE = 6, + IA_GOFO_MSG_ERR_GENERAL_SYSCOM_FAIL = 7, + IA_GOFO_MSG_ERR_GENERAL_N +}; + +#pragma pack(push, 1) +#define IA_GOFO_MSG_TYPE_RESERVED 0 +#define IA_GOFO_MSG_TYPE_INDIRECT 1 +#define IA_GOFO_MSG_TYPE_LOG 2 +#define IA_GOFO_MSG_TYPE_GENERAL_ERR 3 + +struct ia_gofo_msg_header { + struct ia_gofo_tlv_header tlv_header; + struct ia_gofo_tlv_list msg_options; + u64 user_token; +}; + +struct ia_gofo_msg_header_ack { + struct ia_gofo_msg_header header; + struct ia_gofo_msg_err err; + +}; + +struct ia_gofo_msg_general_err { + struct ia_gofo_msg_header_ack header; +}; + +#pragma pack(pop) + +#pragma pack(push, 1) +enum ia_gofo_msg_link_streaming_mode { + IA_GOFO_MSG_LINK_STREAMING_MODE_SOFF = 0, + IA_GOFO_MSG_LINK_STREAMING_MODE_DOFF = 1, + IA_GOFO_MSG_LINK_STREAMING_MODE_BCLM = 2, + IA_GOFO_MSG_LINK_STREAMING_MODE_BCSM_FIX = 3, + IA_GOFO_MSG_LINK_STREAMING_MODE_N +}; + +enum ia_gofo_soc_pbk_instance_id { + IA_GOFO_SOC_PBK_ID0 = 0, + IA_GOFO_SOC_PBK_ID1 = 1, + IA_GOFO_SOC_PBK_ID_N +}; + +#define IA_GOFO_MSG_LINK_PBK_MAX_SLOTS (2U) + +struct ia_gofo_msg_indirect { + struct ia_gofo_msg_header header; + struct ia_gofo_tlv_header ref_header; + ia_gofo_addr_t ref_msg_ptr; +}; + +#pragma pack(pop) + +#pragma pack(push, 1) +#define IA_GOFO_MSG_LOG_MAX_PARAMS (4U) +#define IA_GOFO_MSG_LOG_DOC_FMT_ID_MIN (0U) + +#define IA_GOFO_MSG_LOG_DOC_FMT_ID_MAX (4095U) +#define IA_GOFO_MSG_LOG_FMT_ID_INVALID (0xfffffffU) + +struct ia_gofo_msg_log_info { + u16 log_counter; + u8 msg_parameter_types; + /* [0:0] is_out_of_order, [1:3] logger_channel, [4:7] reserved */ + u8 logger_opts; + u32 fmt_id; + u32 params[IA_GOFO_MSG_LOG_MAX_PARAMS]; +}; + +struct ia_gofo_msg_log_info_ts { + u64 msg_ts; + struct ia_gofo_msg_log_info log_info; +}; + +struct ia_gofo_msg_log { + struct ia_gofo_msg_header header; + struct ia_gofo_msg_log_info_ts log_info_ts; +}; + +#pragma pack(pop) + +#define IA_GOFO_MSG_ABI_OUT_ACK_QUEUE_ID (0U) +#define IA_GOFO_MSG_ABI_OUT_LOG_QUEUE_ID (1U) +#define IA_GOFO_MSG_ABI_IN_DEV_QUEUE_ID (2U) + +#endif diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_config_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_config_abi.h new file mode 100644 index 000000000000..c3f62aaedd86 --- /dev/null +++ b/drivers/staging/media/ipu7/abi/ipu7_fw_config_abi.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2021 - 2025 Intel Corporation + */ + +#ifndef IPU7_FW_CONFIG_ABI_H +#define IPU7_FW_CONFIG_ABI_H + +#include <linux/types.h> + +#define IPU_CONFIG_ABI_WDT_TIMER_DISABLED 0U +#define IPU_CONFIG_ABI_CMD_TIMER_DISABLED 0U + +struct ipu7_wdt_abi { + u32 wdt_timer1_us; + u32 wdt_timer2_us; +}; + +#endif diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_insys_config_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_insys_config_abi.h new file mode 100644 index 000000000000..f161a605c500 --- /dev/null +++ b/drivers/staging/media/ipu7/abi/ipu7_fw_insys_config_abi.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2021 - 2025 Intel Corporation + */ + +#ifndef IPU7_FW_INSYS_CONFIG_ABI_H +#define IPU7_FW_INSYS_CONFIG_ABI_H + +#include "ipu7_fw_boot_abi.h" +#include "ipu7_fw_config_abi.h" +#include "ipu7_fw_isys_abi.h" + +struct ipu7_insys_config { + u32 timeout_val_ms; + struct ia_gofo_logger_config logger_config; + struct ipu7_wdt_abi wdt_config; +}; + +#endif diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h new file mode 100644 index 000000000000..c42d0b7a2627 --- /dev/null +++ b/drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h @@ -0,0 +1,412 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 - 2025 Intel Corporation + */ + +#ifndef IPU7_FW_ISYS_ABI_H +#define IPU7_FW_ISYS_ABI_H + +#include "ipu7_fw_common_abi.h" +#include "ipu7_fw_isys_abi.h" + +#define IPU_INSYS_MAX_OUTPUT_QUEUES (3U) +#define IPU_INSYS_STREAM_ID_MAX (16U) + +#define IPU_INSYS_MAX_INPUT_QUEUES (IPU_INSYS_STREAM_ID_MAX + 1U) +#define IPU_INSYS_OUTPUT_FIRST_QUEUE (0U) +#define IPU_INSYS_OUTPUT_LAST_QUEUE (IPU_INSYS_MAX_OUTPUT_QUEUES - 1U) +#define IPU_INSYS_OUTPUT_MSG_QUEUE (IPU_INSYS_OUTPUT_FIRST_QUEUE) +#define IPU_INSYS_OUTPUT_LOG_QUEUE (IPU_INSYS_OUTPUT_FIRST_QUEUE + 1U) +#define IPU_INSYS_OUTPUT_RESERVED_QUEUE (IPU_INSYS_OUTPUT_LAST_QUEUE) +#define IPU_INSYS_INPUT_FIRST_QUEUE (IPU_INSYS_MAX_OUTPUT_QUEUES) +#define IPU_INSYS_INPUT_LAST_QUEUE \ + (IPU_INSYS_INPUT_FIRST_QUEUE + IPU_INSYS_MAX_INPUT_QUEUES - 1U) +#define IPU_INSYS_INPUT_DEV_QUEUE (IPU_INSYS_INPUT_FIRST_QUEUE) +#define IPU_INSYS_INPUT_MSG_QUEUE (IPU_INSYS_INPUT_FIRST_QUEUE + 1U) +#define IPU_INSYS_INPUT_MSG_MAX_QUEUE (IPU_INSYS_MAX_INPUT_QUEUES - 1U) + +#define MAX_OPINS_FOR_SINGLE_IPINS (3U) +#define DEV_SEND_QUEUE_SIZE (IPU_INSYS_STREAM_ID_MAX) + +#define PIN_PLANES_MAX (4U) + +#define INSYS_MSG_ERR_STREAM_INSUFFICIENT_RESOURCES_INPUT \ + INSYS_MSG_ERR_STREAM_INSUFFICIENT_RESOURCES + +typedef u64 ipu7_insys_return_token; + +enum ipu7_insys_resp_type { + IPU_INSYS_RESP_TYPE_STREAM_OPEN_DONE = 0, + IPU_INSYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK = 1, + IPU_INSYS_RESP_TYPE_STREAM_CAPTURE_ACK = 2, + IPU_INSYS_RESP_TYPE_STREAM_ABORT_ACK = 3, + IPU_INSYS_RESP_TYPE_STREAM_FLUSH_ACK = 4, + IPU_INSYS_RESP_TYPE_STREAM_CLOSE_ACK = 5, + IPU_INSYS_RESP_TYPE_PIN_DATA_READY = 6, + IPU_INSYS_RESP_TYPE_FRAME_SOF = 7, + IPU_INSYS_RESP_TYPE_FRAME_EOF = 8, + IPU_INSYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE = 9, + IPU_INSYS_RESP_TYPE_STREAM_CAPTURE_DONE = 10, + IPU_INSYS_RESP_TYPE_PWM_IRQ = 11, + N_IPU_INSYS_RESP_TYPE +}; + +enum ipu7_insys_send_type { + IPU_INSYS_SEND_TYPE_STREAM_OPEN = 0, + IPU_INSYS_SEND_TYPE_STREAM_START_AND_CAPTURE = 1, + IPU_INSYS_SEND_TYPE_STREAM_CAPTURE = 2, + IPU_INSYS_SEND_TYPE_STREAM_ABORT = 3, + IPU_INSYS_SEND_TYPE_STREAM_FLUSH = 4, + IPU_INSYS_SEND_TYPE_STREAM_CLOSE = 5, + N_IPU_INSYS_SEND_TYPE +}; + +enum ipu7_insys_mipi_vc { + IPU_INSYS_MIPI_VC_0 = 0, + IPU_INSYS_MIPI_VC_1 = 1, + IPU_INSYS_MIPI_VC_2 = 2, + IPU_INSYS_MIPI_VC_3 = 3, + IPU_INSYS_MIPI_VC_4 = 4, + IPU_INSYS_MIPI_VC_5 = 5, + IPU_INSYS_MIPI_VC_6 = 6, + IPU_INSYS_MIPI_VC_7 = 7, + IPU_INSYS_MIPI_VC_8 = 8, + IPU_INSYS_MIPI_VC_9 = 9, + IPU_INSYS_MIPI_VC_10 = 10, + IPU_INSYS_MIPI_VC_11 = 11, + IPU_INSYS_MIPI_VC_12 = 12, + IPU_INSYS_MIPI_VC_13 = 13, + IPU_INSYS_MIPI_VC_14 = 14, + IPU_INSYS_MIPI_VC_15 = 15, + N_IPU_INSYS_MIPI_VC +}; + +enum ipu7_insys_mipi_port { + IPU_INSYS_MIPI_PORT_0 = 0, + IPU_INSYS_MIPI_PORT_1 = 1, + IPU_INSYS_MIPI_PORT_2 = 2, + IPU_INSYS_MIPI_PORT_3 = 3, + IPU_INSYS_MIPI_PORT_4 = 4, + IPU_INSYS_MIPI_PORT_5 = 5, + NA_IPU_INSYS_MIPI_PORT +}; + +enum ipu7_insys_frame_format_type { + IPU_INSYS_FRAME_FORMAT_NV11 = 0, + IPU_INSYS_FRAME_FORMAT_NV12 = 1, + IPU_INSYS_FRAME_FORMAT_NV12_16 = 2, + IPU_INSYS_FRAME_FORMAT_NV12_TILEY = 3, + IPU_INSYS_FRAME_FORMAT_NV16 = 4, + IPU_INSYS_FRAME_FORMAT_NV21 = 5, + IPU_INSYS_FRAME_FORMAT_NV61 = 6, + IPU_INSYS_FRAME_FORMAT_YV12 = 7, + IPU_INSYS_FRAME_FORMAT_YV16 = 8, + IPU_INSYS_FRAME_FORMAT_YUV420 = 9, + IPU_INSYS_FRAME_FORMAT_YUV420_10 = 10, + IPU_INSYS_FRAME_FORMAT_YUV420_12 = 11, + IPU_INSYS_FRAME_FORMAT_YUV420_14 = 12, + IPU_INSYS_FRAME_FORMAT_YUV420_16 = 13, + IPU_INSYS_FRAME_FORMAT_YUV422 = 14, + IPU_INSYS_FRAME_FORMAT_YUV422_16 = 15, + IPU_INSYS_FRAME_FORMAT_UYVY = 16, + IPU_INSYS_FRAME_FORMAT_YUYV = 17, + IPU_INSYS_FRAME_FORMAT_YUV444 = 18, + IPU_INSYS_FRAME_FORMAT_YUV_LINE = 19, + IPU_INSYS_FRAME_FORMAT_RAW8 = 20, + IPU_INSYS_FRAME_FORMAT_RAW10 = 21, + IPU_INSYS_FRAME_FORMAT_RAW12 = 22, + IPU_INSYS_FRAME_FORMAT_RAW14 = 23, + IPU_INSYS_FRAME_FORMAT_RAW16 = 24, + IPU_INSYS_FRAME_FORMAT_RGB565 = 25, + IPU_INSYS_FRAME_FORMAT_PLANAR_RGB888 = 26, + IPU_INSYS_FRAME_FORMAT_RGBA888 = 27, + IPU_INSYS_FRAME_FORMAT_QPLANE6 = 28, + IPU_INSYS_FRAME_FORMAT_BINARY_8 = 29, + IPU_INSYS_FRAME_FORMAT_Y_8 = 30, + IPU_INSYS_FRAME_FORMAT_ARGB888 = 31, + IPU_INSYS_FRAME_FORMAT_BGRA888 = 32, + IPU_INSYS_FRAME_FORMAT_ABGR888 = 33, + N_IPU_INSYS_FRAME_FORMAT +}; + +#define IPU_INSYS_FRAME_FORMAT_RAW (IPU_INSYS_FRAME_FORMAT_RAW16) +#define N_IPU_INSYS_MIPI_DATA_TYPE 0x40 + +enum ipu7_insys_mipi_dt_rename_mode { + IPU_INSYS_MIPI_DT_NO_RENAME = 0, + IPU_INSYS_MIPI_DT_RENAMED_MODE = 1, + N_IPU_INSYS_MIPI_DT_MODE +}; + +#define IPU_INSYS_SEND_MSG_ENABLED 1U +#define IPU_INSYS_SEND_MSG_DISABLED 0U + +#define IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_SOF BIT(0) +#define IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_EOF BIT(1) +#define IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_SOF BIT(2) +#define IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_EOF BIT(3) +#define IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_SOF_DISCARDED BIT(4) +#define IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_EOF_DISCARDED BIT(5) +#define IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_SOF_DISCARDED BIT(6) +#define IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_EOF_DISCARDED BIT(7) +#define IPU_INSYS_STREAM_SYNC_MSG_ENABLE_MSG_SEND_RESP ( \ + IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_SOF | \ + IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_EOF | \ + IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_SOF_DISCARDED | \ + IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_EOF_DISCARDED) +#define IPU_INSYS_STREAM_SYNC_MSG_ENABLE_MSG_SEND_IRQ ( \ + IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_SOF | \ + IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_EOF | \ + IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_SOF_DISCARDED | \ + IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_EOF_DISCARDED) + +#define IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_OPEN_DONE BIT(0) +#define IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_OPEN_DONE BIT(1) +#define IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_START_ACK BIT(2) +#define IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_START_ACK BIT(3) +#define IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_CLOSE_ACK BIT(4) +#define IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_CLOSE_ACK BIT(5) +#define IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_FLUSH_ACK BIT(6) +#define IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_FLUSH_ACK BIT(7) +#define IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_ABORT_ACK BIT(8) +#define IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_ABORT_ACK BIT(9) +#define IPU_INSYS_STREAM_ENABLE_MSG_SEND_RESP ( \ + IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_OPEN_DONE | \ + IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_START_ACK | \ + IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_CLOSE_ACK | \ + IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_FLUSH_ACK | \ + IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_ABORT_ACK) +#define IPU_INSYS_STREAM_ENABLE_MSG_SEND_IRQ ( \ + IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_OPEN_DONE | \ + IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_START_ACK | \ + IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_CLOSE_ACK | \ + IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_FLUSH_ACK | \ + IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_ABORT_ACK) + +#define IPU_INSYS_FRAME_MSG_SEND_RESP_CAPTURE_ACK BIT(0) +#define IPU_INSYS_FRAME_MSG_SEND_IRQ_CAPTURE_ACK BIT(1) +#define IPU_INSYS_FRAME_MSG_SEND_RESP_CAPTURE_DONE BIT(2) +#define IPU_INSYS_FRAME_MSG_SEND_IRQ_CAPTURE_DONE BIT(3) +#define IPU_INSYS_FRAME_MSG_SEND_RESP_PIN_DATA_READY BIT(4) +#define IPU_INSYS_FRAME_MSG_SEND_IRQ_PIN_DATA_READY BIT(5) +#define IPU_INSYS_FRAME_ENABLE_MSG_SEND_RESP ( \ + IPU_INSYS_FRAME_MSG_SEND_RESP_CAPTURE_ACK | \ + IPU_INSYS_FRAME_MSG_SEND_RESP_CAPTURE_DONE | \ + IPU_INSYS_FRAME_MSG_SEND_RESP_PIN_DATA_READY) +#define IPU_INSYS_FRAME_ENABLE_MSG_SEND_IRQ ( \ + IPU_INSYS_FRAME_MSG_SEND_IRQ_CAPTURE_ACK | \ + IPU_INSYS_FRAME_MSG_SEND_IRQ_CAPTURE_DONE | \ + IPU_INSYS_FRAME_MSG_SEND_IRQ_PIN_DATA_READY) + +enum ipu7_insys_output_link_dest { + IPU_INSYS_OUTPUT_LINK_DEST_MEM = 0, + IPU_INSYS_OUTPUT_LINK_DEST_PSYS = 1, + IPU_INSYS_OUTPUT_LINK_DEST_IPU_EXTERNAL = 2 +}; + +enum ipu7_insys_dpcm_type { + IPU_INSYS_DPCM_TYPE_DISABLED = 0, + IPU_INSYS_DPCM_TYPE_10_8_10 = 1, + IPU_INSYS_DPCM_TYPE_12_8_12 = 2, + IPU_INSYS_DPCM_TYPE_12_10_12 = 3, + N_IPU_INSYS_DPCM_TYPE +}; + +enum ipu7_insys_dpcm_predictor { + IPU_INSYS_DPCM_PREDICTOR_1 = 0, + IPU_INSYS_DPCM_PREDICTOR_2 = 1, + N_IPU_INSYS_DPCM_PREDICTOR +}; + +enum ipu7_insys_send_queue_token_flag { + IPU_INSYS_SEND_QUEUE_TOKEN_FLAG_NONE = 0, + IPU_INSYS_SEND_QUEUE_TOKEN_FLAG_FLUSH_FORCE = 1 +}; + +#pragma pack(push, 1) +struct ipu7_insys_resolution { + u32 width; + u32 height; +}; + +struct ipu7_insys_capture_output_pin_payload { + u64 user_token; + ia_gofo_addr_t addr; + u8 pad[4]; +}; + +struct ipu7_insys_output_link { + u32 buffer_lines; + u16 foreign_key; + u16 granularity_pointer_update; + u8 msg_link_streaming_mode; + u8 pbk_id; + u8 pbk_slot_id; + u8 dest; + u8 use_sw_managed; + u8 is_snoop; + u8 pad[2]; +}; + +struct ipu7_insys_output_cropping { + u16 line_top; + u16 line_bottom; +}; + +struct ipu7_insys_output_dpcm { + u8 enable; + u8 type; + u8 predictor; + u8 pad; +}; + +struct ipu7_insys_output_pin { + struct ipu7_insys_output_link link; + struct ipu7_insys_output_cropping crop; + struct ipu7_insys_output_dpcm dpcm; + u32 stride; + u16 ft; + u8 send_irq; + u8 input_pin_id; + u8 early_ack_en; + u8 pad[3]; +}; + +struct ipu7_insys_input_pin { + struct ipu7_insys_resolution input_res; + u16 sync_msg_map; + u8 dt; + u8 disable_mipi_unpacking; + u8 dt_rename_mode; + u8 mapped_dt; + u8 pad[2]; +}; + +struct ipu7_insys_stream_cfg { + struct ipu7_insys_input_pin input_pins[4]; + struct ipu7_insys_output_pin output_pins[4]; + u16 stream_msg_map; + u8 port_id; + u8 vc; + u8 nof_input_pins; + u8 nof_output_pins; + u8 pad[2]; +}; + +struct ipu7_insys_buffset { + struct ipu7_insys_capture_output_pin_payload output_pins[4]; + u8 capture_msg_map; + u8 frame_id; + u8 skip_frame; + u8 pad[5]; +}; + +struct ipu7_insys_resp { + u64 buf_id; + struct ipu7_insys_capture_output_pin_payload pin; + struct ia_gofo_msg_err error_info; + u32 timestamp[2]; + u8 type; + u8 msg_link_streaming_mode; + u8 stream_id; + u8 pin_id; + u8 frame_id; + u8 skip_frame; + u8 pad[2]; +}; + +struct ipu7_insys_resp_queue_token { + struct ipu7_insys_resp resp_info; +}; + +struct ipu7_insys_send_queue_token { + u64 buf_handle; + ia_gofo_addr_t addr; + u16 stream_id; + u8 send_type; + u8 flag; +}; + +#pragma pack(pop) + +enum insys_msg_err_stream { + INSYS_MSG_ERR_STREAM_OK = IA_GOFO_MSG_ERR_OK, + INSYS_MSG_ERR_STREAM_STREAM_ID = 1, + INSYS_MSG_ERR_STREAM_MAX_OPINS = 2, + INSYS_MSG_ERR_STREAM_MAX_IPINS = 3, + INSYS_MSG_ERR_STREAM_STREAM_MESSAGES_MAP = 4, + INSYS_MSG_ERR_STREAM_SYNC_MESSAGES_MAP = 5, + INSYS_MSG_ERR_STREAM_SENSOR_TYPE = 6, + INSYS_MSG_ERR_STREAM_FOREIGN_KEY = 7, + INSYS_MSG_ERR_STREAM_STREAMING_MODE = 8, + INSYS_MSG_ERR_STREAM_DPCM_EN = 9, + INSYS_MSG_ERR_STREAM_DPCM_TYPE = 10, + INSYS_MSG_ERR_STREAM_DPCM_PREDICTOR = 11, + INSYS_MSG_ERR_STREAM_GRANULARITY_POINTER_UPDATE = 12, + INSYS_MSG_ERR_STREAM_MPF_LUT_ENTRY_RESOURCES_BUSY = 13, + INSYS_MSG_ERR_STREAM_MPF_DEV_ID = 14, + INSYS_MSG_ERR_STREAM_BUFFER_LINES = 15, + INSYS_MSG_ERR_STREAM_IPIN_ID = 16, + INSYS_MSG_ERR_STREAM_DATA_TYPE = 17, + INSYS_MSG_ERR_STREAM_STREAMING_PROTOCOL_STATE = 18, + INSYS_MSG_ERR_STREAM_SYSCOM_FLUSH = 19, + INSYS_MSG_ERR_STREAM_MIPI_VC = 20, + INSYS_MSG_ERR_STREAM_STREAM_SRC = 21, + INSYS_MSG_ERR_STREAM_PBK_ID = 22, + INSYS_MSG_ERR_STREAM_CMD_QUEUE_DEALLOCATE = 23, + INSYS_MSG_ERR_STREAM_INSUFFICIENT_RESOURCES = 24, + INSYS_MSG_ERR_STREAM_IPIN_CONFIGURATION = 25, + INSYS_MSG_ERR_STREAM_INVALID_STATE = 26, + INSYS_MSG_ERR_STREAM_SW_MANAGED = 27, + INSYS_MSG_ERR_STREAM_PBK_SLOT_ID = 28, + INSYS_MSG_ERR_STREAM_FLUSH_TIMEOUT = 29, + INSYS_MSG_ERR_STREAM_IPIN_WIDTH = 30, + INSYS_MSG_ERR_STREAM_IPIN_HEIGHT = 31, + INSYS_MSG_ERR_STREAM_OUTPUT_PIN_EARLY_ACK_EN = 32, + INSYS_MSG_ERR_STREAM_INCONSISTENT_PARAMS = 33, + INSYS_MSG_ERR_STREAM_PLANE_COUNT = 34, + INSYS_MSG_ERR_STREAM_FRAME_FORMAT_TYPE = 35, + INSYS_MSG_ERR_STREAM_INSUFFICIENT_RESOURCES_OUTPUT = 36, + INSYS_MSG_ERR_STREAM_WIDTH_OUTPUT_SIZE = 37, + INSYS_MSG_ERR_STREAM_CLOSED = 38, + INSYS_MSG_ERR_STREAM_N +}; + +enum insys_msg_err_capture { + INSYS_MSG_ERR_CAPTURE_OK = IA_GOFO_MSG_ERR_OK, + INSYS_MSG_ERR_CAPTURE_STREAM_ID = 1, + INSYS_MSG_ERR_CAPTURE_PAYLOAD_PTR = 2, + INSYS_MSG_ERR_CAPTURE_MEM_SLOT = 3, + INSYS_MSG_ERR_CAPTURE_STREAMING_MODE = 4, + INSYS_MSG_ERR_CAPTURE_AVAILABLE_CMD_SLOT = 5, + INSYS_MSG_ERR_CAPTURE_CONSUMED_CMD_SLOT = 6, + INSYS_MSG_ERR_CAPTURE_CMD_SLOT_PAYLOAD_PTR = 7, + INSYS_MSG_ERR_CAPTURE_CMD_PREPARE = 8, + INSYS_MSG_ERR_CAPTURE_OUTPUT_PIN = 9, + INSYS_MSG_ERR_CAPTURE_SYNC_FRAME_DROP = 10, + INSYS_MSG_ERR_CAPTURE_FRAME_MESSAGES_MAP = 11, + INSYS_MSG_ERR_CAPTURE_TIMEOUT = 12, + INSYS_MSG_ERR_CAPTURE_INVALID_STREAM_STATE = 13, + INSYS_MSG_ERR_CAPTURE_HW_ERR_MULTIBIT_PH_ERROR_DETECTED = 14, + INSYS_MSG_ERR_CAPTURE_HW_ERR_PAYLOAD_CRC_ERROR = 15, + INSYS_MSG_ERR_CAPTURE_HW_ERR_INPUT_DATA_LOSS_ELASTIC_FIFO_OVFL = 16, + INSYS_MSG_ERR_CAPTURE_HW_ERR_PIXEL_BUFFER_OVERFLOW = 17, + INSYS_MSG_ERR_CAPTURE_HW_ERR_BAD_FRAME_DIM = 18, + INSYS_MSG_ERR_CAPTURE_HW_ERR_PHY_SYNC_ERR = 19, + INSYS_MSG_ERR_CAPTURE_HW_ERR_SECURE_TOUCH = 20, + INSYS_MSG_ERR_CAPTURE_HW_ERR_MASTER_SLAVE_SYNC_ERR = 21, + INSYS_MSG_ERR_CAPTURE_FRAME_SKIP_ERR = 22, + INSYS_MSG_ERR_CAPTURE_FE_INPUT_FIFO_OVERFLOW_ERR = 23, + INSYS_MSG_ERR_CAPTURE_CMD_SUBMIT_TO_HW = 24, + INSYS_MSG_ERR_CAPTURE_N +}; + +enum insys_msg_err_groups { + INSYS_MSG_ERR_GROUP_RESERVED = IA_GOFO_MSG_ERR_GROUP_RESERVED, + INSYS_MSG_ERR_GROUP_GENERAL = IA_GOFO_MSG_ERR_GROUP_GENERAL, + INSYS_MSG_ERR_GROUP_STREAM = 2, + INSYS_MSG_ERR_GROUP_CAPTURE = 3, + INSYS_MSG_ERR_GROUP_N, +}; + +#endif diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_msg_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_msg_abi.h new file mode 100644 index 000000000000..8a78dd0936df --- /dev/null +++ b/drivers/staging/media/ipu7/abi/ipu7_fw_msg_abi.h @@ -0,0 +1,465 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 - 2025 Intel Corporation + */ + +#ifndef IPU7_FW_MSG_ABI_H +#define IPU7_FW_MSG_ABI_H + +#include "ipu7_fw_common_abi.h" + +#pragma pack(push, 1) +enum ipu7_msg_type { + IPU_MSG_TYPE_RESERVED = IA_GOFO_MSG_TYPE_RESERVED, + IPU_MSG_TYPE_INDIRECT = IA_GOFO_MSG_TYPE_INDIRECT, + IPU_MSG_TYPE_DEV_LOG = IA_GOFO_MSG_TYPE_LOG, + IPU_MSG_TYPE_GENERAL_ERR = IA_GOFO_MSG_TYPE_GENERAL_ERR, + IPU_MSG_TYPE_DEV_OPEN = 4, + IPU_MSG_TYPE_DEV_OPEN_ACK = 5, + IPU_MSG_TYPE_GRAPH_OPEN = 6, + IPU_MSG_TYPE_GRAPH_OPEN_ACK = 7, + IPU_MSG_TYPE_TASK_REQ = 8, + IPU_MSG_TYPE_TASK_DONE = 9, + IPU_MSG_TYPE_GRAPH_CLOSE = 10, + IPU_MSG_TYPE_GRAPH_CLOSE_ACK = 11, + IPU_MSG_TYPE_DEV_CLOSE = 12, + IPU_MSG_TYPE_DEV_CLOSE_ACK = 13, + IPU_MSG_TYPE_TERM_EVENT = 14, + IPU_MSG_TYPE_N, +}; + +#define IPU_MSG_MAX_NODE_TERMS (64U) +#define IPU_MSG_MAX_FRAGS (7U) + +enum ipu7_msg_node_type { + IPU_MSG_NODE_TYPE_PAD = 0, + IPU_MSG_NODE_TYPE_BASE, + IPU_MSG_NODE_TYPE_N +}; + +#define IPU_MSG_NODE_MAX_DEVICES (128U) +#define DEB_NUM_UINT32 (IPU_MSG_NODE_MAX_DEVICES / (sizeof(u32) * 8U)) + +typedef u32 ipu7_msg_teb_t[2]; +typedef u32 ipu7_msg_deb_t[DEB_NUM_UINT32]; + +#define IPU_MSG_NODE_MAX_ROUTE_ENABLES (128U) +#define RBM_NUM_UINT32 (IPU_MSG_NODE_MAX_ROUTE_ENABLES / (sizeof(u32) * 8U)) + +typedef u32 ipu7_msg_rbm_t[RBM_NUM_UINT32]; + +enum ipu7_msg_node_profile_type { + IPU_MSG_NODE_PROFILE_TYPE_PAD = 0, + IPU_MSG_NODE_PROFILE_TYPE_BASE, + IPU_MSG_NODE_PROFILE_TYPE_CB, + IPU_MSG_NODE_PROFILE_TYPE_N +}; + +struct ipu7_msg_node_profile { + struct ia_gofo_tlv_header tlv_header; + ipu7_msg_teb_t teb; +}; + +struct ipu7_msg_cb_profile { + struct ipu7_msg_node_profile profile_base; + ipu7_msg_deb_t deb; + ipu7_msg_rbm_t rbm; + ipu7_msg_rbm_t reb; +}; + +#define IPU_MSG_NODE_MAX_PROFILES (2U) +#define IPU_MSG_NODE_DEF_PROFILE_IDX (0U) +#define IPU_MSG_NODE_RSRC_ID_EXT_IP (0xffU) + +#define IPU_MSG_NODE_DONT_CARE_TEB_HI (0xffffffffU) +#define IPU_MSG_NODE_DONT_CARE_TEB_LO (0xffffffffU) +#define IPU_MSG_NODE_RSRC_ID_IS (0xfeU) + +struct ipu7_msg_node { + struct ia_gofo_tlv_header tlv_header; + u8 node_rsrc_id; + u8 node_ctx_id; + u8 num_frags; + u8 reserved[1]; + struct ia_gofo_tlv_list profiles_list; + struct ia_gofo_tlv_list terms_list; + struct ia_gofo_tlv_list node_options; +}; + +enum ipu7_msg_node_option_types { + IPU_MSG_NODE_OPTION_TYPES_PADDING = 0, + IPU_MSG_NODE_OPTION_TYPES_N +}; + +#pragma pack(pop) + +#pragma pack(push, 1) + +enum ipu7_msg_link_type { + IPU_MSG_LINK_TYPE_PAD = 0, + IPU_MSG_LINK_TYPE_GENERIC = 1, + IPU_MSG_LINK_TYPE_N +}; + +enum ipu7_msg_link_option_types { + IPU_MSG_LINK_OPTION_TYPES_PADDING = 0, + IPU_MSG_LINK_OPTION_TYPES_CMPRS = 1, + IPU_MSG_LINK_OPTION_TYPES_N +}; + +enum ipu7_msg_link_cmprs_option_bit_depth { + IPU_MSG_LINK_CMPRS_OPTION_8BPP = 0, + IPU_MSG_LINK_CMPRS_OPTION_10BPP = 1, + IPU_MSG_LINK_CMPRS_OPTION_12BPP = 2, +}; + +#define IPU_MSG_LINK_CMPRS_SPACE_SAVING_DENOM (128U) +#define IPU_MSG_LINK_CMPRS_LOSSY_CFG_PAYLOAD_SIZE (5U) +#define IPU_MSG_LINK_CMPRS_SPACE_SAVING_NUM_MAX \ + (IPU_MSG_LINK_CMPRS_SPACE_SAVING_DENOM - 1U) + +struct ipu7_msg_link_cmprs_plane_desc { + u8 plane_enable; + u8 cmprs_enable; + u8 encoder_plane_id; + u8 decoder_plane_id; + u8 cmprs_is_lossy; + u8 cmprs_is_footprint; + u8 bit_depth; + u8 space_saving_numerator; + u32 pixels_offset; + u32 ts_offset; + u32 tile_row_to_tile_row_stride; + u32 rows_of_tiles; + u32 lossy_cfg[IPU_MSG_LINK_CMPRS_LOSSY_CFG_PAYLOAD_SIZE]; +}; + +#define IPU_MSG_LINK_CMPRS_MAX_PLANES (2U) +#define IPU_MSG_LINK_CMPRS_NO_ALIGN_INTERVAL (0U) +#define IPU_MSG_LINK_CMPRS_MIN_ALIGN_INTERVAL (16U) +#define IPU_MSG_LINK_CMPRS_MAX_ALIGN_INTERVAL (1024U) +struct ipu7_msg_link_cmprs_option { + struct ia_gofo_tlv_header header; + u32 cmprs_buf_size; + u16 align_interval; + u8 reserved[2]; + struct ipu7_msg_link_cmprs_plane_desc plane_descs[2]; +}; + +struct ipu7_msg_link_ep { + u8 node_ctx_id; + u8 term_id; +}; + +struct ipu7_msg_link_ep_pair { + struct ipu7_msg_link_ep ep_src; + struct ipu7_msg_link_ep ep_dst; +}; + +#define IPU_MSG_LINK_FOREIGN_KEY_NONE (65535U) +#define IPU_MSG_LINK_FOREIGN_KEY_MAX (64U) +#define IPU_MSG_LINK_PBK_ID_DONT_CARE (255U) +#define IPU_MSG_LINK_PBK_SLOT_ID_DONT_CARE (255U) +#define IPU_MSG_LINK_TERM_ID_DONT_CARE (0xffU) + +struct ipu7_msg_link { + struct ia_gofo_tlv_header tlv_header; + struct ipu7_msg_link_ep_pair endpoints; + u16 foreign_key; + u8 streaming_mode; + u8 pbk_id; + u8 pbk_slot_id; + u8 delayed_link; + u8 reserved[2]; + struct ia_gofo_tlv_list link_options; +}; + +#pragma pack(pop) + +enum ipu7_msg_dev_state { + IPU_MSG_DEV_STATE_CLOSED = 0, + IPU_MSG_DEV_STATE_OPEN_WAIT = 1, + IPU_MSG_DEV_STATE_OPEN = 2, + IPU_MSG_DEV_STATE_CLOSE_WAIT = 3, + IPU_MSG_DEV_STATE_N +}; + +enum ipu7_msg_graph_state { + IPU_MSG_GRAPH_STATE_CLOSED = 0, + IPU_MSG_GRAPH_STATE_OPEN_WAIT = 1, + IPU_MSG_GRAPH_STATE_OPEN = 2, + IPU_MSG_GRAPH_STATE_CLOSE_WAIT = 3, + IPU_MSG_GRAPH_STATE_N +}; + +enum ipu7_msg_task_state { + IPU_MSG_TASK_STATE_DONE = 0, + IPU_MSG_TASK_STATE_WAIT_DONE = 1, + IPU_MSG_TASK_STATE_N +}; + +enum ipu7_msg_err_groups { + IPU_MSG_ERR_GROUP_RESERVED = IA_GOFO_MSG_ERR_GROUP_RESERVED, + IPU_MSG_ERR_GROUP_GENERAL = IA_GOFO_MSG_ERR_GROUP_GENERAL, + IPU_MSG_ERR_GROUP_DEVICE = 2, + IPU_MSG_ERR_GROUP_GRAPH = 3, + IPU_MSG_ERR_GROUP_TASK = 4, + IPU_MSG_ERR_GROUP_N, +}; + +#pragma pack(push, 1) +struct ipu7_msg_task { + struct ia_gofo_msg_header header; + u8 graph_id; + u8 profile_idx; + u8 node_ctx_id; + u8 frame_id; + u8 frag_id; + u8 req_done_msg; + u8 req_done_irq; + u8 reserved[1]; + ipu7_msg_teb_t payload_reuse_bm; + ia_gofo_addr_t term_buffers[IPU_MSG_MAX_NODE_TERMS]; +}; + +struct ipu7_msg_task_done { + struct ia_gofo_msg_header_ack header; + u8 graph_id; + u8 frame_id; + u8 node_ctx_id; + u8 profile_idx; + u8 frag_id; + u8 reserved[3]; +}; + +enum ipu7_msg_err_task { + IPU_MSG_ERR_TASK_OK = IA_GOFO_MSG_ERR_OK, + IPU_MSG_ERR_TASK_GRAPH_ID = 1, + IPU_MSG_ERR_TASK_NODE_CTX_ID = 2, + IPU_MSG_ERR_TASK_PROFILE_IDX = 3, + IPU_MSG_ERR_TASK_CTX_MEMORY_TASK = 4, + IPU_MSG_ERR_TASK_TERM_PAYLOAD_PTR = 5, + IPU_MSG_ERR_TASK_FRAME_ID = 6, + IPU_MSG_ERR_TASK_FRAG_ID = 7, + IPU_MSG_ERR_TASK_EXEC_EXT = 8, + IPU_MSG_ERR_TASK_EXEC_SBX = 9, + IPU_MSG_ERR_TASK_EXEC_INT = 10, + IPU_MSG_ERR_TASK_EXEC_UNKNOWN = 11, + IPU_MSG_ERR_TASK_PRE_EXEC = 12, + IPU_MSG_ERR_TASK_N +}; + +#pragma pack(pop) + +#pragma pack(push, 1) +enum ipu7_msg_term_type { + IPU_MSG_TERM_TYPE_PAD = 0, + IPU_MSG_TERM_TYPE_BASE, + IPU_MSG_TERM_TYPE_N, +}; + +#define IPU_MSG_TERM_EVENT_TYPE_NONE 0U +#define IPU_MSG_TERM_EVENT_TYPE_PROGRESS 1U +#define IPU_MSG_TERM_EVENT_TYPE_N (IPU_MSG_TERM_EVENT_TYPE_PROGRESS + 1U) + +struct ipu7_msg_term { + struct ia_gofo_tlv_header tlv_header; + u8 term_id; + u8 event_req_bm; + u8 reserved[2]; + u32 payload_size; + struct ia_gofo_tlv_list term_options; +}; + +enum ipu7_msg_term_option_types { + IPU_MSG_TERM_OPTION_TYPES_PADDING = 0, + IPU_MSG_TERM_OPTION_TYPES_N +}; + +struct ipu7_msg_term_event { + struct ia_gofo_msg_header header; + u8 graph_id; + u8 frame_id; + u8 node_ctx_id; + u8 profile_idx; + u8 frag_id; + u8 term_id; + u8 event_type; + u8 reserved[1]; + u64 event_ts; +}; + +#pragma pack(pop) + +#pragma pack(push, 1) +#define IPU_MSG_DEVICE_SEND_MSG_ENABLED 1U +#define IPU_MSG_DEVICE_SEND_MSG_DISABLED 0U + +#define IPU_MSG_DEVICE_OPEN_SEND_RESP BIT(0) +#define IPU_MSG_DEVICE_OPEN_SEND_IRQ BIT(1) + +#define IPU_MSG_DEVICE_CLOSE_SEND_RESP BIT(0) +#define IPU_MSG_DEVICE_CLOSE_SEND_IRQ BIT(1) + +struct ipu7_msg_dev_open { + struct ia_gofo_msg_header header; + u32 max_graphs; + u8 dev_msg_map; + u8 enable_power_gating; + u8 reserved[2]; +}; + +struct ipu7_msg_dev_open_ack { + struct ia_gofo_msg_header_ack header; +}; + +struct ipu7_msg_dev_close { + struct ia_gofo_msg_header header; + u8 dev_msg_map; + u8 reserved[7]; +}; + +struct ipu7_msg_dev_close_ack { + struct ia_gofo_msg_header_ack header; +}; + +enum ipu7_msg_err_device { + IPU_MSG_ERR_DEVICE_OK = IA_GOFO_MSG_ERR_OK, + IPU_MSG_ERR_DEVICE_MAX_GRAPHS = 1, + IPU_MSG_ERR_DEVICE_MSG_MAP = 2, + IPU_MSG_ERR_DEVICE_N +}; + +#pragma pack(pop) + +#pragma pack(push, 1) +#define IPU_MSG_GRAPH_ID_UNKNOWN (0xffU) +#define IPU_MSG_GRAPH_SEND_MSG_ENABLED 1U +#define IPU_MSG_GRAPH_SEND_MSG_DISABLED 0U + +#define IPU_MSG_GRAPH_OPEN_SEND_RESP BIT(0) +#define IPU_MSG_GRAPH_OPEN_SEND_IRQ BIT(1) + +#define IPU_MSG_GRAPH_CLOSE_SEND_RESP BIT(0) +#define IPU_MSG_GRAPH_CLOSE_SEND_IRQ BIT(1) + +struct ipu7_msg_graph_open { + struct ia_gofo_msg_header header; + struct ia_gofo_tlv_list nodes; + struct ia_gofo_tlv_list links; + u8 graph_id; + u8 graph_msg_map; + u8 reserved[6]; +}; + +enum ipu7_msg_graph_ack_option_types { + IPU_MSG_GRAPH_ACK_OPTION_TYPES_PADDING = 0, + IPU_MSG_GRAPH_ACK_TASK_Q_INFO, + IPU_MSG_GRAPH_ACK_OPTION_TYPES_N +}; + +struct ipu7_msg_graph_open_ack_task_q_info { + struct ia_gofo_tlv_header header; + u8 node_ctx_id; + u8 q_id; + u8 reserved[2]; +}; + +struct ipu7_msg_graph_open_ack { + struct ia_gofo_msg_header_ack header; + u8 graph_id; + u8 reserved[7]; +}; + +struct ipu7_msg_graph_close { + struct ia_gofo_msg_header header; + u8 graph_id; + u8 graph_msg_map; + u8 reserved[6]; +}; + +struct ipu7_msg_graph_close_ack { + struct ia_gofo_msg_header_ack header; + u8 graph_id; + u8 reserved[7]; +}; + +enum ipu7_msg_err_graph { + IPU_MSG_ERR_GRAPH_OK = IA_GOFO_MSG_ERR_OK, + IPU_MSG_ERR_GRAPH_GRAPH_STATE = 1, + IPU_MSG_ERR_GRAPH_MAX_GRAPHS = 2, + IPU_MSG_ERR_GRAPH_GRAPH_ID = 3, + IPU_MSG_ERR_GRAPH_NODE_CTX_ID = 4, + IPU_MSG_ERR_GRAPH_NODE_RSRC_ID = 5, + IPU_MSG_ERR_GRAPH_PROFILE_IDX = 6, + IPU_MSG_ERR_GRAPH_TERM_ID = 7, + IPU_MSG_ERR_GRAPH_TERM_PAYLOAD_SIZE = 8, + IPU_MSG_ERR_GRAPH_LINK_NODE_CTX_ID = 9, + IPU_MSG_ERR_GRAPH_LINK_TERM_ID = 10, + IPU_MSG_ERR_GRAPH_PROFILE_TYPE = 11, + IPU_MSG_ERR_GRAPH_NUM_FRAGS = 12, + IPU_MSG_ERR_GRAPH_QUEUE_ID_USAGE = 13, + IPU_MSG_ERR_GRAPH_QUEUE_OPEN = 14, + IPU_MSG_ERR_GRAPH_QUEUE_CLOSE = 15, + IPU_MSG_ERR_GRAPH_QUEUE_ID_TASK_REQ_MISMATCH = 16, + IPU_MSG_ERR_GRAPH_CTX_MEMORY_FGRAPH = 17, + IPU_MSG_ERR_GRAPH_CTX_MEMORY_NODE = 18, + IPU_MSG_ERR_GRAPH_CTX_MEMORY_NODE_PROFILE = 19, + IPU_MSG_ERR_GRAPH_CTX_MEMORY_TERM = 20, + IPU_MSG_ERR_GRAPH_CTX_MEMORY_LINK = 21, + IPU_MSG_ERR_GRAPH_CTX_MSG_MAP = 22, + IPU_MSG_ERR_GRAPH_CTX_FOREIGN_KEY = 23, + IPU_MSG_ERR_GRAPH_CTX_STREAMING_MODE = 24, + IPU_MSG_ERR_GRAPH_CTX_PBK_RSRC = 25, + IPU_MSG_ERR_GRAPH_UNSUPPORTED_EVENT_TYPE = 26, + IPU_MSG_ERR_GRAPH_TOO_MANY_EVENTS = 27, + IPU_MSG_ERR_GRAPH_CTX_MEMORY_CMPRS = 28, + IPU_MSG_ERR_GRAPH_CTX_CMPRS_ALIGN_INTERVAL = 29, + IPU_MSG_ERR_GRAPH_CTX_CMPRS_PLANE_ID = 30, + IPU_MSG_ERR_GRAPH_CTX_CMPRS_UNSUPPORTED_MODE = 31, + IPU_MSG_ERR_GRAPH_CTX_CMPRS_BIT_DEPTH = 32, + IPU_MSG_ERR_GRAPH_CTX_CMPRS_STRIDE_ALIGNMENT = 33, + IPU_MSG_ERR_GRAPH_CTX_CMPRS_SUB_BUFFER_ALIGNMENT = 34, + IPU_MSG_ERR_GRAPH_CTX_CMPRS_LAYOUT_ORDER = 35, + IPU_MSG_ERR_GRAPH_CTX_CMPRS_LAYOUT_OVERLAP = 36, + IPU_MSG_ERR_GRAPH_CTX_CMPRS_BUFFER_TOO_SMALL = 37, + IPU_MSG_ERR_GRAPH_CTX_DELAYED_LINK = 38, + IPU_MSG_ERR_GRAPH_N +}; + +#pragma pack(pop) + +#define FWPS_MSG_ABI_MAX_INPUT_QUEUES (60U) +#define FWPS_MSG_ABI_MAX_OUTPUT_QUEUES (2U) +#define FWPS_MSG_ABI_MAX_QUEUES \ + (FWPS_MSG_ABI_MAX_OUTPUT_QUEUES + FWPS_MSG_ABI_MAX_INPUT_QUEUES) + +#define FWPS_MSG_ABI_OUT_ACK_QUEUE_ID (IA_GOFO_MSG_ABI_OUT_ACK_QUEUE_ID) +#define FWPS_MSG_ABI_OUT_LOG_QUEUE_ID (IA_GOFO_MSG_ABI_OUT_LOG_QUEUE_ID) +#if (FWPS_MSG_ABI_OUT_LOG_QUEUE_ID >= FWPS_MSG_ABI_MAX_OUTPUT_QUEUES) +#error "Maximum output queues configuration is too small to fit ACK and LOG \ +queues" +#endif +#define FWPS_MSG_ABI_IN_DEV_QUEUE_ID (IA_GOFO_MSG_ABI_IN_DEV_QUEUE_ID) +#define FWPS_MSG_ABI_IN_RESERVED_QUEUE_ID (3U) +#define FWPS_MSG_ABI_IN_FIRST_TASK_QUEUE_ID \ + (FWPS_MSG_ABI_IN_RESERVED_QUEUE_ID + 1U) + +#if (FWPS_MSG_ABI_IN_FIRST_TASK_QUEUE_ID >= FWPS_MSG_ABI_MAX_INPUT_QUEUES) +#error "Maximum queues configuration is too small to fit minimum number of \ +useful queues" +#endif + +#define FWPS_MSG_ABI_IN_LAST_TASK_QUEUE_ID (FWPS_MSG_ABI_MAX_QUEUES - 1U) +#define FWPS_MSG_ABI_IN_MAX_TASK_QUEUES \ + (FWPS_MSG_ABI_IN_LAST_TASK_QUEUE_ID - \ + FWPS_MSG_ABI_IN_FIRST_TASK_QUEUE_ID + 1U) +#define FWPS_MSG_ABI_OUT_FIRST_QUEUE_ID (FWPS_MSG_ABI_OUT_ACK_QUEUE_ID) +#define FWPS_MSG_ABI_OUT_LAST_QUEUE_ID (FWPS_MSG_ABI_MAX_OUTPUT_QUEUES - 1U) +#define FWPS_MSG_ABI_IN_FIRST_QUEUE_ID (FWPS_MSG_ABI_IN_DEV_QUEUE_ID) +#define FWPS_MSG_ABI_IN_LAST_QUEUE_ID (FWPS_MSG_ABI_IN_LAST_TASK_QUEUE_ID) + +#define FWPS_MSG_HOST2FW_MAX_SIZE (2U * 1024U) +#define FWPS_MSG_FW2HOST_MAX_SIZE (256U) + +#endif diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_psys_config_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_psys_config_abi.h new file mode 100644 index 000000000000..0af04c8c6a88 --- /dev/null +++ b/drivers/staging/media/ipu7/abi/ipu7_fw_psys_config_abi.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 - 2025 Intel Corporation + */ + +#ifndef IPU7_PSYS_CONFIG_ABI_H_INCLUDED__ +#define IPU7_PSYS_CONFIG_ABI_H_INCLUDED__ + +#include <linux/types.h> + +#include "ipu7_fw_boot_abi.h" +#include "ipu7_fw_config_abi.h" + +struct ipu7_psys_config { + u32 use_debug_manifest; + u32 timeout_val_ms; + u32 compression_support_enabled; + struct ia_gofo_logger_config logger_config; + struct ipu7_wdt_abi wdt_config; + u8 ipu_psys_debug_bitmask; + u8 padding[3]; +}; + +#endif diff --git a/drivers/staging/media/ipu7/abi/ipu7_fw_syscom_abi.h b/drivers/staging/media/ipu7/abi/ipu7_fw_syscom_abi.h new file mode 100644 index 000000000000..bfa5258d5b97 --- /dev/null +++ b/drivers/staging/media/ipu7/abi/ipu7_fw_syscom_abi.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 - 2025 Intel Corporation + */ + +#ifndef IPU7_FW_SYSCOM_ABI_H +#define IPU7_FW_SYSCOM_ABI_H + +#include <linux/types.h> + +#include "ipu7_fw_common_abi.h" + +#pragma pack(push, 1) +#define SYSCOM_QUEUE_MIN_CAPACITY 2U + +struct syscom_queue_params_config { + ia_gofo_addr_t token_array_mem; + u16 token_size_in_bytes; + u16 max_capacity; +}; + +struct syscom_config_s { + u16 max_output_queues; + u16 max_input_queues; +}; + +#pragma pack(pop) + +static inline struct syscom_queue_params_config * +syscom_config_get_queue_configs(struct syscom_config_s *config) +{ + return (struct syscom_queue_params_config *)(&config[1]); +} + +static inline const struct syscom_queue_params_config * +syscom_config_get_queue_configs_const(const struct syscom_config_s *config) +{ + return (const struct syscom_queue_params_config *)(&config[1]); +} + +#pragma pack(push, 1) +struct syscom_queue_indices_s { + u32 read_index; + u32 write_index; +}; + +#pragma pack(pop) + +#endif diff --git a/drivers/staging/media/ipu7/ipu7-boot.c b/drivers/staging/media/ipu7/ipu7-boot.c new file mode 100644 index 000000000000..d7901ff78b38 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-boot.c @@ -0,0 +1,430 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 - 2025 Intel Corporation + */ + +#include <linux/bug.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/module.h> +#include <linux/iopoll.h> +#include <linux/string.h> +#include <linux/types.h> + +#include "abi/ipu7_fw_boot_abi.h" + +#include "ipu7.h" +#include "ipu7-boot.h" +#include "ipu7-bus.h" +#include "ipu7-buttress-regs.h" +#include "ipu7-dma.h" +#include "ipu7-platform-regs.h" +#include "ipu7-syscom.h" + +#define IPU_FW_START_STOP_TIMEOUT 2000 +#define IPU_BOOT_CELL_RESET_TIMEOUT (2 * USEC_PER_SEC) +#define BOOT_STATE_IS_CRITICAL(s) IA_GOFO_FW_BOOT_STATE_IS_CRITICAL(s) +#define BOOT_STATE_IS_READY(s) ((s) == IA_GOFO_FW_BOOT_STATE_READY) +#define BOOT_STATE_IS_INACTIVE(s) ((s) == IA_GOFO_FW_BOOT_STATE_INACTIVE) + +struct ipu7_boot_context { + u32 base; + u32 dmem_address; + u32 status_ctrl_reg; + u32 fw_start_address_reg; + u32 fw_code_base_reg; +}; + +static const struct ipu7_boot_context contexts[IPU_SUBSYS_NUM] = { + { + /* ISYS */ + .dmem_address = IPU_ISYS_DMEM_OFFSET, + .status_ctrl_reg = BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS, + .fw_start_address_reg = BUTTRESS_REG_DRV_IS_UCX_START_ADDR, + .fw_code_base_reg = IS_UC_CTRL_BASE + }, + { + /* PSYS */ + .dmem_address = IPU_PSYS_DMEM_OFFSET, + .status_ctrl_reg = BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS, + .fw_start_address_reg = BUTTRESS_REG_DRV_PS_UCX_START_ADDR, + .fw_code_base_reg = PS_UC_CTRL_BASE + } +}; + +static u32 get_fw_boot_reg_addr(const struct ipu7_bus_device *adev, + enum ia_gofo_buttress_reg_id reg) +{ + u32 base = (adev->subsys == IPU_IS) ? 0U : (u32)IA_GOFO_FW_BOOT_ID_MAX; + + return BUTTRESS_FW_BOOT_PARAMS_ENTRY(base + (u32)reg); +} + +static void write_fw_boot_param(const struct ipu7_bus_device *adev, + enum ia_gofo_buttress_reg_id reg, + u32 val) +{ + void __iomem *base = adev->isp->base; + + dev_dbg(&adev->auxdev.dev, + "write boot param reg: %d addr: %x val: 0x%x\n", + reg, get_fw_boot_reg_addr(adev, reg), val); + writel(val, base + get_fw_boot_reg_addr(adev, reg)); +} + +static u32 read_fw_boot_param(const struct ipu7_bus_device *adev, + enum ia_gofo_buttress_reg_id reg) +{ + void __iomem *base = adev->isp->base; + + return readl(base + get_fw_boot_reg_addr(adev, reg)); +} + +static int ipu7_boot_cell_reset(const struct ipu7_bus_device *adev) +{ + const struct ipu7_boot_context *ctx = &contexts[adev->subsys]; + const struct device *dev = &adev->auxdev.dev; + u32 ucx_ctrl_status = ctx->status_ctrl_reg; + u32 timeout = IPU_BOOT_CELL_RESET_TIMEOUT; + void __iomem *base = adev->isp->base; + u32 val, val2; + int ret; + + dev_dbg(dev, "cell enter reset...\n"); + val = readl(base + ucx_ctrl_status); + dev_dbg(dev, "cell_ctrl_reg addr = 0x%x, val = 0x%x\n", + ucx_ctrl_status, val); + + dev_dbg(dev, "force cell reset...\n"); + val |= UCX_CTL_RESET; + val &= ~UCX_CTL_RUN; + + dev_dbg(dev, "write status_ctrl_reg(0x%x) to 0x%x\n", + ucx_ctrl_status, val); + writel(val, base + ucx_ctrl_status); + + ret = readl_poll_timeout(base + ucx_ctrl_status, val2, + (val2 & 0x3U) == (val & 0x3U), 100, timeout); + if (ret) { + dev_err(dev, "cell enter reset timeout. status: 0x%x\n", val2); + return -ETIMEDOUT; + } + + dev_dbg(dev, "cell exit reset...\n"); + val = readl(base + ucx_ctrl_status); + WARN((!(val & UCX_CTL_RESET) || val & UCX_CTL_RUN), + "cell status 0x%x", val); + + val &= ~(UCX_CTL_RESET | UCX_CTL_RUN); + dev_dbg(dev, "write status_ctrl_reg(0x%x) to 0x%x\n", + ucx_ctrl_status, val); + writel(val, base + ucx_ctrl_status); + + ret = readl_poll_timeout(base + ucx_ctrl_status, val2, + (val2 & 0x3U) == (val & 0x3U), 100, timeout); + if (ret) { + dev_err(dev, "cell exit reset timeout. status: 0x%x\n", val2); + return -ETIMEDOUT; + } + + return 0; +} + +static void ipu7_boot_cell_start(const struct ipu7_bus_device *adev) +{ + const struct ipu7_boot_context *ctx = &contexts[adev->subsys]; + void __iomem *base = adev->isp->base; + const struct device *dev = &adev->auxdev.dev; + u32 val; + + dev_dbg(dev, "starting cell...\n"); + val = readl(base + ctx->status_ctrl_reg); + WARN_ON(val & (UCX_CTL_RESET | UCX_CTL_RUN)); + + val &= ~UCX_CTL_RESET; + val |= UCX_CTL_RUN; + dev_dbg(dev, "write status_ctrl_reg(0x%x) to 0x%x\n", + ctx->status_ctrl_reg, val); + writel(val, base + ctx->status_ctrl_reg); +} + +static void ipu7_boot_cell_stop(const struct ipu7_bus_device *adev) +{ + const struct ipu7_boot_context *ctx = &contexts[adev->subsys]; + void __iomem *base = adev->isp->base; + const struct device *dev = &adev->auxdev.dev; + u32 val; + + dev_dbg(dev, "stopping cell...\n"); + + val = readl(base + ctx->status_ctrl_reg); + val &= ~UCX_CTL_RUN; + dev_dbg(dev, "write status_ctrl_reg(0x%x) to 0x%x\n", + ctx->status_ctrl_reg, val); + writel(val, base + ctx->status_ctrl_reg); + + /* Wait for uC transactions complete */ + usleep_range(10, 20); + + val = readl(base + ctx->status_ctrl_reg); + val |= UCX_CTL_RESET; + dev_dbg(dev, "write status_ctrl_reg(0x%x) to 0x%x\n", + ctx->status_ctrl_reg, val); + writel(val, base + ctx->status_ctrl_reg); +} + +static int ipu7_boot_cell_init(const struct ipu7_bus_device *adev) +{ + const struct ipu7_boot_context *ctx = &contexts[adev->subsys]; + void __iomem *base = adev->isp->base; + + dev_dbg(&adev->auxdev.dev, "write fw_start_address_reg(0x%x) to 0x%x\n", + ctx->fw_start_address_reg, adev->fw_entry); + writel(adev->fw_entry, base + ctx->fw_start_address_reg); + + return ipu7_boot_cell_reset(adev); +} + +static void init_boot_config(struct ia_gofo_boot_config *boot_config, + u32 length, u8 major) +{ + /* syscom version, new syscom2 version */ + boot_config->length = length; + boot_config->config_version.major = 1U; + boot_config->config_version.minor = 0U; + boot_config->config_version.subminor = 0U; + boot_config->config_version.patch = 0U; + + /* msg version for task interface */ + boot_config->client_version_support.num_versions = 1U; + boot_config->client_version_support.versions[0].major = major; + boot_config->client_version_support.versions[0].minor = 0U; + boot_config->client_version_support.versions[0].subminor = 0U; + boot_config->client_version_support.versions[0].patch = 0U; +} + +int ipu7_boot_init_boot_config(struct ipu7_bus_device *adev, + struct syscom_queue_config *qconfigs, + int num_queues, u32 uc_freq, + dma_addr_t subsys_config, u8 major) +{ + u32 total_queue_size_aligned = 0; + struct ipu7_syscom_context *syscom = adev->syscom; + struct ia_gofo_boot_config *boot_config; + struct syscom_queue_params_config *cfgs; + struct device *dev = &adev->auxdev.dev; + struct syscom_config_s *syscfg; + dma_addr_t queue_mem_dma_ptr; + void *queue_mem_ptr; + unsigned int i; + + dev_dbg(dev, "boot config queues_nr: %d freq: %u sys_conf: 0x%pad\n", + num_queues, uc_freq, &subsys_config); + /* Allocate boot config. */ + adev->boot_config_size = + sizeof(*cfgs) * num_queues + sizeof(*boot_config); + adev->boot_config = ipu7_dma_alloc(adev, adev->boot_config_size, + &adev->boot_config_dma_addr, + GFP_KERNEL, 0); + if (!adev->boot_config) { + dev_err(dev, "Failed to allocate boot config.\n"); + return -ENOMEM; + } + + boot_config = adev->boot_config; + memset(boot_config, 0, sizeof(struct ia_gofo_boot_config)); + init_boot_config(boot_config, adev->boot_config_size, major); + boot_config->subsys_config = subsys_config; + + boot_config->uc_tile_frequency = uc_freq; + boot_config->uc_tile_frequency_units = + IA_GOFO_FW_BOOT_UC_FREQUENCY_UNITS_MHZ; + boot_config->syscom_context_config.max_output_queues = + syscom->num_output_queues; + boot_config->syscom_context_config.max_input_queues = + syscom->num_input_queues; + + ipu7_dma_sync_single(adev, adev->boot_config_dma_addr, + adev->boot_config_size); + + for (i = 0; i < num_queues; i++) { + u32 queue_size = qconfigs[i].max_capacity * + qconfigs[i].token_size_in_bytes; + + queue_size = ALIGN(queue_size, 64U); + total_queue_size_aligned += queue_size; + qconfigs[i].queue_size = queue_size; + } + + /* Allocate queue memory */ + syscom->queue_mem = ipu7_dma_alloc(adev, total_queue_size_aligned, + &syscom->queue_mem_dma_addr, + GFP_KERNEL, 0); + if (!syscom->queue_mem) { + dev_err(dev, "Failed to allocate queue memory.\n"); + return -ENOMEM; + } + syscom->queue_mem_size = total_queue_size_aligned; + + syscfg = &boot_config->syscom_context_config; + cfgs = ipu7_syscom_get_queue_config(syscfg); + queue_mem_ptr = syscom->queue_mem; + queue_mem_dma_ptr = syscom->queue_mem_dma_addr; + for (i = 0; i < num_queues; i++) { + cfgs[i].token_array_mem = queue_mem_dma_ptr; + cfgs[i].max_capacity = qconfigs[i].max_capacity; + cfgs[i].token_size_in_bytes = qconfigs[i].token_size_in_bytes; + qconfigs[i].token_array_mem = queue_mem_ptr; + queue_mem_dma_ptr += qconfigs[i].queue_size; + queue_mem_ptr += qconfigs[i].queue_size; + } + + ipu7_dma_sync_single(adev, syscom->queue_mem_dma_addr, + total_queue_size_aligned); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ipu7_boot_init_boot_config, "INTEL_IPU7"); + +void ipu7_boot_release_boot_config(struct ipu7_bus_device *adev) +{ + struct ipu7_syscom_context *syscom = adev->syscom; + + if (syscom->queue_mem) { + ipu7_dma_free(adev, syscom->queue_mem_size, + syscom->queue_mem, + syscom->queue_mem_dma_addr, 0); + syscom->queue_mem = NULL; + syscom->queue_mem_dma_addr = 0; + } + + if (adev->boot_config) { + ipu7_dma_free(adev, adev->boot_config_size, + adev->boot_config, + adev->boot_config_dma_addr, 0); + adev->boot_config = NULL; + adev->boot_config_dma_addr = 0; + } +} +EXPORT_SYMBOL_NS_GPL(ipu7_boot_release_boot_config, "INTEL_IPU7"); + +int ipu7_boot_start_fw(const struct ipu7_bus_device *adev) +{ + const struct device *dev = &adev->auxdev.dev; + u32 timeout = IPU_FW_START_STOP_TIMEOUT; + void __iomem *base = adev->isp->base; + u32 boot_state, last_boot_state; + u32 indices_addr, msg_ver, id; + int ret; + + ret = ipu7_boot_cell_init(adev); + if (ret) + return ret; + + dev_dbg(dev, "start booting fw...\n"); + /* store "uninit" state to syscom/boot state reg */ + write_fw_boot_param(adev, IA_GOFO_FW_BOOT_STATE_ID, + IA_GOFO_FW_BOOT_STATE_UNINIT); + /* + * Set registers to zero + * (not strictly required, but recommended for diagnostics) + */ + write_fw_boot_param(adev, + IA_GOFO_FW_BOOT_SYSCOM_QUEUE_INDICES_BASE_ID, 0); + write_fw_boot_param(adev, IA_GOFO_FW_BOOT_MESSAGING_VERSION_ID, 0); + /* store firmware configuration address */ + write_fw_boot_param(adev, IA_GOFO_FW_BOOT_CONFIG_ID, + adev->boot_config_dma_addr); + + /* Kick uC, then wait for boot complete */ + ipu7_boot_cell_start(adev); + + last_boot_state = IA_GOFO_FW_BOOT_STATE_UNINIT; + while (timeout--) { + boot_state = read_fw_boot_param(adev, + IA_GOFO_FW_BOOT_STATE_ID); + if (boot_state != last_boot_state) { + dev_dbg(dev, "boot state changed from 0x%x to 0x%x\n", + last_boot_state, boot_state); + last_boot_state = boot_state; + } + if (BOOT_STATE_IS_CRITICAL(boot_state) || + BOOT_STATE_IS_READY(boot_state)) + break; + usleep_range(1000, 1200); + } + + if (BOOT_STATE_IS_CRITICAL(boot_state)) { + ipu7_dump_fw_error_log(adev); + dev_err(dev, "critical boot state error 0x%x\n", boot_state); + return -EINVAL; + } else if (!BOOT_STATE_IS_READY(boot_state)) { + dev_err(dev, "fw boot timeout. state: 0x%x\n", boot_state); + return -ETIMEDOUT; + } + dev_dbg(dev, "fw boot done.\n"); + + /* Get FW syscom queue indices addr */ + id = IA_GOFO_FW_BOOT_SYSCOM_QUEUE_INDICES_BASE_ID; + indices_addr = read_fw_boot_param(adev, id); + adev->syscom->queue_indices = base + indices_addr; + dev_dbg(dev, "fw queue indices offset is 0x%x\n", indices_addr); + + /* Get message version. */ + msg_ver = read_fw_boot_param(adev, + IA_GOFO_FW_BOOT_MESSAGING_VERSION_ID); + dev_dbg(dev, "ipu message version is 0x%08x\n", msg_ver); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ipu7_boot_start_fw, "INTEL_IPU7"); + +int ipu7_boot_stop_fw(const struct ipu7_bus_device *adev) +{ + const struct device *dev = &adev->auxdev.dev; + u32 timeout = IPU_FW_START_STOP_TIMEOUT; + u32 boot_state; + + boot_state = read_fw_boot_param(adev, IA_GOFO_FW_BOOT_STATE_ID); + if (BOOT_STATE_IS_CRITICAL(boot_state) || + !BOOT_STATE_IS_READY(boot_state)) { + dev_err(dev, "fw not ready for shutdown, state 0x%x\n", + boot_state); + return -EBUSY; + } + + /* Issue shutdown to start shutdown process */ + dev_dbg(dev, "stopping fw...\n"); + write_fw_boot_param(adev, IA_GOFO_FW_BOOT_STATE_ID, + IA_GOFO_FW_BOOT_STATE_SHUTDOWN_CMD); + while (timeout--) { + boot_state = read_fw_boot_param(adev, + IA_GOFO_FW_BOOT_STATE_ID); + if (BOOT_STATE_IS_CRITICAL(boot_state) || + BOOT_STATE_IS_INACTIVE(boot_state)) + break; + usleep_range(1000, 1200); + } + + if (BOOT_STATE_IS_CRITICAL(boot_state)) { + ipu7_dump_fw_error_log(adev); + dev_err(dev, "critical boot state error 0x%x\n", boot_state); + return -EINVAL; + } else if (!BOOT_STATE_IS_INACTIVE(boot_state)) { + dev_err(dev, "stop fw timeout. state: 0x%x\n", boot_state); + return -ETIMEDOUT; + } + + ipu7_boot_cell_stop(adev); + dev_dbg(dev, "stop fw done.\n"); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ipu7_boot_stop_fw, "INTEL_IPU7"); + +u32 ipu7_boot_get_boot_state(const struct ipu7_bus_device *adev) +{ + return read_fw_boot_param(adev, IA_GOFO_FW_BOOT_STATE_ID); +} +EXPORT_SYMBOL_NS_GPL(ipu7_boot_get_boot_state, "INTEL_IPU7"); diff --git a/drivers/staging/media/ipu7/ipu7-boot.h b/drivers/staging/media/ipu7/ipu7-boot.h new file mode 100644 index 000000000000..5600be849931 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-boot.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2022 - 2025 Intel Corporation + */ + +#ifndef IPU7_BOOT_H +#define IPU7_BOOT_H + +#include <linux/types.h> + +struct ipu7_bus_device; +struct syscom_queue_config; + +#define FW_QUEUE_CONFIG_SIZE(num_queues) \ + (sizeof(struct syscom_queue_config) * (num_queues)) + +int ipu7_boot_init_boot_config(struct ipu7_bus_device *adev, + struct syscom_queue_config *qconfigs, + int num_queues, u32 uc_freq, + dma_addr_t subsys_config, u8 major); +void ipu7_boot_release_boot_config(struct ipu7_bus_device *adev); +int ipu7_boot_start_fw(const struct ipu7_bus_device *adev); +int ipu7_boot_stop_fw(const struct ipu7_bus_device *adev); +u32 ipu7_boot_get_boot_state(const struct ipu7_bus_device *adev); +#endif diff --git a/drivers/staging/media/ipu7/ipu7-bus.c b/drivers/staging/media/ipu7/ipu7-bus.c new file mode 100644 index 000000000000..7da44fde002a --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-bus.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <linux/auxiliary_bus.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/err.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/pci.h> +#include <linux/pm_domain.h> +#include <linux/pm_runtime.h> +#include <linux/slab.h> + +#include "ipu7.h" +#include "ipu7-bus.h" +#include "ipu7-boot.h" +#include "ipu7-dma.h" + +static int bus_pm_runtime_suspend(struct device *dev) +{ + struct ipu7_bus_device *adev = to_ipu7_bus_device(dev); + int ret; + + ret = pm_generic_runtime_suspend(dev); + if (ret) + return ret; + + ret = ipu_buttress_powerdown(dev, adev->ctrl); + if (!ret) + return 0; + + dev_err(dev, "power down failed!\n"); + + /* Powering down failed, attempt to resume device now */ + ret = pm_generic_runtime_resume(dev); + if (!ret) + return -EBUSY; + + return -EIO; +} + +static int bus_pm_runtime_resume(struct device *dev) +{ + struct ipu7_bus_device *adev = to_ipu7_bus_device(dev); + int ret; + + ret = ipu_buttress_powerup(dev, adev->ctrl); + if (ret) + return ret; + + ret = pm_generic_runtime_resume(dev); + if (ret) + goto out_err; + + return 0; + +out_err: + ipu_buttress_powerdown(dev, adev->ctrl); + + return -EBUSY; +} + +static struct dev_pm_domain ipu7_bus_pm_domain = { + .ops = { + .runtime_suspend = bus_pm_runtime_suspend, + .runtime_resume = bus_pm_runtime_resume, + }, +}; + +static DEFINE_MUTEX(ipu7_bus_mutex); +static void ipu7_bus_release(struct device *dev) +{ + struct ipu7_bus_device *adev = to_ipu7_bus_device(dev); + + kfree(adev->pdata); + kfree(adev); +} + +struct ipu7_bus_device * +ipu7_bus_initialize_device(struct pci_dev *pdev, struct device *parent, + void *pdata, const struct ipu_buttress_ctrl *ctrl, + const char *name) +{ + struct auxiliary_device *auxdev; + struct ipu7_bus_device *adev; + struct ipu7_device *isp = pci_get_drvdata(pdev); + int ret; + + adev = kzalloc(sizeof(*adev), GFP_KERNEL); + if (!adev) + return ERR_PTR(-ENOMEM); + + adev->isp = isp; + adev->ctrl = ctrl; + adev->pdata = pdata; + auxdev = &adev->auxdev; + auxdev->name = name; + auxdev->id = (pci_domain_nr(pdev->bus) << 16) | + PCI_DEVID(pdev->bus->number, pdev->devfn); + + auxdev->dev.parent = parent; + auxdev->dev.release = ipu7_bus_release; + + ret = auxiliary_device_init(auxdev); + if (ret < 0) { + dev_err(&isp->pdev->dev, "auxiliary device init failed (%d)\n", + ret); + kfree(adev); + return ERR_PTR(ret); + } + + dev_pm_domain_set(&auxdev->dev, &ipu7_bus_pm_domain); + + pm_runtime_forbid(&adev->auxdev.dev); + pm_runtime_enable(&adev->auxdev.dev); + + return adev; +} + +int ipu7_bus_add_device(struct ipu7_bus_device *adev) +{ + struct auxiliary_device *auxdev = &adev->auxdev; + int ret; + + ret = auxiliary_device_add(auxdev); + if (ret) { + auxiliary_device_uninit(auxdev); + return ret; + } + + mutex_lock(&ipu7_bus_mutex); + list_add(&adev->list, &adev->isp->devices); + mutex_unlock(&ipu7_bus_mutex); + + pm_runtime_allow(&auxdev->dev); + + return 0; +} + +void ipu7_bus_del_devices(struct pci_dev *pdev) +{ + struct ipu7_device *isp = pci_get_drvdata(pdev); + struct ipu7_bus_device *adev, *save; + + mutex_lock(&ipu7_bus_mutex); + + list_for_each_entry_safe(adev, save, &isp->devices, list) { + pm_runtime_disable(&adev->auxdev.dev); + list_del(&adev->list); + auxiliary_device_delete(&adev->auxdev); + auxiliary_device_uninit(&adev->auxdev); + } + + mutex_unlock(&ipu7_bus_mutex); +} diff --git a/drivers/staging/media/ipu7/ipu7-bus.h b/drivers/staging/media/ipu7/ipu7-bus.h new file mode 100644 index 000000000000..45157df16e90 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-bus.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_BUS_H +#define IPU7_BUS_H + +#include <linux/auxiliary_bus.h> +#include <linux/container_of.h> +#include <linux/device.h> +#include <linux/irqreturn.h> +#include <linux/list.h> +#include <linux/scatterlist.h> +#include <linux/types.h> + +#include "abi/ipu7_fw_boot_abi.h" + +#include "ipu7-syscom.h" + +struct pci_dev; +struct ipu_buttress_ctrl; +struct ipu7_mmu; +struct ipu7_device; + +enum ipu7_subsys { + IPU_IS = 0, + IPU_PS = 1, + IPU_SUBSYS_NUM = 2, +}; + +struct ipu7_bus_device { + struct auxiliary_device auxdev; + const struct auxiliary_driver *auxdrv; + const struct ipu7_auxdrv_data *auxdrv_data; + struct list_head list; + enum ipu7_subsys subsys; + void *pdata; + struct ipu7_mmu *mmu; + struct ipu7_device *isp; + const struct ipu_buttress_ctrl *ctrl; + u64 dma_mask; + struct sg_table fw_sgt; + u32 fw_entry; + struct ipu7_syscom_context *syscom; + struct ia_gofo_boot_config *boot_config; + dma_addr_t boot_config_dma_addr; + u32 boot_config_size; +}; + +struct ipu7_auxdrv_data { + irqreturn_t (*isr)(struct ipu7_bus_device *adev); + irqreturn_t (*isr_threaded)(struct ipu7_bus_device *adev); + bool wake_isr_thread; +}; + +#define to_ipu7_bus_device(_dev) \ + container_of(to_auxiliary_dev(_dev), struct ipu7_bus_device, auxdev) +#define auxdev_to_adev(_auxdev) \ + container_of(_auxdev, struct ipu7_bus_device, auxdev) +#define ipu7_bus_get_drvdata(adev) dev_get_drvdata(&(adev)->auxdev.dev) + +struct ipu7_bus_device * +ipu7_bus_initialize_device(struct pci_dev *pdev, struct device *parent, + void *pdata, const struct ipu_buttress_ctrl *ctrl, + const char *name); +int ipu7_bus_add_device(struct ipu7_bus_device *adev); +void ipu7_bus_del_devices(struct pci_dev *pdev); +#endif diff --git a/drivers/staging/media/ipu7/ipu7-buttress-regs.h b/drivers/staging/media/ipu7/ipu7-buttress-regs.h new file mode 100644 index 000000000000..3eafd6a3813d --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-buttress-regs.h @@ -0,0 +1,461 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 - 2025 Intel Corporation + */ + +#ifndef IPU7_BUTTRESS_REGS_H +#define IPU7_BUTTRESS_REGS_H + +#define BUTTRESS_REG_IRQ_STATUS 0x2000 +#define BUTTRESS_REG_IRQ_STATUS_UNMASKED 0x2004 +#define BUTTRESS_REG_IRQ_ENABLE 0x2008 +#define BUTTRESS_REG_IRQ_CLEAR 0x200c +#define BUTTRESS_REG_IRQ_MASK 0x2010 +#define BUTTRESS_REG_TSC_CMD 0x2014 +#define BUTTRESS_REG_TSC_CTL 0x2018 +#define BUTTRESS_REG_TSC_LO 0x201c +#define BUTTRESS_REG_TSC_HI 0x2020 + +/* valid for PTL */ +#define BUTTRESS_REG_PB_TIMESTAMP_LO 0x2030 +#define BUTTRESS_REG_PB_TIMESTAMP_HI 0x2034 +#define BUTTRESS_REG_PB_TIMESTAMP_VALID 0x2038 + +#define BUTTRESS_REG_PS_WORKPOINT_REQ 0x2100 +#define BUTTRESS_REG_IS_WORKPOINT_REQ 0x2104 +#define BUTTRESS_REG_PS_WORKPOINT_DOMAIN_REQ 0x2108 +#define BUTTRESS_REG_PS_DOMAINS_STATUS 0x2110 +#define BUTTRESS_REG_PWR_STATUS 0x2114 +#define BUTTRESS_REG_PS_WORKPOINT_REQ_SHADOW 0x2120 +#define BUTTRESS_REG_IS_WORKPOINT_REQ_SHADOW 0x2124 +#define BUTTRESS_REG_PS_WORKPOINT_DOMAIN_REQ_SHADOW 0x2128 +#define BUTTRESS_REG_ISPS_WORKPOINT_DOWNLOAD 0x212c +#define BUTTRESS_REG_PG_FLOW_OVERRIDE 0x2180 +#define BUTTRESS_REG_GLOBAL_OVERRIDE_UNGATE_CTL 0x2184 +#define BUTTRESS_REG_PWR_FSM_CTL 0x2188 +#define BUTTRESS_REG_IDLE_WDT 0x218c +#define BUTTRESS_REG_PS_PWR_DOMAIN_EVENTQ_EN 0x2190 +#define BUTTRESS_REG_PS_PWR_DOMAIN_EVENTQ_ADDR 0x2194 +#define BUTTRESS_REG_PS_PWR_DOMAIN_EVENTQ_DATA 0x2198 +#define BUTTRESS_REG_POWER_EN_DELAY 0x219c +#define IPU7_BUTTRESS_REG_LTR_CONTROL 0x21a0 +#define IPU7_BUTTRESS_REG_NDE_CONTROL 0x21a4 +#define IPU7_BUTTRESS_REG_INT_FRM_PUNIT 0x21a8 +#define IPU8_BUTTRESS_REG_LTR_CONTROL 0x21a4 +#define IPU8_BUTTRESS_REG_NDE_CONTROL 0x21a8 +#define IPU8_BUTTRESS_REG_INT_FRM_PUNIT 0x21ac +#define BUTTRESS_REG_SLEEP_LEVEL_CFG 0x21b0 +#define BUTTRESS_REG_SLEEP_LEVEL_STS 0x21b4 +#define BUTTRESS_REG_DVFS_FSM_STATUS 0x21b8 +#define BUTTRESS_REG_PS_PLL_ENABLE 0x21bc +#define BUTTRESS_REG_D2D_CTL 0x21d4 +#define BUTTRESS_REG_IB_CLK_CTL 0x21d8 +#define BUTTRESS_REG_IB_CRO_CLK_CTL 0x21dc +#define BUTTRESS_REG_FUNC_FUSES 0x21e0 +#define BUTTRESS_REG_ISOCH_CTL 0x21e4 +#define BUTTRESS_REG_WORKPOINT_CTL 0x21f0 +#define BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS 0x2200 +#define BUTTRESS_REG_DRV_IS_UCX_START_ADDR 0x2204 +#define BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS 0x2208 +#define BUTTRESS_REG_DRV_PS_UCX_START_ADDR 0x220c +#define BUTTRESS_REG_DRV_UCX_RESET_CFG 0x2210 + +/* configured by CSE */ +#define BUTTRESS_REG_CSE_IS_UCX_CONTROL_STATUS 0x2300 +#define BUTTRESS_REG_CSE_IS_UCX_START_ADDR 0x2304 +#define BUTTRESS_REG_CSE_PS_UCX_CONTROL_STATUS 0x2308 +#define BUTTRESS_REG_CSE_PS_UCX_START_ADDR 0x230c + +#define BUTTRESS_REG_CAMERA_MASK 0x2310 +#define BUTTRESS_REG_FW_CTL 0x2314 +#define BUTTRESS_REG_SECURITY_CTL 0x2318 +#define BUTTRESS_REG_FUNCTIONAL_FW_SETUP 0x231c +#define BUTTRESS_REG_FW_BASE 0x2320 +#define BUTTRESS_REG_FW_BASE_LIMIT 0x2324 +#define BUTTRESS_REG_FW_SCRATCH_BASE 0x2328 +#define BUTTRESS_REG_FW_SCRATCH_LIMIT 0x232c +#define BUTTRESS_REG_CSE_ACTION 0x2330 + +/* configured by SW */ +#define BUTTRESS_REG_FW_RESET_CTL 0x2334 +#define BUTTRESS_REG_FW_SOURCE_SIZE 0x2338 +#define BUTTRESS_REG_FW_SOURCE_BASE 0x233c + +#define BUTTRESS_REG_IPU_SEC_CP_LSB 0x2400 +#define BUTTRESS_REG_IPU_SEC_CP_MSB 0x2404 +#define BUTTRESS_REG_IPU_SEC_WAC_LSB 0x2408 +#define BUTTRESS_REG_IPU_SEC_WAC_MSB 0x240c +#define BUTTRESS_REG_IPU_SEC_RAC_LSB 0x2410 +#define BUTTRESS_REG_IPU_SEC_RAC_MSB 0x2414 +#define BUTTRESS_REG_IPU_DRV_CP_LSB 0x2418 +#define BUTTRESS_REG_IPU_DRV_CP_MSB 0x241c +#define BUTTRESS_REG_IPU_DRV_WAC_LSB 0x2420 +#define BUTTRESS_REG_IPU_DRV_WAC_MSB 0x2424 +#define BUTTRESS_REG_IPU_DRV_RAC_LSB 0x2428 +#define BUTTRESS_REG_IPU_DRV_RAC_MSB 0x242c +#define BUTTRESS_REG_IPU_FW_CP_LSB 0x2430 +#define BUTTRESS_REG_IPU_FW_CP_MSB 0x2434 +#define BUTTRESS_REG_IPU_FW_WAC_LSB 0x2438 +#define BUTTRESS_REG_IPU_FW_WAC_MSB 0x243c +#define BUTTRESS_REG_IPU_FW_RAC_LSB 0x2440 +#define BUTTRESS_REG_IPU_FW_RAC_MSB 0x2444 +#define BUTTRESS_REG_IPU_BIOS_SEC_CP_LSB 0x2448 +#define BUTTRESS_REG_IPU_BIOS_SEC_CP_MSB 0x244c +#define BUTTRESS_REG_IPU_BIOS_SEC_WAC_LSB 0x2450 +#define BUTTRESS_REG_IPU_BIOS_SEC_WAC_MSB 0x2454 +#define BUTTRESS_REG_IPU_BIOS_SEC_RAC_LSB 0x2458 +#define BUTTRESS_REG_IPU_BIOS_SEC_RAC_MSB 0x245c +#define BUTTRESS_REG_IPU_DFD_CP_LSB 0x2460 +#define BUTTRESS_REG_IPU_DFD_CP_MSB 0x2464 +#define BUTTRESS_REG_IPU_DFD_WAC_LSB 0x2468 +#define BUTTRESS_REG_IPU_DFD_WAC_MSB 0x246c +#define BUTTRESS_REG_IPU_DFD_RAC_LSB 0x2470 +#define BUTTRESS_REG_IPU_DFD_RAC_MSB 0x2474 +#define BUTTRESS_REG_CSE2IUDB0 0x2500 +#define BUTTRESS_REG_CSE2IUDATA0 0x2504 +#define BUTTRESS_REG_CSE2IUCSR 0x2508 +#define BUTTRESS_REG_IU2CSEDB0 0x250c +#define BUTTRESS_REG_IU2CSEDATA0 0x2510 +#define BUTTRESS_REG_IU2CSECSR 0x2514 +#define BUTTRESS_REG_CSE2IUDB0_CR_SHADOW 0x2520 +#define BUTTRESS_REG_CSE2IUDATA0_CR_SHADOW 0x2524 +#define BUTTRESS_REG_CSE2IUCSR_CR_SHADOW 0x2528 +#define BUTTRESS_REG_IU2CSEDB0_CR_SHADOW 0x252c +#define BUTTRESS_REG_DVFS_FSM_SURVIVABILITY 0x2900 +#define BUTTRESS_REG_FLOWS_FSM_SURVIVABILITY 0x2904 +#define BUTTRESS_REG_FABRICS_FSM_SURVIVABILITY 0x2908 +#define BUTTRESS_REG_PS_SUB1_PM_FSM_SURVIVABILITY 0x290c +#define BUTTRESS_REG_PS_SUB0_PM_FSM_SURVIVABILITY 0x2910 +#define BUTTRESS_REG_PS_PM_FSM_SURVIVABILITY 0x2914 +#define BUTTRESS_REG_IS_PM_FSM_SURVIVABILITY 0x2918 +#define BUTTRESS_REG_FLR_RST_FSM_SURVIVABILITY 0x291c +#define BUTTRESS_REG_FW_RST_FSM_SURVIVABILITY 0x2920 +#define BUTTRESS_REG_RESETPREP_FSM_SURVIVABILITY 0x2924 +#define BUTTRESS_REG_POWER_FSM_DOMAIN_STATUS 0x3000 +#define BUTTRESS_REG_IDLEREQ_STATUS1 0x3004 +#define BUTTRESS_REG_POWER_FSM_STATUS_IS_PS 0x3008 +#define BUTTRESS_REG_POWER_ACK_B_STATUS 0x300c +#define BUTTRESS_REG_DOMAIN_RETENTION_CTL 0x3010 +#define BUTTRESS_REG_CG_CTRL_BITS 0x3014 +#define BUTTRESS_REG_IS_IFC_STATUS0 0x3018 +#define BUTTRESS_REG_IS_IFC_STATUS1 0x301c +#define BUTTRESS_REG_PS_IFC_STATUS0 0x3020 +#define BUTTRESS_REG_PS_IFC_STATUS1 0x3024 +#define BUTTRESS_REG_BTRS_IFC_STATUS0 0x3028 +#define BUTTRESS_REG_BTRS_IFC_STATUS1 0x302c +#define BUTTRESS_REG_IPU_SKU 0x3030 +#define BUTTRESS_REG_PS_IDLEACK 0x3034 +#define BUTTRESS_REG_IS_IDLEACK 0x3038 +#define BUTTRESS_REG_SPARE_REGS_0 0x303c +#define BUTTRESS_REG_SPARE_REGS_1 0x3040 +#define BUTTRESS_REG_SPARE_REGS_2 0x3044 +#define BUTTRESS_REG_SPARE_REGS_3 0x3048 +#define BUTTRESS_REG_IUNIT_ACV 0x304c +#define BUTTRESS_REG_CHICKEN_BITS 0x3050 +#define BUTTRESS_REG_SBENDPOINT_CFG 0x3054 +#define BUTTRESS_REG_ECC_ERR_LOG 0x3058 +#define BUTTRESS_REG_POWER_FSM_STATUS 0x3070 +#define BUTTRESS_REG_RESET_FSM_STATUS 0x3074 +#define BUTTRESS_REG_IDLE_STATUS 0x3078 +#define BUTTRESS_REG_IDLEACK_STATUS 0x307c +#define BUTTRESS_REG_IPU_DEBUG 0x3080 + +#define BUTTRESS_REG_FW_BOOT_PARAMS0 0x4000 +#define BUTTRESS_REG_FW_BOOT_PARAMS1 0x4004 +#define BUTTRESS_REG_FW_BOOT_PARAMS2 0x4008 +#define BUTTRESS_REG_FW_BOOT_PARAMS3 0x400c +#define BUTTRESS_REG_FW_BOOT_PARAMS4 0x4010 +#define BUTTRESS_REG_FW_BOOT_PARAMS5 0x4014 +#define BUTTRESS_REG_FW_BOOT_PARAMS6 0x4018 +#define BUTTRESS_REG_FW_BOOT_PARAMS7 0x401c +#define BUTTRESS_REG_FW_BOOT_PARAMS8 0x4020 +#define BUTTRESS_REG_FW_BOOT_PARAMS9 0x4024 +#define BUTTRESS_REG_FW_BOOT_PARAMS10 0x4028 +#define BUTTRESS_REG_FW_BOOT_PARAMS11 0x402c +#define BUTTRESS_REG_FW_BOOT_PARAMS12 0x4030 +#define BUTTRESS_REG_FW_BOOT_PARAMS13 0x4034 +#define BUTTRESS_REG_FW_BOOT_PARAMS14 0x4038 +#define BUTTRESS_REG_FW_BOOT_PARAMS15 0x403c + +#define BUTTRESS_FW_BOOT_PARAMS_ENTRY(i) \ + (BUTTRESS_REG_FW_BOOT_PARAMS0 + ((i) * 4U)) +#define BUTTRESS_REG_FW_GP(i) (0x4040 + 0x4 * (i)) +#define BUTTRESS_REG_FPGA_SUPPORT(i) (0x40c0 + 0x4 * (i)) + +#define BUTTRESS_REG_FW_GP8 0x4060 +#define BUTTRESS_REG_FW_GP24 0x40a0 + +#define BUTTRESS_REG_GPIO_0_PADCFG_ADDR_CR 0x4100 +#define BUTTRESS_REG_GPIO_1_PADCFG_ADDR_CR 0x4104 +#define BUTTRESS_REG_GPIO_2_PADCFG_ADDR_CR 0x4108 +#define BUTTRESS_REG_GPIO_3_PADCFG_ADDR_CR 0x410c +#define BUTTRESS_REG_GPIO_4_PADCFG_ADDR_CR 0x4110 +#define BUTTRESS_REG_GPIO_5_PADCFG_ADDR_CR 0x4114 +#define BUTTRESS_REG_GPIO_6_PADCFG_ADDR_CR 0x4118 +#define BUTTRESS_REG_GPIO_7_PADCFG_ADDR_CR 0x411c +#define BUTTRESS_REG_GPIO_ENABLE 0x4140 +#define BUTTRESS_REG_GPIO_VALUE_CR 0x4144 + +#define BUTTRESS_REG_IS_MEM_CORRECTABLE_ERROR_STATUS 0x5000 +#define BUTTRESS_REG_IS_MEM_FATAL_ERROR_STATUS 0x5004 +#define BUTTRESS_REG_IS_MEM_NON_FATAL_ERROR_STATUS 0x5008 +#define BUTTRESS_REG_IS_MEM_CHECK_PASSED 0x500c +#define BUTTRESS_REG_IS_MEM_ERROR_INJECT 0x5010 +#define BUTTRESS_REG_IS_MEM_ERROR_CLEAR 0x5014 +#define BUTTRESS_REG_PS_MEM_CORRECTABLE_ERROR_STATUS 0x5040 +#define BUTTRESS_REG_PS_MEM_FATAL_ERROR_STATUS 0x5044 +#define BUTTRESS_REG_PS_MEM_NON_FATAL_ERROR_STATUS 0x5048 +#define BUTTRESS_REG_PS_MEM_CHECK_PASSED 0x504c +#define BUTTRESS_REG_PS_MEM_ERROR_INJECT 0x5050 +#define BUTTRESS_REG_PS_MEM_ERROR_CLEAR 0x5054 + +#define BUTTRESS_REG_IS_AB_REGION_MIN_ADDRESS(i) (0x6000 + 0x8 * (i)) +#define BUTTRESS_REG_IS_AB_REGION_MAX_ADDRESS(i) (0x6004 + 0x8 * (i)) +#define BUTTRESS_REG_IS_AB_VIOLATION_LOG0 0x6080 +#define BUTTRESS_REG_IS_AB_VIOLATION_LOG1 0x6084 +#define BUTTRESS_REG_PS_AB_REGION_MIN_ADDRESS(i) (0x6100 + 0x8 * (i)) +#define BUTTRESS_REG_PS_AB_REGION_MAX_ADDRESS0 (0x6104 + 0x8 * (i)) +#define BUTTRESS_REG_PS_AB_VIOLATION_LOG0 0x6180 +#define BUTTRESS_REG_PS_AB_VIOLATION_LOG1 0x6184 +#define BUTTRESS_REG_PS_DEBUG_AB_VIOLATION_LOG0 0x6200 +#define BUTTRESS_REG_PS_DEBUG_AB_VIOLATION_LOG1 0x6204 +#define BUTTRESS_REG_IS_DEBUG_AB_VIOLATION_LOG0 0x6208 +#define BUTTRESS_REG_IS_DEBUG_AB_VIOLATION_LOG1 0x620c +#define BUTTRESS_REG_IB_DVP_AB_VIOLATION_LOG0 0x6210 +#define BUTTRESS_REG_IB_DVP_AB_VIOLATION_LOG1 0x6214 +#define BUTTRESS_REG_IB_ATB2DTF_AB_VIOLATION_LOG0 0x6218 +#define BUTTRESS_REG_IB_ATB2DTF_AB_VIOLATION_LOG1 0x621c +#define BUTTRESS_REG_AB_ENABLE 0x6220 +#define BUTTRESS_REG_AB_DEFAULT_ACCESS 0x6230 + +/* Indicates CSE has received an IPU driver IPC transaction */ +#define BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE BIT(0) +/* Indicates an IPC transaction from CSE has arrived */ +#define BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING BIT(1) +/* Indicates a CSR update from CSE has arrived */ +#define BUTTRESS_IRQ_CSE_CSR_SET BIT(2) +/* Indicates an interrupt set by Punit (not in use at this time) */ +#define BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ BIT(3) +/* Indicates an SAI violation was detected on access to IB registers */ +#define BUTTRESS_IRQ_SAI_VIOLATION BIT(4) +/* Indicates a transaction to IS was not able to pass the access blocker */ +#define BUTTRESS_IRQ_IS_AB_VIOLATION BIT(5) +/* Indicates a transaction to PS was not able to pass the access blocker */ +#define BUTTRESS_IRQ_PS_AB_VIOLATION BIT(6) +/* Indicates an error response was detected by the IB config NoC */ +#define BUTTRESS_IRQ_IB_CFG_NOC_ERR_IRQ BIT(7) +/* Indicates an error response was detected by the IB data NoC */ +#define BUTTRESS_IRQ_IB_DATA_NOC_ERR_IRQ BIT(8) +/* Transaction to DVP regs was not able to pass the access blocker */ +#define BUTTRESS_IRQ_IB_DVP_AB_VIOLATION BIT(9) +/* Transaction to ATB2DTF regs was not able to pass the access blocker */ +#define BUTTRESS_IRQ_ATB2DTF_AB_VIOLATION BIT(10) +/* Transaction to IS debug regs was not able to pass the access blocker */ +#define BUTTRESS_IRQ_IS_DEBUG_AB_VIOLATION BIT(11) +/* Transaction to PS debug regs was not able to pass the access blocker */ +#define BUTTRESS_IRQ_PS_DEBUG_AB_VIOLATION BIT(12) +/* Indicates timeout occurred waiting for a response from a target */ +#define BUTTRESS_IRQ_IB_CFG_NOC_TIMEOUT_IRQ BIT(13) +/* Set when any correctable ECC error input wire to buttress is set */ +#define BUTTRESS_IRQ_ECC_CORRECTABLE BIT(14) +/* Any noncorrectable-nonfatal ECC error input wire to buttress is set */ +#define BUTTRESS_IRQ_ECC_NONCORRECTABLE_NONFATAL BIT(15) +/* Set when any noncorrectable-fatal ECC error input wire to buttress is set */ +#define BUTTRESS_IRQ_ECC_NONCORRECTABLE_FATAL BIT(16) +/* Set when timeout occurred waiting for a response from a target */ +#define BUTTRESS_IRQ_IS_CFG_NOC_TIMEOUT_IRQ BIT(17) +#define BUTTRESS_IRQ_PS_CFG_NOC_TIMEOUT_IRQ BIT(18) +#define BUTTRESS_IRQ_LB_CFG_NOC_TIMEOUT_IRQ BIT(19) +/* IS FW double exception event */ +#define BUTTRESS_IRQ_IS_UC_PFATAL_ERROR BIT(26) +/* PS FW double exception event */ +#define BUTTRESS_IRQ_PS_UC_PFATAL_ERROR BIT(27) +/* IS FW watchdog event */ +#define BUTTRESS_IRQ_IS_WATCHDOG BIT(28) +/* PS FW watchdog event */ +#define BUTTRESS_IRQ_PS_WATCHDOG BIT(29) +/* IS IRC irq out */ +#define BUTTRESS_IRQ_IS_IRQ BIT(30) +/* PS IRC irq out */ +#define BUTTRESS_IRQ_PS_IRQ BIT(31) + +/* buttress irq */ +#define BUTTRESS_PWR_STATUS_HH_STATE_IDLE 0U +#define BUTTRESS_PWR_STATUS_HH_STATE_IN_PRGS 1U +#define BUTTRESS_PWR_STATUS_HH_STATE_DONE 2U +#define BUTTRESS_PWR_STATUS_HH_STATE_ERR 3U + +#define BUTTRESS_TSC_CMD_START_TSC_SYNC BIT(0) +#define BUTTRESS_PWR_STATUS_HH_STATUS_SHIFT 11 +#define BUTTRESS_PWR_STATUS_HH_STATUS_MASK (0x3U << 11) +#define BUTTRESS_TSW_WA_SOFT_RESET BIT(8) +/* new for PTL */ +#define BUTTRESS_SEL_PB_TIMESTAMP BIT(9) +#define BUTTRESS_IRQS (BUTTRESS_IRQ_IS_IRQ | \ + BUTTRESS_IRQ_PS_IRQ | \ + BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING | \ + BUTTRESS_IRQ_CSE_CSR_SET | \ + BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE | \ + BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ) + +/* Iunit to CSE regs */ +#define BUTTRESS_IU2CSEDB0_BUSY BIT(31) +#define BUTTRESS_IU2CSEDB0_SHORT_FORMAT_SHIFT 27 +#define BUTTRESS_IU2CSEDB0_CLIENT_ID_SHIFT 10 +#define BUTTRESS_IU2CSEDB0_IPC_CLIENT_ID_VAL 2 + +#define BUTTRESS_IU2CSEDATA0_IPC_BOOT_LOAD 1 +#define BUTTRESS_IU2CSEDATA0_IPC_AUTH_RUN 2 +#define BUTTRESS_IU2CSEDATA0_IPC_AUTH_REPLACE 3 +#define BUTTRESS_IU2CSEDATA0_IPC_UPDATE_SECURE_TOUCH 16 + +#define BUTTRESS_CSE2IUDATA0_IPC_BOOT_LOAD_DONE BIT(0) +#define BUTTRESS_CSE2IUDATA0_IPC_AUTH_RUN_DONE BIT(1) +#define BUTTRESS_CSE2IUDATA0_IPC_AUTH_REPLACE_DONE BIT(2) +#define BUTTRESS_CSE2IUDATA0_IPC_UPDATE_SECURE_TOUCH_DONE BIT(4) + +#define BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE1 BIT(0) +#define BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE2 BIT(1) +#define BUTTRESS_IU2CSECSR_IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE BIT(2) +#define BUTTRESS_IU2CSECSR_IPC_PEER_ASSERTED_REG_VALID_REQ BIT(3) +#define BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID BIT(4) +#define BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ BIT(5) + +/* 0x20 == NACK, 0xf == unknown command */ +#define BUTTRESS_CSE2IUDATA0_IPC_NACK 0xf20 +#define BUTTRESS_CSE2IUDATA0_IPC_NACK_MASK 0xffff + +/* IS/PS freq control */ +#define BUTTRESS_IS_FREQ_CTL_RATIO_MASK 0xffU +#define BUTTRESS_PS_FREQ_CTL_RATIO_MASK 0xffU + +#define IPU7_IS_FREQ_MAX 450 +#define IPU7_IS_FREQ_MIN 50 +#define IPU7_PS_FREQ_MAX 750 +#define BUTTRESS_PS_FREQ_RATIO_STEP 25U +/* valid for IPU8 */ +#define BUTTRESS_IS_FREQ_RATIO_STEP 25U + +/* IS: 400mhz, PS: 500mhz */ +#define IPU7_IS_FREQ_CTL_DEFAULT_RATIO 0x1b +#define IPU7_PS_FREQ_CTL_DEFAULT_RATIO 0x14 +/* IS: 400mhz, PS: 400mhz */ +#define IPU8_IS_FREQ_CTL_DEFAULT_RATIO 0x10 +#define IPU8_PS_FREQ_CTL_DEFAULT_RATIO 0x10 + +#define IPU_FREQ_CTL_CDYN 0x80 +#define IPU_FREQ_CTL_RATIO_SHIFT 0x0 +#define IPU_FREQ_CTL_CDYN_SHIFT 0x8 + +/* buttree power status */ +#define IPU_BUTTRESS_PWR_STATE_IS_PWR_SHIFT 0 +#define IPU_BUTTRESS_PWR_STATE_IS_PWR_MASK \ + (0x3U << IPU_BUTTRESS_PWR_STATE_IS_PWR_SHIFT) + +#define IPU_BUTTRESS_PWR_STATE_PS_PWR_SHIFT 4 +#define IPU_BUTTRESS_PWR_STATE_PS_PWR_MASK \ + (0x3U << IPU_BUTTRESS_PWR_STATE_PS_PWR_SHIFT) + +#define IPU_BUTTRESS_PWR_STATE_DN_DONE 0x0 +#define IPU_BUTTRESS_PWR_STATE_UP_PROCESS 0x1 +#define IPU_BUTTRESS_PWR_STATE_DN_PROCESS 0x2 +#define IPU_BUTTRESS_PWR_STATE_UP_DONE 0x3 + +#define BUTTRESS_PWR_STATE_IS_PWR_SHIFT 3 +#define BUTTRESS_PWR_STATE_IS_PWR_MASK (0x3 << 3) + +#define BUTTRESS_PWR_STATE_PS_PWR_SHIFT 6 +#define BUTTRESS_PWR_STATE_PS_PWR_MASK (0x3 << 6) + +#define PS_FSM_CG BIT(3) + +#define BUTTRESS_OVERRIDE_IS_CLK BIT(1) +#define BUTTRESS_OVERRIDE_PS_CLK BIT(2) +/* ps_pll only valid for ipu8 */ +#define BUTTRESS_OWN_ACK_PS_PLL BIT(8) +#define BUTTRESS_OWN_ACK_IS_CLK BIT(9) +#define BUTTRESS_OWN_ACK_PS_CLK BIT(10) + +/* FW reset ctrl */ +#define BUTTRESS_FW_RESET_CTL_START BIT(0) +#define BUTTRESS_FW_RESET_CTL_DONE BIT(1) + +/* security */ +#define BUTTRESS_SECURITY_CTL_FW_SECURE_MODE BIT(16) +#define BUTTRESS_SECURITY_CTL_FW_SETUP_MASK GENMASK(4, 0) + +#define BUTTRESS_SECURITY_CTL_FW_SETUP_DONE BIT(0) +#define BUTTRESS_SECURITY_CTL_AUTH_DONE BIT(1) +#define BUTTRESS_SECURITY_CTL_AUTH_FAILED BIT(3) + +/* D2D */ +#define BUTTRESS_D2D_PWR_EN BIT(0) +#define BUTTRESS_D2D_PWR_ACK BIT(4) + +/* NDE */ +#define NDE_VAL_MASK GENMASK(9, 0) +#define NDE_SCALE_MASK GENMASK(12, 10) +#define NDE_VALID_MASK BIT(13) +#define NDE_RESVEC_MASK GENMASK(19, 16) +#define NDE_IN_VBLANK_DIS_MASK BIT(31) + +#define BUTTRESS_NDE_VAL_ACTIVE 48 +#define BUTTRESS_NDE_SCALE_ACTIVE 2 +#define BUTTRESS_NDE_VALID_ACTIVE 1 + +#define BUTTRESS_NDE_VAL_DEFAULT 1023 +#define BUTTRESS_NDE_SCALE_DEFAULT 2 +#define BUTTRESS_NDE_VALID_DEFAULT 0 + +/* IS and PS UCX control */ +#define UCX_CTL_RESET BIT(0) +#define UCX_CTL_RUN BIT(1) +#define UCX_CTL_WAKEUP BIT(2) +#define UCX_CTL_SPARE GENMASK(7, 3) +#define UCX_STS_PWR GENMASK(17, 16) +#define UCX_STS_SLEEPING BIT(18) + +/* offset from PHY base */ +#define PHY_CSI_CFG 0xc0 +#define PHY_CSI_RCOMP_CONTROL 0xc8 +#define PHY_CSI_BSCAN_EXCLUDE 0xd8 + +#define PHY_CPHY_DLL_OVRD(x) (0x100 + 0x100 * (x)) +#define PHY_DPHY_DLL_OVRD(x) (0x14c + 0x100 * (x)) +#define PHY_CPHY_RX_CONTROL1(x) (0x110 + 0x100 * (x)) +#define PHY_CPHY_RX_CONTROL2(x) (0x114 + 0x100 * (x)) +#define PHY_DPHY_CFG(x) (0x148 + 0x100 * (x)) +#define PHY_BB_AFE_CONFIG(x) (0x174 + 0x100 * (x)) + +/* PB registers */ +#define INTERRUPT_STATUS 0x0 +#define BTRS_LOCAL_INTERRUPT_MASK 0x4 +#define GLOBAL_INTERRUPT_MASK 0x8 +#define HM_ATS 0xc +#define ATS_ERROR_LOG1 0x10 +#define ATS_ERROR_LOG2 0x14 +#define ATS_ERROR_CLEAR 0x18 +#define CFI_0_ERROR_LOG 0x1c +#define CFI_0_ERROR_CLEAR 0x20 +#define HASH_CONFIG 0x2c +#define TLBID_HASH_ENABLE_31_0 0x30 +#define TLBID_HASH_ENABLE_63_32 0x34 +#define TLBID_HASH_ENABLE_95_64 0x38 +#define TLBID_HASH_ENABLE_127_96 0x3c +#define CFI_1_ERROR_LOGGING 0x40 +#define CFI_1_ERROR_CLEAR 0x44 +#define IMR_ERROR_LOGGING_LOW 0x48 +#define IMR_ERROR_LOGGING_HIGH 0x4c +#define IMR_ERROR_CLEAR 0x50 +#define PORT_ARBITRATION_WEIGHTS 0x54 +#define IMR_ERROR_LOGGING_CFI_1_LOW 0x58 +#define IMR_ERROR_LOGGING_CFI_1_HIGH 0x5c +#define IMR_ERROR_CLEAR_CFI_1 0x60 +#define BAR2_MISC_CONFIG 0x64 +#define RSP_ID_CONFIG_AXI2CFI_0 0x68 +#define RSP_ID_CONFIG_AXI2CFI_1 0x6c +#define PB_DRIVER_PCODE_MAILBOX_STATUS 0x70 +#define PB_DRIVER_PCODE_MAILBOX_INTERFACE 0x74 +#define PORT_ARBITRATION_WEIGHTS_ATS 0x78 + +#endif /* IPU7_BUTTRESS_REGS_H */ diff --git a/drivers/staging/media/ipu7/ipu7-buttress.c b/drivers/staging/media/ipu7/ipu7-buttress.c new file mode 100644 index 000000000000..e5707f5e300b --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-buttress.c @@ -0,0 +1,1192 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <asm/cpu_device_id.h> +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/completion.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/firmware.h> +#include <linux/interrupt.h> +#include <linux/iopoll.h> +#include <linux/math64.h> +#include <linux/mm.h> +#include <linux/mutex.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/pm_runtime.h> +#include <linux/scatterlist.h> +#include <linux/types.h> + +#include "ipu7.h" +#include "ipu7-bus.h" +#include "ipu7-buttress.h" +#include "ipu7-buttress-regs.h" + +#define BOOTLOADER_STATUS_OFFSET BUTTRESS_REG_FW_BOOT_PARAMS7 + +#define BOOTLOADER_MAGIC_KEY 0xb00710adU + +#define ENTRY BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE1 +#define EXIT BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE2 +#define QUERY BUTTRESS_IU2CSECSR_IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE + +#define BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX 10U + +#define BUTTRESS_POWER_TIMEOUT_US (200 * USEC_PER_MSEC) + +#define BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US (5 * USEC_PER_SEC) +#define BUTTRESS_CSE_AUTHENTICATE_TIMEOUT_US (10 * USEC_PER_SEC) +#define BUTTRESS_CSE_FWRESET_TIMEOUT_US (100 * USEC_PER_MSEC) + +#define BUTTRESS_IPC_TX_TIMEOUT_MS MSEC_PER_SEC +#define BUTTRESS_IPC_RX_TIMEOUT_MS MSEC_PER_SEC +#define BUTTRESS_IPC_VALIDITY_TIMEOUT_US (1 * USEC_PER_SEC) +#define BUTTRESS_TSC_SYNC_TIMEOUT_US (5 * USEC_PER_MSEC) + +#define BUTTRESS_IPC_RESET_RETRY 2000U +#define BUTTRESS_CSE_IPC_RESET_RETRY 4U +#define BUTTRESS_IPC_CMD_SEND_RETRY 1U + +struct ipu7_ipc_buttress_msg { + u32 cmd; + u32 expected_resp; + bool require_resp; + u8 cmd_size; +}; + +static const u32 ipu7_adev_irq_mask[2] = { + BUTTRESS_IRQ_IS_IRQ, + BUTTRESS_IRQ_PS_IRQ +}; + +int ipu_buttress_ipc_reset(struct ipu7_device *isp, + struct ipu_buttress_ipc *ipc) +{ + unsigned int retries = BUTTRESS_IPC_RESET_RETRY; + struct ipu_buttress *b = &isp->buttress; + struct device *dev = &isp->pdev->dev; + u32 val = 0, csr_in_clr; + + if (!isp->secure_mode) { + dev_dbg(dev, "Skip IPC reset for non-secure mode\n"); + return 0; + } + + mutex_lock(&b->ipc_mutex); + + /* Clear-by-1 CSR (all bits), corresponding internal states. */ + val = readl(isp->base + ipc->csr_in); + writel(val, isp->base + ipc->csr_in); + + /* Set peer CSR bit IPC_PEER_COMP_ACTIONS_RST_PHASE1 */ + writel(ENTRY, isp->base + ipc->csr_out); + /* + * Clear-by-1 all CSR bits EXCEPT following + * bits: + * A. IPC_PEER_COMP_ACTIONS_RST_PHASE1. + * B. IPC_PEER_COMP_ACTIONS_RST_PHASE2. + * C. Possibly custom bits, depending on + * their role. + */ + csr_in_clr = BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ | + BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID | + BUTTRESS_IU2CSECSR_IPC_PEER_ASSERTED_REG_VALID_REQ | QUERY; + + do { + usleep_range(400, 500); + val = readl(isp->base + ipc->csr_in); + switch (val) { + case ENTRY | EXIT: + case ENTRY | EXIT | QUERY: + /* + * 1) Clear-by-1 CSR bits + * (IPC_PEER_COMP_ACTIONS_RST_PHASE1, + * IPC_PEER_COMP_ACTIONS_RST_PHASE2). + * 2) Set peer CSR bit + * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE. + */ + writel(ENTRY | EXIT, isp->base + ipc->csr_in); + writel(QUERY, isp->base + ipc->csr_out); + break; + case ENTRY: + case ENTRY | QUERY: + /* + * 1) Clear-by-1 CSR bits + * (IPC_PEER_COMP_ACTIONS_RST_PHASE1, + * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE). + * 2) Set peer CSR bit + * IPC_PEER_COMP_ACTIONS_RST_PHASE1. + */ + writel(ENTRY | QUERY, isp->base + ipc->csr_in); + writel(ENTRY, isp->base + ipc->csr_out); + break; + case EXIT: + case EXIT | QUERY: + /* + * Clear-by-1 CSR bit + * IPC_PEER_COMP_ACTIONS_RST_PHASE2. + * 1) Clear incoming doorbell. + * 2) Clear-by-1 all CSR bits EXCEPT following + * bits: + * A. IPC_PEER_COMP_ACTIONS_RST_PHASE1. + * B. IPC_PEER_COMP_ACTIONS_RST_PHASE2. + * C. Possibly custom bits, depending on + * their role. + * 3) Set peer CSR bit + * IPC_PEER_COMP_ACTIONS_RST_PHASE2. + */ + writel(EXIT, isp->base + ipc->csr_in); + writel(0, isp->base + ipc->db0_in); + writel(csr_in_clr, isp->base + ipc->csr_in); + writel(EXIT, isp->base + ipc->csr_out); + + /* + * Read csr_in again to make sure if RST_PHASE2 is done. + * If csr_in is QUERY, it should be handled again. + */ + usleep_range(200, 300); + val = readl(isp->base + ipc->csr_in); + if (val & QUERY) { + dev_dbg(dev, + "RST_PHASE2 retry csr_in = %x\n", val); + break; + } + mutex_unlock(&b->ipc_mutex); + return 0; + case QUERY: + /* + * 1) Clear-by-1 CSR bit + * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE. + * 2) Set peer CSR bit + * IPC_PEER_COMP_ACTIONS_RST_PHASE1 + */ + writel(QUERY, isp->base + ipc->csr_in); + writel(ENTRY, isp->base + ipc->csr_out); + break; + default: + dev_dbg_ratelimited(dev, "Unexpected CSR 0x%x\n", val); + break; + } + } while (retries--); + + mutex_unlock(&b->ipc_mutex); + dev_err(dev, "Timed out while waiting for CSE\n"); + + return -ETIMEDOUT; +} + +static void ipu_buttress_ipc_validity_close(struct ipu7_device *isp, + struct ipu_buttress_ipc *ipc) +{ + writel(BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ, + isp->base + ipc->csr_out); +} + +static int +ipu_buttress_ipc_validity_open(struct ipu7_device *isp, + struct ipu_buttress_ipc *ipc) +{ + unsigned int mask = BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID; + void __iomem *addr; + int ret; + u32 val; + + writel(BUTTRESS_IU2CSECSR_IPC_PEER_ASSERTED_REG_VALID_REQ, + isp->base + ipc->csr_out); + + addr = isp->base + ipc->csr_in; + ret = readl_poll_timeout(addr, val, val & mask, 200, + BUTTRESS_IPC_VALIDITY_TIMEOUT_US); + if (ret) { + dev_err(&isp->pdev->dev, "CSE validity timeout 0x%x\n", val); + ipu_buttress_ipc_validity_close(isp, ipc); + } + + return ret; +} + +static void ipu_buttress_ipc_recv(struct ipu7_device *isp, + struct ipu_buttress_ipc *ipc, u32 *ipc_msg) +{ + if (ipc_msg) + *ipc_msg = readl(isp->base + ipc->data0_in); + writel(0, isp->base + ipc->db0_in); +} + +static int ipu_buttress_ipc_send_msg(struct ipu7_device *isp, + struct ipu7_ipc_buttress_msg *msg) +{ + unsigned long tx_timeout_jiffies, rx_timeout_jiffies; + unsigned int retry = BUTTRESS_IPC_CMD_SEND_RETRY; + struct ipu_buttress *b = &isp->buttress; + struct ipu_buttress_ipc *ipc = &b->cse; + struct device *dev = &isp->pdev->dev; + int tout; + u32 val; + int ret; + + mutex_lock(&b->ipc_mutex); + + ret = ipu_buttress_ipc_validity_open(isp, ipc); + if (ret) { + dev_err(dev, "IPC validity open failed\n"); + goto out; + } + + tx_timeout_jiffies = msecs_to_jiffies(BUTTRESS_IPC_TX_TIMEOUT_MS); + rx_timeout_jiffies = msecs_to_jiffies(BUTTRESS_IPC_RX_TIMEOUT_MS); + +try: + reinit_completion(&ipc->send_complete); + if (msg->require_resp) + reinit_completion(&ipc->recv_complete); + + dev_dbg(dev, "IPC command: 0x%x\n", msg->cmd); + writel(msg->cmd, isp->base + ipc->data0_out); + val = BUTTRESS_IU2CSEDB0_BUSY | msg->cmd_size; + writel(val, isp->base + ipc->db0_out); + + tout = wait_for_completion_timeout(&ipc->send_complete, + tx_timeout_jiffies); + if (!tout) { + dev_err(dev, "send IPC response timeout\n"); + if (!retry--) { + ret = -ETIMEDOUT; + goto out; + } + + /* Try again if CSE is not responding on first try */ + writel(0, isp->base + ipc->db0_out); + goto try; + } + + if (!msg->require_resp) { + ret = -EIO; + goto out; + } + + tout = wait_for_completion_timeout(&ipc->recv_complete, + rx_timeout_jiffies); + if (!tout) { + dev_err(dev, "recv IPC response timeout\n"); + ret = -ETIMEDOUT; + goto out; + } + + if (ipc->nack_mask && + (ipc->recv_data & ipc->nack_mask) == ipc->nack) { + dev_err(dev, "IPC NACK for cmd 0x%x\n", msg->cmd); + ret = -EIO; + goto out; + } + + if (ipc->recv_data != msg->expected_resp) { + dev_err(dev, + "expected resp: 0x%x, IPC response: 0x%x\n", + msg->expected_resp, ipc->recv_data); + ret = -EIO; + goto out; + } + + dev_dbg(dev, "IPC commands done\n"); + +out: + ipu_buttress_ipc_validity_close(isp, ipc); + mutex_unlock(&b->ipc_mutex); + + return ret; +} + +static int ipu_buttress_ipc_send(struct ipu7_device *isp, + u32 ipc_msg, u32 size, bool require_resp, + u32 expected_resp) +{ + struct ipu7_ipc_buttress_msg msg = { + .cmd = ipc_msg, + .cmd_size = size, + .require_resp = require_resp, + .expected_resp = expected_resp, + }; + + return ipu_buttress_ipc_send_msg(isp, &msg); +} + +static irqreturn_t ipu_buttress_call_isr(struct ipu7_bus_device *adev) +{ + irqreturn_t ret = IRQ_WAKE_THREAD; + + if (!adev || !adev->auxdrv || !adev->auxdrv_data) + return IRQ_NONE; + + if (adev->auxdrv_data->isr) + ret = adev->auxdrv_data->isr(adev); + + if (ret == IRQ_WAKE_THREAD && !adev->auxdrv_data->isr_threaded) + ret = IRQ_NONE; + + return ret; +} + +irqreturn_t ipu_buttress_isr(int irq, void *isp_ptr) +{ + struct ipu7_device *isp = isp_ptr; + struct ipu7_bus_device *adev[] = { isp->isys, isp->psys }; + struct ipu_buttress *b = &isp->buttress; + struct device *dev = &isp->pdev->dev; + irqreturn_t ret = IRQ_NONE; + u32 pb_irq, pb_local_irq; + u32 disable_irqs = 0; + u32 irq_status; + unsigned int i; + + pm_runtime_get_noresume(dev); + + pb_irq = readl(isp->pb_base + INTERRUPT_STATUS); + writel(pb_irq, isp->pb_base + INTERRUPT_STATUS); + + /* check btrs ATS, CFI and IMR errors, BIT(0) is unused for IPU */ + pb_local_irq = readl(isp->pb_base + BTRS_LOCAL_INTERRUPT_MASK); + if (pb_local_irq & ~BIT(0)) { + dev_warn(dev, "PB interrupt status 0x%x local 0x%x\n", pb_irq, + pb_local_irq); + dev_warn(dev, "Details: %x %x %x %x %x %x %x %x\n", + readl(isp->pb_base + ATS_ERROR_LOG1), + readl(isp->pb_base + ATS_ERROR_LOG2), + readl(isp->pb_base + CFI_0_ERROR_LOG), + readl(isp->pb_base + CFI_1_ERROR_LOGGING), + readl(isp->pb_base + IMR_ERROR_LOGGING_LOW), + readl(isp->pb_base + IMR_ERROR_LOGGING_HIGH), + readl(isp->pb_base + IMR_ERROR_LOGGING_CFI_1_LOW), + readl(isp->pb_base + IMR_ERROR_LOGGING_CFI_1_HIGH)); + } + + irq_status = readl(isp->base + BUTTRESS_REG_IRQ_STATUS); + if (!irq_status) { + pm_runtime_put_noidle(dev); + return IRQ_NONE; + } + + do { + writel(irq_status, isp->base + BUTTRESS_REG_IRQ_CLEAR); + + for (i = 0; i < ARRAY_SIZE(ipu7_adev_irq_mask); i++) { + irqreturn_t r = ipu_buttress_call_isr(adev[i]); + + if (!(irq_status & ipu7_adev_irq_mask[i])) + continue; + + if (r == IRQ_WAKE_THREAD) { + ret = IRQ_WAKE_THREAD; + disable_irqs |= ipu7_adev_irq_mask[i]; + } else if (ret == IRQ_NONE && r == IRQ_HANDLED) { + ret = IRQ_HANDLED; + } + } + + if (irq_status & (BUTTRESS_IRQS | BUTTRESS_IRQ_SAI_VIOLATION) && + ret == IRQ_NONE) + ret = IRQ_HANDLED; + + if (irq_status & BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING) { + dev_dbg(dev, "BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING\n"); + ipu_buttress_ipc_recv(isp, &b->cse, &b->cse.recv_data); + complete(&b->cse.recv_complete); + } + + if (irq_status & BUTTRESS_IRQ_CSE_CSR_SET) + dev_dbg(dev, "BUTTRESS_IRQ_CSE_CSR_SET\n"); + + if (irq_status & BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE) { + dev_dbg(dev, "BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE\n"); + complete(&b->cse.send_complete); + } + + if (irq_status & BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ) + dev_dbg(dev, "BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ\n"); + + if (irq_status & BUTTRESS_IRQ_SAI_VIOLATION && + ipu_buttress_get_secure_mode(isp)) + dev_err(dev, "BUTTRESS_IRQ_SAI_VIOLATION\n"); + + irq_status = readl(isp->base + BUTTRESS_REG_IRQ_STATUS); + } while (irq_status); + + if (disable_irqs) + writel(BUTTRESS_IRQS & ~disable_irqs, + isp->base + BUTTRESS_REG_IRQ_ENABLE); + + pm_runtime_put(dev); + + return ret; +} + +irqreturn_t ipu_buttress_isr_threaded(int irq, void *isp_ptr) +{ + struct ipu7_device *isp = isp_ptr; + struct ipu7_bus_device *adev[] = { isp->isys, isp->psys }; + const struct ipu7_auxdrv_data *drv_data = NULL; + irqreturn_t ret = IRQ_NONE; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(ipu7_adev_irq_mask) && adev[i]; i++) { + drv_data = adev[i]->auxdrv_data; + if (!drv_data) + continue; + + if (drv_data->wake_isr_thread && + drv_data->isr_threaded(adev[i]) == IRQ_HANDLED) + ret = IRQ_HANDLED; + } + + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_ENABLE); + + return ret; +} + +static int isys_d2d_power(struct device *dev, bool on) +{ + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp; + int ret = 0; + u32 target = on ? BUTTRESS_D2D_PWR_ACK : 0U; + u32 val; + + dev_dbg(dev, "power %s isys d2d.\n", on ? "UP" : "DOWN"); + val = readl(isp->base + BUTTRESS_REG_D2D_CTL); + if ((val & BUTTRESS_D2D_PWR_ACK) == target) { + dev_info(dev, "d2d already in %s state.\n", + on ? "UP" : "DOWN"); + return 0; + } + + val = on ? val | BUTTRESS_D2D_PWR_EN : val & (~BUTTRESS_D2D_PWR_EN); + writel(val, isp->base + BUTTRESS_REG_D2D_CTL); + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_D2D_CTL, + val, (val & BUTTRESS_D2D_PWR_ACK) == target, + 100, BUTTRESS_POWER_TIMEOUT_US); + if (ret) + dev_err(dev, "power %s d2d timeout. status: 0x%x\n", + on ? "UP" : "DOWN", val); + + return ret; +} + +static void isys_nde_control(struct device *dev, bool on) +{ + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp; + u32 val, value, scale, valid, resvec; + u32 nde_reg; + + if (on) { + value = BUTTRESS_NDE_VAL_ACTIVE; + scale = BUTTRESS_NDE_SCALE_ACTIVE; + valid = BUTTRESS_NDE_VALID_ACTIVE; + } else { + value = BUTTRESS_NDE_VAL_DEFAULT; + scale = BUTTRESS_NDE_SCALE_DEFAULT; + valid = BUTTRESS_NDE_VALID_DEFAULT; + } + + /* only set the fabrics resource ownership for ipu8 */ + nde_reg = is_ipu8(isp->hw_ver) ? IPU8_BUTTRESS_REG_NDE_CONTROL : + IPU7_BUTTRESS_REG_NDE_CONTROL; + resvec = is_ipu8(isp->hw_ver) ? 0x2 : 0xe; + val = FIELD_PREP(NDE_VAL_MASK, value) | + FIELD_PREP(NDE_SCALE_MASK, scale) | + FIELD_PREP(NDE_VALID_MASK, valid) | + FIELD_PREP(NDE_RESVEC_MASK, resvec); + + writel(val, isp->base + nde_reg); +} + +static int ipu7_buttress_powerup(struct device *dev, + const struct ipu_buttress_ctrl *ctrl) +{ + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp; + u32 val, exp_sts; + int ret = 0; + + if (!ctrl) + return 0; + + mutex_lock(&isp->buttress.power_mutex); + + exp_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift; + if (ctrl->subsys_id == IPU_IS) { + ret = isys_d2d_power(dev, true); + if (ret) + goto out_power; + isys_nde_control(dev, true); + } + + /* request clock resource ownership */ + val = readl(isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG); + val |= ctrl->ovrd_clk; + writel(val, isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG); + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_SLEEP_LEVEL_STS, + val, (val & ctrl->own_clk_ack), + 100, BUTTRESS_POWER_TIMEOUT_US); + if (ret) + dev_warn(dev, "request clk ownership timeout. status 0x%x\n", + val); + + val = ctrl->ratio << ctrl->ratio_shift | ctrl->cdyn << ctrl->cdyn_shift; + + dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val, + ctrl->subsys_id == IPU_IS ? "IS" : "PS"); + writel(val, isp->base + ctrl->freq_ctl); + + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS, + val, ((val & ctrl->pwr_sts_mask) == exp_sts), + 100, BUTTRESS_POWER_TIMEOUT_US); + if (ret) { + dev_err(dev, "%s power up timeout with status: 0x%x\n", + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val); + goto out_power; + } + + dev_dbg(dev, "%s power up successfully. status: 0x%x\n", + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val); + + /* release clock resource ownership */ + val = readl(isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG); + val &= ~ctrl->ovrd_clk; + writel(val, isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG); + +out_power: + mutex_unlock(&isp->buttress.power_mutex); + + return ret; +} + +static int ipu7_buttress_powerdown(struct device *dev, + const struct ipu_buttress_ctrl *ctrl) +{ + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp; + u32 val, exp_sts; + int ret = 0; + + if (!ctrl) + return 0; + + mutex_lock(&isp->buttress.power_mutex); + + exp_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift; + val = 0x8U << ctrl->ratio_shift; + + dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val, + ctrl->subsys_id == IPU_IS ? "IS" : "PS"); + writel(val, isp->base + ctrl->freq_ctl); + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS, + val, ((val & ctrl->pwr_sts_mask) == exp_sts), + 100, BUTTRESS_POWER_TIMEOUT_US); + if (ret) { + dev_err(dev, "%s power down timeout with status: 0x%x\n", + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val); + goto out_power; + } + + dev_dbg(dev, "%s power down successfully. status: 0x%x\n", + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val); +out_power: + if (ctrl->subsys_id == IPU_IS && !ret) { + isys_d2d_power(dev, false); + isys_nde_control(dev, false); + } + + mutex_unlock(&isp->buttress.power_mutex); + + return ret; +} + +static int ipu8_buttress_powerup(struct device *dev, + const struct ipu_buttress_ctrl *ctrl) +{ + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp; + u32 sleep_level_reg = BUTTRESS_REG_SLEEP_LEVEL_STS; + u32 val, exp_sts; + int ret = 0; + + if (!ctrl) + return 0; + + mutex_lock(&isp->buttress.power_mutex); + exp_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift; + if (ctrl->subsys_id == IPU_IS) { + ret = isys_d2d_power(dev, true); + if (ret) + goto out_power; + isys_nde_control(dev, true); + } + + /* request ps_pll when psys freq > 400Mhz */ + if (ctrl->subsys_id == IPU_PS && ctrl->ratio > 0x10) { + writel(1, isp->base + BUTTRESS_REG_PS_PLL_ENABLE); + ret = readl_poll_timeout(isp->base + sleep_level_reg, + val, (val & ctrl->own_clk_ack), + 100, BUTTRESS_POWER_TIMEOUT_US); + if (ret) + dev_warn(dev, "ps_pll req ack timeout. status 0x%x\n", + val); + } + + val = ctrl->ratio << ctrl->ratio_shift | ctrl->cdyn << ctrl->cdyn_shift; + dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val, + ctrl->subsys_id == IPU_IS ? "IS" : "PS"); + writel(val, isp->base + ctrl->freq_ctl); + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS, + val, ((val & ctrl->pwr_sts_mask) == exp_sts), + 100, BUTTRESS_POWER_TIMEOUT_US); + if (ret) { + dev_err(dev, "%s power up timeout with status: 0x%x\n", + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val); + goto out_power; + } + + dev_dbg(dev, "%s power up successfully. status: 0x%x\n", + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val); +out_power: + mutex_unlock(&isp->buttress.power_mutex); + + return ret; +} + +static int ipu8_buttress_powerdown(struct device *dev, + const struct ipu_buttress_ctrl *ctrl) +{ + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp; + u32 val, exp_sts; + int ret = 0; + + if (!ctrl) + return 0; + + mutex_lock(&isp->buttress.power_mutex); + exp_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift; + + if (ctrl->subsys_id == IPU_PS) + val = 0x10U << ctrl->ratio_shift; + else + val = 0x8U << ctrl->ratio_shift; + + dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val, + ctrl->subsys_id == IPU_IS ? "IS" : "PS"); + writel(val, isp->base + ctrl->freq_ctl); + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS, + val, ((val & ctrl->pwr_sts_mask) == exp_sts), + 100, BUTTRESS_POWER_TIMEOUT_US); + if (ret) { + dev_err(dev, "%s power down timeout with status: 0x%x\n", + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val); + goto out_power; + } + + dev_dbg(dev, "%s power down successfully. status: 0x%x\n", + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val); +out_power: + if (ctrl->subsys_id == IPU_IS && !ret) { + isys_d2d_power(dev, false); + isys_nde_control(dev, false); + } + + if (ctrl->subsys_id == IPU_PS) { + val = readl(isp->base + BUTTRESS_REG_SLEEP_LEVEL_STS); + if (val & ctrl->own_clk_ack) + writel(0, isp->base + BUTTRESS_REG_PS_PLL_ENABLE); + } + mutex_unlock(&isp->buttress.power_mutex); + + return ret; +} + +int ipu_buttress_powerup(struct device *dev, + const struct ipu_buttress_ctrl *ctrl) +{ + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp; + + if (is_ipu8(isp->hw_ver)) + return ipu8_buttress_powerup(dev, ctrl); + + return ipu7_buttress_powerup(dev, ctrl); +} + +int ipu_buttress_powerdown(struct device *dev, + const struct ipu_buttress_ctrl *ctrl) +{ + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp; + + if (is_ipu8(isp->hw_ver)) + return ipu8_buttress_powerdown(dev, ctrl); + + return ipu7_buttress_powerdown(dev, ctrl); +} + +bool ipu_buttress_get_secure_mode(struct ipu7_device *isp) +{ + u32 val; + + val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL); + + return val & BUTTRESS_SECURITY_CTL_FW_SECURE_MODE; +} + +bool ipu_buttress_auth_done(struct ipu7_device *isp) +{ + u32 val; + + if (!isp->secure_mode) + return true; + + val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL); + val = FIELD_GET(BUTTRESS_SECURITY_CTL_FW_SETUP_MASK, val); + + return val == BUTTRESS_SECURITY_CTL_AUTH_DONE; +} +EXPORT_SYMBOL_NS_GPL(ipu_buttress_auth_done, "INTEL_IPU7"); + +int ipu_buttress_get_isys_freq(struct ipu7_device *isp, u32 *freq) +{ + u32 reg_val; + int ret; + + ret = pm_runtime_get_sync(&isp->isys->auxdev.dev); + if (ret < 0) { + pm_runtime_put(&isp->isys->auxdev.dev); + dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n", ret); + return ret; + } + + reg_val = readl(isp->base + BUTTRESS_REG_IS_WORKPOINT_REQ); + + pm_runtime_put(&isp->isys->auxdev.dev); + + if (is_ipu8(isp->hw_ver)) + *freq = (reg_val & BUTTRESS_IS_FREQ_CTL_RATIO_MASK) * 25; + else + *freq = (reg_val & BUTTRESS_IS_FREQ_CTL_RATIO_MASK) * 50 / 3; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ipu_buttress_get_isys_freq, "INTEL_IPU7"); + +int ipu_buttress_get_psys_freq(struct ipu7_device *isp, u32 *freq) +{ + u32 reg_val; + int ret; + + ret = pm_runtime_get_sync(&isp->psys->auxdev.dev); + if (ret < 0) { + pm_runtime_put(&isp->psys->auxdev.dev); + dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n", ret); + return ret; + } + + reg_val = readl(isp->base + BUTTRESS_REG_PS_WORKPOINT_REQ); + + pm_runtime_put(&isp->psys->auxdev.dev); + + reg_val &= BUTTRESS_PS_FREQ_CTL_RATIO_MASK; + *freq = BUTTRESS_PS_FREQ_RATIO_STEP * reg_val; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ipu_buttress_get_psys_freq, "INTEL_IPU7"); + +int ipu_buttress_reset_authentication(struct ipu7_device *isp) +{ + struct device *dev = &isp->pdev->dev; + int ret; + u32 val; + + if (!isp->secure_mode) { + dev_dbg(dev, "Skip auth for non-secure mode\n"); + return 0; + } + + writel(BUTTRESS_FW_RESET_CTL_START, isp->base + + BUTTRESS_REG_FW_RESET_CTL); + + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_FW_RESET_CTL, val, + val & BUTTRESS_FW_RESET_CTL_DONE, 500, + BUTTRESS_CSE_FWRESET_TIMEOUT_US); + if (ret) { + dev_err(dev, "Time out while resetting authentication state\n"); + return ret; + } + + dev_dbg(dev, "FW reset for authentication done\n"); + writel(0, isp->base + BUTTRESS_REG_FW_RESET_CTL); + /* leave some time for HW restore */ + usleep_range(800, 1000); + + return 0; +} + +int ipu_buttress_authenticate(struct ipu7_device *isp) +{ + struct ipu_buttress *b = &isp->buttress; + struct device *dev = &isp->pdev->dev; + u32 data, mask, done, fail; + int ret; + + if (!isp->secure_mode) { + dev_dbg(dev, "Skip auth for non-secure mode\n"); + return 0; + } + + mutex_lock(&b->auth_mutex); + + if (ipu_buttress_auth_done(isp)) { + ret = 0; + goto out_unlock; + } + + /* + * BUTTRESS_REG_FW_SOURCE_BASE needs to be set with FW CPD + * package address for secure mode. + */ + + writel(isp->cpd_fw->size, isp->base + BUTTRESS_REG_FW_SOURCE_SIZE); + writel(sg_dma_address(isp->psys->fw_sgt.sgl), + isp->base + BUTTRESS_REG_FW_SOURCE_BASE); + + /* + * Write boot_load into IU2CSEDATA0 + * Write sizeof(boot_load) | 0x2 << CLIENT_ID to + * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as + */ + dev_info(dev, "Sending BOOT_LOAD to CSE\n"); + ret = ipu_buttress_ipc_send(isp, BUTTRESS_IU2CSEDATA0_IPC_BOOT_LOAD, + 1, true, + BUTTRESS_CSE2IUDATA0_IPC_BOOT_LOAD_DONE); + if (ret) { + dev_err(dev, "CSE boot_load failed\n"); + goto out_unlock; + } + + mask = BUTTRESS_SECURITY_CTL_FW_SETUP_MASK; + done = BUTTRESS_SECURITY_CTL_FW_SETUP_DONE; + fail = BUTTRESS_SECURITY_CTL_AUTH_FAILED; + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_SECURITY_CTL, data, + ((data & mask) == done || + (data & mask) == fail), 500, + BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US); + if (ret) { + dev_err(dev, "CSE boot_load timeout\n"); + goto out_unlock; + } + + if ((data & mask) == fail) { + dev_err(dev, "CSE auth failed\n"); + ret = -EINVAL; + goto out_unlock; + } + + ret = readl_poll_timeout(isp->base + BOOTLOADER_STATUS_OFFSET, + data, data == BOOTLOADER_MAGIC_KEY, 500, + BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US); + if (ret) { + dev_err(dev, "Unexpected magic number 0x%x\n", data); + goto out_unlock; + } + + /* + * Write authenticate_run into IU2CSEDATA0 + * Write sizeof(boot_load) | 0x2 << CLIENT_ID to + * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as + */ + dev_info(dev, "Sending AUTHENTICATE_RUN to CSE\n"); + ret = ipu_buttress_ipc_send(isp, BUTTRESS_IU2CSEDATA0_IPC_AUTH_RUN, + 1, true, + BUTTRESS_CSE2IUDATA0_IPC_AUTH_RUN_DONE); + if (ret) { + dev_err(dev, "CSE authenticate_run failed\n"); + goto out_unlock; + } + + done = BUTTRESS_SECURITY_CTL_AUTH_DONE; + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_SECURITY_CTL, data, + ((data & mask) == done || + (data & mask) == fail), 500, + BUTTRESS_CSE_AUTHENTICATE_TIMEOUT_US); + if (ret) { + dev_err(dev, "CSE authenticate timeout\n"); + goto out_unlock; + } + + if ((data & mask) == fail) { + dev_err(dev, "CSE boot_load failed\n"); + ret = -EINVAL; + goto out_unlock; + } + + dev_info(dev, "CSE authenticate_run done\n"); + +out_unlock: + mutex_unlock(&b->auth_mutex); + + return ret; +} + +static int ipu_buttress_send_tsc_request(struct ipu7_device *isp) +{ + u32 val, mask, done; + int ret; + + mask = BUTTRESS_PWR_STATUS_HH_STATUS_MASK; + + writel(BUTTRESS_TSC_CMD_START_TSC_SYNC, + isp->base + BUTTRESS_REG_TSC_CMD); + + val = readl(isp->base + BUTTRESS_REG_PWR_STATUS); + val = FIELD_GET(mask, val); + if (val == BUTTRESS_PWR_STATUS_HH_STATE_ERR) { + dev_err(&isp->pdev->dev, "Start tsc sync failed\n"); + return -EINVAL; + } + + done = BUTTRESS_PWR_STATUS_HH_STATE_DONE; + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS, val, + FIELD_GET(mask, val) == done, 500, + BUTTRESS_TSC_SYNC_TIMEOUT_US); + if (ret) + dev_err(&isp->pdev->dev, "Start tsc sync timeout\n"); + + return ret; +} + +int ipu_buttress_start_tsc_sync(struct ipu7_device *isp) +{ + void __iomem *base = isp->base; + unsigned int i; + u32 val; + + if (is_ipu8(isp->hw_ver)) { + for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) { + val = readl(base + BUTTRESS_REG_PB_TIMESTAMP_VALID); + if (val == 1) + return 0; + usleep_range(40, 50); + } + + dev_err(&isp->pdev->dev, "PB HH sync failed (valid %u)\n", val); + return -ETIMEDOUT; + } + + if (is_ipu7p5(isp->hw_ver)) { + val = readl(base + BUTTRESS_REG_TSC_CTL); + val |= BUTTRESS_SEL_PB_TIMESTAMP; + writel(val, base + BUTTRESS_REG_TSC_CTL); + + for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) { + val = readl(base + BUTTRESS_REG_PB_TIMESTAMP_VALID); + if (val == 1) + return 0; + usleep_range(40, 50); + } + + dev_err(&isp->pdev->dev, "PB HH sync failed (valid %u)\n", val); + + return -ETIMEDOUT; + } + + for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) { + int ret; + + ret = ipu_buttress_send_tsc_request(isp); + if (ret != -ETIMEDOUT) + return ret; + + val = readl(base + BUTTRESS_REG_TSC_CTL); + val = val | BUTTRESS_TSW_WA_SOFT_RESET; + writel(val, base + BUTTRESS_REG_TSC_CTL); + val = val & (~BUTTRESS_TSW_WA_SOFT_RESET); + writel(val, base + BUTTRESS_REG_TSC_CTL); + } + + dev_err(&isp->pdev->dev, "TSC sync failed (timeout)\n"); + + return -ETIMEDOUT; +} +EXPORT_SYMBOL_NS_GPL(ipu_buttress_start_tsc_sync, "INTEL_IPU7"); + +void ipu_buttress_tsc_read(struct ipu7_device *isp, u64 *val) +{ + unsigned long flags; + u32 tsc_hi, tsc_lo; + + local_irq_save(flags); + if (is_ipu7(isp->hw_ver)) { + tsc_lo = readl(isp->base + BUTTRESS_REG_TSC_LO); + tsc_hi = readl(isp->base + BUTTRESS_REG_TSC_HI); + } else { + tsc_lo = readl(isp->base + BUTTRESS_REG_PB_TIMESTAMP_LO); + tsc_hi = readl(isp->base + BUTTRESS_REG_PB_TIMESTAMP_HI); + } + *val = (u64)tsc_hi << 32 | tsc_lo; + local_irq_restore(flags); +} +EXPORT_SYMBOL_NS_GPL(ipu_buttress_tsc_read, "INTEL_IPU7"); + +u64 ipu_buttress_tsc_ticks_to_ns(u64 ticks, const struct ipu7_device *isp) +{ + u64 ns = ticks * 10000; + + /* + * converting TSC tick count to ns is calculated by: + * Example (TSC clock frequency is 19.2MHz): + * ns = ticks * 1000 000 000 / 19.2Mhz + * = ticks * 1000 000 000 / 19200000Hz + * = ticks * 10000 / 192 ns + */ + return div_u64(ns, isp->buttress.ref_clk); +} +EXPORT_SYMBOL_NS_GPL(ipu_buttress_tsc_ticks_to_ns, "INTEL_IPU7"); + +/* trigger uc control to wakeup fw */ +void ipu_buttress_wakeup_is_uc(const struct ipu7_device *isp) +{ + u32 val; + + val = readl(isp->base + BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS); + val |= UCX_CTL_WAKEUP; + writel(val, isp->base + BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS); +} +EXPORT_SYMBOL_NS_GPL(ipu_buttress_wakeup_is_uc, "INTEL_IPU7"); + +void ipu_buttress_wakeup_ps_uc(const struct ipu7_device *isp) +{ + u32 val; + + val = readl(isp->base + BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS); + val |= UCX_CTL_WAKEUP; + writel(val, isp->base + BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS); +} +EXPORT_SYMBOL_NS_GPL(ipu_buttress_wakeup_ps_uc, "INTEL_IPU7"); + +static const struct x86_cpu_id ipu_misc_cfg_exclusion[] = { + X86_MATCH_VFM_STEPS(INTEL_PANTHERLAKE_L, 0x1, 0x1, 0), + {}, +}; + +static void ipu_buttress_setup(struct ipu7_device *isp) +{ + struct device *dev = &isp->pdev->dev; + u32 val; + + /* program PB BAR */ +#define WRXREQOP_OVRD_VAL_MASK GENMASK(22, 19) + writel(0, isp->pb_base + GLOBAL_INTERRUPT_MASK); + val = readl(isp->pb_base + BAR2_MISC_CONFIG); + if (is_ipu7(isp->hw_ver) || x86_match_cpu(ipu_misc_cfg_exclusion)) + val |= 0x100U; + else + val |= FIELD_PREP(WRXREQOP_OVRD_VAL_MASK, 0xf) | + BIT(18) | 0x100U; + + writel(val, isp->pb_base + BAR2_MISC_CONFIG); + val = readl(isp->pb_base + BAR2_MISC_CONFIG); + + if (is_ipu8(isp->hw_ver)) { + writel(BIT(13), isp->pb_base + TLBID_HASH_ENABLE_63_32); + writel(BIT(9), isp->pb_base + TLBID_HASH_ENABLE_95_64); + dev_dbg(dev, "IPU8 TLBID_HASH %x %x\n", + readl(isp->pb_base + TLBID_HASH_ENABLE_63_32), + readl(isp->pb_base + TLBID_HASH_ENABLE_95_64)); + } else if (is_ipu7p5(isp->hw_ver)) { + writel(BIT(14), isp->pb_base + TLBID_HASH_ENABLE_63_32); + writel(BIT(9), isp->pb_base + TLBID_HASH_ENABLE_95_64); + dev_dbg(dev, "IPU7P5 TLBID_HASH %x %x\n", + readl(isp->pb_base + TLBID_HASH_ENABLE_63_32), + readl(isp->pb_base + TLBID_HASH_ENABLE_95_64)); + } else { + writel(BIT(22), isp->pb_base + TLBID_HASH_ENABLE_63_32); + writel(BIT(1), isp->pb_base + TLBID_HASH_ENABLE_127_96); + dev_dbg(dev, "TLBID_HASH %x %x\n", + readl(isp->pb_base + TLBID_HASH_ENABLE_63_32), + readl(isp->pb_base + TLBID_HASH_ENABLE_127_96)); + } + + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_CLEAR); + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_MASK); + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_ENABLE); + /* LNL SW workaround for PS PD hang when PS sub-domain during PD */ + writel(PS_FSM_CG, isp->base + BUTTRESS_REG_CG_CTRL_BITS); +} + +void ipu_buttress_restore(struct ipu7_device *isp) +{ + struct ipu_buttress *b = &isp->buttress; + + ipu_buttress_setup(isp); + + writel(b->wdt_cached_value, isp->base + BUTTRESS_REG_IDLE_WDT); +} + +int ipu_buttress_init(struct ipu7_device *isp) +{ + int ret, ipc_reset_retry = BUTTRESS_CSE_IPC_RESET_RETRY; + struct ipu_buttress *b = &isp->buttress; + struct device *dev = &isp->pdev->dev; + u32 val; + + mutex_init(&b->power_mutex); + mutex_init(&b->auth_mutex); + mutex_init(&b->cons_mutex); + mutex_init(&b->ipc_mutex); + init_completion(&b->cse.send_complete); + init_completion(&b->cse.recv_complete); + + b->cse.nack = BUTTRESS_CSE2IUDATA0_IPC_NACK; + b->cse.nack_mask = BUTTRESS_CSE2IUDATA0_IPC_NACK_MASK; + b->cse.csr_in = BUTTRESS_REG_CSE2IUCSR; + b->cse.csr_out = BUTTRESS_REG_IU2CSECSR; + b->cse.db0_in = BUTTRESS_REG_CSE2IUDB0; + b->cse.db0_out = BUTTRESS_REG_IU2CSEDB0; + b->cse.data0_in = BUTTRESS_REG_CSE2IUDATA0; + b->cse.data0_out = BUTTRESS_REG_IU2CSEDATA0; + + isp->secure_mode = ipu_buttress_get_secure_mode(isp); + val = readl(isp->base + BUTTRESS_REG_IPU_SKU); + dev_info(dev, "IPU%u SKU %u in %s mode mask 0x%x\n", val & 0xfU, + (val >> 4) & 0x7U, isp->secure_mode ? "secure" : "non-secure", + readl(isp->base + BUTTRESS_REG_CAMERA_MASK)); + b->wdt_cached_value = readl(isp->base + BUTTRESS_REG_IDLE_WDT); + b->ref_clk = 384; + + ipu_buttress_setup(isp); + + /* Retry couple of times in case of CSE initialization is delayed */ + do { + ret = ipu_buttress_ipc_reset(isp, &b->cse); + if (ret) { + dev_warn(dev, "IPC reset protocol failed, retrying\n"); + } else { + dev_dbg(dev, "IPC reset done\n"); + return 0; + } + } while (ipc_reset_retry--); + + dev_err(dev, "IPC reset protocol failed\n"); + + mutex_destroy(&b->power_mutex); + mutex_destroy(&b->auth_mutex); + mutex_destroy(&b->cons_mutex); + mutex_destroy(&b->ipc_mutex); + + return ret; +} + +void ipu_buttress_exit(struct ipu7_device *isp) +{ + struct ipu_buttress *b = &isp->buttress; + + writel(0, isp->base + BUTTRESS_REG_IRQ_ENABLE); + mutex_destroy(&b->power_mutex); + mutex_destroy(&b->auth_mutex); + mutex_destroy(&b->cons_mutex); + mutex_destroy(&b->ipc_mutex); +} diff --git a/drivers/staging/media/ipu7/ipu7-buttress.h b/drivers/staging/media/ipu7/ipu7-buttress.h new file mode 100644 index 000000000000..8da7dd612575 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-buttress.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_BUTTRESS_H +#define IPU7_BUTTRESS_H + +#include <linux/completion.h> +#include <linux/irqreturn.h> +#include <linux/list.h> +#include <linux/mutex.h> + +struct device; +struct ipu7_device; + +struct ipu_buttress_ctrl { + u32 subsys_id; + u32 freq_ctl, pwr_sts_shift, pwr_sts_mask, pwr_sts_on, pwr_sts_off; + u32 ratio; + u32 ratio_shift; + u32 cdyn; + u32 cdyn_shift; + u32 ovrd_clk; + u32 own_clk_ack; +}; + +struct ipu_buttress_ipc { + struct completion send_complete; + struct completion recv_complete; + u32 nack; + u32 nack_mask; + u32 recv_data; + u32 csr_out; + u32 csr_in; + u32 db0_in; + u32 db0_out; + u32 data0_out; + u32 data0_in; +}; + +struct ipu_buttress { + struct mutex power_mutex, auth_mutex, cons_mutex, ipc_mutex; + struct ipu_buttress_ipc cse; + u32 psys_min_freq; + u32 wdt_cached_value; + u8 psys_force_ratio; + bool force_suspend; + u32 ref_clk; +}; + +int ipu_buttress_ipc_reset(struct ipu7_device *isp, + struct ipu_buttress_ipc *ipc); +int ipu_buttress_powerup(struct device *dev, + const struct ipu_buttress_ctrl *ctrl); +int ipu_buttress_powerdown(struct device *dev, + const struct ipu_buttress_ctrl *ctrl); +bool ipu_buttress_get_secure_mode(struct ipu7_device *isp); +int ipu_buttress_authenticate(struct ipu7_device *isp); +int ipu_buttress_reset_authentication(struct ipu7_device *isp); +bool ipu_buttress_auth_done(struct ipu7_device *isp); +int ipu_buttress_get_isys_freq(struct ipu7_device *isp, u32 *freq); +int ipu_buttress_get_psys_freq(struct ipu7_device *isp, u32 *freq); +int ipu_buttress_start_tsc_sync(struct ipu7_device *isp); +void ipu_buttress_tsc_read(struct ipu7_device *isp, u64 *val); +u64 ipu_buttress_tsc_ticks_to_ns(u64 ticks, const struct ipu7_device *isp); + +irqreturn_t ipu_buttress_isr(int irq, void *isp_ptr); +irqreturn_t ipu_buttress_isr_threaded(int irq, void *isp_ptr); +int ipu_buttress_init(struct ipu7_device *isp); +void ipu_buttress_exit(struct ipu7_device *isp); +void ipu_buttress_csi_port_config(struct ipu7_device *isp, + u32 legacy, u32 combo); +void ipu_buttress_restore(struct ipu7_device *isp); +void ipu_buttress_wakeup_is_uc(const struct ipu7_device *isp); +void ipu_buttress_wakeup_ps_uc(const struct ipu7_device *isp); +#endif /* IPU7_BUTTRESS_H */ diff --git a/drivers/staging/media/ipu7/ipu7-cpd.c b/drivers/staging/media/ipu7/ipu7-cpd.c new file mode 100644 index 000000000000..4f49fb57eae4 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-cpd.c @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2015 - 2025 Intel Corporation + */ + +#include <linux/device.h> +#include <linux/export.h> +#include <linux/gfp_types.h> +#include <linux/pci.h> +#include <linux/sizes.h> +#include <linux/slab.h> +#include <linux/types.h> + +#include "ipu7.h" +#include "ipu7-cpd.h" + +/* $CPD */ +#define CPD_HDR_MARK 0x44504324 + +/* Maximum size is 4K DWORDs or 16KB */ +#define MAX_MANIFEST_SIZE (SZ_4K * sizeof(u32)) + +#define CPD_MANIFEST_IDX 0 +#define CPD_BINARY_START_IDX 1U +#define CPD_METADATA_START_IDX 2U +#define CPD_BINARY_NUM 2U /* ISYS + PSYS */ +/* + * Entries include: + * 1 manifest entry. + * 1 metadata entry for each sub system(ISYS and PSYS). + * 1 binary entry for each sub system(ISYS and PSYS). + */ +#define CPD_ENTRY_NUM (CPD_BINARY_NUM * 2U + 1U) + +#define CPD_METADATA_ATTR 0xa +#define CPD_METADATA_IPL 0x1c +#define ONLINE_METADATA_SIZE 128U +#define ONLINE_METADATA_LINES 6U + +struct ipu7_cpd_hdr { + u32 hdr_mark; + u32 ent_cnt; + u8 hdr_ver; + u8 ent_ver; + u8 hdr_len; + u8 rsvd; + u8 partition_name[4]; + u32 crc32; +} __packed; + +struct ipu7_cpd_ent { + u8 name[12]; + u32 offset; + u32 len; + u8 rsvd[4]; +} __packed; + +struct ipu7_cpd_metadata_hdr { + u32 type; + u32 len; +} __packed; + +struct ipu7_cpd_metadata_attr { + struct ipu7_cpd_metadata_hdr hdr; + u8 compression_type; + u8 encryption_type; + u8 rsvd[2]; + u32 uncompressed_size; + u32 compressed_size; + u32 module_id; + u8 hash[48]; +} __packed; + +struct ipu7_cpd_metadata_ipl { + struct ipu7_cpd_metadata_hdr hdr; + u32 param[4]; + u8 rsvd[8]; +} __packed; + +struct ipu7_cpd_metadata { + struct ipu7_cpd_metadata_attr attr; + struct ipu7_cpd_metadata_ipl ipl; +} __packed; + +static inline struct ipu7_cpd_ent *ipu7_cpd_get_entry(const void *cpd, int idx) +{ + const struct ipu7_cpd_hdr *cpd_hdr = cpd; + + return ((struct ipu7_cpd_ent *)((u8 *)cpd + cpd_hdr->hdr_len)) + idx; +} + +#define ipu7_cpd_get_manifest(cpd) ipu7_cpd_get_entry(cpd, 0) + +static struct ipu7_cpd_metadata *ipu7_cpd_get_metadata(const void *cpd, int idx) +{ + struct ipu7_cpd_ent *cpd_ent = + ipu7_cpd_get_entry(cpd, CPD_METADATA_START_IDX + idx * 2); + + return (struct ipu7_cpd_metadata *)((u8 *)cpd + cpd_ent->offset); +} + +static int ipu7_cpd_validate_cpd(struct ipu7_device *isp, + const void *cpd, unsigned long data_size) +{ + const struct ipu7_cpd_hdr *cpd_hdr = cpd; + struct device *dev = &isp->pdev->dev; + struct ipu7_cpd_ent *ent; + unsigned int i; + u8 len; + + len = cpd_hdr->hdr_len; + + /* Ensure cpd hdr is within moduledata */ + if (data_size < len) { + dev_err(dev, "Invalid CPD moduledata size\n"); + return -EINVAL; + } + + /* Check for CPD file marker */ + if (cpd_hdr->hdr_mark != CPD_HDR_MARK) { + dev_err(dev, "Invalid CPD header marker\n"); + return -EINVAL; + } + + /* Sanity check for CPD entry header */ + if (cpd_hdr->ent_cnt != CPD_ENTRY_NUM) { + dev_err(dev, "Invalid CPD entry number %d\n", + cpd_hdr->ent_cnt); + return -EINVAL; + } + if ((data_size - len) / sizeof(*ent) < cpd_hdr->ent_cnt) { + dev_err(dev, "Invalid CPD entry headers\n"); + return -EINVAL; + } + + /* Ensure that all entries are within moduledata */ + ent = (struct ipu7_cpd_ent *)(((u8 *)cpd_hdr) + len); + for (i = 0; i < cpd_hdr->ent_cnt; i++) { + if (data_size < ent->offset || + data_size - ent->offset < ent->len) { + dev_err(dev, "Invalid CPD entry %d\n", i); + return -EINVAL; + } + ent++; + } + + return 0; +} + +static int ipu7_cpd_validate_metadata(struct ipu7_device *isp, + const void *cpd, int idx) +{ + const struct ipu7_cpd_ent *cpd_ent = + ipu7_cpd_get_entry(cpd, CPD_METADATA_START_IDX + idx * 2); + const struct ipu7_cpd_metadata *metadata = + ipu7_cpd_get_metadata(cpd, idx); + struct device *dev = &isp->pdev->dev; + + /* Sanity check for metadata size */ + if (cpd_ent->len != sizeof(struct ipu7_cpd_metadata)) { + dev_err(dev, "Invalid metadata size\n"); + return -EINVAL; + } + + /* Validate type and length of metadata sections */ + if (metadata->attr.hdr.type != CPD_METADATA_ATTR) { + dev_err(dev, "Invalid metadata attr type (%d)\n", + metadata->attr.hdr.type); + return -EINVAL; + } + if (metadata->attr.hdr.len != sizeof(struct ipu7_cpd_metadata_attr)) { + dev_err(dev, "Invalid metadata attr size (%d)\n", + metadata->attr.hdr.len); + return -EINVAL; + } + if (metadata->ipl.hdr.type != CPD_METADATA_IPL) { + dev_err(dev, "Invalid metadata ipl type (%d)\n", + metadata->ipl.hdr.type); + return -EINVAL; + } + if (metadata->ipl.hdr.len != sizeof(struct ipu7_cpd_metadata_ipl)) { + dev_err(dev, "Invalid metadata ipl size (%d)\n", + metadata->ipl.hdr.len); + return -EINVAL; + } + + return 0; +} + +int ipu7_cpd_validate_cpd_file(struct ipu7_device *isp, const void *cpd_file, + unsigned long cpd_file_size) +{ + struct device *dev = &isp->pdev->dev; + struct ipu7_cpd_ent *ent; + unsigned int i; + int ret; + char *buf; + + ret = ipu7_cpd_validate_cpd(isp, cpd_file, cpd_file_size); + if (ret) { + dev_err(dev, "Invalid CPD in file\n"); + return -EINVAL; + } + + /* Sanity check for manifest size */ + ent = ipu7_cpd_get_manifest(cpd_file); + if (ent->len > MAX_MANIFEST_SIZE) { + dev_err(dev, "Invalid manifest size\n"); + return -EINVAL; + } + + /* Validate metadata */ + for (i = 0; i < CPD_BINARY_NUM; i++) { + ret = ipu7_cpd_validate_metadata(isp, cpd_file, i); + if (ret) { + dev_err(dev, "Invalid metadata%d\n", i); + return ret; + } + } + + /* Get fw binary version. */ + buf = kmalloc(ONLINE_METADATA_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + for (i = 0; i < CPD_BINARY_NUM; i++) { + char *lines[ONLINE_METADATA_LINES]; + char *info = buf; + unsigned int l; + + ent = ipu7_cpd_get_entry(cpd_file, + CPD_BINARY_START_IDX + i * 2U); + memcpy(info, (u8 *)cpd_file + ent->offset + ent->len - + ONLINE_METADATA_SIZE, ONLINE_METADATA_SIZE); + for (l = 0; l < ONLINE_METADATA_LINES; l++) { + lines[l] = strsep((char **)&info, "\n"); + if (!lines[l]) + break; + } + if (l < ONLINE_METADATA_LINES) { + dev_err(dev, "Failed to parse fw binary%d info.\n", i); + continue; + } + dev_info(dev, "FW binary%d info:\n", i); + dev_info(dev, "Name: %s\n", lines[1]); + dev_info(dev, "Version: %s\n", lines[2]); + dev_info(dev, "Timestamp: %s\n", lines[3]); + dev_info(dev, "Commit: %s\n", lines[4]); + } + kfree(buf); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ipu7_cpd_validate_cpd_file, "INTEL_IPU7"); + +int ipu7_cpd_copy_binary(const void *cpd, const char *name, + void *code_region, u32 *entry) +{ + unsigned int i; + + for (i = 0; i < CPD_BINARY_NUM; i++) { + const struct ipu7_cpd_ent *binary = + ipu7_cpd_get_entry(cpd, CPD_BINARY_START_IDX + i * 2U); + const struct ipu7_cpd_metadata *metadata = + ipu7_cpd_get_metadata(cpd, i); + + if (!strncmp(binary->name, name, sizeof(binary->name))) { + memcpy(code_region + metadata->ipl.param[0], + cpd + binary->offset, binary->len); + *entry = metadata->ipl.param[2]; + return 0; + } + } + + return -ENOENT; +} +EXPORT_SYMBOL_NS_GPL(ipu7_cpd_copy_binary, "INTEL_IPU7"); diff --git a/drivers/staging/media/ipu7/ipu7-cpd.h b/drivers/staging/media/ipu7/ipu7-cpd.h new file mode 100644 index 000000000000..b4178848c6b9 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-cpd.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2015 - 2025 Intel Corporation + */ + +#ifndef IPU7_CPD_H +#define IPU7_CPD_H + +struct ipu7_device; + +int ipu7_cpd_validate_cpd_file(struct ipu7_device *isp, + const void *cpd_file, + unsigned long cpd_file_size); +int ipu7_cpd_copy_binary(const void *cpd, const char *name, + void *code_region, u32 *entry); +#endif /* IPU7_CPD_H */ diff --git a/drivers/staging/media/ipu7/ipu7-dma.c b/drivers/staging/media/ipu7/ipu7-dma.c new file mode 100644 index 000000000000..a118b41b2f34 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-dma.c @@ -0,0 +1,477 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <linux/cacheflush.h> +#include <linux/dma-mapping.h> +#include <linux/iova.h> +#include <linux/list.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/scatterlist.h> +#include <linux/slab.h> +#include <linux/types.h> + +#include "ipu7.h" +#include "ipu7-bus.h" +#include "ipu7-dma.h" +#include "ipu7-mmu.h" + +struct vm_info { + struct list_head list; + struct page **pages; + dma_addr_t ipu7_iova; + void *vaddr; + unsigned long size; +}; + +static struct vm_info *get_vm_info(struct ipu7_mmu *mmu, dma_addr_t iova) +{ + struct vm_info *info, *save; + + list_for_each_entry_safe(info, save, &mmu->vma_list, list) { + if (iova >= info->ipu7_iova && + iova < (info->ipu7_iova + info->size)) + return info; + } + + return NULL; +} + +static void __clear_buffer(struct page *page, size_t size, unsigned long attrs) +{ + void *ptr; + + if (!page) + return; + /* + * Ensure that the allocated pages are zeroed, and that any data + * lurking in the kernel direct-mapped region is invalidated. + */ + ptr = page_address(page); + memset(ptr, 0, size); + if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) + clflush_cache_range(ptr, size); +} + +static struct page **__alloc_buffer(size_t size, gfp_t gfp, unsigned long attrs) +{ + unsigned int count = PHYS_PFN(size); + unsigned int array_size = count * sizeof(struct page *); + struct page **pages; + int i = 0; + + pages = kvzalloc(array_size, GFP_KERNEL); + if (!pages) + return NULL; + + gfp |= __GFP_NOWARN; + + while (count) { + int j, order = __fls(count); + + pages[i] = alloc_pages(gfp, order); + while (!pages[i] && order) + pages[i] = alloc_pages(gfp, --order); + if (!pages[i]) + goto error; + + if (order) { + split_page(pages[i], order); + j = 1U << order; + while (j--) + pages[i + j] = pages[i] + j; + } + + __clear_buffer(pages[i], PAGE_SIZE << order, attrs); + i += 1U << order; + count -= 1U << order; + } + + return pages; +error: + while (i--) + if (pages[i]) + __free_pages(pages[i], 0); + kvfree(pages); + return NULL; +} + +static void __free_buffer(struct page **pages, size_t size, unsigned long attrs) +{ + unsigned int count = PHYS_PFN(size); + unsigned int i; + + for (i = 0; i < count && pages[i]; i++) { + __clear_buffer(pages[i], PAGE_SIZE, attrs); + __free_pages(pages[i], 0); + } + + kvfree(pages); +} + +void ipu7_dma_sync_single(struct ipu7_bus_device *sys, dma_addr_t dma_handle, + size_t size) +{ + void *vaddr; + u32 offset; + struct vm_info *info; + struct ipu7_mmu *mmu = sys->mmu; + + info = get_vm_info(mmu, dma_handle); + if (WARN_ON(!info)) + return; + + offset = dma_handle - info->ipu7_iova; + if (WARN_ON(size > (info->size - offset))) + return; + + vaddr = info->vaddr + offset; + clflush_cache_range(vaddr, size); +} +EXPORT_SYMBOL_NS_GPL(ipu7_dma_sync_single, "INTEL_IPU7"); + +void ipu7_dma_sync_sg(struct ipu7_bus_device *sys, struct scatterlist *sglist, + unsigned int nents) +{ + struct scatterlist *sg; + int i; + + for_each_sg(sglist, sg, nents, i) + clflush_cache_range(sg_virt(sg), sg->length); +} +EXPORT_SYMBOL_NS_GPL(ipu7_dma_sync_sg, "INTEL_IPU7"); + +void ipu7_dma_sync_sgtable(struct ipu7_bus_device *sys, struct sg_table *sgt) +{ + ipu7_dma_sync_sg(sys, sgt->sgl, sgt->orig_nents); +} +EXPORT_SYMBOL_NS_GPL(ipu7_dma_sync_sgtable, "INTEL_IPU7"); + +void *ipu7_dma_alloc(struct ipu7_bus_device *sys, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + unsigned long attrs) +{ + struct device *dev = &sys->auxdev.dev; + struct pci_dev *pdev = sys->isp->pdev; + dma_addr_t pci_dma_addr, ipu7_iova; + struct ipu7_mmu *mmu = sys->mmu; + struct vm_info *info; + unsigned long count; + struct page **pages; + struct iova *iova; + unsigned int i; + int ret; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return NULL; + + size = PAGE_ALIGN(size); + count = PHYS_PFN(size); + + iova = alloc_iova(&mmu->dmap->iovad, count, + PHYS_PFN(mmu->dmap->mmu_info->aperture_end), 0); + if (!iova) + goto out_kfree; + + pages = __alloc_buffer(size, gfp, attrs); + if (!pages) + goto out_free_iova; + + dev_dbg(dev, "dma_alloc: size %zu iova low pfn %lu, high pfn %lu\n", + size, iova->pfn_lo, iova->pfn_hi); + for (i = 0; iova->pfn_lo + i <= iova->pfn_hi; i++) { + pci_dma_addr = dma_map_page_attrs(&pdev->dev, pages[i], 0, + PAGE_SIZE, DMA_BIDIRECTIONAL, + attrs); + dev_dbg(dev, "dma_alloc: mapped pci_dma_addr %pad\n", + &pci_dma_addr); + if (dma_mapping_error(&pdev->dev, pci_dma_addr)) { + dev_err(dev, "pci_dma_mapping for page[%d] failed", i); + goto out_unmap; + } + + ret = ipu7_mmu_map(mmu->dmap->mmu_info, + PFN_PHYS(iova->pfn_lo + i), pci_dma_addr, + PAGE_SIZE); + if (ret) { + dev_err(dev, "ipu7_mmu_map for pci_dma[%d] %pad failed", + i, &pci_dma_addr); + dma_unmap_page_attrs(&pdev->dev, pci_dma_addr, + PAGE_SIZE, DMA_BIDIRECTIONAL, + attrs); + goto out_unmap; + } + } + + info->vaddr = vmap(pages, count, VM_USERMAP, PAGE_KERNEL); + if (!info->vaddr) + goto out_unmap; + + *dma_handle = PFN_PHYS(iova->pfn_lo); + + info->pages = pages; + info->ipu7_iova = *dma_handle; + info->size = size; + list_add(&info->list, &mmu->vma_list); + + return info->vaddr; + +out_unmap: + while (i--) { + ipu7_iova = PFN_PHYS(iova->pfn_lo + i); + pci_dma_addr = ipu7_mmu_iova_to_phys(mmu->dmap->mmu_info, + ipu7_iova); + dma_unmap_page_attrs(&pdev->dev, pci_dma_addr, PAGE_SIZE, + DMA_BIDIRECTIONAL, attrs); + + ipu7_mmu_unmap(mmu->dmap->mmu_info, ipu7_iova, PAGE_SIZE); + } + + __free_buffer(pages, size, attrs); + +out_free_iova: + __free_iova(&mmu->dmap->iovad, iova); +out_kfree: + kfree(info); + + return NULL; +} +EXPORT_SYMBOL_NS_GPL(ipu7_dma_alloc, "INTEL_IPU7"); + +void ipu7_dma_free(struct ipu7_bus_device *sys, size_t size, void *vaddr, + dma_addr_t dma_handle, unsigned long attrs) +{ + struct ipu7_mmu *mmu = sys->mmu; + struct pci_dev *pdev = sys->isp->pdev; + struct iova *iova = find_iova(&mmu->dmap->iovad, PHYS_PFN(dma_handle)); + dma_addr_t pci_dma_addr, ipu7_iova; + struct vm_info *info; + struct page **pages; + unsigned int i; + + if (WARN_ON(!iova)) + return; + + info = get_vm_info(mmu, dma_handle); + if (WARN_ON(!info)) + return; + + if (WARN_ON(!info->vaddr)) + return; + + if (WARN_ON(!info->pages)) + return; + + list_del(&info->list); + + size = PAGE_ALIGN(size); + + pages = info->pages; + + vunmap(vaddr); + + for (i = 0; i < PHYS_PFN(size); i++) { + ipu7_iova = PFN_PHYS(iova->pfn_lo + i); + pci_dma_addr = ipu7_mmu_iova_to_phys(mmu->dmap->mmu_info, + ipu7_iova); + dma_unmap_page_attrs(&pdev->dev, pci_dma_addr, PAGE_SIZE, + DMA_BIDIRECTIONAL, attrs); + } + + ipu7_mmu_unmap(mmu->dmap->mmu_info, PFN_PHYS(iova->pfn_lo), + PFN_PHYS(iova_size(iova))); + + __free_buffer(pages, size, attrs); + + mmu->tlb_invalidate(mmu); + + __free_iova(&mmu->dmap->iovad, iova); + + kfree(info); +} +EXPORT_SYMBOL_NS_GPL(ipu7_dma_free, "INTEL_IPU7"); + +int ipu7_dma_mmap(struct ipu7_bus_device *sys, struct vm_area_struct *vma, + void *addr, dma_addr_t iova, size_t size, + unsigned long attrs) +{ + struct ipu7_mmu *mmu = sys->mmu; + size_t count = PFN_UP(size); + struct vm_info *info; + size_t i; + int ret; + + info = get_vm_info(mmu, iova); + if (!info) + return -EFAULT; + + if (!info->vaddr) + return -EFAULT; + + if (vma->vm_start & ~PAGE_MASK) + return -EINVAL; + + if (size > info->size) + return -EFAULT; + + for (i = 0; i < count; i++) { + ret = vm_insert_page(vma, vma->vm_start + PFN_PHYS(i), + info->pages[i]); + if (ret < 0) + return ret; + } + + return 0; +} + +void ipu7_dma_unmap_sg(struct ipu7_bus_device *sys, struct scatterlist *sglist, + int nents, enum dma_data_direction dir, + unsigned long attrs) +{ + struct device *dev = &sys->auxdev.dev; + struct ipu7_mmu *mmu = sys->mmu; + struct iova *iova = find_iova(&mmu->dmap->iovad, + PHYS_PFN(sg_dma_address(sglist))); + struct scatterlist *sg; + dma_addr_t pci_dma_addr; + unsigned int i; + + if (!nents) + return; + + if (WARN_ON(!iova)) + return; + + /* + * Before IPU7 mmu unmap, return the pci dma address back to sg + * assume the nents is less than orig_nents as the least granule + * is 1 SZ_4K page + */ + dev_dbg(dev, "trying to unmap concatenated %u ents\n", nents); + for_each_sg(sglist, sg, nents, i) { + dev_dbg(dev, "unmap sg[%d] %pad size %u\n", i, + &sg_dma_address(sg), sg_dma_len(sg)); + pci_dma_addr = ipu7_mmu_iova_to_phys(mmu->dmap->mmu_info, + sg_dma_address(sg)); + dev_dbg(dev, "return pci_dma_addr %pad back to sg[%d]\n", + &pci_dma_addr, i); + sg_dma_address(sg) = pci_dma_addr; + } + + dev_dbg(dev, "ipu7_mmu_unmap low pfn %lu high pfn %lu\n", + iova->pfn_lo, iova->pfn_hi); + ipu7_mmu_unmap(mmu->dmap->mmu_info, PFN_PHYS(iova->pfn_lo), + PFN_PHYS(iova_size(iova))); + + mmu->tlb_invalidate(mmu); + __free_iova(&mmu->dmap->iovad, iova); +} +EXPORT_SYMBOL_NS_GPL(ipu7_dma_unmap_sg, "INTEL_IPU7"); + +int ipu7_dma_map_sg(struct ipu7_bus_device *sys, struct scatterlist *sglist, + int nents, enum dma_data_direction dir, + unsigned long attrs) +{ + struct device *dev = &sys->auxdev.dev; + struct ipu7_mmu *mmu = sys->mmu; + struct scatterlist *sg; + struct iova *iova; + size_t npages = 0; + unsigned long iova_addr; + int i; + + for_each_sg(sglist, sg, nents, i) { + if (sg->offset) { + dev_err(dev, "Unsupported non-zero sg[%d].offset %x\n", + i, sg->offset); + return -EFAULT; + } + } + + for_each_sg(sglist, sg, nents, i) + npages += PFN_UP(sg_dma_len(sg)); + + dev_dbg(dev, "dmamap trying to map %d ents %zu pages\n", + nents, npages); + + if (attrs & DMA_ATTR_RESERVE_REGION) { + /* + * Reserve iova with size aligned to IPU_FW_CODE_REGION_SIZE. + * Only apply for non-secure mode. + */ + unsigned long lo, hi; + + lo = iova_pfn(&mmu->dmap->iovad, IPU_FW_CODE_REGION_START); + hi = iova_pfn(&mmu->dmap->iovad, IPU_FW_CODE_REGION_END) - 1U; + iova = reserve_iova(&mmu->dmap->iovad, lo, hi); + if (!iova) { + dev_err(dev, "Reserve iova[%lx:%lx] failed.\n", lo, hi); + return -ENOMEM; + } + dev_dbg(dev, "iova[%lx:%lx] reserved for FW code.\n", lo, hi); + } else { + iova = alloc_iova(&mmu->dmap->iovad, npages, + PHYS_PFN(mmu->dmap->mmu_info->aperture_end), + 0); + if (!iova) + return 0; + } + + dev_dbg(dev, "dmamap: iova low pfn %lu, high pfn %lu\n", iova->pfn_lo, + iova->pfn_hi); + + iova_addr = iova->pfn_lo; + for_each_sg(sglist, sg, nents, i) { + phys_addr_t iova_pa; + int ret; + + iova_pa = PFN_PHYS(iova_addr); + dev_dbg(dev, "mapping entry %d: iova %pap phy %pap size %d\n", + i, &iova_pa, &sg_dma_address(sg), sg_dma_len(sg)); + + ret = ipu7_mmu_map(mmu->dmap->mmu_info, PFN_PHYS(iova_addr), + sg_dma_address(sg), + PAGE_ALIGN(sg_dma_len(sg))); + if (ret) + goto out_fail; + + sg_dma_address(sg) = PFN_PHYS(iova_addr); + + iova_addr += PFN_UP(sg_dma_len(sg)); + } + + dev_dbg(dev, "dmamap %d ents %zu pages mapped\n", nents, npages); + + return nents; + +out_fail: + ipu7_dma_unmap_sg(sys, sglist, i, dir, attrs); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ipu7_dma_map_sg, "INTEL_IPU7"); + +int ipu7_dma_map_sgtable(struct ipu7_bus_device *sys, struct sg_table *sgt, + enum dma_data_direction dir, unsigned long attrs) +{ + int nents; + + nents = ipu7_dma_map_sg(sys, sgt->sgl, sgt->nents, dir, attrs); + if (nents < 0) + return nents; + + sgt->nents = nents; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ipu7_dma_map_sgtable, "INTEL_IPU7"); + +void ipu7_dma_unmap_sgtable(struct ipu7_bus_device *sys, struct sg_table *sgt, + enum dma_data_direction dir, unsigned long attrs) +{ + ipu7_dma_unmap_sg(sys, sgt->sgl, sgt->nents, dir, attrs); +} +EXPORT_SYMBOL_NS_GPL(ipu7_dma_unmap_sgtable, "INTEL_IPU7"); diff --git a/drivers/staging/media/ipu7/ipu7-dma.h b/drivers/staging/media/ipu7/ipu7-dma.h new file mode 100644 index 000000000000..fe789af5e664 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-dma.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 2013--2025 Intel Corporation */ + +#ifndef IPU7_DMA_H +#define IPU7_DMA_H + +#include <linux/dma-map-ops.h> +#include <linux/dma-mapping.h> +#include <linux/iova.h> +#include <linux/scatterlist.h> +#include <linux/types.h> + +#include "ipu7-bus.h" + +#define DMA_ATTR_RESERVE_REGION BIT(31) +struct ipu7_mmu_info; + +struct ipu7_dma_mapping { + struct ipu7_mmu_info *mmu_info; + struct iova_domain iovad; +}; + +void ipu7_dma_sync_single(struct ipu7_bus_device *sys, dma_addr_t dma_handle, + size_t size); +void ipu7_dma_sync_sg(struct ipu7_bus_device *sys, struct scatterlist *sglist, + unsigned int nents); +void ipu7_dma_sync_sgtable(struct ipu7_bus_device *sys, struct sg_table *sgt); +void *ipu7_dma_alloc(struct ipu7_bus_device *sys, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + unsigned long attrs); +void ipu7_dma_free(struct ipu7_bus_device *sys, size_t size, void *vaddr, + dma_addr_t dma_handle, unsigned long attrs); +int ipu7_dma_mmap(struct ipu7_bus_device *sys, struct vm_area_struct *vma, + void *addr, dma_addr_t iova, size_t size, + unsigned long attrs); +int ipu7_dma_map_sg(struct ipu7_bus_device *sys, struct scatterlist *sglist, + int nents, enum dma_data_direction dir, + unsigned long attrs); +void ipu7_dma_unmap_sg(struct ipu7_bus_device *sys, struct scatterlist *sglist, + int nents, enum dma_data_direction dir, + unsigned long attrs); +int ipu7_dma_map_sgtable(struct ipu7_bus_device *sys, struct sg_table *sgt, + enum dma_data_direction dir, unsigned long attrs); +void ipu7_dma_unmap_sgtable(struct ipu7_bus_device *sys, struct sg_table *sgt, + enum dma_data_direction dir, unsigned long attrs); +#endif /* IPU7_DMA_H */ diff --git a/drivers/staging/media/ipu7/ipu7-fw-isys.c b/drivers/staging/media/ipu7/ipu7-fw-isys.c new file mode 100644 index 000000000000..e4b9c364572b --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-fw-isys.c @@ -0,0 +1,301 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <linux/cacheflush.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/types.h> + +#include "abi/ipu7_fw_insys_config_abi.h" +#include "abi/ipu7_fw_isys_abi.h" + +#include "ipu7.h" +#include "ipu7-boot.h" +#include "ipu7-bus.h" +#include "ipu7-dma.h" +#include "ipu7-fw-isys.h" +#include "ipu7-isys.h" +#include "ipu7-platform-regs.h" +#include "ipu7-syscom.h" + +static const char * const send_msg_types[N_IPU_INSYS_SEND_TYPE] = { + "STREAM_OPEN", + "STREAM_START_AND_CAPTURE", + "STREAM_CAPTURE", + "STREAM_ABORT", + "STREAM_FLUSH", + "STREAM_CLOSE" +}; + +int ipu7_fw_isys_complex_cmd(struct ipu7_isys *isys, + const unsigned int stream_handle, + void *cpu_mapped_buf, + dma_addr_t dma_mapped_buf, + size_t size, u16 send_type) +{ + struct ipu7_syscom_context *ctx = isys->adev->syscom; + struct device *dev = &isys->adev->auxdev.dev; + struct ipu7_insys_send_queue_token *token; + + if (send_type >= N_IPU_INSYS_SEND_TYPE) + return -EINVAL; + + dev_dbg(dev, "send_token: %s\n", send_msg_types[send_type]); + + /* + * Time to flush cache in case we have some payload. Not all messages + * have that + */ + if (cpu_mapped_buf) + clflush_cache_range(cpu_mapped_buf, size); + + token = ipu7_syscom_get_token(ctx, stream_handle + + IPU_INSYS_INPUT_MSG_QUEUE); + if (!token) + return -EBUSY; + + token->addr = dma_mapped_buf; + token->buf_handle = (unsigned long)cpu_mapped_buf; + token->send_type = send_type; + token->stream_id = stream_handle; + token->flag = IPU_INSYS_SEND_QUEUE_TOKEN_FLAG_NONE; + + ipu7_syscom_put_token(ctx, stream_handle + IPU_INSYS_INPUT_MSG_QUEUE); + /* now wakeup FW */ + ipu_buttress_wakeup_is_uc(isys->adev->isp); + + return 0; +} + +int ipu7_fw_isys_simple_cmd(struct ipu7_isys *isys, + const unsigned int stream_handle, u16 send_type) +{ + return ipu7_fw_isys_complex_cmd(isys, stream_handle, NULL, 0, 0, + send_type); +} + +int ipu7_fw_isys_init(struct ipu7_isys *isys) +{ + struct syscom_queue_config *queue_configs; + struct ipu7_bus_device *adev = isys->adev; + struct device *dev = &adev->auxdev.dev; + struct ipu7_insys_config *isys_config; + struct ipu7_syscom_context *syscom; + dma_addr_t isys_config_dma_addr; + unsigned int i, num_queues; + u32 freq; + u8 major; + int ret; + + /* Allocate and init syscom context. */ + syscom = devm_kzalloc(dev, sizeof(struct ipu7_syscom_context), + GFP_KERNEL); + if (!syscom) + return -ENOMEM; + + adev->syscom = syscom; + syscom->num_input_queues = IPU_INSYS_MAX_INPUT_QUEUES; + syscom->num_output_queues = IPU_INSYS_MAX_OUTPUT_QUEUES; + num_queues = syscom->num_input_queues + syscom->num_output_queues; + queue_configs = devm_kzalloc(dev, FW_QUEUE_CONFIG_SIZE(num_queues), + GFP_KERNEL); + if (!queue_configs) { + ipu7_fw_isys_release(isys); + return -ENOMEM; + } + syscom->queue_configs = queue_configs; + queue_configs[IPU_INSYS_OUTPUT_MSG_QUEUE].max_capacity = + IPU_ISYS_SIZE_RECV_QUEUE; + queue_configs[IPU_INSYS_OUTPUT_MSG_QUEUE].token_size_in_bytes = + sizeof(struct ipu7_insys_resp); + queue_configs[IPU_INSYS_OUTPUT_LOG_QUEUE].max_capacity = + IPU_ISYS_SIZE_LOG_QUEUE; + queue_configs[IPU_INSYS_OUTPUT_LOG_QUEUE].token_size_in_bytes = + sizeof(struct ipu7_insys_resp); + queue_configs[IPU_INSYS_OUTPUT_RESERVED_QUEUE].max_capacity = 0; + queue_configs[IPU_INSYS_OUTPUT_RESERVED_QUEUE].token_size_in_bytes = 0; + + queue_configs[IPU_INSYS_INPUT_DEV_QUEUE].max_capacity = + IPU_ISYS_MAX_STREAMS; + queue_configs[IPU_INSYS_INPUT_DEV_QUEUE].token_size_in_bytes = + sizeof(struct ipu7_insys_send_queue_token); + + for (i = IPU_INSYS_INPUT_MSG_QUEUE; i < num_queues; i++) { + queue_configs[i].max_capacity = IPU_ISYS_SIZE_SEND_QUEUE; + queue_configs[i].token_size_in_bytes = + sizeof(struct ipu7_insys_send_queue_token); + } + + /* Allocate ISYS subsys config. */ + isys_config = ipu7_dma_alloc(adev, sizeof(struct ipu7_insys_config), + &isys_config_dma_addr, GFP_KERNEL, 0); + if (!isys_config) { + dev_err(dev, "Failed to allocate isys subsys config.\n"); + ipu7_fw_isys_release(isys); + return -ENOMEM; + } + isys->subsys_config = isys_config; + isys->subsys_config_dma_addr = isys_config_dma_addr; + memset(isys_config, 0, sizeof(struct ipu7_insys_config)); + isys_config->logger_config.use_source_severity = 0; + isys_config->logger_config.use_channels_enable_bitmask = 1; + isys_config->logger_config.channels_enable_bitmask = + LOGGER_CONFIG_CHANNEL_ENABLE_SYSCOM_BITMASK; + isys_config->logger_config.hw_printf_buffer_base_addr = 0U; + isys_config->logger_config.hw_printf_buffer_size_bytes = 0U; + isys_config->wdt_config.wdt_timer1_us = 0; + isys_config->wdt_config.wdt_timer2_us = 0; + ret = ipu_buttress_get_isys_freq(adev->isp, &freq); + if (ret) { + dev_err(dev, "Failed to get ISYS frequency.\n"); + ipu7_fw_isys_release(isys); + return ret; + } + + ipu7_dma_sync_single(adev, isys_config_dma_addr, + sizeof(struct ipu7_insys_config)); + + major = is_ipu8(adev->isp->hw_ver) ? 2U : 1U; + ret = ipu7_boot_init_boot_config(adev, queue_configs, num_queues, + freq, isys_config_dma_addr, major); + if (ret) + ipu7_fw_isys_release(isys); + + return ret; +} + +void ipu7_fw_isys_release(struct ipu7_isys *isys) +{ + struct ipu7_bus_device *adev = isys->adev; + + ipu7_boot_release_boot_config(adev); + if (isys->subsys_config) { + ipu7_dma_free(adev, + sizeof(struct ipu7_insys_config), + isys->subsys_config, + isys->subsys_config_dma_addr, 0); + isys->subsys_config = NULL; + isys->subsys_config_dma_addr = 0; + } +} + +int ipu7_fw_isys_open(struct ipu7_isys *isys) +{ + return ipu7_boot_start_fw(isys->adev); +} + +int ipu7_fw_isys_close(struct ipu7_isys *isys) +{ + return ipu7_boot_stop_fw(isys->adev); +} + +struct ipu7_insys_resp *ipu7_fw_isys_get_resp(struct ipu7_isys *isys) +{ + return (struct ipu7_insys_resp *) + ipu7_syscom_get_token(isys->adev->syscom, + IPU_INSYS_OUTPUT_MSG_QUEUE); +} + +void ipu7_fw_isys_put_resp(struct ipu7_isys *isys) +{ + ipu7_syscom_put_token(isys->adev->syscom, IPU_INSYS_OUTPUT_MSG_QUEUE); +} + +void ipu7_fw_isys_dump_stream_cfg(struct device *dev, + struct ipu7_insys_stream_cfg *cfg) +{ + unsigned int i; + + dev_dbg(dev, "---------------------------\n"); + dev_dbg(dev, "IPU_FW_ISYS_STREAM_CFG_DATA\n"); + + dev_dbg(dev, ".port id %d\n", cfg->port_id); + dev_dbg(dev, ".vc %d\n", cfg->vc); + dev_dbg(dev, ".nof_input_pins = %d\n", cfg->nof_input_pins); + dev_dbg(dev, ".nof_output_pins = %d\n", cfg->nof_output_pins); + dev_dbg(dev, ".stream_msg_map = 0x%x\n", cfg->stream_msg_map); + + for (i = 0; i < cfg->nof_input_pins; i++) { + dev_dbg(dev, ".input_pin[%d]:\n", i); + dev_dbg(dev, "\t.dt = 0x%0x\n", + cfg->input_pins[i].dt); + dev_dbg(dev, "\t.disable_mipi_unpacking = %d\n", + cfg->input_pins[i].disable_mipi_unpacking); + dev_dbg(dev, "\t.dt_rename_mode = %d\n", + cfg->input_pins[i].dt_rename_mode); + dev_dbg(dev, "\t.mapped_dt = 0x%0x\n", + cfg->input_pins[i].mapped_dt); + dev_dbg(dev, "\t.input_res = %d x %d\n", + cfg->input_pins[i].input_res.width, + cfg->input_pins[i].input_res.height); + dev_dbg(dev, "\t.sync_msg_map = 0x%x\n", + cfg->input_pins[i].sync_msg_map); + } + + for (i = 0; i < cfg->nof_output_pins; i++) { + dev_dbg(dev, ".output_pin[%d]:\n", i); + dev_dbg(dev, "\t.input_pin_id = %d\n", + cfg->output_pins[i].input_pin_id); + dev_dbg(dev, "\t.stride = %d\n", cfg->output_pins[i].stride); + dev_dbg(dev, "\t.send_irq = %d\n", + cfg->output_pins[i].send_irq); + dev_dbg(dev, "\t.ft = %d\n", cfg->output_pins[i].ft); + + dev_dbg(dev, "\t.link.buffer_lines = %d\n", + cfg->output_pins[i].link.buffer_lines); + dev_dbg(dev, "\t.link.foreign_key = %d\n", + cfg->output_pins[i].link.foreign_key); + dev_dbg(dev, "\t.link.granularity_pointer_update = %d\n", + cfg->output_pins[i].link.granularity_pointer_update); + dev_dbg(dev, "\t.link.msg_link_streaming_mode = %d\n", + cfg->output_pins[i].link.msg_link_streaming_mode); + dev_dbg(dev, "\t.link.pbk_id = %d\n", + cfg->output_pins[i].link.pbk_id); + dev_dbg(dev, "\t.link.pbk_slot_id = %d\n", + cfg->output_pins[i].link.pbk_slot_id); + dev_dbg(dev, "\t.link.dest = %d\n", + cfg->output_pins[i].link.dest); + dev_dbg(dev, "\t.link.use_sw_managed = %d\n", + cfg->output_pins[i].link.use_sw_managed); + dev_dbg(dev, "\t.link.is_snoop = %d\n", + cfg->output_pins[i].link.is_snoop); + + dev_dbg(dev, "\t.crop.line_top = %d\n", + cfg->output_pins[i].crop.line_top); + dev_dbg(dev, "\t.crop.line_bottom = %d\n", + cfg->output_pins[i].crop.line_bottom); + + dev_dbg(dev, "\t.dpcm_enable = %d\n", + cfg->output_pins[i].dpcm.enable); + dev_dbg(dev, "\t.dpcm.type = %d\n", + cfg->output_pins[i].dpcm.type); + dev_dbg(dev, "\t.dpcm.predictor = %d\n", + cfg->output_pins[i].dpcm.predictor); + } + dev_dbg(dev, "---------------------------\n"); +} + +void ipu7_fw_isys_dump_frame_buff_set(struct device *dev, + struct ipu7_insys_buffset *buf, + unsigned int outputs) +{ + unsigned int i; + + dev_dbg(dev, "--------------------------\n"); + dev_dbg(dev, "IPU_ISYS_BUFF_SET\n"); + dev_dbg(dev, ".capture_msg_map = %d\n", buf->capture_msg_map); + dev_dbg(dev, ".frame_id = %d\n", buf->frame_id); + dev_dbg(dev, ".skip_frame = %d\n", buf->skip_frame); + + for (i = 0; i < outputs; i++) { + dev_dbg(dev, ".output_pin[%d]:\n", i); + dev_dbg(dev, "\t.user_token = %llx\n", + buf->output_pins[i].user_token); + dev_dbg(dev, "\t.addr = 0x%x\n", buf->output_pins[i].addr); + } + dev_dbg(dev, "---------------------------\n"); +} diff --git a/drivers/staging/media/ipu7/ipu7-fw-isys.h b/drivers/staging/media/ipu7/ipu7-fw-isys.h new file mode 100644 index 000000000000..b556feda6b08 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-fw-isys.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_FW_ISYS_H +#define IPU7_FW_ISYS_H + +#include <linux/types.h> + +#include "abi/ipu7_fw_isys_abi.h" + +struct device; +struct ipu7_insys_buffset; +struct ipu7_insys_stream_cfg; +struct ipu7_isys; + +/* From here on type defines not coming from the ISYSAPI interface */ + +int ipu7_fw_isys_init(struct ipu7_isys *isys); +void ipu7_fw_isys_release(struct ipu7_isys *isys); +int ipu7_fw_isys_open(struct ipu7_isys *isys); +int ipu7_fw_isys_close(struct ipu7_isys *isys); + +void ipu7_fw_isys_dump_stream_cfg(struct device *dev, + struct ipu7_insys_stream_cfg *cfg); +void ipu7_fw_isys_dump_frame_buff_set(struct device *dev, + struct ipu7_insys_buffset *buf, + unsigned int outputs); +int ipu7_fw_isys_simple_cmd(struct ipu7_isys *isys, + const unsigned int stream_handle, u16 send_type); +int ipu7_fw_isys_complex_cmd(struct ipu7_isys *isys, + const unsigned int stream_handle, + void *cpu_mapped_buf, + dma_addr_t dma_mapped_buf, + size_t size, u16 send_type); +struct ipu7_insys_resp *ipu7_fw_isys_get_resp(struct ipu7_isys *isys); +void ipu7_fw_isys_put_resp(struct ipu7_isys *isys); +#endif diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c new file mode 100644 index 000000000000..b8c5db7ae300 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c @@ -0,0 +1,1034 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <linux/bitmap.h> +#include <linux/bug.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/iopoll.h> +#include <linux/kernel.h> +#include <linux/types.h> + +#include <media/mipi-csi2.h> +#include <media/v4l2-device.h> + +#include "ipu7.h" +#include "ipu7-bus.h" +#include "ipu7-buttress.h" +#include "ipu7-isys.h" +#include "ipu7-isys-csi2.h" +#include "ipu7-isys-csi2-regs.h" +#include "ipu7-platform-regs.h" +#include "ipu7-isys-csi-phy.h" + +#define PORT_A 0U +#define PORT_B 1U +#define PORT_C 2U +#define PORT_D 3U + +#define N_DATA_IDS 8U +static DECLARE_BITMAP(data_ids, N_DATA_IDS); + +struct ddlcal_counter_ref_s { + u16 min_mbps; + u16 max_mbps; + + u16 ddlcal_counter_ref; +}; + +struct ddlcal_params { + u16 min_mbps; + u16 max_mbps; + u16 oa_lanex_hsrx_cdphy_sel_fast; + u16 ddlcal_max_phase; + u16 phase_bound; + u16 ddlcal_dll_fbk; + u16 ddlcal_ddl_coarse_bank; + u16 fjump_deskew; + u16 min_eye_opening_deskew; +}; + +struct i_thssettle_params { + u16 min_mbps; + u16 max_mbps; + u16 i_thssettle; +}; + + /* lane2 for 4l3t, lane1 for 2l2t */ +struct oa_lane_clk_div_params { + u16 min_mbps; + u16 max_mbps; + u16 oa_lane_hsrx_hs_clk_div; +}; + +struct cdr_fbk_cap_prog_params { + u16 min_mbps; + u16 max_mbps; + u16 val; +}; + +static const struct ddlcal_counter_ref_s table0[] = { + { 1500, 1999, 118 }, + { 2000, 2499, 157 }, + { 2500, 3499, 196 }, + { 3500, 4499, 274 }, + { 4500, 4500, 352 }, + { } +}; + +static const struct ddlcal_params table1[] = { + { 1500, 1587, 0, 143, 167, 17, 3, 4, 29 }, + { 1588, 1687, 0, 135, 167, 15, 3, 4, 27 }, + { 1688, 1799, 0, 127, 135, 15, 2, 4, 26 }, + { 1800, 1928, 0, 119, 135, 13, 2, 3, 24 }, + { 1929, 2076, 0, 111, 135, 13, 2, 3, 23 }, + { 2077, 2249, 0, 103, 135, 11, 2, 3, 21 }, + { 2250, 2454, 0, 95, 103, 11, 1, 3, 19 }, + { 2455, 2699, 0, 87, 103, 9, 1, 3, 18 }, + { 2700, 2999, 0, 79, 103, 9, 1, 2, 16 }, + { 3000, 3229, 0, 71, 71, 7, 1, 2, 15 }, + { 3230, 3599, 1, 87, 103, 9, 1, 3, 18 }, + { 3600, 3999, 1, 79, 103, 9, 1, 2, 16 }, + { 4000, 4499, 1, 71, 103, 7, 1, 2, 15 }, + { 4500, 4500, 1, 63, 71, 7, 0, 2, 13 }, + { } +}; + +static const struct i_thssettle_params table2[] = { + { 80, 124, 24 }, + { 125, 249, 20 }, + { 250, 499, 16 }, + { 500, 749, 14 }, + { 750, 1499, 13 }, + { 1500, 4500, 12 }, + { } +}; + +static const struct oa_lane_clk_div_params table6[] = { + { 80, 159, 0x1 }, + { 160, 319, 0x2 }, + { 320, 639, 0x3 }, + { 640, 1279, 0x4 }, + { 1280, 2560, 0x5 }, + { 2561, 4500, 0x6 }, + { } +}; + +static const struct cdr_fbk_cap_prog_params table7[] = { + { 80, 919, 0 }, + { 920, 1029, 1 }, + { 1030, 1169, 2 }, + { 1170, 1349, 3 }, + { 1350, 1589, 4 }, + { 1590, 1949, 5 }, + { 1950, 2499, 6 }, + { } +}; + +static void dwc_phy_write(struct ipu7_isys *isys, u32 id, u32 addr, u16 data) +{ + void __iomem *isys_base = isys->pdata->base; + void __iomem *base = isys_base + IS_IO_CDPHY_BASE(id); + + dev_dbg(&isys->adev->auxdev.dev, "phy write: reg 0x%zx = data 0x%04x", + base + addr - isys_base, data); + writew(data, base + addr); +} + +static u16 dwc_phy_read(struct ipu7_isys *isys, u32 id, u32 addr) +{ + void __iomem *isys_base = isys->pdata->base; + void __iomem *base = isys_base + IS_IO_CDPHY_BASE(id); + u16 data; + + data = readw(base + addr); + dev_dbg(&isys->adev->auxdev.dev, "phy read: reg 0x%zx = data 0x%04x", + base + addr - isys_base, data); + + return data; +} + +static void dwc_csi_write(struct ipu7_isys *isys, u32 id, u32 addr, u32 data) +{ + void __iomem *isys_base = isys->pdata->base; + void __iomem *base = isys_base + IS_IO_CSI2_HOST_BASE(id); + struct device *dev = &isys->adev->auxdev.dev; + + dev_dbg(dev, "csi write: reg 0x%zx = data 0x%08x", + base + addr - isys_base, data); + writel(data, base + addr); + dev_dbg(dev, "csi read: reg 0x%zx = data 0x%08x", + base + addr - isys_base, readl(base + addr)); +} + +static void gpreg_write(struct ipu7_isys *isys, u32 id, u32 addr, u32 data) +{ + void __iomem *isys_base = isys->pdata->base; + u32 gpreg = isys->pdata->ipdata->csi2.gpreg; + void __iomem *base = isys_base + gpreg + 0x1000 * id; + struct device *dev = &isys->adev->auxdev.dev; + + dev_dbg(dev, "gpreg write: reg 0x%zx = data 0x%08x", + base + addr - isys_base, data); + writel(data, base + addr); + dev_dbg(dev, "gpreg read: reg 0x%zx = data 0x%08x", + base + addr - isys_base, readl(base + addr)); +} + +static u32 dwc_csi_read(struct ipu7_isys *isys, u32 id, u32 addr) +{ + void __iomem *isys_base = isys->pdata->base; + void __iomem *base = isys_base + IS_IO_CSI2_HOST_BASE(id); + u32 data; + + data = readl(base + addr); + dev_dbg(&isys->adev->auxdev.dev, "csi read: reg 0x%zx = data 0x%x", + base + addr - isys_base, data); + + return data; +} + +static void dwc_phy_write_mask(struct ipu7_isys *isys, u32 id, u32 addr, + u16 val, u8 lo, u8 hi) +{ + u32 temp, mask; + + WARN_ON(lo > hi); + WARN_ON(hi > 15); + + mask = ((~0U - (1U << lo) + 1U)) & (~0U >> (31 - hi)); + temp = dwc_phy_read(isys, id, addr); + temp &= ~mask; + temp |= (val << lo) & mask; + dwc_phy_write(isys, id, addr, temp); +} + +static void dwc_csi_write_mask(struct ipu7_isys *isys, u32 id, u32 addr, + u32 val, u8 hi, u8 lo) +{ + u32 temp, mask; + + WARN_ON(lo > hi); + + mask = ((~0U - (1U << lo) + 1U)) & (~0U >> (31 - hi)); + temp = dwc_csi_read(isys, id, addr); + temp &= ~mask; + temp |= (val << lo) & mask; + dwc_csi_write(isys, id, addr, temp); +} + +static void ipu7_isys_csi_ctrl_cfg(struct ipu7_isys_csi2 *csi2) +{ + struct ipu7_isys *isys = csi2->isys; + struct device *dev = &isys->adev->auxdev.dev; + u32 id, lanes, phy_mode; + u32 val; + + id = csi2->port; + lanes = csi2->nlanes; + phy_mode = csi2->phy_mode; + dev_dbg(dev, "csi-%d controller init with %u lanes, phy mode %u", + id, lanes, phy_mode); + + val = dwc_csi_read(isys, id, VERSION); + dev_dbg(dev, "csi-%d controller version = 0x%x", id, val); + + /* num of active data lanes */ + dwc_csi_write(isys, id, N_LANES, lanes - 1); + dwc_csi_write(isys, id, CDPHY_MODE, phy_mode); + dwc_csi_write(isys, id, VC_EXTENSION, 0); + + /* only mask PHY_FATAL and PKT_FATAL interrupts */ + dwc_csi_write(isys, id, INT_MSK_PHY_FATAL, 0xff); + dwc_csi_write(isys, id, INT_MSK_PKT_FATAL, 0x3); + dwc_csi_write(isys, id, INT_MSK_PHY, 0x0); + dwc_csi_write(isys, id, INT_MSK_LINE, 0x0); + dwc_csi_write(isys, id, INT_MSK_BNDRY_FRAME_FATAL, 0x0); + dwc_csi_write(isys, id, INT_MSK_SEQ_FRAME_FATAL, 0x0); + dwc_csi_write(isys, id, INT_MSK_CRC_FRAME_FATAL, 0x0); + dwc_csi_write(isys, id, INT_MSK_PLD_CRC_FATAL, 0x0); + dwc_csi_write(isys, id, INT_MSK_DATA_ID, 0x0); + dwc_csi_write(isys, id, INT_MSK_ECC_CORRECTED, 0x0); +} + +static void ipu7_isys_csi_phy_reset(struct ipu7_isys *isys, u32 id) +{ + dwc_csi_write(isys, id, PHY_SHUTDOWNZ, 0); + dwc_csi_write(isys, id, DPHY_RSTZ, 0); + dwc_csi_write(isys, id, CSI2_RESETN, 0); + gpreg_write(isys, id, PHY_RESET, 0); + gpreg_write(isys, id, PHY_SHUTDOWN, 0); +} + +/* 8 Data ID monitors, each Data ID is composed by pair of VC and data type */ +static int __dids_config(struct ipu7_isys_csi2 *csi2, u32 id, u8 vc, u8 dt) +{ + struct ipu7_isys *isys = csi2->isys; + u32 reg, n; + u8 lo, hi; + int ret; + + dev_dbg(&isys->adev->auxdev.dev, "config CSI-%u with vc:%u dt:0x%02x\n", + id, vc, dt); + + dwc_csi_write(isys, id, VC_EXTENSION, 0x0); + n = find_first_zero_bit(data_ids, N_DATA_IDS); + if (n == N_DATA_IDS) + return -ENOSPC; + + ret = test_and_set_bit(n, data_ids); + if (ret) + return -EBUSY; + + reg = n < 4 ? DATA_IDS_VC_1 : DATA_IDS_VC_2; + lo = (n % 4) * 8; + hi = lo + 4; + dwc_csi_write_mask(isys, id, reg, vc & GENMASK(4, 0), hi, lo); + + reg = n < 4 ? DATA_IDS_1 : DATA_IDS_2; + lo = (n % 4) * 8; + hi = lo + 5; + dwc_csi_write_mask(isys, id, reg, dt & GENMASK(5, 0), hi, lo); + + return 0; +} + +static int ipu7_isys_csi_ctrl_dids_config(struct ipu7_isys_csi2 *csi2, u32 id) +{ + struct v4l2_mbus_frame_desc_entry *desc_entry = NULL; + struct device *dev = &csi2->isys->adev->auxdev.dev; + struct v4l2_mbus_frame_desc desc; + struct v4l2_subdev *ext_sd; + struct media_pad *pad; + unsigned int i; + int ret; + + pad = media_entity_remote_source_pad_unique(&csi2->asd.sd.entity); + if (IS_ERR(pad)) { + dev_warn(dev, "can't get remote source pad of %s (%ld)\n", + csi2->asd.sd.name, PTR_ERR(pad)); + return PTR_ERR(pad); + } + + ext_sd = media_entity_to_v4l2_subdev(pad->entity); + if (WARN(!ext_sd, "Failed to get subdev for entity %s\n", + pad->entity->name)) + return -ENODEV; + + ret = v4l2_subdev_call(ext_sd, pad, get_frame_desc, pad->index, &desc); + if (ret) + return ret; + + if (desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) { + dev_warn(dev, "Unsupported frame descriptor type\n"); + return -EINVAL; + } + + for (i = 0; i < desc.num_entries; i++) { + desc_entry = &desc.entry[i]; + if (desc_entry->bus.csi2.vc < IPU7_NR_OF_CSI2_VC) { + ret = __dids_config(csi2, id, desc_entry->bus.csi2.vc, + desc_entry->bus.csi2.dt); + if (ret) + return ret; + } + } + + return 0; +} + +#define CDPHY_TIMEOUT 5000000U +static int ipu7_isys_phy_ready(struct ipu7_isys *isys, u32 id) +{ + void __iomem *isys_base = isys->pdata->base; + u32 gpreg_offset = isys->pdata->ipdata->csi2.gpreg; + void __iomem *gpreg = isys_base + gpreg_offset + 0x1000 * id; + struct device *dev = &isys->adev->auxdev.dev; + unsigned int i; + u32 phy_ready; + u32 reg, rext; + int ret; + + dev_dbg(dev, "waiting phy ready...\n"); + ret = readl_poll_timeout(gpreg + PHY_READY, phy_ready, + phy_ready & BIT(0) && phy_ready != ~0U, + 100, CDPHY_TIMEOUT); + dev_dbg(dev, "phy %u ready = 0x%08x\n", id, readl(gpreg + PHY_READY)); + dev_dbg(dev, "csi %u PHY_RX = 0x%08x\n", id, + dwc_csi_read(isys, id, PHY_RX)); + dev_dbg(dev, "csi %u PHY_STOPSTATE = 0x%08x\n", id, + dwc_csi_read(isys, id, PHY_STOPSTATE)); + dev_dbg(dev, "csi %u PHY_CAL = 0x%08x\n", id, + dwc_csi_read(isys, id, PHY_CAL)); + for (i = 0; i < 4U; i++) { + reg = CORE_DIG_DLANE_0_R_HS_RX_0 + (i * 0x400U); + dev_dbg(dev, "phy %u DLANE%u skewcal = 0x%04x\n", + id, i, dwc_phy_read(isys, id, reg)); + } + dev_dbg(dev, "phy %u DDLCAL = 0x%04x\n", id, + dwc_phy_read(isys, id, PPI_CALIBCTRL_R_COMMON_CALIBCTRL_2_5)); + dev_dbg(dev, "phy %u TERMCAL = 0x%04x\n", id, + dwc_phy_read(isys, id, PPI_R_TERMCAL_DEBUG_0)); + dev_dbg(dev, "phy %u LPDCOCAL = 0x%04x\n", id, + dwc_phy_read(isys, id, PPI_R_LPDCOCAL_DEBUG_RB)); + dev_dbg(dev, "phy %u HSDCOCAL = 0x%04x\n", id, + dwc_phy_read(isys, id, PPI_R_HSDCOCAL_DEBUG_RB)); + dev_dbg(dev, "phy %u LPDCOCAL_VT = 0x%04x\n", id, + dwc_phy_read(isys, id, PPI_R_LPDCOCAL_DEBUG_VT)); + + if (!ret) { + if (id) { + dev_dbg(dev, "ignore phy %u rext\n", id); + return 0; + } + + rext = dwc_phy_read(isys, id, + CORE_DIG_IOCTRL_R_AFE_CB_CTRL_2_15) & 0xfU; + dev_dbg(dev, "phy %u rext value = %u\n", id, rext); + isys->phy_rext_cal = (rext ? rext : 5); + + return 0; + } + + dev_err(dev, "wait phy ready timeout!\n"); + + return ret; +} + +static int lookup_table1(u64 mbps) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(table1); i++) { + if (mbps >= table1[i].min_mbps && mbps <= table1[i].max_mbps) + return i; + } + + return -ENXIO; +} + +static const u16 deskew_fine_mem[] = { + 0x0404, 0x040c, 0x0414, 0x041c, + 0x0423, 0x0429, 0x0430, 0x043a, + 0x0445, 0x044a, 0x0450, 0x045a, + 0x0465, 0x0469, 0x0472, 0x047a, + 0x0485, 0x0489, 0x0490, 0x049a, + 0x04a4, 0x04ac, 0x04b4, 0x04bc, + 0x04c4, 0x04cc, 0x04d4, 0x04dc, + 0x04e4, 0x04ec, 0x04f4, 0x04fc, + 0x0504, 0x050c, 0x0514, 0x051c, + 0x0523, 0x0529, 0x0530, 0x053a, + 0x0545, 0x054a, 0x0550, 0x055a, + 0x0565, 0x0569, 0x0572, 0x057a, + 0x0585, 0x0589, 0x0590, 0x059a, + 0x05a4, 0x05ac, 0x05b4, 0x05bc, + 0x05c4, 0x05cc, 0x05d4, 0x05dc, + 0x05e4, 0x05ec, 0x05f4, 0x05fc, + 0x0604, 0x060c, 0x0614, 0x061c, + 0x0623, 0x0629, 0x0632, 0x063a, + 0x0645, 0x064a, 0x0650, 0x065a, + 0x0665, 0x0669, 0x0672, 0x067a, + 0x0685, 0x0689, 0x0690, 0x069a, + 0x06a4, 0x06ac, 0x06b4, 0x06bc, + 0x06c4, 0x06cc, 0x06d4, 0x06dc, + 0x06e4, 0x06ec, 0x06f4, 0x06fc, + 0x0704, 0x070c, 0x0714, 0x071c, + 0x0723, 0x072a, 0x0730, 0x073a, + 0x0745, 0x074a, 0x0750, 0x075a, + 0x0765, 0x0769, 0x0772, 0x077a, + 0x0785, 0x0789, 0x0790, 0x079a, + 0x07a4, 0x07ac, 0x07b4, 0x07bc, + 0x07c4, 0x07cc, 0x07d4, 0x07dc, + 0x07e4, 0x07ec, 0x07f4, 0x07fc, +}; + +static void ipu7_isys_dphy_config(struct ipu7_isys *isys, u8 id, u8 lanes, + bool aggregation, u64 mbps) +{ + u16 hsrxval0 = 0; + u16 hsrxval1 = 0; + u16 hsrxval2 = 0; + int index; + u16 reg; + u16 val; + u32 i; + + dwc_phy_write_mask(isys, id, CORE_DIG_RW_COMMON_7, 0, 0, 9); + if (mbps > 1500) + dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_DPHY_7, + 40, 0, 7); + else + dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_DPHY_7, + 104, 0, 7); + + dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_DPHY_8, 80, 0, 7); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_0, 191, 0, 9); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_7, 34, 7, 12); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_1, 38, 8, 15); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_2, 4, 12, 15); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_2, 2, 10, 11); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_2, 1, 8, 8); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_2, 38, 0, 7); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_2, 1, 9, 9); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_4, 10, 0, 9); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_6, 20, 0, 9); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_7, 19, 0, 6); + + for (i = 0; i < ARRAY_SIZE(table0); i++) { + if (mbps >= table0[i].min_mbps && mbps <= table0[i].max_mbps) { + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_3, + table0[i].ddlcal_counter_ref, + 0, 9); + break; + } + } + + index = lookup_table1(mbps); + if (index >= 0) { + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_1, + table1[index].phase_bound, 0, 7); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_5, + table1[index].ddlcal_dll_fbk, 4, 9); + dwc_phy_write_mask(isys, id, PPI_RW_DDLCAL_CFG_5, + table1[index].ddlcal_ddl_coarse_bank, 0, 3); + + reg = CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_8; + val = table1[index].oa_lanex_hsrx_cdphy_sel_fast; + for (i = 0; i < lanes + 1; i++) + dwc_phy_write_mask(isys, id, reg + (i * 0x400), val, + 12, 12); + } + + reg = CORE_DIG_DLANE_0_RW_LP_0; + for (i = 0; i < lanes; i++) + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 6, 8, 11); + + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_2, + 0, 0, 0); + if (!is_ipu7(isys->adev->isp->hw_ver) || + id == PORT_B || id == PORT_C) { + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_2, + 1, 0, 0); + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_2, + 0, 0, 0); + } else { + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_2, + 0, 0, 0); + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_2, + 1, 0, 0); + } + + if (lanes == 4 && is_ipu7(isys->adev->isp->hw_ver)) { + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_2, + 0, 0, 0); + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_2, + 0, 0, 0); + } + + dwc_phy_write_mask(isys, id, CORE_DIG_RW_COMMON_6, 1, 0, 2); + dwc_phy_write_mask(isys, id, CORE_DIG_RW_COMMON_6, 1, 3, 5); + + reg = CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_12; + val = (mbps > 1500) ? 0 : 1; + for (i = 0; i < lanes + 1; i++) { + dwc_phy_write_mask(isys, id, reg + (i * 0x400), val, 1, 1); + dwc_phy_write_mask(isys, id, reg + (i * 0x400), !val, 3, 3); + } + + reg = CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_13; + val = (mbps > 1500) ? 0 : 1; + for (i = 0; i < lanes + 1; i++) { + dwc_phy_write_mask(isys, id, reg + (i * 0x400), val, 1, 1); + dwc_phy_write_mask(isys, id, reg + (i * 0x400), val, 3, 3); + } + + if (!is_ipu7(isys->adev->isp->hw_ver) || id == PORT_B || id == PORT_C) + reg = CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_9; + else + reg = CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_9; + + for (i = 0; i < ARRAY_SIZE(table6); i++) { + if (mbps >= table6[i].min_mbps && mbps <= table6[i].max_mbps) { + dwc_phy_write_mask(isys, id, reg, + table6[i].oa_lane_hsrx_hs_clk_div, + 5, 7); + break; + } + } + + if (aggregation) { + dwc_phy_write_mask(isys, id, CORE_DIG_RW_COMMON_0, 1, + 1, 1); + + reg = CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_15; + dwc_phy_write_mask(isys, id, reg, 3, 3, 4); + + val = (id == PORT_A) ? 3 : 0; + reg = CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_15; + dwc_phy_write_mask(isys, id, reg, val, 3, 4); + + reg = CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_15; + dwc_phy_write_mask(isys, id, reg, 3, 3, 4); + } + + dwc_phy_write_mask(isys, id, CORE_DIG_DLANE_CLK_RW_HS_RX_0, 28, 0, 7); + dwc_phy_write_mask(isys, id, CORE_DIG_DLANE_CLK_RW_HS_RX_7, 6, 0, 7); + + reg = CORE_DIG_DLANE_0_RW_HS_RX_0; + for (i = 0; i < ARRAY_SIZE(table2); i++) { + if (mbps >= table2[i].min_mbps && mbps <= table2[i].max_mbps) { + u8 j; + + for (j = 0; j < lanes; j++) + dwc_phy_write_mask(isys, id, reg + (j * 0x400), + table2[i].i_thssettle, + 8, 15); + break; + } + } + + /* deskew */ + for (i = 0; i < lanes; i++) { + reg = CORE_DIG_DLANE_0_RW_CFG_1; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), + ((mbps > 1500) ? 0x1 : 0x2), 2, 3); + + reg = CORE_DIG_DLANE_0_RW_HS_RX_2; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), + ((mbps > 2500) ? 0 : 1), 15, 15); + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 1, 13, 13); + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 7, 9, 12); + + reg = CORE_DIG_DLANE_0_RW_LP_0; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 1, 12, 15); + + reg = CORE_DIG_DLANE_0_RW_LP_2; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 0, 0, 0); + + reg = CORE_DIG_DLANE_0_RW_HS_RX_1; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 16, 0, 7); + + reg = CORE_DIG_DLANE_0_RW_HS_RX_3; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 2, 0, 2); + index = lookup_table1(mbps); + if (index >= 0) { + val = table1[index].fjump_deskew; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), val, + 3, 8); + } + + reg = CORE_DIG_DLANE_0_RW_HS_RX_4; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 150, 0, 15); + + reg = CORE_DIG_DLANE_0_RW_HS_RX_5; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 0, 0, 7); + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 1, 8, 15); + + reg = CORE_DIG_DLANE_0_RW_HS_RX_6; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 2, 0, 7); + index = lookup_table1(mbps); + if (index >= 0) { + val = table1[index].min_eye_opening_deskew; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), val, + 8, 15); + } + reg = CORE_DIG_DLANE_0_RW_HS_RX_7; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 0, 13, 13); + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 0, 15, 15); + + reg = CORE_DIG_DLANE_0_RW_HS_RX_9; + index = lookup_table1(mbps); + if (index >= 0) { + val = table1[index].ddlcal_max_phase; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), + val, 0, 7); + } + } + + dwc_phy_write_mask(isys, id, CORE_DIG_DLANE_CLK_RW_LP_0, 1, 12, 15); + dwc_phy_write_mask(isys, id, CORE_DIG_DLANE_CLK_RW_LP_2, 0, 0, 0); + + for (i = 0; i < ARRAY_SIZE(deskew_fine_mem); i++) + dwc_phy_write_mask(isys, id, CORE_DIG_COMMON_RW_DESKEW_FINE_MEM, + deskew_fine_mem[i], 0, 15); + + if (mbps > 1500) { + hsrxval0 = 4; + hsrxval2 = 3; + } + + if (mbps > 2500) + hsrxval1 = 2; + + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_9, + hsrxval0, 0, 2); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_9, + hsrxval0, 0, 2); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_9, + hsrxval0, 0, 2); + if (lanes == 4 && is_ipu7(isys->adev->isp->hw_ver)) { + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_9, + hsrxval0, 0, 2); + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_9, + hsrxval0, 0, 2); + } + + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_9, + hsrxval1, 3, 4); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_9, + hsrxval1, 3, 4); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_9, + hsrxval1, 3, 4); + if (lanes == 4 && is_ipu7(isys->adev->isp->hw_ver)) { + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_9, + hsrxval1, 3, 4); + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_9, + hsrxval1, 3, 4); + } + + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_15, + hsrxval2, 0, 2); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_15, + hsrxval2, 0, 2); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_15, + hsrxval2, 0, 2); + if (lanes == 4 && is_ipu7(isys->adev->isp->hw_ver)) { + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_15, + hsrxval2, 0, 2); + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_15, + hsrxval2, 0, 2); + } + + /* force and override rext */ + if (isys->phy_rext_cal && id) { + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_8, + isys->phy_rext_cal, 0, 3); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_7, + 1, 11, 11); + } +} + +static void ipu7_isys_cphy_config(struct ipu7_isys *isys, u8 id, u8 lanes, + bool aggregation, u64 mbps) +{ + u8 trios = 2; + u16 coarse_target; + u16 deass_thresh; + u16 delay_thresh; + u16 reset_thresh; + u16 cap_prog = 6U; + u16 reg; + u16 val; + u32 i; + u64 r64; + u32 r; + + if (is_ipu7p5(isys->adev->isp->hw_ver)) + val = 0x15; + else + val = 0x155; + + if (is_ipu7(isys->adev->isp->hw_ver)) + trios = 3; + + dwc_phy_write_mask(isys, id, CORE_DIG_RW_COMMON_7, val, 0, 9); + dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_DPHY_7, 104, 0, 7); + dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_DPHY_8, 16, 0, 7); + + reg = CORE_DIG_CLANE_0_RW_LP_0; + for (i = 0; i < trios; i++) + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 6, 8, 11); + + val = (mbps > 900U) ? 1U : 0U; + for (i = 0; i < trios; i++) { + reg = CORE_DIG_CLANE_0_RW_HS_RX_0; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 1, 0, 0); + dwc_phy_write_mask(isys, id, reg + (i * 0x400), val, 1, 1); + + reg = CORE_DIG_CLANE_0_RW_HS_RX_1; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 38, 0, 15); + + reg = CORE_DIG_CLANE_0_RW_HS_RX_5; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 38, 0, 15); + + reg = CORE_DIG_CLANE_0_RW_HS_RX_6; + dwc_phy_write_mask(isys, id, reg + (i * 0x400), 10, 0, 15); + } + + /* + * Below 900Msps, always use the same value. + * The formula is suitable for data rate 80-3500Msps. + * Timebase (us) = 1, DIV = 32, TDDL (UI) = 0.5 + */ + if (mbps >= 80U) + coarse_target = DIV_ROUND_UP_ULL(mbps, 16) - 1; + else + coarse_target = 56; + + for (i = 0; i < trios; i++) { + reg = CORE_DIG_CLANE_0_RW_HS_RX_2 + i * 0x400; + dwc_phy_write_mask(isys, id, reg, coarse_target, 0, 15); + } + + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_2, 1, 0, 0); + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_2, 0, 0, 0); + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_2, 1, 0, 0); + + if (!is_ipu7p5(isys->adev->isp->hw_ver) && lanes == 4) { + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_2, + 1, 0, 0); + dwc_phy_write_mask(isys, id, + CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_2, + 0, 0, 0); + } + + for (i = 0; i < trios; i++) { + reg = CORE_DIG_RW_TRIO0_0 + i * 0x400; + dwc_phy_write_mask(isys, id, reg, 1, 6, 8); + dwc_phy_write_mask(isys, id, reg, 1, 3, 5); + dwc_phy_write_mask(isys, id, reg, 2, 0, 2); + } + + deass_thresh = (u16)div64_u64_rem(7 * 1000 * 6, mbps * 5U, &r64) + 1; + if (r64 != 0) + deass_thresh++; + + reg = CORE_DIG_RW_TRIO0_2; + for (i = 0; i < trios; i++) + dwc_phy_write_mask(isys, id, reg + 0x400 * i, + deass_thresh, 0, 7); + + delay_thresh = div64_u64((224U - (9U * 7U)) * 1000U, 5U * mbps) - 7u; + + if (delay_thresh < 1) + delay_thresh = 1; + + reg = CORE_DIG_RW_TRIO0_1; + for (i = 0; i < trios; i++) + dwc_phy_write_mask(isys, id, reg + 0x400 * i, + delay_thresh, 0, 15); + + reset_thresh = (u16)div_u64_rem(2U * 5U * mbps, 7U * 1000U, &r); + if (!r) + reset_thresh--; + + if (reset_thresh < 1) + reset_thresh = 1; + + reg = CORE_DIG_RW_TRIO0_0; + for (i = 0; i < trios; i++) + dwc_phy_write_mask(isys, id, reg + 0x400 * i, + reset_thresh, 9, 11); + + reg = CORE_DIG_CLANE_0_RW_LP_0; + for (i = 0; i < trios; i++) + dwc_phy_write_mask(isys, id, reg + 0x400 * i, 1, 12, 15); + + reg = CORE_DIG_CLANE_0_RW_LP_2; + for (i = 0; i < trios; i++) + dwc_phy_write_mask(isys, id, reg + 0x400 * i, 0, 0, 0); + + reg = CORE_DIG_CLANE_0_RW_HS_RX_0; + for (i = 0; i < trios; i++) + dwc_phy_write_mask(isys, id, reg + 0x400 * i, 12, 2, 6); + + for (i = 0; i < ARRAY_SIZE(table7); i++) { + if (mbps >= table7[i].min_mbps && mbps <= table7[i].max_mbps) { + cap_prog = table7[i].val; + break; + } + } + + for (i = 0; i < (lanes + 1); i++) { + reg = CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_9 + 0x400 * i; + dwc_phy_write_mask(isys, id, reg, 4U, 0, 2); + dwc_phy_write_mask(isys, id, reg, 0U, 3, 4); + + reg = CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_7 + 0x400 * i; + dwc_phy_write_mask(isys, id, reg, cap_prog, 10, 12); + } +} + +static int ipu7_isys_phy_config(struct ipu7_isys *isys, u8 id, u8 lanes, + bool aggregation) +{ + struct device *dev = &isys->adev->auxdev.dev; + u32 phy_mode; + s64 link_freq; + u64 mbps; + + if (aggregation) + link_freq = ipu7_isys_csi2_get_link_freq(&isys->csi2[0]); + else + link_freq = ipu7_isys_csi2_get_link_freq(&isys->csi2[id]); + + if (link_freq < 0) { + dev_err(dev, "get link freq failed (%lld)\n", link_freq); + return link_freq; + } + + mbps = div_u64(link_freq, 500000); + dev_dbg(dev, "config phy %u with lanes %u aggregation %d mbps %lld\n", + id, lanes, aggregation, mbps); + + dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_DPHY_10, 48, 0, 7); + dwc_phy_write_mask(isys, id, CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_2, + 1, 12, 13); + dwc_phy_write_mask(isys, id, CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_0, + 63, 2, 7); + dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_STARTUP_1_1, + 563, 0, 11); + dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_DPHY_2, 5, 0, 7); + /* bypass the RCAL state (bit6) */ + if (aggregation && id != PORT_A) + dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_DPHY_2, 0x45, + 0, 7); + + dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_DPHY_6, 39, 0, 7); + dwc_phy_write_mask(isys, id, PPI_CALIBCTRL_RW_COMMON_BG_0, 500, 0, 8); + dwc_phy_write_mask(isys, id, PPI_RW_TERMCAL_CFG_0, 38, 0, 6); + dwc_phy_write_mask(isys, id, PPI_RW_OFFSETCAL_CFG_0, 7, 0, 4); + dwc_phy_write_mask(isys, id, PPI_RW_LPDCOCAL_TIMEBASE, 153, 0, 9); + dwc_phy_write_mask(isys, id, PPI_RW_LPDCOCAL_NREF, 800, 0, 10); + dwc_phy_write_mask(isys, id, PPI_RW_LPDCOCAL_NREF_RANGE, 27, 0, 4); + dwc_phy_write_mask(isys, id, PPI_RW_LPDCOCAL_TWAIT_CONFIG, 47, 0, 8); + dwc_phy_write_mask(isys, id, PPI_RW_LPDCOCAL_TWAIT_CONFIG, 127, 9, 15); + dwc_phy_write_mask(isys, id, PPI_RW_LPDCOCAL_VT_CONFIG, 47, 7, 15); + dwc_phy_write_mask(isys, id, PPI_RW_LPDCOCAL_VT_CONFIG, 27, 2, 6); + dwc_phy_write_mask(isys, id, PPI_RW_LPDCOCAL_VT_CONFIG, 3, 0, 1); + dwc_phy_write_mask(isys, id, PPI_RW_LPDCOCAL_COARSE_CFG, 1, 0, 1); + dwc_phy_write_mask(isys, id, PPI_RW_COMMON_CFG, 3, 0, 1); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_0, + 0, 10, 10); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_1, + 1, 10, 10); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_1, + 0, 15, 15); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_3, + 3, 8, 9); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_0, + 0, 15, 15); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_6, + 7, 12, 14); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_7, + 0, 8, 10); + dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_5, + 0, 8, 8); + + if (aggregation) + phy_mode = isys->csi2[0].phy_mode; + else + phy_mode = isys->csi2[id].phy_mode; + + if (phy_mode == PHY_MODE_DPHY) { + ipu7_isys_dphy_config(isys, id, lanes, aggregation, mbps); + } else if (phy_mode == PHY_MODE_CPHY) { + ipu7_isys_cphy_config(isys, id, lanes, aggregation, mbps); + } else { + dev_err(dev, "unsupported phy mode %d!\n", + isys->csi2[id].phy_mode); + } + + return 0; +} + +int ipu7_isys_csi_phy_powerup(struct ipu7_isys_csi2 *csi2) +{ + struct ipu7_isys *isys = csi2->isys; + u32 lanes = csi2->nlanes; + bool aggregation = false; + u32 id = csi2->port; + int ret; + + /* lanes remapping for aggregation (port AB) mode */ + if (!is_ipu7(isys->adev->isp->hw_ver) && lanes > 2 && id == PORT_A) { + aggregation = true; + lanes = 2; + } + + ipu7_isys_csi_phy_reset(isys, id); + gpreg_write(isys, id, PHY_CLK_LANE_CONTROL, 0x1); + gpreg_write(isys, id, PHY_CLK_LANE_FORCE_CONTROL, 0x2); + gpreg_write(isys, id, PHY_LANE_CONTROL_EN, (1U << lanes) - 1U); + gpreg_write(isys, id, PHY_LANE_FORCE_CONTROL, 0xf); + gpreg_write(isys, id, PHY_MODE, csi2->phy_mode); + + /* config PORT_B if aggregation mode */ + if (aggregation) { + ipu7_isys_csi_phy_reset(isys, PORT_B); + gpreg_write(isys, PORT_B, PHY_CLK_LANE_CONTROL, 0x0); + gpreg_write(isys, PORT_B, PHY_LANE_CONTROL_EN, 0x3); + gpreg_write(isys, PORT_B, PHY_CLK_LANE_FORCE_CONTROL, 0x2); + gpreg_write(isys, PORT_B, PHY_LANE_FORCE_CONTROL, 0xf); + gpreg_write(isys, PORT_B, PHY_MODE, csi2->phy_mode); + } + + ipu7_isys_csi_ctrl_cfg(csi2); + ipu7_isys_csi_ctrl_dids_config(csi2, id); + + ret = ipu7_isys_phy_config(isys, id, lanes, aggregation); + if (ret < 0) + return ret; + + gpreg_write(isys, id, PHY_RESET, 1); + gpreg_write(isys, id, PHY_SHUTDOWN, 1); + dwc_csi_write(isys, id, DPHY_RSTZ, 1); + dwc_csi_write(isys, id, PHY_SHUTDOWNZ, 1); + dwc_csi_write(isys, id, CSI2_RESETN, 1); + + ret = ipu7_isys_phy_ready(isys, id); + if (ret < 0) + return ret; + + gpreg_write(isys, id, PHY_LANE_FORCE_CONTROL, 0); + gpreg_write(isys, id, PHY_CLK_LANE_FORCE_CONTROL, 0); + + /* config PORT_B if aggregation mode */ + if (aggregation) { + ret = ipu7_isys_phy_config(isys, PORT_B, 2, aggregation); + if (ret < 0) + return ret; + + gpreg_write(isys, PORT_B, PHY_RESET, 1); + gpreg_write(isys, PORT_B, PHY_SHUTDOWN, 1); + dwc_csi_write(isys, PORT_B, DPHY_RSTZ, 1); + dwc_csi_write(isys, PORT_B, PHY_SHUTDOWNZ, 1); + dwc_csi_write(isys, PORT_B, CSI2_RESETN, 1); + ret = ipu7_isys_phy_ready(isys, PORT_B); + if (ret < 0) + return ret; + + gpreg_write(isys, PORT_B, PHY_LANE_FORCE_CONTROL, 0); + gpreg_write(isys, PORT_B, PHY_CLK_LANE_FORCE_CONTROL, 0); + } + + return 0; +} + +void ipu7_isys_csi_phy_powerdown(struct ipu7_isys_csi2 *csi2) +{ + struct ipu7_isys *isys = csi2->isys; + + ipu7_isys_csi_phy_reset(isys, csi2->port); + if (!is_ipu7(isys->adev->isp->hw_ver) && + csi2->nlanes > 2U && csi2->port == PORT_A) + ipu7_isys_csi_phy_reset(isys, PORT_B); +} diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.h b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.h new file mode 100644 index 000000000000..dfdcb61540c4 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_ISYS_CSI_PHY_H +#define IPU7_ISYS_CSI_PHY_H + +struct ipu7_isys; + +#define PHY_MODE_DPHY 0U +#define PHY_MODE_CPHY 1U + +int ipu7_isys_csi_phy_powerup(struct ipu7_isys_csi2 *csi2); +void ipu7_isys_csi_phy_powerdown(struct ipu7_isys_csi2 *csi2); +#endif diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi2-regs.h b/drivers/staging/media/ipu7/ipu7-isys-csi2-regs.h new file mode 100644 index 000000000000..aad52c44a005 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys-csi2-regs.h @@ -0,0 +1,1197 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 - 2025 Intel Corporation + */ + +#ifndef IPU7_ISYS_CSI2_REG_H +#define IPU7_ISYS_CSI2_REG_H + +/* IS main regs base */ +#define IS_MAIN_BASE 0x240000 +#define IS_MAIN_S2B_BASE (IS_MAIN_BASE + 0x22000) +#define IS_MAIN_B2O_BASE (IS_MAIN_BASE + 0x26000) +#define IS_MAIN_ISD_M0_BASE (IS_MAIN_BASE + 0x2b000) +#define IS_MAIN_ISD_M1_BASE (IS_MAIN_BASE + 0x2b100) +#define IS_MAIN_ISD_INT_BASE (IS_MAIN_BASE + 0x2b200) +#define IS_MAIN_GDA_BASE (IS_MAIN_BASE + 0x32000) +#define IS_MAIN_GPREGS_MAIN_BASE (IS_MAIN_BASE + 0x32500) +#define IS_MAIN_IRQ_CTRL_BASE (IS_MAIN_BASE + 0x32700) +#define IS_MAIN_PWM_CTRL_BASE (IS_MAIN_BASE + 0x32b00) + +#define S2B_IRQ_COMMON_0_CTL_STATUS (IS_MAIN_S2B_BASE + 0x1c) +#define S2B_IRQ_COMMON_0_CTL_CLEAR (IS_MAIN_S2B_BASE + 0x20) +#define S2B_IRQ_COMMON_0_CTL_ENABLE (IS_MAIN_S2B_BASE + 0x24) +#define S2B_IID_IRQ_CTL_STATUS(iid) (IS_MAIN_S2B_BASE + 0x94 + \ + 0x100 * (iid)) + +#define B2O_IRQ_COMMON_0_CTL_STATUS (IS_MAIN_B2O_BASE + 0x30) +#define B2O_IRQ_COMMON_0_CTL_CLEAR (IS_MAIN_B2O_BASE + 0x34) +#define B2O_IRQ_COMMON_0_CTL_ENABLE (IS_MAIN_B2O_BASE + 0x38) +#define B2O_IID_IRQ_CTL_STATUS(oid) (IS_MAIN_B2O_BASE + 0x3dc + \ + 0x200 * (oid)) + +#define ISD_M0_IRQ_CTL_STATUS (IS_MAIN_ISD_M0_BASE + 0x1c) +#define ISD_M0_IRQ_CTL_CLEAR (IS_MAIN_ISD_M0_BASE + 0x20) +#define ISD_M0_IRQ_CTL_ENABLE (IS_MAIN_ISD_M0_BASE + 0x24) + +#define ISD_M1_IRQ_CTL_STATUS (IS_MAIN_ISD_M1_BASE + 0x1c) +#define ISD_M1_IRQ_CTL_CLEAR (IS_MAIN_ISD_M1_BASE + 0x20) +#define ISD_M1_IRQ_CTL_ENABLE (IS_MAIN_ISD_M1_BASE + 0x24) + +#define ISD_INT_IRQ_CTL_STATUS (IS_MAIN_ISD_INT_BASE + 0x1c) +#define ISD_INT_IRQ_CTL_CLEAR (IS_MAIN_ISD_INT_BASE + 0x20) +#define ISD_INT_IRQ_CTL_ENABLE (IS_MAIN_ISD_INT_BASE + 0x24) + +#define GDA_IRQ_CTL_STATUS (IS_MAIN_GDA_BASE + 0x1c) +#define GDA_IRQ_CTL_CLEAR (IS_MAIN_GDA_BASE + 0x20) +#define GDA_IRQ_CTL_ENABLE (IS_MAIN_GDA_BASE + 0x24) + +#define IS_MAIN_IRQ_CTL_EDGE IS_MAIN_IRQ_CTRL_BASE +#define IS_MAIN_IRQ_CTL_MASK (IS_MAIN_IRQ_CTRL_BASE + 0x4) +#define IS_MAIN_IRQ_CTL_STATUS (IS_MAIN_IRQ_CTRL_BASE + 0x8) +#define IS_MAIN_IRQ_CTL_CLEAR (IS_MAIN_IRQ_CTRL_BASE + 0xc) +#define IS_MAIN_IRQ_CTL_ENABLE (IS_MAIN_IRQ_CTRL_BASE + 0x10) +#define IS_MAIN_IRQ_CTL_LEVEL_NOT_PULSE (IS_MAIN_IRQ_CTRL_BASE + 0x14) + +/* IS IO regs base */ +#define IS_PHY_NUM 4U +#define IS_IO_BASE 0x280000 + +/* dwc csi cdphy registers */ +#define IS_IO_CDPHY_BASE(i) (IS_IO_BASE + 0x10000 * (i)) +#define PPI_STARTUP_RW_COMMON_DPHY_0 0x1800 +#define PPI_STARTUP_RW_COMMON_DPHY_1 0x1802 +#define PPI_STARTUP_RW_COMMON_DPHY_2 0x1804 +#define PPI_STARTUP_RW_COMMON_DPHY_3 0x1806 +#define PPI_STARTUP_RW_COMMON_DPHY_4 0x1808 +#define PPI_STARTUP_RW_COMMON_DPHY_5 0x180a +#define PPI_STARTUP_RW_COMMON_DPHY_6 0x180c +#define PPI_STARTUP_RW_COMMON_DPHY_7 0x180e +#define PPI_STARTUP_RW_COMMON_DPHY_8 0x1810 +#define PPI_STARTUP_RW_COMMON_DPHY_9 0x1812 +#define PPI_STARTUP_RW_COMMON_DPHY_A 0x1814 +#define PPI_STARTUP_RW_COMMON_DPHY_10 0x1820 +#define PPI_STARTUP_RW_COMMON_STARTUP_1_1 0x1822 +#define PPI_STARTUP_RW_COMMON_STARTUP_1_2 0x1824 +#define PPI_CALIBCTRL_RW_COMMON_CALIBCTRL_2_0 0x1840 +#define PPI_CALIBCTRL_R_COMMON_CALIBCTRL_2_1 0x1842 +#define PPI_CALIBCTRL_R_COMMON_CALIBCTRL_2_2 0x1844 +#define PPI_CALIBCTRL_R_COMMON_CALIBCTRL_2_3 0x1846 +#define PPI_CALIBCTRL_R_COMMON_CALIBCTRL_2_4 0x1848 +#define PPI_CALIBCTRL_R_COMMON_CALIBCTRL_2_5 0x184a +#define PPI_CALIBCTRL_RW_COMMON_BG_0 0x184c +#define PPI_CALIBCTRL_RW_COMMON_CALIBCTRL_2_7 0x184e +#define PPI_CALIBCTRL_RW_ADC_CFG_0 0x1850 +#define PPI_CALIBCTRL_RW_ADC_CFG_1 0x1852 +#define PPI_CALIBCTRL_R_ADC_DEBUG 0x1854 +#define PPI_RW_LPDCOCAL_TOP_OVERRIDE 0x1c00 +#define PPI_RW_LPDCOCAL_TIMEBASE 0x1c02 +#define PPI_RW_LPDCOCAL_NREF 0x1c04 +#define PPI_RW_LPDCOCAL_NREF_RANGE 0x1c06 +#define PPI_RW_LPDCOCAL_NREF_TRIGGER_MAN 0x1c08 +#define PPI_RW_LPDCOCAL_TWAIT_CONFIG 0x1c0a +#define PPI_RW_LPDCOCAL_VT_CONFIG 0x1c0c +#define PPI_R_LPDCOCAL_DEBUG_RB 0x1c0e +#define PPI_RW_LPDCOCAL_COARSE_CFG 0x1c10 +#define PPI_R_LPDCOCAL_DEBUG_COARSE_RB 0x1c12 +#define PPI_R_LPDCOCAL_DEBUG_COARSE_MEAS_0_RB 0x1c14 +#define PPI_R_LPDCOCAL_DEBUG_COARSE_MEAS_1_RB 0x1c16 +#define PPI_R_LPDCOCAL_DEBUG_COARSE_FWORD_RB 0x1c18 +#define PPI_R_LPDCOCAL_DEBUG_MEASURE_CURR_ERROR 0x1c1a +#define PPI_R_LPDCOCAL_DEBUG_MEASURE_LAST_ERROR 0x1c1c +#define PPI_R_LPDCOCAL_DEBUG_VT 0x1c1e +#define PPI_RW_LB_TIMEBASE_CONFIG 0x1c20 +#define PPI_RW_LB_STARTCMU_CONFIG 0x1c22 +#define PPI_R_LBPULSE_COUNTER_RB 0x1c24 +#define PPI_R_LB_START_CMU_RB 0x1c26 +#define PPI_RW_LB_DPHY_BURST_START 0x1c28 +#define PPI_RW_LB_CPHY_BURST_START 0x1c2a +#define PPI_RW_DDLCAL_CFG_0 0x1c40 +#define PPI_RW_DDLCAL_CFG_1 0x1c42 +#define PPI_RW_DDLCAL_CFG_2 0x1c44 +#define PPI_RW_DDLCAL_CFG_3 0x1c46 +#define PPI_RW_DDLCAL_CFG_4 0x1c48 +#define PPI_RW_DDLCAL_CFG_5 0x1c4a +#define PPI_RW_DDLCAL_CFG_6 0x1c4c +#define PPI_RW_DDLCAL_CFG_7 0x1c4e +#define PPI_R_DDLCAL_DEBUG_0 0x1c50 +#define PPI_R_DDLCAL_DEBUG_1 0x1c52 +#define PPI_RW_PARITY_TEST 0x1c60 +#define PPI_RW_STARTUP_OVR_0 0x1c62 +#define PPI_RW_STARTUP_STATE_OVR_1 0x1c64 +#define PPI_RW_DTB_SELECTOR 0x1c66 +#define PPI_RW_DPHY_CLK_SPARE 0x1c6a +#define PPI_RW_COMMON_CFG 0x1c6c +#define PPI_RW_TERMCAL_CFG_0 0x1c80 +#define PPI_R_TERMCAL_DEBUG_0 0x1c82 +#define PPI_RW_TERMCAL_CTRL_0 0x1c84 +#define PPI_RW_OFFSETCAL_CFG_0 0x1ca0 +#define PPI_R_OFFSETCAL_DEBUG_LANE0 0x1ca2 +#define PPI_R_OFFSETCAL_DEBUG_LANE1 0x1ca4 +#define PPI_R_OFFSETCAL_DEBUG_LANE2 0x1ca6 +#define PPI_R_OFFSETCAL_DEBUG_LANE3 0x1ca8 +#define PPI_R_OFFSETCAL_DEBUG_LANE4 0x1caa +#define PPI_RW_HSDCOCAL_CFG_O 0x1d00 +#define PPI_RW_HSDCOCAL_CFG_1 0x1d02 +#define PPI_RW_HSDCOCAL_CFG_2 0x1d04 +#define PPI_RW_HSDCOCAL_CFG_3 0x1d06 +#define PPI_RW_HSDCOCAL_CFG_4 0x1d08 +#define PPI_RW_HSDCOCAL_CFG_5 0x1d0a +#define PPI_RW_HSDCOCAL_CFG_6 0x1d0c +#define PPI_RW_HSDCOCAL_CFG_7 0x1d0e +#define PPI_RW_HSDCOCAL_CFG_8 0x1d10 +#define PPI_R_HSDCOCAL_DEBUG_RB 0x1d12 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE0_OVR_0_0 0x2000 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE0_OVR_0_1 0x2002 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE0_OVR_0_2 0x2004 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE0_OVR_0_3 0x2006 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE0_OVR_0_4 0x2008 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE0_OVR_0_5 0x200a +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE0_OVR_0_6 0x200c +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE0_OVR_0_7 0x200e +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE0_OVR_0_8 0x2010 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE0_OVR_0_9 0x2012 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE0_OVR_0_10 0x2014 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE0_OVR_0_11 0x2016 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE0_OVR_0_12 0x2018 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE0_OVR_0_13 0x201a +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE0_OVR_0_14 0x201c +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE0_OVR_0_15 0x201e +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_1_0 0x2020 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_1_1 0x2022 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_1_2 0x2024 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_1_3 0x2026 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_1_4 0x2028 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_1_5 0x202a +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_1_6 0x202c +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_1_7 0x202e +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_1_8 0x2030 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_1_9 0x2032 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE0_OVR_1_10 0x2034 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE0_OVR_1_11 0x2036 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE0_OVR_1_12 0x2038 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE0_OVR_1_13 0x203a +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE0_OVR_1_14 0x203c +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE0_OVR_1_15 0x203e +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_0 0x2040 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_1 0x2042 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_2 0x2044 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_3 0x2046 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_4 0x2048 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_5 0x204a +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_6 0x204c +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_7 0x204e +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_8 0x2050 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_9 0x2052 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_10 0x2054 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_11 0x2056 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_12 0x2058 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_13 0x205a +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_14 0x205c +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_15 0x205e +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_3_0 0x2060 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_3_1 0x2062 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_3_2 0x2064 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_3_3 0x2066 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_3_4 0x2068 +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_3_5 0x206a +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_3_6 0x206c +#define CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_3_7 0x206e +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_3_8 0x2070 +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_3_9 0x2072 +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_3_10 0x2074 +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_3_11 0x2076 +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_3_12 0x2078 +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_3_13 0x207a +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_3_14 0x207c +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_3_15 0x207e +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_4_0 0x2080 +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_4_1 0x2082 +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_4_2 0x2084 +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_4_3 0x2086 +#define CORE_DIG_IOCTRL_R_AFE_LANE0_CTRL_4_4 0x2088 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE0_OVR_5_0 0x20a0 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE0_OVR_5_1 0x20a2 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_5_2 0x20a4 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE0_OVR_5_3 0x20a6 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE0_OVR_5_4 0x20a8 +#define CORE_DIG_RW_TRIO0_0 0x2100 +#define CORE_DIG_RW_TRIO0_1 0x2102 +#define CORE_DIG_RW_TRIO0_2 0x2104 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE1_OVR_0_0 0x2400 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE1_OVR_0_1 0x2402 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE1_OVR_0_2 0x2404 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE1_OVR_0_3 0x2406 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE1_OVR_0_4 0x2408 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE1_OVR_0_5 0x240a +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE1_OVR_0_6 0x240c +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE1_OVR_0_7 0x240e +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE1_OVR_0_8 0x2410 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE1_OVR_0_9 0x2412 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE1_OVR_0_10 0x2414 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE1_OVR_0_11 0x2416 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE1_OVR_0_12 0x2418 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE1_OVR_0_13 0x241a +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE1_OVR_0_14 0x241c +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE1_OVR_0_15 0x241e +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_1_0 0x2420 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_1_1 0x2422 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_1_2 0x2424 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_1_3 0x2426 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_1_4 0x2428 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_1_5 0x242a +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_1_6 0x242c +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_1_7 0x242e +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_1_8 0x2430 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_1_9 0x2432 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE1_OVR_1_10 0x2434 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE1_OVR_1_11 0x2436 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE1_OVR_1_12 0x2438 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE1_OVR_1_13 0x243a +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE1_OVR_1_14 0x243c +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE1_OVR_1_15 0x243e +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_0 0x2440 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_1 0x2442 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_2 0x2444 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_3 0x2446 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_4 0x2448 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_5 0x244a +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_6 0x244c +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_7 0x244e +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_8 0x2450 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_9 0x2452 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_10 0x2454 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_11 0x2456 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_12 0x2458 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_13 0x245a +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_14 0x245c +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_15 0x245e +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_3_0 0x2460 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_3_1 0x2462 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_3_2 0x2464 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_3_3 0x2466 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_3_4 0x2468 +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_3_5 0x246a +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_3_6 0x246c +#define CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_3_7 0x246e +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_3_8 0x2470 +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_3_9 0x2472 +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_3_10 0x2474 +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_3_11 0x2476 +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_3_12 0x2478 +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_3_13 0x247a +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_3_14 0x247c +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_3_15 0x247e +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_4_0 0x2480 +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_4_1 0x2482 +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_4_2 0x2484 +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_4_3 0x2486 +#define CORE_DIG_IOCTRL_R_AFE_LANE1_CTRL_4_4 0x2488 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE1_OVR_5_0 0x24a0 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE1_OVR_5_1 0x24a2 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_5_2 0x24a4 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE1_OVR_5_3 0x24a6 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE1_OVR_5_4 0x24a8 +#define CORE_DIG_RW_TRIO1_0 0x2500 +#define CORE_DIG_RW_TRIO1_1 0x2502 +#define CORE_DIG_RW_TRIO1_2 0x2504 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE2_OVR_0_0 0x2800 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE2_OVR_0_1 0x2802 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE2_OVR_0_2 0x2804 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE2_OVR_0_3 0x2806 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE2_OVR_0_4 0x2808 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE2_OVR_0_5 0x280a +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE2_OVR_0_6 0x280c +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE2_OVR_0_7 0x280e +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE2_OVR_0_8 0x2810 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE2_OVR_0_9 0x2812 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE2_OVR_0_10 0x2814 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE2_OVR_0_11 0x2816 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE2_OVR_0_12 0x2818 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE2_OVR_0_13 0x281a +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE2_OVR_0_14 0x281c +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE2_OVR_0_15 0x281e +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_1_0 0x2820 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_1_1 0x2822 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_1_2 0x2824 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_1_3 0x2826 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_1_4 0x2828 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_1_5 0x282a +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_1_6 0x282c +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_1_7 0x282e +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_1_8 0x2830 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_1_9 0x2832 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE2_OVR_1_10 0x2834 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE2_OVR_1_11 0x2836 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE2_OVR_1_12 0x2838 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE2_OVR_1_13 0x283a +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE2_OVR_1_14 0x283c +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE2_OVR_1_15 0x283e +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_0 0x2840 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_1 0x2842 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_2 0x2844 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_3 0x2846 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_4 0x2848 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_5 0x284a +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_6 0x284c +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_7 0x284e +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_8 0x2850 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_9 0x2852 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_10 0x2854 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_11 0x2856 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_12 0x2858 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_13 0x285a +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_14 0x285c +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_15 0x285e +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_3_0 0x2860 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_3_1 0x2862 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_3_2 0x2864 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_3_3 0x2866 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_3_4 0x2868 +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_3_5 0x286a +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_3_6 0x286c +#define CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_3_7 0x286e +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_3_8 0x2870 +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_3_9 0x2872 +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_3_10 0x2874 +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_3_11 0x2876 +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_3_12 0x2878 +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_3_13 0x287a +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_3_14 0x287c +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_3_15 0x287e +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_4_0 0x2880 +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_4_1 0x2882 +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_4_2 0x2884 +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_4_3 0x2886 +#define CORE_DIG_IOCTRL_R_AFE_LANE2_CTRL_4_4 0x2888 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE2_OVR_5_0 0x28a0 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE2_OVR_5_1 0x28a2 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_5_2 0x28a4 +#define CORE_DIG_IOCTRL_RW_CPHY_PPI_LANE2_OVR_5_3 0x28a6 +#define CORE_DIG_IOCTRL_R_CPHY_PPI_LANE2_OVR_5_4 0x28a8 +#define CORE_DIG_RW_TRIO2_0 0x2900 +#define CORE_DIG_RW_TRIO2_1 0x2902 +#define CORE_DIG_RW_TRIO2_2 0x2904 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE3_OVR_0_0 0x2c00 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE3_OVR_0_1 0x2c02 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE3_OVR_0_2 0x2c04 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE3_OVR_0_3 0x2c06 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE3_OVR_0_4 0x2c08 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE3_OVR_0_5 0x2c0a +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE3_OVR_0_6 0x2c0c +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE3_OVR_0_7 0x2c0e +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_LANE3_OVR_0_8 0x2c10 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE3_OVR_0_9 0x2c12 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE3_OVR_0_10 0x2c14 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE3_OVR_0_11 0x2c16 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE3_OVR_0_12 0x2c18 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE3_OVR_0_13 0x2c1a +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE3_OVR_0_14 0x2c1c +#define CORE_DIG_IOCTRL_R_DPHY_PPI_LANE3_OVR_0_15 0x2c1e +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_0 0x2c40 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_1 0x2c42 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_2 0x2c44 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_3 0x2c46 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_4 0x2c48 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_5 0x2c4a +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_6 0x2c4c +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_7 0x2c4e +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_8 0x2c50 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_9 0x2c52 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_10 0x2c54 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_11 0x2c56 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_12 0x2c58 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_13 0x2c5a +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_14 0x2c5c +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_15 0x2c5e +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_3_0 0x2c60 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_3_1 0x2c62 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_3_2 0x2c64 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_3_3 0x2c66 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_3_4 0x2c68 +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_3_5 0x2c6a +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_3_6 0x2c6c +#define CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_3_7 0x2c6e +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_3_8 0x2c70 +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_3_9 0x2c72 +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_3_10 0x2c74 +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_3_11 0x2c76 +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_3_12 0x2c78 +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_3_13 0x2c7a +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_3_14 0x2c7c +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_3_15 0x2c7e +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_4_0 0x2c80 +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_4_1 0x2c82 +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_4_2 0x2c84 +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_4_3 0x2c86 +#define CORE_DIG_IOCTRL_R_AFE_LANE3_CTRL_4_4 0x2c88 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_0 0x3040 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_1 0x3042 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_2 0x3044 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_3 0x3046 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_4 0x3048 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_5 0x304a +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_6 0x304c +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_7 0x304e +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_8 0x3050 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_9 0x3052 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_10 0x3054 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_11 0x3056 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_12 0x3058 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_13 0x305a +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_14 0x305c +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_15 0x305e +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_3_0 0x3060 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_3_1 0x3062 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_3_2 0x3064 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_3_3 0x3066 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_3_4 0x3068 +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_3_5 0x306a +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_3_6 0x306c +#define CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_3_7 0x306e +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_3_8 0x3070 +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_3_9 0x3072 +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_3_10 0x3074 +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_3_11 0x3076 +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_3_12 0x3078 +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_3_13 0x307a +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_3_14 0x307c +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_3_15 0x307e +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_4_0 0x3080 +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_4_1 0x3082 +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_4_2 0x3084 +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_4_3 0x3086 +#define CORE_DIG_IOCTRL_R_AFE_LANE4_CTRL_4_4 0x3088 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_CLK_OVR_0_0 0x3400 +#define CORE_DIG_IOCTRL_RW_DPHY_PPI_CLK_OVR_0_1 0x3402 +#define CORE_DIG_IOCTRL_R_DPHY_PPI_CLK_OVR_0_2 0x3404 +#define CORE_DIG_IOCTRL_RW_COMMON_PPI_OVR_0_0 0x3800 +#define CORE_DIG_IOCTRL_RW_COMMON_PPI_OVR_0_1 0x3802 +#define CORE_DIG_IOCTRL_RW_COMMON_PPI_OVR_0_2 0x3804 +#define CORE_DIG_IOCTRL_RW_COMMON_PPI_OVR_0_3 0x3806 +#define CORE_DIG_IOCTRL_RW_COMMON_PPI_OVR_0_4 0x3808 +#define CORE_DIG_IOCTRL_RW_COMMON_PPI_OVR_0_5 0x380a +#define CORE_DIG_IOCTRL_RW_COMMON_PPI_OVR_0_6 0x380c +#define CORE_DIG_IOCTRL_RW_COMMON_PPI_OVR_0_7 0x380e +#define CORE_DIG_IOCTRL_RW_COMMON_PPI_OVR_0_8 0x3810 +#define CORE_DIG_IOCTRL_RW_COMMON_PPI_OVR_0_9 0x3812 +#define CORE_DIG_IOCTRL_RW_COMMON_PPI_OVR_0_10 0x3814 +#define CORE_DIG_IOCTRL_R_COMMON_PPI_OVR_0_11 0x3816 +#define CORE_DIG_IOCTRL_R_COMMON_PPI_OVR_0_12 0x3818 +#define CORE_DIG_IOCTRL_R_COMMON_PPI_OVR_0_13 0x381a +#define CORE_DIG_IOCTRL_R_COMMON_PPI_OVR_0_14 0x381c +#define CORE_DIG_IOCTRL_R_COMMON_PPI_OVR_0_15 0x381e +#define CORE_DIG_IOCTRL_R_COMMON_PPI_OVR_1_0 0x3820 +#define CORE_DIG_IOCTRL_R_COMMON_PPI_OVR_1_1 0x3822 +#define CORE_DIG_IOCTRL_R_COMMON_PPI_OVR_1_2 0x3824 +#define CORE_DIG_IOCTRL_R_COMMON_PPI_OVR_1_3 0x3826 +#define CORE_DIG_IOCTRL_R_COMMON_PPI_OVR_1_4 0x3828 +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_0 0x3840 +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_1 0x3842 +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_2 0x3844 +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_3 0x3846 +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_4 0x3848 +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_5 0x384a +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_6 0x384c +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_7 0x384e +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_8 0x3850 +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_9 0x3852 +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_10 0x3854 +#define CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_11 0x3856 +#define CORE_DIG_IOCTRL_R_AFE_CB_CTRL_2_12 0x3858 +#define CORE_DIG_IOCTRL_R_AFE_CB_CTRL_2_13 0x385a +#define CORE_DIG_IOCTRL_R_AFE_CB_CTRL_2_14 0x385c +#define CORE_DIG_IOCTRL_R_AFE_CB_CTRL_2_15 0x385e +#define CORE_DIG_IOCTRL_R_AFE_CB_CTRL_3_0 0x3860 +#define CORE_DIG_RW_COMMON_0 0x3880 +#define CORE_DIG_RW_COMMON_1 0x3882 +#define CORE_DIG_RW_COMMON_2 0x3884 +#define CORE_DIG_RW_COMMON_3 0x3886 +#define CORE_DIG_RW_COMMON_4 0x3888 +#define CORE_DIG_RW_COMMON_5 0x388a +#define CORE_DIG_RW_COMMON_6 0x388c +#define CORE_DIG_RW_COMMON_7 0x388e +#define CORE_DIG_RW_COMMON_8 0x3890 +#define CORE_DIG_RW_COMMON_9 0x3892 +#define CORE_DIG_RW_COMMON_10 0x3894 +#define CORE_DIG_RW_COMMON_11 0x3896 +#define CORE_DIG_RW_COMMON_12 0x3898 +#define CORE_DIG_RW_COMMON_13 0x389a +#define CORE_DIG_RW_COMMON_14 0x389c +#define CORE_DIG_RW_COMMON_15 0x389e +#define CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_0 0x39e0 +#define CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_1 0x39e2 +#define CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_2 0x39e4 +#define CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_3 0x39e6 +#define CORE_DIG_COMMON_RW_DESKEW_FINE_MEM 0x3fe0 +#define CORE_DIG_COMMON_R_DESKEW_FINE_MEM 0x3fe2 +#define PPI_RW_DPHY_LANE0_LBERT_0 0x4000 +#define PPI_RW_DPHY_LANE0_LBERT_1 0x4002 +#define PPI_R_DPHY_LANE0_LBERT_0 0x4004 +#define PPI_R_DPHY_LANE0_LBERT_1 0x4006 +#define PPI_RW_DPHY_LANE0_SPARE 0x4008 +#define PPI_RW_DPHY_LANE1_LBERT_0 0x4400 +#define PPI_RW_DPHY_LANE1_LBERT_1 0x4402 +#define PPI_R_DPHY_LANE1_LBERT_0 0x4404 +#define PPI_R_DPHY_LANE1_LBERT_1 0x4406 +#define PPI_RW_DPHY_LANE1_SPARE 0x4408 +#define PPI_RW_DPHY_LANE2_LBERT_0 0x4800 +#define PPI_RW_DPHY_LANE2_LBERT_1 0x4802 +#define PPI_R_DPHY_LANE2_LBERT_0 0x4804 +#define PPI_R_DPHY_LANE2_LBERT_1 0x4806 +#define PPI_RW_DPHY_LANE2_SPARE 0x4808 +#define PPI_RW_DPHY_LANE3_LBERT_0 0x4c00 +#define PPI_RW_DPHY_LANE3_LBERT_1 0x4c02 +#define PPI_R_DPHY_LANE3_LBERT_0 0x4c04 +#define PPI_R_DPHY_LANE3_LBERT_1 0x4c06 +#define PPI_RW_DPHY_LANE3_SPARE 0x4c08 +#define CORE_DIG_DLANE_0_RW_CFG_0 0x6000 +#define CORE_DIG_DLANE_0_RW_CFG_1 0x6002 +#define CORE_DIG_DLANE_0_RW_CFG_2 0x6004 +#define CORE_DIG_DLANE_0_RW_LP_0 0x6080 +#define CORE_DIG_DLANE_0_RW_LP_1 0x6082 +#define CORE_DIG_DLANE_0_RW_LP_2 0x6084 +#define CORE_DIG_DLANE_0_R_LP_0 0x60a0 +#define CORE_DIG_DLANE_0_R_LP_1 0x60a2 +#define CORE_DIG_DLANE_0_R_HS_TX_0 0x60e0 +#define CORE_DIG_DLANE_0_RW_HS_RX_0 0x6100 +#define CORE_DIG_DLANE_0_RW_HS_RX_1 0x6102 +#define CORE_DIG_DLANE_0_RW_HS_RX_2 0x6104 +#define CORE_DIG_DLANE_0_RW_HS_RX_3 0x6106 +#define CORE_DIG_DLANE_0_RW_HS_RX_4 0x6108 +#define CORE_DIG_DLANE_0_RW_HS_RX_5 0x610a +#define CORE_DIG_DLANE_0_RW_HS_RX_6 0x610c +#define CORE_DIG_DLANE_0_RW_HS_RX_7 0x610e +#define CORE_DIG_DLANE_0_RW_HS_RX_8 0x6110 +#define CORE_DIG_DLANE_0_RW_HS_RX_9 0x6112 +#define CORE_DIG_DLANE_0_R_HS_RX_0 0x6120 +#define CORE_DIG_DLANE_0_R_HS_RX_1 0x6122 +#define CORE_DIG_DLANE_0_R_HS_RX_2 0x6124 +#define CORE_DIG_DLANE_0_R_HS_RX_3 0x6126 +#define CORE_DIG_DLANE_0_R_HS_RX_4 0x6128 +#define CORE_DIG_DLANE_0_RW_HS_TX_0 0x6200 +#define CORE_DIG_DLANE_0_RW_HS_TX_1 0x6202 +#define CORE_DIG_DLANE_0_RW_HS_TX_2 0x6204 +#define CORE_DIG_DLANE_0_RW_HS_TX_3 0x6206 +#define CORE_DIG_DLANE_0_RW_HS_TX_4 0x6208 +#define CORE_DIG_DLANE_0_RW_HS_TX_5 0x620a +#define CORE_DIG_DLANE_0_RW_HS_TX_6 0x620c +#define CORE_DIG_DLANE_0_RW_HS_TX_7 0x620e +#define CORE_DIG_DLANE_0_RW_HS_TX_8 0x6210 +#define CORE_DIG_DLANE_0_RW_HS_TX_9 0x6212 +#define CORE_DIG_DLANE_0_RW_HS_TX_10 0x6214 +#define CORE_DIG_DLANE_0_RW_HS_TX_11 0x6216 +#define CORE_DIG_DLANE_0_RW_HS_TX_12 0x6218 +#define CORE_DIG_DLANE_1_RW_CFG_0 0x6400 +#define CORE_DIG_DLANE_1_RW_CFG_1 0x6402 +#define CORE_DIG_DLANE_1_RW_CFG_2 0x6404 +#define CORE_DIG_DLANE_1_RW_LP_0 0x6480 +#define CORE_DIG_DLANE_1_RW_LP_1 0x6482 +#define CORE_DIG_DLANE_1_RW_LP_2 0x6484 +#define CORE_DIG_DLANE_1_R_LP_0 0x64a0 +#define CORE_DIG_DLANE_1_R_LP_1 0x64a2 +#define CORE_DIG_DLANE_1_R_HS_TX_0 0x64e0 +#define CORE_DIG_DLANE_1_RW_HS_RX_0 0x6500 +#define CORE_DIG_DLANE_1_RW_HS_RX_1 0x6502 +#define CORE_DIG_DLANE_1_RW_HS_RX_2 0x6504 +#define CORE_DIG_DLANE_1_RW_HS_RX_3 0x6506 +#define CORE_DIG_DLANE_1_RW_HS_RX_4 0x6508 +#define CORE_DIG_DLANE_1_RW_HS_RX_5 0x650a +#define CORE_DIG_DLANE_1_RW_HS_RX_6 0x650c +#define CORE_DIG_DLANE_1_RW_HS_RX_7 0x650e +#define CORE_DIG_DLANE_1_RW_HS_RX_8 0x6510 +#define CORE_DIG_DLANE_1_RW_HS_RX_9 0x6512 +#define CORE_DIG_DLANE_1_R_HS_RX_0 0x6520 +#define CORE_DIG_DLANE_1_R_HS_RX_1 0x6522 +#define CORE_DIG_DLANE_1_R_HS_RX_2 0x6524 +#define CORE_DIG_DLANE_1_R_HS_RX_3 0x6526 +#define CORE_DIG_DLANE_1_R_HS_RX_4 0x6528 +#define CORE_DIG_DLANE_1_RW_HS_TX_0 0x6600 +#define CORE_DIG_DLANE_1_RW_HS_TX_1 0x6602 +#define CORE_DIG_DLANE_1_RW_HS_TX_2 0x6604 +#define CORE_DIG_DLANE_1_RW_HS_TX_3 0x6606 +#define CORE_DIG_DLANE_1_RW_HS_TX_4 0x6608 +#define CORE_DIG_DLANE_1_RW_HS_TX_5 0x660a +#define CORE_DIG_DLANE_1_RW_HS_TX_6 0x660c +#define CORE_DIG_DLANE_1_RW_HS_TX_7 0x660e +#define CORE_DIG_DLANE_1_RW_HS_TX_8 0x6610 +#define CORE_DIG_DLANE_1_RW_HS_TX_9 0x6612 +#define CORE_DIG_DLANE_1_RW_HS_TX_10 0x6614 +#define CORE_DIG_DLANE_1_RW_HS_TX_11 0x6616 +#define CORE_DIG_DLANE_1_RW_HS_TX_12 0x6618 +#define CORE_DIG_DLANE_2_RW_CFG_0 0x6800 +#define CORE_DIG_DLANE_2_RW_CFG_1 0x6802 +#define CORE_DIG_DLANE_2_RW_CFG_2 0x6804 +#define CORE_DIG_DLANE_2_RW_LP_0 0x6880 +#define CORE_DIG_DLANE_2_RW_LP_1 0x6882 +#define CORE_DIG_DLANE_2_RW_LP_2 0x6884 +#define CORE_DIG_DLANE_2_R_LP_0 0x68a0 +#define CORE_DIG_DLANE_2_R_LP_1 0x68a2 +#define CORE_DIG_DLANE_2_R_HS_TX_0 0x68e0 +#define CORE_DIG_DLANE_2_RW_HS_RX_0 0x6900 +#define CORE_DIG_DLANE_2_RW_HS_RX_1 0x6902 +#define CORE_DIG_DLANE_2_RW_HS_RX_2 0x6904 +#define CORE_DIG_DLANE_2_RW_HS_RX_3 0x6906 +#define CORE_DIG_DLANE_2_RW_HS_RX_4 0x6908 +#define CORE_DIG_DLANE_2_RW_HS_RX_5 0x690a +#define CORE_DIG_DLANE_2_RW_HS_RX_6 0x690c +#define CORE_DIG_DLANE_2_RW_HS_RX_7 0x690e +#define CORE_DIG_DLANE_2_RW_HS_RX_8 0x6910 +#define CORE_DIG_DLANE_2_RW_HS_RX_9 0x6912 +#define CORE_DIG_DLANE_2_R_HS_RX_0 0x6920 +#define CORE_DIG_DLANE_2_R_HS_RX_1 0x6922 +#define CORE_DIG_DLANE_2_R_HS_RX_2 0x6924 +#define CORE_DIG_DLANE_2_R_HS_RX_3 0x6926 +#define CORE_DIG_DLANE_2_R_HS_RX_4 0x6928 +#define CORE_DIG_DLANE_2_RW_HS_TX_0 0x6a00 +#define CORE_DIG_DLANE_2_RW_HS_TX_1 0x6a02 +#define CORE_DIG_DLANE_2_RW_HS_TX_2 0x6a04 +#define CORE_DIG_DLANE_2_RW_HS_TX_3 0x6a06 +#define CORE_DIG_DLANE_2_RW_HS_TX_4 0x6a08 +#define CORE_DIG_DLANE_2_RW_HS_TX_5 0x6a0a +#define CORE_DIG_DLANE_2_RW_HS_TX_6 0x6a0c +#define CORE_DIG_DLANE_2_RW_HS_TX_7 0x6a0e +#define CORE_DIG_DLANE_2_RW_HS_TX_8 0x6a10 +#define CORE_DIG_DLANE_2_RW_HS_TX_9 0x6a12 +#define CORE_DIG_DLANE_2_RW_HS_TX_10 0x6a14 +#define CORE_DIG_DLANE_2_RW_HS_TX_11 0x6a16 +#define CORE_DIG_DLANE_2_RW_HS_TX_12 0x6a18 +#define CORE_DIG_DLANE_3_RW_CFG_0 0x6c00 +#define CORE_DIG_DLANE_3_RW_CFG_1 0x6c02 +#define CORE_DIG_DLANE_3_RW_CFG_2 0x6c04 +#define CORE_DIG_DLANE_3_RW_LP_0 0x6c80 +#define CORE_DIG_DLANE_3_RW_LP_1 0x6c82 +#define CORE_DIG_DLANE_3_RW_LP_2 0x6c84 +#define CORE_DIG_DLANE_3_R_LP_0 0x6ca0 +#define CORE_DIG_DLANE_3_R_LP_1 0x6ca2 +#define CORE_DIG_DLANE_3_R_HS_TX_0 0x6ce0 +#define CORE_DIG_DLANE_3_RW_HS_RX_0 0x6d00 +#define CORE_DIG_DLANE_3_RW_HS_RX_1 0x6d02 +#define CORE_DIG_DLANE_3_RW_HS_RX_2 0x6d04 +#define CORE_DIG_DLANE_3_RW_HS_RX_3 0x6d06 +#define CORE_DIG_DLANE_3_RW_HS_RX_4 0x6d08 +#define CORE_DIG_DLANE_3_RW_HS_RX_5 0x6d0a +#define CORE_DIG_DLANE_3_RW_HS_RX_6 0x6d0c +#define CORE_DIG_DLANE_3_RW_HS_RX_7 0x6d0e +#define CORE_DIG_DLANE_3_RW_HS_RX_8 0x6d10 +#define CORE_DIG_DLANE_3_RW_HS_RX_9 0x6d12 +#define CORE_DIG_DLANE_3_R_HS_RX_0 0x6d20 +#define CORE_DIG_DLANE_3_R_HS_RX_1 0x6d22 +#define CORE_DIG_DLANE_3_R_HS_RX_2 0x6d24 +#define CORE_DIG_DLANE_3_R_HS_RX_3 0x6d26 +#define CORE_DIG_DLANE_3_R_HS_RX_4 0x6d28 +#define CORE_DIG_DLANE_3_RW_HS_TX_0 0x6e00 +#define CORE_DIG_DLANE_3_RW_HS_TX_1 0x6e02 +#define CORE_DIG_DLANE_3_RW_HS_TX_2 0x6e04 +#define CORE_DIG_DLANE_3_RW_HS_TX_3 0x6e06 +#define CORE_DIG_DLANE_3_RW_HS_TX_4 0x6e08 +#define CORE_DIG_DLANE_3_RW_HS_TX_5 0x6e0a +#define CORE_DIG_DLANE_3_RW_HS_TX_6 0x6e0c +#define CORE_DIG_DLANE_3_RW_HS_TX_7 0x6e0e +#define CORE_DIG_DLANE_3_RW_HS_TX_8 0x6e10 +#define CORE_DIG_DLANE_3_RW_HS_TX_9 0x6e12 +#define CORE_DIG_DLANE_3_RW_HS_TX_10 0x6e14 +#define CORE_DIG_DLANE_3_RW_HS_TX_11 0x6e16 +#define CORE_DIG_DLANE_3_RW_HS_TX_12 0x6e18 +#define CORE_DIG_DLANE_CLK_RW_CFG_0 0x7000 +#define CORE_DIG_DLANE_CLK_RW_CFG_1 0x7002 +#define CORE_DIG_DLANE_CLK_RW_CFG_2 0x7004 +#define CORE_DIG_DLANE_CLK_RW_LP_0 0x7080 +#define CORE_DIG_DLANE_CLK_RW_LP_1 0x7082 +#define CORE_DIG_DLANE_CLK_RW_LP_2 0x7084 +#define CORE_DIG_DLANE_CLK_R_LP_0 0x70a0 +#define CORE_DIG_DLANE_CLK_R_LP_1 0x70a2 +#define CORE_DIG_DLANE_CLK_R_HS_TX_0 0x70e0 +#define CORE_DIG_DLANE_CLK_RW_HS_RX_0 0x7100 +#define CORE_DIG_DLANE_CLK_RW_HS_RX_1 0x7102 +#define CORE_DIG_DLANE_CLK_RW_HS_RX_2 0x7104 +#define CORE_DIG_DLANE_CLK_RW_HS_RX_3 0x7106 +#define CORE_DIG_DLANE_CLK_RW_HS_RX_4 0x7108 +#define CORE_DIG_DLANE_CLK_RW_HS_RX_5 0x710a +#define CORE_DIG_DLANE_CLK_RW_HS_RX_6 0x710c +#define CORE_DIG_DLANE_CLK_RW_HS_RX_7 0x710e +#define CORE_DIG_DLANE_CLK_RW_HS_RX_8 0x7110 +#define CORE_DIG_DLANE_CLK_RW_HS_RX_9 0x7112 +#define CORE_DIG_DLANE_CLK_R_HS_RX_0 0x7120 +#define CORE_DIG_DLANE_CLK_R_HS_RX_1 0x7122 +#define CORE_DIG_DLANE_CLK_R_HS_RX_2 0x7124 +#define CORE_DIG_DLANE_CLK_R_HS_RX_3 0x7126 +#define CORE_DIG_DLANE_CLK_R_HS_RX_4 0x7128 +#define CORE_DIG_DLANE_CLK_RW_HS_TX_0 0x7200 +#define CORE_DIG_DLANE_CLK_RW_HS_TX_1 0x7202 +#define CORE_DIG_DLANE_CLK_RW_HS_TX_2 0x7204 +#define CORE_DIG_DLANE_CLK_RW_HS_TX_3 0x7206 +#define CORE_DIG_DLANE_CLK_RW_HS_TX_4 0x7208 +#define CORE_DIG_DLANE_CLK_RW_HS_TX_5 0x720a +#define CORE_DIG_DLANE_CLK_RW_HS_TX_6 0x720c +#define CORE_DIG_DLANE_CLK_RW_HS_TX_7 0x720e +#define CORE_DIG_DLANE_CLK_RW_HS_TX_8 0x7210 +#define CORE_DIG_DLANE_CLK_RW_HS_TX_9 0x7212 +#define CORE_DIG_DLANE_CLK_RW_HS_TX_10 0x7214 +#define CORE_DIG_DLANE_CLK_RW_HS_TX_11 0x7216 +#define CORE_DIG_DLANE_CLK_RW_HS_TX_12 0x7218 +#define PPI_RW_CPHY_TRIO0_LBERT_0 0x8000 +#define PPI_RW_CPHY_TRIO0_LBERT_1 0x8002 +#define PPI_R_CPHY_TRIO0_LBERT_0 0x8004 +#define PPI_R_CPHY_TRIO0_LBERT_1 0x8006 +#define PPI_RW_CPHY_TRIO0_SPARE 0x8008 +#define PPI_RW_CPHY_TRIO1_LBERT_0 0x8400 +#define PPI_RW_CPHY_TRIO1_LBERT_1 0x8402 +#define PPI_R_CPHY_TRIO1_LBERT_0 0x8404 +#define PPI_R_CPHY_TRIO1_LBERT_1 0x8406 +#define PPI_RW_CPHY_TRIO1_SPARE 0x8408 +#define PPI_RW_CPHY_TRIO2_LBERT_0 0x8800 +#define PPI_RW_CPHY_TRIO2_LBERT_1 0x8802 +#define PPI_R_CPHY_TRIO2_LBERT_0 0x8804 +#define PPI_R_CPHY_TRIO2_LBERT_1 0x8806 +#define PPI_RW_CPHY_TRIO2_SPARE 0x8808 +#define CORE_DIG_CLANE_0_RW_CFG_0 0xa000 +#define CORE_DIG_CLANE_0_RW_CFG_2 0xa004 +#define CORE_DIG_CLANE_0_RW_LP_0 0xa080 +#define CORE_DIG_CLANE_0_RW_LP_1 0xa082 +#define CORE_DIG_CLANE_0_RW_LP_2 0xa084 +#define CORE_DIG_CLANE_0_R_LP_0 0xa0a0 +#define CORE_DIG_CLANE_0_R_LP_1 0xa0a2 +#define CORE_DIG_CLANE_0_RW_HS_RX_0 0xa100 +#define CORE_DIG_CLANE_0_RW_HS_RX_1 0xa102 +#define CORE_DIG_CLANE_0_RW_HS_RX_2 0xa104 +#define CORE_DIG_CLANE_0_RW_HS_RX_3 0xa106 +#define CORE_DIG_CLANE_0_RW_HS_RX_4 0xa108 +#define CORE_DIG_CLANE_0_RW_HS_RX_5 0xa10a +#define CORE_DIG_CLANE_0_RW_HS_RX_6 0xa10c +#define CORE_DIG_CLANE_0_R_RX_0 0xa120 +#define CORE_DIG_CLANE_0_R_RX_1 0xa122 +#define CORE_DIG_CLANE_0_R_TX_0 0xa124 +#define CORE_DIG_CLANE_0_R_RX_2 0xa126 +#define CORE_DIG_CLANE_0_R_RX_3 0xa128 +#define CORE_DIG_CLANE_0_RW_HS_TX_0 0xa200 +#define CORE_DIG_CLANE_0_RW_HS_TX_1 0xa202 +#define CORE_DIG_CLANE_0_RW_HS_TX_2 0xa204 +#define CORE_DIG_CLANE_0_RW_HS_TX_3 0xa206 +#define CORE_DIG_CLANE_0_RW_HS_TX_4 0xa208 +#define CORE_DIG_CLANE_0_RW_HS_TX_5 0xa20a +#define CORE_DIG_CLANE_0_RW_HS_TX_6 0xa20c +#define CORE_DIG_CLANE_0_RW_HS_TX_7 0xa20e +#define CORE_DIG_CLANE_0_RW_HS_TX_8 0xa210 +#define CORE_DIG_CLANE_0_RW_HS_TX_9 0xa212 +#define CORE_DIG_CLANE_0_RW_HS_TX_10 0xa214 +#define CORE_DIG_CLANE_0_RW_HS_TX_11 0xa216 +#define CORE_DIG_CLANE_0_RW_HS_TX_12 0xa218 +#define CORE_DIG_CLANE_0_RW_HS_TX_13 0xa21a +#define CORE_DIG_CLANE_1_RW_CFG_0 0xa400 +#define CORE_DIG_CLANE_1_RW_CFG_2 0xa404 +#define CORE_DIG_CLANE_1_RW_LP_0 0xa480 +#define CORE_DIG_CLANE_1_RW_LP_1 0xa482 +#define CORE_DIG_CLANE_1_RW_LP_2 0xa484 +#define CORE_DIG_CLANE_1_R_LP_0 0xa4a0 +#define CORE_DIG_CLANE_1_R_LP_1 0xa4a2 +#define CORE_DIG_CLANE_1_RW_HS_RX_0 0xa500 +#define CORE_DIG_CLANE_1_RW_HS_RX_1 0xa502 +#define CORE_DIG_CLANE_1_RW_HS_RX_2 0xa504 +#define CORE_DIG_CLANE_1_RW_HS_RX_3 0xa506 +#define CORE_DIG_CLANE_1_RW_HS_RX_4 0xa508 +#define CORE_DIG_CLANE_1_RW_HS_RX_5 0xa50a +#define CORE_DIG_CLANE_1_RW_HS_RX_6 0xa50c +#define CORE_DIG_CLANE_1_R_RX_0 0xa520 +#define CORE_DIG_CLANE_1_R_RX_1 0xa522 +#define CORE_DIG_CLANE_1_R_TX_0 0xa524 +#define CORE_DIG_CLANE_1_R_RX_2 0xa526 +#define CORE_DIG_CLANE_1_R_RX_3 0xa528 +#define CORE_DIG_CLANE_1_RW_HS_TX_0 0xa600 +#define CORE_DIG_CLANE_1_RW_HS_TX_1 0xa602 +#define CORE_DIG_CLANE_1_RW_HS_TX_2 0xa604 +#define CORE_DIG_CLANE_1_RW_HS_TX_3 0xa606 +#define CORE_DIG_CLANE_1_RW_HS_TX_4 0xa608 +#define CORE_DIG_CLANE_1_RW_HS_TX_5 0xa60a +#define CORE_DIG_CLANE_1_RW_HS_TX_6 0xa60c +#define CORE_DIG_CLANE_1_RW_HS_TX_7 0xa60e +#define CORE_DIG_CLANE_1_RW_HS_TX_8 0xa610 +#define CORE_DIG_CLANE_1_RW_HS_TX_9 0xa612 +#define CORE_DIG_CLANE_1_RW_HS_TX_10 0xa614 +#define CORE_DIG_CLANE_1_RW_HS_TX_11 0xa616 +#define CORE_DIG_CLANE_1_RW_HS_TX_12 0xa618 +#define CORE_DIG_CLANE_1_RW_HS_TX_13 0xa61a +#define CORE_DIG_CLANE_2_RW_CFG_0 0xa800 +#define CORE_DIG_CLANE_2_RW_CFG_2 0xa804 +#define CORE_DIG_CLANE_2_RW_LP_0 0xa880 +#define CORE_DIG_CLANE_2_RW_LP_1 0xa882 +#define CORE_DIG_CLANE_2_RW_LP_2 0xa884 +#define CORE_DIG_CLANE_2_R_LP_0 0xa8a0 +#define CORE_DIG_CLANE_2_R_LP_1 0xa8a2 +#define CORE_DIG_CLANE_2_RW_HS_RX_0 0xa900 +#define CORE_DIG_CLANE_2_RW_HS_RX_1 0xa902 +#define CORE_DIG_CLANE_2_RW_HS_RX_2 0xa904 +#define CORE_DIG_CLANE_2_RW_HS_RX_3 0xa906 +#define CORE_DIG_CLANE_2_RW_HS_RX_4 0xa908 +#define CORE_DIG_CLANE_2_RW_HS_RX_5 0xa90a +#define CORE_DIG_CLANE_2_RW_HS_RX_6 0xa90c +#define CORE_DIG_CLANE_2_R_RX_0 0xa920 +#define CORE_DIG_CLANE_2_R_RX_1 0xa922 +#define CORE_DIG_CLANE_2_R_TX_0 0xa924 +#define CORE_DIG_CLANE_2_R_RX_2 0xa926 +#define CORE_DIG_CLANE_2_R_RX_3 0xa928 +#define CORE_DIG_CLANE_2_RW_HS_TX_0 0xaa00 +#define CORE_DIG_CLANE_2_RW_HS_TX_1 0xaa02 +#define CORE_DIG_CLANE_2_RW_HS_TX_2 0xaa04 +#define CORE_DIG_CLANE_2_RW_HS_TX_3 0xaa06 +#define CORE_DIG_CLANE_2_RW_HS_TX_4 0xaa08 +#define CORE_DIG_CLANE_2_RW_HS_TX_5 0xaa0a +#define CORE_DIG_CLANE_2_RW_HS_TX_6 0xaa0c +#define CORE_DIG_CLANE_2_RW_HS_TX_7 0xaa0e +#define CORE_DIG_CLANE_2_RW_HS_TX_8 0xaa10 +#define CORE_DIG_CLANE_2_RW_HS_TX_9 0xaa12 +#define CORE_DIG_CLANE_2_RW_HS_TX_10 0xaa14 +#define CORE_DIG_CLANE_2_RW_HS_TX_11 0xaa16 +#define CORE_DIG_CLANE_2_RW_HS_TX_12 0xaa18 +#define CORE_DIG_CLANE_2_RW_HS_TX_13 0xaa1a + +/* dwc csi host controller registers */ +#define IS_IO_CSI2_HOST_BASE(i) (IS_IO_BASE + 0x40000 + \ + 0x2000 * (i)) +#define VERSION 0x0 +#define N_LANES 0x4 +#define CSI2_RESETN 0x8 +#define INT_ST_MAIN 0xc +#define DATA_IDS_1 0x10 +#define DATA_IDS_2 0x14 +#define CDPHY_MODE 0x1c +#define DATA_IDS_VC_1 0x30 +#define DATA_IDS_VC_2 0x34 +#define PHY_SHUTDOWNZ 0x40 +#define DPHY_RSTZ 0x44 +#define PHY_RX 0x48 +#define PHY_STOPSTATE 0x4c +#define PHY_TEST_CTRL0 0x50 +#define PHY_TEST_CTRL1 0x54 +#define PPI_PG_PATTERN_VRES 0x60 +#define PPI_PG_PATTERN_HRES 0x64 +#define PPI_PG_CONFIG 0x68 +#define PPI_PG_ENABLE 0x6c +#define PPI_PG_STATUS 0x70 +#define VC_EXTENSION 0xc8 +#define PHY_CAL 0xcc +#define INT_ST_PHY_FATAL 0xe0 +#define INT_MSK_PHY_FATAL 0xe4 +#define INT_FORCE_PHY_FATAL 0xe8 +#define INT_ST_PKT_FATAL 0xf0 +#define INT_MSK_PKT_FATAL 0xf4 +#define INT_FORCE_PKT_FATAL 0xf8 +#define INT_ST_PHY 0x110 +#define INT_MSK_PHY 0x114 +#define INT_FORCE_PHY 0x118 +#define INT_ST_LINE 0x130 +#define INT_MSK_LINE 0x134 +#define INT_FORCE_LINE 0x138 +#define INT_ST_BNDRY_FRAME_FATAL 0x280 +#define INT_MSK_BNDRY_FRAME_FATAL 0x284 +#define INT_FORCE_BNDRY_FRAME_FATAL 0x288 +#define INT_ST_SEQ_FRAME_FATAL 0x290 +#define INT_MSK_SEQ_FRAME_FATAL 0x294 +#define INT_FORCE_SEQ_FRAME_FATAL 0x298 +#define INT_ST_CRC_FRAME_FATAL 0x2a0 +#define INT_MSK_CRC_FRAME_FATAL 0x2a4 +#define INT_FORCE_CRC_FRAME_FATAL 0x2a8 +#define INT_ST_PLD_CRC_FATAL 0x2b0 +#define INT_MSK_PLD_CRC_FATAL 0x2b4 +#define INT_FORCE_PLD_CRC_FATAL 0x2b8 +#define INT_ST_DATA_ID 0x2c0 +#define INT_MSK_DATA_ID 0x2c4 +#define INT_FORCE_DATA_ID 0x2c8 +#define INT_ST_ECC_CORRECTED 0x2d0 +#define INT_MSK_ECC_CORRECTED 0x2d4 +#define INT_FORCE_ECC_CORRECTED 0x2d8 +#define SCRAMBLING 0x300 +#define SCRAMBLING_SEED1 0x304 +#define SCRAMBLING_SEED2 0x308 +#define SCRAMBLING_SEED3 0x30c +#define SCRAMBLING_SEED4 0x310 +#define SCRAMBLING 0x300 + +#define IS_IO_CSI2_ADPL_PORT_BASE(i) (IS_IO_BASE + 0x40800 + \ + 0x2000 * (i)) +#define CSI2_ADPL_INPUT_MODE 0x0 +#define CSI2_ADPL_CSI_RX_ERR_IRQ_CLEAR_EN 0x4 +#define CSI2_ADPL_CSI_RX_ERR_IRQ_CLEAR_ADDR 0x8 +#define CSI2_ADPL_CSI_RX_ERR_IRQ_STATUS 0xc +#define CSI2_ADPL_IRQ_CTL_COMMON_STATUS 0xa4 +#define CSI2_ADPL_IRQ_CTL_COMMON_CLEAR 0xa8 +#define CSI2_ADPL_IRQ_CTL_COMMON_ENABLE 0xac +#define CSI2_ADPL_IRQ_CTL_FS_STATUS 0xbc +#define CSI2_ADPL_IRQ_CTL_FS_CLEAR 0xc0 +#define CSI2_ADPL_IRQ_CTL_FS_ENABLE 0xc4 +#define CSI2_ADPL_IRQ_CTL_FE_STATUS 0xc8 +#define CSI2_ADPL_IRQ_CTL_FE_CLEAR 0xcc +#define CSI2_ADPL_IRQ_CTL_FE_ENABLE 0xd0 + +/* software control the legacy csi irq */ +#define IS_IO_CSI2_ERR_LEGACY_IRQ_CTL_BASE(i) (IS_IO_BASE + 0x40c00 + \ + 0x2000 * (i)) +#define IS_IO_CSI2_SYNC_LEGACY_IRQ_CTL_BASE(i) (IS_IO_BASE + 0x40d00 + \ + 0x2000 * (i)) +#define IS_IO_CSI2_LEGACY_IRQ_CTRL_BASE (IS_IO_BASE + 0x49000) +#define IS_IO_CSI2_IRQ_CTRL_BASE (IS_IO_BASE + 0x4e100) + +#define IRQ_CTL_EDGE 0x0 +#define IRQ_CTL_MASK 0x4 +#define IRQ_CTL_STATUS 0x8 +#define IRQ_CTL_CLEAR 0xc +#define IRQ_CTL_ENABLE 0x10 +/* FE irq for PTL */ +#define IRQ1_CTL_MASK 0x14 +#define IRQ1_CTL_STATUS 0x18 +#define IRQ1_CTL_CLEAR 0x1c +#define IRQ1_CTL_ENABLE 0x20 + +/* software to set the clock gate to use the port or mgc */ +#define IS_IO_GPREGS_BASE (IS_IO_BASE + 0x49200) +#define SRST_PORT_ARB 0x0 +#define SRST_MGC 0x4 +#define SRST_WIDTH_CONV 0x8 +#define SRST_CSI_IRQ 0xc +#define SRST_CSI_LEGACY_IRQ 0x10 +#define CLK_EN_TXCLKESC 0x14 +#define CLK_DIV_FACTOR_IS_CLK 0x18 +#define CLK_DIV_FACTOR_APB_CLK 0x1c +#define CSI_PORT_CLK_GATE 0x20 +#define CSI_PORTAB_AGGREGATION 0x24 +#define MGC_CLK_GATE 0x2c +#define CG_CTRL_BITS 0x3c +#define SPARE_RW 0xf8 +#define SPARE_RO 0xfc + +#define IS_IO_CSI2_MPF_PORT_BASE(i) (IS_IO_BASE + 0x53000 + \ + 0x1000 * (i)) +#define MPF_16_IRQ_CNTRL_STATUS 0x238 +#define MPF_16_IRQ_CNTRL_CLEAR 0x23c +#define MPF_16_IRQ_CNTRL_ENABLE 0x240 + +/* software config the phy */ +#define IS_IO_CSI2_GPREGS_BASE (IS_IO_BASE + 0x53400) +#define IPU8_IS_IO_CSI2_GPREGS_BASE (IS_IO_BASE + 0x40e00) +#define CSI_ADAPT_LAYER_SRST 0x0 +#define MPF_SRST_RST 0x4 +#define CSI_ERR_IRQ_CTRL_SRST 0x8 +#define CSI_SYNC_RC_SRST 0xc +#define CSI_CG_CTRL_BITS 0x10 +#define SOC_CSI2HOST_SELECT 0x14 +#define PHY_RESET 0x18 +#define PHY_SHUTDOWN 0x1c +#define PHY_MODE 0x20 +#define PHY_READY 0x24 +#define PHY_CLK_LANE_FORCE_CONTROL 0x28 +#define PHY_CLK_LANE_CONTROL 0x2c +#define PHY_CLK_LANE_STATUS 0x30 +#define PHY_LANE_RX_ESC_REQ 0x34 +#define PHY_LANE_RX_ESC_DATA 0x38 +#define PHY_LANE_TURNDISABLE 0x3c +#define PHY_LANE_DIRECTION 0x40 +#define PHY_LANE_FORCE_CONTROL 0x44 +#define PHY_LANE_CONTROL_EN 0x48 +#define PHY_LANE_CONTROL_DATAWIDTH 0x4c +#define PHY_LANE_STATUS 0x50 +#define PHY_LANE_ERR 0x54 +#define PHY_LANE_RXALP 0x58 +#define PHY_LANE_RXALP_NIBBLE 0x5c +#define PHY_PARITY_ERROR 0x60 +#define PHY_DEBUG_REGS_CLK_GATE_EN 0x64 +#define SPARE_RW 0xf8 +#define SPARE_RO 0xfc + +/* software not touch */ +#define PORT_ARB_BASE (IS_IO_BASE + 0x4e000) +#define PORT_ARB_IRQ_CTL_STATUS 0x4 +#define PORT_ARB_IRQ_CTL_CLEAR 0x8 +#define PORT_ARB_IRQ_CTL_ENABLE 0xc + +#define MGC_PPC 4U +#define MGC_DTYPE_RAW(i) (((i) - 8) / 2) +#define IS_IO_MGC_BASE (IS_IO_BASE + 0x48000) +#define MGC_KICK 0x0 +#define MGC_ASYNC_STOP 0x4 +#define MGC_PORT_OFFSET 0x100 +#define MGC_CSI_PORT_MAP(i) (0x8 + (i) * 0x4) +#define MGC_MG_PORT(i) (IS_IO_MGC_BASE + \ + (i) * MGC_PORT_OFFSET) +/* per mgc instance */ +#define MGC_MG_CSI_ADAPT_LAYER_TYPE 0x28 +#define MGC_MG_MODE 0x2c +#define MGC_MG_INIT_COUNTER 0x30 +#define MGC_MG_MIPI_VC 0x34 +#define MGC_MG_MIPI_DTYPES 0x38 +#define MGC_MG_MULTI_DTYPES_MODE 0x3c +#define MGC_MG_NOF_FRAMES 0x40 +#define MGC_MG_FRAME_DIM 0x44 +#define MGC_MG_HBLANK 0x48 +#define MGC_MG_VBLANK 0x4c +#define MGC_MG_TPG_MODE 0x50 +#define MGC_MG_TPG_R0 0x54 +#define MGC_MG_TPG_G0 0x58 +#define MGC_MG_TPG_B0 0x5c +#define MGC_MG_TPG_R1 0x60 +#define MGC_MG_TPG_G1 0x64 +#define MGC_MG_TPG_B1 0x68 +#define MGC_MG_TPG_FACTORS 0x6c +#define MGC_MG_TPG_MASKS 0x70 +#define MGC_MG_TPG_XY_MASK 0x74 +#define MGC_MG_TPG_TILE_DIM 0x78 +#define MGC_MG_PRBS_LFSR_INIT_0 0x7c +#define MGC_MG_PRBS_LFSR_INIT_1 0x80 +#define MGC_MG_SYNC_STOP_POINT 0x84 +#define MGC_MG_SYNC_STOP_POINT_LOC 0x88 +#define MGC_MG_ERR_INJECT 0x8c +#define MGC_MG_ERR_LOCATION 0x90 +#define MGC_MG_DTO_SPEED_CTRL_EN 0x94 +#define MGC_MG_DTO_SPEED_CTRL_INCR_VAL 0x98 +#define MGC_MG_HOR_LOC_STTS 0x9c +#define MGC_MG_VER_LOC_STTS 0xa0 +#define MGC_MG_FRAME_NUM_STTS 0xa4 +#define MGC_MG_BUSY_STTS 0xa8 +#define MGC_MG_STOPPED_STTS 0xac +/* tile width and height in pixels for Chess board and Color palette */ +#define MGC_TPG_TILE_WIDTH 64U +#define MGC_TPG_TILE_HEIGHT 64U + +#define IPU_CSI_PORT_A_ADDR_OFFSET 0x0 +#define IPU_CSI_PORT_B_ADDR_OFFSET 0x0 +#define IPU_CSI_PORT_C_ADDR_OFFSET 0x0 +#define IPU_CSI_PORT_D_ADDR_OFFSET 0x0 + +/* + * 0 - CSI RX Port 0 interrupt; + * 1 - MPF Port 0 interrupt; + * 2 - CSI RX Port 1 interrupt; + * 3 - MPF Port 1 interrupt; + * 4 - CSI RX Port 2 interrupt; + * 5 - MPF Port 2 interrupt; + * 6 - CSI RX Port 3 interrupt; + * 7 - MPF Port 3 interrupt; + * 8 - Port ARB FIFO 0 overflow; + * 9 - Port ARB FIFO 1 overflow; + * 10 - Port ARB FIFO 2 overflow; + * 11 - Port ARB FIFO 3 overflow; + * 12 - isys_cfgnoc_err_probe_intl; + * 13-15 - reserved + */ +#define IPU7_CSI_IS_IO_IRQ_MASK 0xffff + +/* Adapter layer irq */ +#define IPU7_CSI_ADPL_IRQ_MASK 0xffff + +/* sw irq from legacy irq control + * legacy irq status + * IPU7 + * 0 - CSI Port 0 error interrupt + * 1 - CSI Port 0 sync interrupt + * 2 - CSI Port 1 error interrupt + * 3 - CSI Port 1 sync interrupt + * 4 - CSI Port 2 error interrupt + * 5 - CSI Port 2 sync interrupt + * 6 - CSI Port 3 error interrupt + * 7 - CSI Port 3 sync interrupt + * IPU7P5 + * 0 - CSI Port 0 error interrupt + * 1 - CSI Port 0 fs interrupt + * 2 - CSI Port 0 fe interrupt + * 3 - CSI Port 1 error interrupt + * 4 - CSI Port 1 fs interrupt + * 5 - CSI Port 1 fe interrupt + * 6 - CSI Port 2 error interrupt + * 7 - CSI Port 2 fs interrupt + * 8 - CSI Port 2 fe interrupt + */ +#define IPU7_CSI_RX_LEGACY_IRQ_MASK 0x1ff + +/* legacy error status per port + * 0 - Error handler FIFO full; + * 1 - Reserved Short Packet encoding detected; + * 2 - Reserved Long Packet encoding detected; + * 3 - Received packet is too short (fewer data words than specified in header); + * 4 - Received packet is too long (more data words than specified in header); + * 5 - Short packet discarded due to errors; + * 6 - Long packet discarded due to errors; + * 7 - CSI Combo Rx interrupt; + * 8 - IDI CDC FIFO overflow; remaining bits are reserved and tied to 0; + */ +#define IPU7_CSI_RX_ERROR_IRQ_MASK 0xfff + +/* + * 0 - VC0 frame start received + * 1 - VC0 frame end received + * 2 - VC1 frame start received + * 3 - VC1 frame end received + * 4 - VC2 frame start received + * 5 - VC2 frame end received + * 6 - VC3 frame start received + * 7 - VC3 frame end received + * 8 - VC4 frame start received + * 9 - VC4 frame end received + * 10 - VC5 frame start received + * 11 - VC5 frame end received + * 12 - VC6 frame start received + * 13 - VC6 frame end received + * 14 - VC7 frame start received + * 15 - VC7 frame end received + * 16 - VC8 frame start received + * 17 - VC8 frame end received + * 18 - VC9 frame start received + * 19 - VC9 frame end received + * 20 - VC10 frame start received + * 21 - VC10 frame end received + * 22 - VC11 frame start received + * 23 - VC11 frame end received + * 24 - VC12 frame start received + * 25 - VC12 frame end received + * 26 - VC13 frame start received + * 27 - VC13 frame end received + * 28 - VC14 frame start received + * 29 - VC14 frame end received + * 30 - VC15 frame start received + * 31 - VC15 frame end received + */ + +#define IPU7_CSI_RX_SYNC_IRQ_MASK 0x0 +#define IPU7P5_CSI_RX_SYNC_FE_IRQ_MASK 0x0 + +#define CSI_RX_NUM_ERRORS_IN_IRQ 12U +#define CSI_RX_NUM_SYNC_IN_IRQ 32U + +enum CSI_FE_MODE_TYPE { + CSI_FE_DPHY_MODE = 0, + CSI_FE_CPHY_MODE = 1, +}; + +enum CSI_FE_INPUT_MODE { + CSI_SENSOR_INPUT = 0, + CSI_MIPIGEN_INPUT = 1, +}; + +enum MGC_CSI_ADPL_TYPE { + MGC_MAPPED_2_LANES = 0, + MGC_MAPPED_4_LANES = 1, +}; + +enum CSI2HOST_SELECTION { + CSI2HOST_SEL_SOC = 0, + CSI2HOST_SEL_CSI2HOST = 1, +}; + +#define IPU7_ISYS_LEGACY_IRQ_CSI2(port) (0x3 << (port)) +#define IPU7P5_ISYS_LEGACY_IRQ_CSI2(port) (0x7 << (port)) + +/* ---------------------------------------------------------------- */ +#define CSI_REG_BASE 0x220000 +#define CSI_REG_BASE_PORT(id) ((id) * 0x1000) + +/* CSI Port General Purpose Registers */ +#define CSI_REG_PORT_GPREG_SRST 0x0 +#define CSI_REG_PORT_GPREG_CSI2_SLV_REG_SRST 0x4 +#define CSI_REG_PORT_GPREG_CSI2_PORT_CONTROL 0x8 + +#define CSI_RX_NUM_IRQ 32U + +#define IPU7_CSI_RX_SYNC_FS_VC 0x55555555 +#define IPU7_CSI_RX_SYNC_FE_VC 0xaaaaaaaa +#define IPU7P5_CSI_RX_SYNC_FS_VC 0xffff +#define IPU7P5_CSI_RX_SYNC_FE_VC 0xffff + +#endif /* IPU7_ISYS_CSI2_REG_H */ diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi2.c b/drivers/staging/media/ipu7/ipu7-isys-csi2.c new file mode 100644 index 000000000000..9c16ae9a0e5b --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys-csi2.c @@ -0,0 +1,543 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <linux/atomic.h> +#include <linux/bits.h> +#include <linux/bug.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/io.h> +#include <linux/minmax.h> +#include <linux/mutex.h> +#include <linux/slab.h> + +#include <media/media-entity.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> +#include <media/v4l2-event.h> +#include <media/v4l2-subdev.h> + +#include "ipu7.h" +#include "ipu7-bus.h" +#include "ipu7-isys.h" +#include "ipu7-isys-csi2.h" +#include "ipu7-isys-csi2-regs.h" +#include "ipu7-isys-csi-phy.h" + +static const u32 csi2_supported_codes[] = { + MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_RGB565_1X16, + MEDIA_BUS_FMT_RGB888_1X24, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_YUYV10_1X20, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + 0, +}; + +s64 ipu7_isys_csi2_get_link_freq(struct ipu7_isys_csi2 *csi2) +{ + struct media_pad *src_pad; + + src_pad = media_entity_remote_source_pad_unique(&csi2->asd.sd.entity); + if (IS_ERR(src_pad)) { + dev_err(&csi2->isys->adev->auxdev.dev, + "can't get source pad of %s (%ld)\n", + csi2->asd.sd.name, PTR_ERR(src_pad)); + return PTR_ERR(src_pad); + } + + return v4l2_get_link_freq(src_pad, 0, 0); +} + +static int csi2_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, + struct v4l2_event_subscription *sub) +{ + struct ipu7_isys_subdev *asd = to_ipu7_isys_subdev(sd); + struct ipu7_isys_csi2 *csi2 = to_ipu7_isys_csi2(asd); + struct device *dev = &csi2->isys->adev->auxdev.dev; + + dev_dbg(dev, "csi2 subscribe event(type %u id %u)\n", + sub->type, sub->id); + + switch (sub->type) { + case V4L2_EVENT_FRAME_SYNC: + return v4l2_event_subscribe(fh, sub, 10, NULL); + case V4L2_EVENT_CTRL: + return v4l2_ctrl_subscribe_event(fh, sub); + default: + return -EINVAL; + } +} + +static const struct v4l2_subdev_core_ops csi2_sd_core_ops = { + .subscribe_event = csi2_subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, +}; + +static void csi2_irq_enable(struct ipu7_isys_csi2 *csi2) +{ + struct ipu7_device *isp = csi2->isys->adev->isp; + unsigned int offset, mask; + + /* enable CSI2 legacy error irq */ + offset = IS_IO_CSI2_ERR_LEGACY_IRQ_CTL_BASE(csi2->port); + mask = IPU7_CSI_RX_ERROR_IRQ_MASK; + writel(mask, csi2->base + offset + IRQ_CTL_CLEAR); + writel(mask, csi2->base + offset + IRQ_CTL_MASK); + writel(mask, csi2->base + offset + IRQ_CTL_ENABLE); + + /* enable CSI2 legacy sync irq */ + offset = IS_IO_CSI2_SYNC_LEGACY_IRQ_CTL_BASE(csi2->port); + mask = IPU7_CSI_RX_SYNC_IRQ_MASK; + writel(mask, csi2->base + offset + IRQ_CTL_CLEAR); + writel(mask, csi2->base + offset + IRQ_CTL_MASK); + writel(mask, csi2->base + offset + IRQ_CTL_ENABLE); + + mask = IPU7P5_CSI_RX_SYNC_FE_IRQ_MASK; + if (!is_ipu7(isp->hw_ver)) { + writel(mask, csi2->base + offset + IRQ1_CTL_CLEAR); + writel(mask, csi2->base + offset + IRQ1_CTL_MASK); + writel(mask, csi2->base + offset + IRQ1_CTL_ENABLE); + } +} + +static void csi2_irq_disable(struct ipu7_isys_csi2 *csi2) +{ + struct ipu7_device *isp = csi2->isys->adev->isp; + unsigned int offset, mask; + + /* disable CSI2 legacy error irq */ + offset = IS_IO_CSI2_ERR_LEGACY_IRQ_CTL_BASE(csi2->port); + mask = IPU7_CSI_RX_ERROR_IRQ_MASK; + writel(mask, csi2->base + offset + IRQ_CTL_CLEAR); + writel(0, csi2->base + offset + IRQ_CTL_MASK); + writel(0, csi2->base + offset + IRQ_CTL_ENABLE); + + /* disable CSI2 legacy sync irq */ + offset = IS_IO_CSI2_SYNC_LEGACY_IRQ_CTL_BASE(csi2->port); + mask = IPU7_CSI_RX_SYNC_IRQ_MASK; + writel(mask, csi2->base + offset + IRQ_CTL_CLEAR); + writel(0, csi2->base + offset + IRQ_CTL_MASK); + writel(0, csi2->base + offset + IRQ_CTL_ENABLE); + + if (!is_ipu7(isp->hw_ver)) { + writel(mask, csi2->base + offset + IRQ1_CTL_CLEAR); + writel(0, csi2->base + offset + IRQ1_CTL_MASK); + writel(0, csi2->base + offset + IRQ1_CTL_ENABLE); + } +} + +static void ipu7_isys_csi2_disable_stream(struct ipu7_isys_csi2 *csi2) +{ + struct ipu7_isys *isys = csi2->isys; + void __iomem *isys_base = isys->pdata->base; + + ipu7_isys_csi_phy_powerdown(csi2); + + writel(0x4, isys_base + IS_IO_GPREGS_BASE + CLK_DIV_FACTOR_APB_CLK); + csi2_irq_disable(csi2); +} + +static int ipu7_isys_csi2_enable_stream(struct ipu7_isys_csi2 *csi2) +{ + struct ipu7_isys *isys = csi2->isys; + struct device *dev = &isys->adev->auxdev.dev; + void __iomem *isys_base = isys->pdata->base; + unsigned int port, nlanes, offset; + int ret; + + port = csi2->port; + nlanes = csi2->nlanes; + + offset = IS_IO_GPREGS_BASE; + writel(0x2, isys_base + offset + CLK_DIV_FACTOR_APB_CLK); + dev_dbg(dev, "port %u CLK_GATE = 0x%04x DIV_FACTOR_APB_CLK=0x%04x\n", + port, readl(isys_base + offset + CSI_PORT_CLK_GATE), + readl(isys_base + offset + CLK_DIV_FACTOR_APB_CLK)); + if (port == 0U && nlanes == 4U && !is_ipu7(isys->adev->isp->hw_ver)) { + dev_dbg(dev, "CSI port %u in aggregation mode\n", port); + writel(0x1, isys_base + offset + CSI_PORTAB_AGGREGATION); + } + + /* input is coming from CSI receiver (sensor) */ + offset = IS_IO_CSI2_ADPL_PORT_BASE(port); + writel(CSI_SENSOR_INPUT, isys_base + offset + CSI2_ADPL_INPUT_MODE); + writel(1, isys_base + offset + CSI2_ADPL_CSI_RX_ERR_IRQ_CLEAR_EN); + + ret = ipu7_isys_csi_phy_powerup(csi2); + if (ret) { + dev_err(dev, "CSI-%d PHY power up failed %d\n", port, ret); + return ret; + } + + csi2_irq_enable(csi2); + + return 0; +} + +static int ipu7_isys_csi2_set_sel(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct ipu7_isys_subdev *asd = to_ipu7_isys_subdev(sd); + struct device *dev = &asd->isys->adev->auxdev.dev; + struct v4l2_mbus_framefmt *sink_ffmt; + struct v4l2_mbus_framefmt *src_ffmt; + struct v4l2_rect *crop; + + if (sel->pad == IPU7_CSI2_PAD_SINK || sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; + + sink_ffmt = v4l2_subdev_state_get_opposite_stream_format(state, + sel->pad, + sel->stream); + if (!sink_ffmt) + return -EINVAL; + + src_ffmt = v4l2_subdev_state_get_format(state, sel->pad, sel->stream); + if (!src_ffmt) + return -EINVAL; + + crop = v4l2_subdev_state_get_crop(state, sel->pad, sel->stream); + if (!crop) + return -EINVAL; + + /* Only vertical cropping is supported */ + sel->r.left = 0; + sel->r.width = sink_ffmt->width; + /* Non-bayer formats can't be single line cropped */ + if (!ipu7_isys_is_bayer_format(sink_ffmt->code)) + sel->r.top &= ~1U; + sel->r.height = clamp(sel->r.height & ~1U, IPU_ISYS_MIN_HEIGHT, + sink_ffmt->height - sel->r.top); + *crop = sel->r; + + /* update source pad format */ + src_ffmt->width = sel->r.width; + src_ffmt->height = sel->r.height; + if (ipu7_isys_is_bayer_format(sink_ffmt->code)) + src_ffmt->code = ipu7_isys_convert_bayer_order(sink_ffmt->code, + sel->r.left, + sel->r.top); + dev_dbg(dev, "set crop for %s sel: %d,%d,%d,%d code: 0x%x\n", + sd->name, sel->r.left, sel->r.top, sel->r.width, sel->r.height, + src_ffmt->code); + + return 0; +} + +static int ipu7_isys_csi2_get_sel(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct v4l2_mbus_framefmt *sink_ffmt; + struct v4l2_rect *crop; + int ret = 0; + + if (sd->entity.pads[sel->pad].flags & MEDIA_PAD_FL_SINK) + return -EINVAL; + + sink_ffmt = v4l2_subdev_state_get_opposite_stream_format(state, + sel->pad, + sel->stream); + if (!sink_ffmt) + return -EINVAL; + + crop = v4l2_subdev_state_get_crop(state, sel->pad, sel->stream); + if (!crop) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = sink_ffmt->width; + sel->r.height = sink_ffmt->height; + break; + case V4L2_SEL_TGT_CROP: + sel->r = *crop; + break; + default: + ret = -EINVAL; + } + + return ret; +} + +/* + * Maximum stream ID is 63 for now, as we use u64 bitmask to represent a set + * of streams. + */ +#define CSI2_SUBDEV_MAX_STREAM_ID 63 + +static int ipu7_isys_csi2_enable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + u32 pad, u64 streams_mask) +{ + struct ipu7_isys_subdev *asd = to_ipu7_isys_subdev(sd); + struct ipu7_isys_csi2 *csi2 = to_ipu7_isys_csi2(asd); + struct v4l2_subdev *r_sd; + struct media_pad *rp; + u32 sink_pad, sink_stream; + int ret, i; + + if (!csi2->stream_count) { + dev_dbg(&csi2->isys->adev->auxdev.dev, + "stream on CSI2-%u with %u lanes\n", csi2->port, + csi2->nlanes); + ret = ipu7_isys_csi2_enable_stream(csi2); + if (ret) + return ret; + } + + for (i = 0; i <= CSI2_SUBDEV_MAX_STREAM_ID; i++) { + if (streams_mask & BIT_ULL(i)) + break; + } + + ret = v4l2_subdev_routing_find_opposite_end(&state->routing, pad, i, + &sink_pad, &sink_stream); + if (ret) + return ret; + + rp = media_pad_remote_pad_first(&sd->entity.pads[IPU7_CSI2_PAD_SINK]); + r_sd = media_entity_to_v4l2_subdev(rp->entity); + + ret = v4l2_subdev_enable_streams(r_sd, rp->index, + BIT_ULL(sink_stream)); + if (!ret) { + csi2->stream_count++; + return 0; + } + + if (!csi2->stream_count) + ipu7_isys_csi2_disable_stream(csi2); + + return ret; +} + +static int ipu7_isys_csi2_disable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + u32 pad, u64 streams_mask) +{ + struct ipu7_isys_subdev *asd = to_ipu7_isys_subdev(sd); + struct ipu7_isys_csi2 *csi2 = to_ipu7_isys_csi2(asd); + struct v4l2_subdev *r_sd; + struct media_pad *rp; + u32 sink_pad, sink_stream; + int ret, i; + + for (i = 0; i <= CSI2_SUBDEV_MAX_STREAM_ID; i++) { + if (streams_mask & BIT_ULL(i)) + break; + } + + ret = v4l2_subdev_routing_find_opposite_end(&state->routing, pad, i, + &sink_pad, &sink_stream); + if (ret) + return ret; + + rp = media_pad_remote_pad_first(&sd->entity.pads[IPU7_CSI2_PAD_SINK]); + r_sd = media_entity_to_v4l2_subdev(rp->entity); + + v4l2_subdev_disable_streams(r_sd, rp->index, BIT_ULL(sink_stream)); + + if (--csi2->stream_count) + return 0; + + dev_dbg(&csi2->isys->adev->auxdev.dev, + "stream off CSI2-%u with %u lanes\n", csi2->port, csi2->nlanes); + + ipu7_isys_csi2_disable_stream(csi2); + + return 0; +} + +static const struct v4l2_subdev_pad_ops csi2_sd_pad_ops = { + .get_fmt = v4l2_subdev_get_fmt, + .set_fmt = ipu7_isys_subdev_set_fmt, + .get_selection = ipu7_isys_csi2_get_sel, + .set_selection = ipu7_isys_csi2_set_sel, + .enum_mbus_code = ipu7_isys_subdev_enum_mbus_code, + .enable_streams = ipu7_isys_csi2_enable_streams, + .disable_streams = ipu7_isys_csi2_disable_streams, + .set_routing = ipu7_isys_subdev_set_routing, +}; + +static const struct v4l2_subdev_ops csi2_sd_ops = { + .core = &csi2_sd_core_ops, + .pad = &csi2_sd_pad_ops, +}; + +static const struct media_entity_operations csi2_entity_ops = { + .link_validate = v4l2_subdev_link_validate, + .has_pad_interdep = v4l2_subdev_has_pad_interdep, +}; + +void ipu7_isys_csi2_cleanup(struct ipu7_isys_csi2 *csi2) +{ + if (!csi2->isys) + return; + + v4l2_device_unregister_subdev(&csi2->asd.sd); + v4l2_subdev_cleanup(&csi2->asd.sd); + ipu7_isys_subdev_cleanup(&csi2->asd); + csi2->isys = NULL; +} + +int ipu7_isys_csi2_init(struct ipu7_isys_csi2 *csi2, + struct ipu7_isys *isys, + void __iomem *base, unsigned int index) +{ + struct device *dev = &isys->adev->auxdev.dev; + int ret; + + csi2->isys = isys; + csi2->base = base; + csi2->port = index; + + if (!is_ipu7(isys->adev->isp->hw_ver)) + csi2->legacy_irq_mask = 0x7U << (index * 3U); + else + csi2->legacy_irq_mask = 0x3U << (index * 2U); + + dev_dbg(dev, "csi-%d legacy irq mask = 0x%x\n", index, + csi2->legacy_irq_mask); + + csi2->asd.sd.entity.ops = &csi2_entity_ops; + csi2->asd.isys = isys; + + ret = ipu7_isys_subdev_init(&csi2->asd, &csi2_sd_ops, 0, + IPU7_NR_OF_CSI2_SINK_PADS, + IPU7_NR_OF_CSI2_SRC_PADS); + if (ret) + return ret; + + csi2->asd.source = (int)index; + csi2->asd.supported_codes = csi2_supported_codes; + snprintf(csi2->asd.sd.name, sizeof(csi2->asd.sd.name), + IPU_ISYS_ENTITY_PREFIX " CSI2 %u", index); + v4l2_set_subdevdata(&csi2->asd.sd, &csi2->asd); + + ret = v4l2_subdev_init_finalize(&csi2->asd.sd); + if (ret) { + dev_err(dev, "failed to init v4l2 subdev (%d)\n", ret); + goto isys_subdev_cleanup; + } + + ret = v4l2_device_register_subdev(&isys->v4l2_dev, &csi2->asd.sd); + if (ret) { + dev_err(dev, "failed to register v4l2 subdev (%d)\n", ret); + goto v4l2_subdev_cleanup; + } + + return 0; + +v4l2_subdev_cleanup: + v4l2_subdev_cleanup(&csi2->asd.sd); +isys_subdev_cleanup: + ipu7_isys_subdev_cleanup(&csi2->asd); + + return ret; +} + +void ipu7_isys_csi2_sof_event_by_stream(struct ipu7_isys_stream *stream) +{ + struct ipu7_isys_csi2 *csi2 = ipu7_isys_subdev_to_csi2(stream->asd); + struct device *dev = &stream->isys->adev->auxdev.dev; + struct video_device *vdev = csi2->asd.sd.devnode; + struct v4l2_event ev = { + .type = V4L2_EVENT_FRAME_SYNC, + }; + + ev.id = stream->vc; + ev.u.frame_sync.frame_sequence = atomic_fetch_inc(&stream->sequence); + v4l2_event_queue(vdev, &ev); + + dev_dbg(dev, "sof_event::csi2-%i sequence: %i, vc: %d\n", + csi2->port, ev.u.frame_sync.frame_sequence, stream->vc); +} + +void ipu7_isys_csi2_eof_event_by_stream(struct ipu7_isys_stream *stream) +{ + struct ipu7_isys_csi2 *csi2 = ipu7_isys_subdev_to_csi2(stream->asd); + struct device *dev = &stream->isys->adev->auxdev.dev; + u32 frame_sequence = atomic_read(&stream->sequence); + + dev_dbg(dev, "eof_event::csi2-%i sequence: %i\n", + csi2->port, frame_sequence); +} + +int ipu7_isys_csi2_get_remote_desc(u32 source_stream, + struct ipu7_isys_csi2 *csi2, + struct media_entity *source_entity, + struct v4l2_mbus_frame_desc_entry *entry, + int *nr_queues) +{ + struct v4l2_mbus_frame_desc_entry *desc_entry = NULL; + struct device *dev = &csi2->isys->adev->auxdev.dev; + struct v4l2_mbus_frame_desc desc; + struct v4l2_subdev *source; + struct media_pad *pad; + unsigned int i; + int ret; + + source = media_entity_to_v4l2_subdev(source_entity); + if (!source) + return -EPIPE; + + pad = media_pad_remote_pad_first(&csi2->asd.pad[IPU7_CSI2_PAD_SINK]); + if (!pad) + return -EPIPE; + + ret = v4l2_subdev_call(source, pad, get_frame_desc, pad->index, &desc); + if (ret) + return ret; + + if (desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) { + dev_err(dev, "Unsupported frame descriptor type\n"); + return -EINVAL; + } + + for (i = 0; i < desc.num_entries; i++) { + if (source_stream == desc.entry[i].stream) { + desc_entry = &desc.entry[i]; + break; + } + } + + if (!desc_entry) { + dev_err(dev, "Failed to find stream %u from remote subdev\n", + source_stream); + return -EINVAL; + } + + if (desc_entry->bus.csi2.vc >= IPU7_NR_OF_CSI2_VC) { + dev_err(dev, "invalid vc %d\n", desc_entry->bus.csi2.vc); + return -EINVAL; + } + + *entry = *desc_entry; + + for (i = 0; i < desc.num_entries; i++) { + if (desc_entry->bus.csi2.vc == desc.entry[i].bus.csi2.vc) + (*nr_queues)++; + } + + return 0; +} diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi2.h b/drivers/staging/media/ipu7/ipu7-isys-csi2.h new file mode 100644 index 000000000000..6c23b80f92a2 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys-csi2.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_ISYS_CSI2_H +#define IPU7_ISYS_CSI2_H + +#include <linux/container_of.h> +#include <linux/types.h> + +#include "ipu7-isys-subdev.h" +#include "ipu7-isys-video.h" + +struct ipu7_isys; +struct ipu7_isys_csi2_pdata; +struct ipu7_isys_stream; + +#define IPU7_NR_OF_CSI2_VC 16U +#define INVALID_VC_ID -1 +#define IPU7_NR_OF_CSI2_SINK_PADS 1U +#define IPU7_CSI2_PAD_SINK 0U +#define IPU7_NR_OF_CSI2_SRC_PADS 8U +#define IPU7_CSI2_PAD_SRC 1U +#define IPU7_NR_OF_CSI2_PADS (IPU7_NR_OF_CSI2_SINK_PADS + \ + IPU7_NR_OF_CSI2_SRC_PADS) + +/* + * struct ipu7_isys_csi2 + * + * @nlanes: number of lanes in the receiver + */ +struct ipu7_isys_csi2 { + struct ipu7_isys_subdev asd; + struct ipu7_isys_csi2_pdata *pdata; + struct ipu7_isys *isys; + struct ipu7_isys_video av[IPU7_NR_OF_CSI2_SRC_PADS]; + + void __iomem *base; + u32 receiver_errors; + u32 legacy_irq_mask; + unsigned int nlanes; + unsigned int port; + unsigned int phy_mode; + unsigned int stream_count; +}; + +#define ipu7_isys_subdev_to_csi2(__sd) \ + container_of(__sd, struct ipu7_isys_csi2, asd) + +#define to_ipu7_isys_csi2(__asd) container_of(__asd, struct ipu7_isys_csi2, asd) + +s64 ipu7_isys_csi2_get_link_freq(struct ipu7_isys_csi2 *csi2); +int ipu7_isys_csi2_init(struct ipu7_isys_csi2 *csi2, struct ipu7_isys *isys, + void __iomem *base, unsigned int index); +void ipu7_isys_csi2_cleanup(struct ipu7_isys_csi2 *csi2); +void ipu7_isys_csi2_sof_event_by_stream(struct ipu7_isys_stream *stream); +void ipu7_isys_csi2_eof_event_by_stream(struct ipu7_isys_stream *stream); +int ipu7_isys_csi2_get_remote_desc(u32 source_stream, + struct ipu7_isys_csi2 *csi2, + struct media_entity *source_entity, + struct v4l2_mbus_frame_desc_entry *entry, + int *nr_queues); +#endif /* IPU7_ISYS_CSI2_H */ diff --git a/drivers/staging/media/ipu7/ipu7-isys-queue.c b/drivers/staging/media/ipu7/ipu7-isys-queue.c new file mode 100644 index 000000000000..7046c29141f8 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys-queue.c @@ -0,0 +1,829 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <linux/atomic.h> +#include <linux/bug.h> +#include <linux/device.h> +#include <linux/list.h> +#include <linux/lockdep.h> +#include <linux/mutex.h> +#include <linux/spinlock.h> +#include <linux/types.h> + +#include <media/media-entity.h> +#include <media/v4l2-subdev.h> +#include <media/videobuf2-dma-sg.h> +#include <media/videobuf2-v4l2.h> + +#include "abi/ipu7_fw_isys_abi.h" + +#include "ipu7-bus.h" +#include "ipu7-dma.h" +#include "ipu7-fw-isys.h" +#include "ipu7-isys.h" +#include "ipu7-isys-csi2-regs.h" +#include "ipu7-isys-video.h" +#include "ipu7-platform-regs.h" + +#define IPU_MAX_FRAME_COUNTER (U8_MAX + 1) + +static int ipu7_isys_buf_init(struct vb2_buffer *vb) +{ + struct ipu7_isys *isys = vb2_get_drv_priv(vb->vb2_queue); + struct sg_table *sg = vb2_dma_sg_plane_desc(vb, 0); + struct vb2_v4l2_buffer *vvb = to_vb2_v4l2_buffer(vb); + struct ipu7_isys_video_buffer *ivb = + vb2_buffer_to_ipu7_isys_video_buffer(vvb); + int ret; + + ret = ipu7_dma_map_sgtable(isys->adev, sg, DMA_TO_DEVICE, 0); + if (ret) + return ret; + + ivb->dma_addr = sg_dma_address(sg->sgl); + + return 0; +} + +static void ipu7_isys_buf_cleanup(struct vb2_buffer *vb) +{ + struct ipu7_isys *isys = vb2_get_drv_priv(vb->vb2_queue); + struct sg_table *sg = vb2_dma_sg_plane_desc(vb, 0); + struct vb2_v4l2_buffer *vvb = to_vb2_v4l2_buffer(vb); + struct ipu7_isys_video_buffer *ivb = + vb2_buffer_to_ipu7_isys_video_buffer(vvb); + + ivb->dma_addr = 0; + ipu7_dma_unmap_sgtable(isys->adev, sg, DMA_TO_DEVICE, 0); +} + +static int ipu7_isys_queue_setup(struct vb2_queue *q, unsigned int *num_buffers, + unsigned int *num_planes, unsigned int sizes[], + struct device *alloc_devs[]) +{ + struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(q); + struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); + struct device *dev = &av->isys->adev->auxdev.dev; + u32 size = av->pix_fmt.sizeimage; + + /* num_planes == 0: we're being called through VIDIOC_REQBUFS */ + if (!*num_planes) { + sizes[0] = size; + } else if (sizes[0] < size) { + dev_dbg(dev, "%s: queue setup: size %u < %u\n", + av->vdev.name, sizes[0], size); + return -EINVAL; + } + + *num_planes = 1; + + return 0; +} + +static int ipu7_isys_buf_prepare(struct vb2_buffer *vb) +{ + struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue); + struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); + struct device *dev = &av->isys->adev->auxdev.dev; + u32 bytesperline = av->pix_fmt.bytesperline; + u32 height = av->pix_fmt.height; + + dev_dbg(dev, "buffer: %s: configured size %u, buffer size %lu\n", + av->vdev.name, av->pix_fmt.sizeimage, vb2_plane_size(vb, 0)); + + if (av->pix_fmt.sizeimage > vb2_plane_size(vb, 0)) + return -EINVAL; + + dev_dbg(dev, "buffer: %s: bytesperline %u, height %u\n", + av->vdev.name, bytesperline, height); + vb2_set_plane_payload(vb, 0, bytesperline * height); + + return 0; +} + +/* + * Queue a buffer list back to incoming or active queues. The buffers + * are removed from the buffer list. + */ +void ipu7_isys_buffer_list_queue(struct ipu7_isys_buffer_list *bl, + unsigned long op_flags, + enum vb2_buffer_state state) +{ + struct ipu7_isys_buffer *ib, *ib_safe; + unsigned long flags; + bool first = true; + + if (!bl) + return; + + WARN_ON_ONCE(!bl->nbufs); + WARN_ON_ONCE(op_flags & IPU_ISYS_BUFFER_LIST_FL_ACTIVE && + op_flags & IPU_ISYS_BUFFER_LIST_FL_INCOMING); + + list_for_each_entry_safe(ib, ib_safe, &bl->head, head) { + struct ipu7_isys_video *av; + + struct vb2_buffer *vb = ipu7_isys_buffer_to_vb2_buffer(ib); + struct ipu7_isys_queue *aq = + vb2_queue_to_isys_queue(vb->vb2_queue); + + av = ipu7_isys_queue_to_video(aq); + spin_lock_irqsave(&aq->lock, flags); + list_del(&ib->head); + if (op_flags & IPU_ISYS_BUFFER_LIST_FL_ACTIVE) + list_add(&ib->head, &aq->active); + else if (op_flags & IPU_ISYS_BUFFER_LIST_FL_INCOMING) + list_add_tail(&ib->head, &aq->incoming); + spin_unlock_irqrestore(&aq->lock, flags); + + if (op_flags & IPU_ISYS_BUFFER_LIST_FL_SET_STATE) + vb2_buffer_done(vb, state); + + if (first) { + dev_dbg(&av->isys->adev->auxdev.dev, + "queue buf list %p flags %lx, s %d, %d bufs\n", + bl, op_flags, state, bl->nbufs); + first = false; + } + + bl->nbufs--; + } + + WARN_ON(bl->nbufs); +} + +/* + * flush_firmware_streamon_fail() - Flush in cases where requests may + * have been queued to firmware and the *firmware streamon fails for a + * reason or another. + */ +static void flush_firmware_streamon_fail(struct ipu7_isys_stream *stream) +{ + struct ipu7_isys_queue *aq; + unsigned long flags; + + lockdep_assert_held(&stream->mutex); + + list_for_each_entry(aq, &stream->queues, node) { + struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); + struct device *dev = &av->isys->adev->auxdev.dev; + struct ipu7_isys_buffer *ib, *ib_safe; + + spin_lock_irqsave(&aq->lock, flags); + list_for_each_entry_safe(ib, ib_safe, &aq->active, head) { + struct vb2_buffer *vb = + ipu7_isys_buffer_to_vb2_buffer(ib); + + list_del(&ib->head); + if (av->streaming) { + dev_dbg(dev, + "%s: queue buffer %u back to incoming\n", + av->vdev.name, vb->index); + /* Queue already streaming, return to driver. */ + list_add(&ib->head, &aq->incoming); + continue; + } + /* Queue not yet streaming, return to user. */ + dev_dbg(dev, "%s: return %u back to videobuf2\n", + av->vdev.name, vb->index); + vb2_buffer_done(ipu7_isys_buffer_to_vb2_buffer(ib), + VB2_BUF_STATE_QUEUED); + } + spin_unlock_irqrestore(&aq->lock, flags); + } +} + +/* + * Attempt obtaining a buffer list from the incoming queues, a list of buffers + * that contains one entry from each video buffer queue. If a buffer can't be + * obtained from every queue, the buffers are returned back to the queue. + */ +static int buffer_list_get(struct ipu7_isys_stream *stream, + struct ipu7_isys_buffer_list *bl) +{ + unsigned long buf_flag = IPU_ISYS_BUFFER_LIST_FL_INCOMING; + struct device *dev = &stream->isys->adev->auxdev.dev; + struct ipu7_isys_queue *aq; + unsigned long flags; + + bl->nbufs = 0; + INIT_LIST_HEAD(&bl->head); + + list_for_each_entry(aq, &stream->queues, node) { + struct ipu7_isys_buffer *ib; + + spin_lock_irqsave(&aq->lock, flags); + if (list_empty(&aq->incoming)) { + spin_unlock_irqrestore(&aq->lock, flags); + if (!list_empty(&bl->head)) + ipu7_isys_buffer_list_queue(bl, buf_flag, 0); + return -ENODATA; + } + + ib = list_last_entry(&aq->incoming, + struct ipu7_isys_buffer, head); + + dev_dbg(dev, "buffer: %s: buffer %u\n", + ipu7_isys_queue_to_video(aq)->vdev.name, + ipu7_isys_buffer_to_vb2_buffer(ib)->index); + list_del(&ib->head); + list_add(&ib->head, &bl->head); + spin_unlock_irqrestore(&aq->lock, flags); + + bl->nbufs++; + } + + dev_dbg(dev, "get buffer list %p, %u buffers\n", bl, bl->nbufs); + + return 0; +} + +static void ipu7_isys_buf_to_fw_frame_buf_pin(struct vb2_buffer *vb, + struct ipu7_insys_buffset *set) +{ + struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue); + struct vb2_v4l2_buffer *vvb = to_vb2_v4l2_buffer(vb); + struct ipu7_isys_video_buffer *ivb = + vb2_buffer_to_ipu7_isys_video_buffer(vvb); + + set->output_pins[aq->fw_output].addr = ivb->dma_addr; + set->output_pins[aq->fw_output].user_token = (uintptr_t)set; +} + +/* + * Convert a buffer list to a isys fw ABI framebuffer set. The + * buffer list is not modified. + */ +#define IPU_ISYS_FRAME_NUM_THRESHOLD (30) +void ipu7_isys_buffer_to_fw_frame_buff(struct ipu7_insys_buffset *set, + struct ipu7_isys_stream *stream, + struct ipu7_isys_buffer_list *bl) +{ + struct ipu7_isys_buffer *ib; + u32 buf_id; + + WARN_ON(!bl->nbufs); + + set->skip_frame = 0; + set->capture_msg_map = IPU_INSYS_FRAME_ENABLE_MSG_SEND_RESP | + IPU_INSYS_FRAME_ENABLE_MSG_SEND_IRQ; + + buf_id = atomic_fetch_inc(&stream->buf_id); + set->frame_id = buf_id % IPU_MAX_FRAME_COUNTER; + + list_for_each_entry(ib, &bl->head, head) { + struct vb2_buffer *vb = ipu7_isys_buffer_to_vb2_buffer(ib); + + ipu7_isys_buf_to_fw_frame_buf_pin(vb, set); + } +} + +/* Start streaming for real. The buffer list must be available. */ +static int ipu7_isys_stream_start(struct ipu7_isys_video *av, + struct ipu7_isys_buffer_list *bl, bool error) +{ + struct ipu7_isys_stream *stream = av->stream; + struct device *dev = &stream->isys->adev->auxdev.dev; + struct ipu7_isys_buffer_list __bl; + int ret; + + mutex_lock(&stream->isys->stream_mutex); + + ret = ipu7_isys_video_set_streaming(av, 1, bl); + mutex_unlock(&stream->isys->stream_mutex); + if (ret) + goto out_requeue; + + stream->streaming = 1; + + bl = &__bl; + + do { + struct ipu7_insys_buffset *buf = NULL; + struct isys_fw_msgs *msg; + enum ipu7_insys_send_type send_type = + IPU_INSYS_SEND_TYPE_STREAM_CAPTURE; + + ret = buffer_list_get(stream, bl); + if (ret < 0) + break; + + msg = ipu7_get_fw_msg_buf(stream); + if (!msg) + return -ENOMEM; + + buf = &msg->fw_msg.frame; + + ipu7_isys_buffer_to_fw_frame_buff(buf, stream, bl); + + ipu7_fw_isys_dump_frame_buff_set(dev, buf, + stream->nr_output_pins); + + ipu7_isys_buffer_list_queue(bl, IPU_ISYS_BUFFER_LIST_FL_ACTIVE, + 0); + + ret = ipu7_fw_isys_complex_cmd(stream->isys, + stream->stream_handle, buf, + msg->dma_addr, sizeof(*buf), + send_type); + } while (!WARN_ON(ret)); + + return 0; + +out_requeue: + if (bl && bl->nbufs) + ipu7_isys_buffer_list_queue(bl, + IPU_ISYS_BUFFER_LIST_FL_INCOMING | + (error ? + IPU_ISYS_BUFFER_LIST_FL_SET_STATE : + 0), error ? VB2_BUF_STATE_ERROR : + VB2_BUF_STATE_QUEUED); + flush_firmware_streamon_fail(stream); + + return ret; +} + +static void buf_queue(struct vb2_buffer *vb) +{ + struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue); + struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); + struct vb2_v4l2_buffer *vvb = to_vb2_v4l2_buffer(vb); + struct ipu7_isys_video_buffer *ivb = + vb2_buffer_to_ipu7_isys_video_buffer(vvb); + struct media_pipeline *media_pipe = + media_entity_pipeline(&av->vdev.entity); + struct device *dev = &av->isys->adev->auxdev.dev; + struct ipu7_isys_stream *stream = av->stream; + struct ipu7_isys_buffer *ib = &ivb->ib; + struct ipu7_insys_buffset *buf = NULL; + struct ipu7_isys_buffer_list bl; + struct isys_fw_msgs *msg; + unsigned long flags; + dma_addr_t dma; + int ret; + + dev_dbg(dev, "queue buffer %u for %s\n", vb->index, av->vdev.name); + + dma = ivb->dma_addr; + dev_dbg(dev, "iova: iova %pad\n", &dma); + + spin_lock_irqsave(&aq->lock, flags); + list_add(&ib->head, &aq->incoming); + spin_unlock_irqrestore(&aq->lock, flags); + + if (!media_pipe || !vb->vb2_queue->start_streaming_called) { + dev_dbg(dev, "media pipeline is not ready for %s\n", + av->vdev.name); + return; + } + + mutex_lock(&stream->mutex); + + if (stream->nr_streaming != stream->nr_queues) { + dev_dbg(dev, "not streaming yet, adding to incoming\n"); + goto out; + } + + /* + * We just put one buffer to the incoming list of this queue + * (above). Let's see whether all queues in the pipeline would + * have a buffer. + */ + ret = buffer_list_get(stream, &bl); + if (ret < 0) { + dev_dbg(dev, "No buffers available\n"); + goto out; + } + + msg = ipu7_get_fw_msg_buf(stream); + if (!msg) { + ret = -ENOMEM; + goto out; + } + + buf = &msg->fw_msg.frame; + + ipu7_isys_buffer_to_fw_frame_buff(buf, stream, &bl); + + ipu7_fw_isys_dump_frame_buff_set(dev, buf, stream->nr_output_pins); + + if (!stream->streaming) { + ret = ipu7_isys_stream_start(av, &bl, true); + if (ret) + dev_err(dev, "stream start failed.\n"); + goto out; + } + + /* + * We must queue the buffers in the buffer list to the + * appropriate video buffer queues BEFORE passing them to the + * firmware since we could get a buffer event back before we + * have queued them ourselves to the active queue. + */ + ipu7_isys_buffer_list_queue(&bl, IPU_ISYS_BUFFER_LIST_FL_ACTIVE, 0); + + ret = ipu7_fw_isys_complex_cmd(stream->isys, stream->stream_handle, + buf, msg->dma_addr, sizeof(*buf), + IPU_INSYS_SEND_TYPE_STREAM_CAPTURE); + if (ret < 0) + dev_err(dev, "send stream capture failed\n"); + +out: + mutex_unlock(&stream->mutex); +} + +static int ipu7_isys_link_fmt_validate(struct ipu7_isys_queue *aq) +{ + struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); + struct device *dev = &av->isys->adev->auxdev.dev; + struct media_pad *remote_pad = + media_pad_remote_pad_first(av->vdev.entity.pads); + struct v4l2_mbus_framefmt format; + struct v4l2_subdev *sd; + u32 r_stream, code; + int ret; + + if (!remote_pad) + return -ENOTCONN; + + sd = media_entity_to_v4l2_subdev(remote_pad->entity); + r_stream = ipu7_isys_get_src_stream_by_src_pad(sd, remote_pad->index); + + ret = ipu7_isys_get_stream_pad_fmt(sd, remote_pad->index, r_stream, + &format); + if (ret) { + dev_dbg(dev, "failed to get %s: pad %d, stream:%d format\n", + sd->entity.name, remote_pad->index, r_stream); + return ret; + } + + if (format.width != av->pix_fmt.width || + format.height != av->pix_fmt.height) { + dev_dbg(dev, "wrong width or height %ux%u (%ux%u expected)\n", + av->pix_fmt.width, av->pix_fmt.height, format.width, + format.height); + return -EINVAL; + } + + code = ipu7_isys_get_isys_format(av->pix_fmt.pixelformat)->code; + if (format.code != code) { + dev_dbg(dev, "wrong mbus code 0x%8.8x (0x%8.8x expected)\n", + code, format.code); + return -EINVAL; + } + + return 0; +} + +static void return_buffers(struct ipu7_isys_queue *aq, + enum vb2_buffer_state state) +{ + struct ipu7_isys_buffer *ib; + struct vb2_buffer *vb; + unsigned long flags; + + spin_lock_irqsave(&aq->lock, flags); + /* + * Something went wrong (FW crash / HW hang / not all buffers + * returned from isys) if there are still buffers queued in active + * queue. We have to clean up places a bit. + */ + while (!list_empty(&aq->active)) { + ib = list_last_entry(&aq->active, struct ipu7_isys_buffer, + head); + vb = ipu7_isys_buffer_to_vb2_buffer(ib); + + list_del(&ib->head); + spin_unlock_irqrestore(&aq->lock, flags); + + vb2_buffer_done(vb, state); + + spin_lock_irqsave(&aq->lock, flags); + } + + while (!list_empty(&aq->incoming)) { + ib = list_last_entry(&aq->incoming, struct ipu7_isys_buffer, + head); + vb = ipu7_isys_buffer_to_vb2_buffer(ib); + list_del(&ib->head); + spin_unlock_irqrestore(&aq->lock, flags); + + vb2_buffer_done(vb, state); + + spin_lock_irqsave(&aq->lock, flags); + } + + spin_unlock_irqrestore(&aq->lock, flags); +} + +static void ipu7_isys_stream_cleanup(struct ipu7_isys_video *av) +{ + video_device_pipeline_stop(&av->vdev); + ipu7_isys_put_stream(av->stream); + av->stream = NULL; +} + +static int start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(q); + struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); + struct device *dev = &av->isys->adev->auxdev.dev; + const struct ipu7_isys_pixelformat *pfmt = + ipu7_isys_get_isys_format(av->pix_fmt.pixelformat); + struct ipu7_isys_buffer_list __bl, *bl = NULL; + struct ipu7_isys_stream *stream; + struct media_entity *source_entity = NULL; + int nr_queues, ret; + + dev_dbg(dev, "stream: %s: width %u, height %u, css pixelformat %u\n", + av->vdev.name, av->pix_fmt.width, av->pix_fmt.height, + pfmt->css_pixelformat); + + ret = ipu7_isys_setup_video(av, &source_entity, &nr_queues); + if (ret < 0) { + dev_dbg(dev, "failed to setup video\n"); + goto out_return_buffers; + } + + ret = ipu7_isys_link_fmt_validate(aq); + if (ret) { + dev_dbg(dev, + "%s: link format validation failed (%d)\n", + av->vdev.name, ret); + goto out_pipeline_stop; + } + + stream = av->stream; + mutex_lock(&stream->mutex); + if (!stream->nr_streaming) { + ret = ipu7_isys_video_prepare_stream(av, source_entity, + nr_queues); + if (ret) { + mutex_unlock(&stream->mutex); + goto out_pipeline_stop; + } + } + + stream->nr_streaming++; + dev_dbg(dev, "queue %u of %u\n", stream->nr_streaming, + stream->nr_queues); + + list_add(&aq->node, &stream->queues); + + if (stream->nr_streaming != stream->nr_queues) + goto out; + + bl = &__bl; + ret = buffer_list_get(stream, bl); + if (ret < 0) { + dev_warn(dev, "no buffer available, DRIVER BUG?\n"); + goto out; + } + + ret = ipu7_isys_fw_open(av->isys); + if (ret) + goto out_stream_start; + + ipu7_isys_setup_hw(av->isys); + + ret = ipu7_isys_stream_start(av, bl, false); + if (ret) + goto out_isys_fw_close; + +out: + mutex_unlock(&stream->mutex); + + return 0; + +out_isys_fw_close: + ipu7_isys_fw_close(av->isys); + +out_stream_start: + list_del(&aq->node); + stream->nr_streaming--; + mutex_unlock(&stream->mutex); + +out_pipeline_stop: + ipu7_isys_stream_cleanup(av); + +out_return_buffers: + return_buffers(aq, VB2_BUF_STATE_QUEUED); + + return ret; +} + +static void stop_streaming(struct vb2_queue *q) +{ + struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(q); + struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); + struct ipu7_isys_stream *stream = av->stream; + + mutex_lock(&stream->mutex); + mutex_lock(&av->isys->stream_mutex); + if (stream->nr_streaming == stream->nr_queues && stream->streaming) + ipu7_isys_video_set_streaming(av, 0, NULL); + mutex_unlock(&av->isys->stream_mutex); + + stream->nr_streaming--; + list_del(&aq->node); + stream->streaming = 0; + + mutex_unlock(&stream->mutex); + + ipu7_isys_stream_cleanup(av); + + return_buffers(aq, VB2_BUF_STATE_ERROR); + + ipu7_isys_fw_close(av->isys); +} + +static unsigned int +get_sof_sequence_by_timestamp(struct ipu7_isys_stream *stream, u64 time) +{ + struct ipu7_isys *isys = stream->isys; + struct device *dev = &isys->adev->auxdev.dev; + unsigned int i; + + /* + * The timestamp is invalid as no TSC in some FPGA platform, + * so get the sequence from pipeline directly in this case. + */ + if (time == 0) + return atomic_read(&stream->sequence) - 1; + + for (i = 0; i < IPU_ISYS_MAX_PARALLEL_SOF; i++) + if (time == stream->seq[i].timestamp) { + dev_dbg(dev, "SOF: using seq nr %u for ts %llu\n", + stream->seq[i].sequence, time); + return stream->seq[i].sequence; + } + + dev_dbg(dev, "SOF: looking for %llu\n", time); + for (i = 0; i < IPU_ISYS_MAX_PARALLEL_SOF; i++) + dev_dbg(dev, "SOF: sequence %u, timestamp value %llu\n", + stream->seq[i].sequence, stream->seq[i].timestamp); + dev_dbg(dev, "SOF sequence number not found\n"); + + return atomic_read(&stream->sequence) - 1; +} + +static u64 get_sof_ns_delta(struct ipu7_isys_video *av, u64 time) +{ + struct ipu7_bus_device *adev = av->isys->adev; + struct ipu7_device *isp = adev->isp; + u64 delta, tsc_now; + + ipu_buttress_tsc_read(isp, &tsc_now); + if (!tsc_now) + return 0; + + delta = tsc_now - time; + + return ipu_buttress_tsc_ticks_to_ns(delta, isp); +} + +static void ipu7_isys_buf_calc_sequence_time(struct ipu7_isys_buffer *ib, + u64 time) +{ + struct vb2_buffer *vb = ipu7_isys_buffer_to_vb2_buffer(ib); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue); + struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); + struct device *dev = &av->isys->adev->auxdev.dev; + struct ipu7_isys_stream *stream = av->stream; + u64 ns; + u32 sequence; + + ns = ktime_get_ns() - get_sof_ns_delta(av, time); + sequence = get_sof_sequence_by_timestamp(stream, time); + + vbuf->vb2_buf.timestamp = ns; + vbuf->sequence = sequence; + + dev_dbg(dev, "buf: %s: buffer done, CPU-timestamp:%lld, sequence:%d\n", + av->vdev.name, ktime_get_ns(), sequence); + dev_dbg(dev, "index:%d, vbuf timestamp:%lld\n", vb->index, + vbuf->vb2_buf.timestamp); +} + +static void ipu7_isys_queue_buf_done(struct ipu7_isys_buffer *ib) +{ + struct vb2_buffer *vb = ipu7_isys_buffer_to_vb2_buffer(ib); + + if (atomic_read(&ib->str2mmio_flag)) { + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); + /* + * Operation on buffer is ended with error and will be reported + * to the userspace when it is de-queued + */ + atomic_set(&ib->str2mmio_flag, 0); + } else { + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + } +} + +void ipu7_isys_queue_buf_ready(struct ipu7_isys_stream *stream, + struct ipu7_insys_resp *info) +{ + struct ipu7_isys_queue *aq = stream->output_pins[info->pin_id].aq; + u64 time = ((u64)info->timestamp[1] << 32 | info->timestamp[0]); + struct ipu7_isys *isys = stream->isys; + struct device *dev = &isys->adev->auxdev.dev; + struct ipu7_isys_buffer *ib; + struct vb2_buffer *vb; + unsigned long flags; + bool first = true; + struct vb2_v4l2_buffer *buf; + + dev_dbg(dev, "buffer: %s: received buffer %8.8x %d\n", + ipu7_isys_queue_to_video(aq)->vdev.name, info->pin.addr, + info->frame_id); + + spin_lock_irqsave(&aq->lock, flags); + if (list_empty(&aq->active)) { + spin_unlock_irqrestore(&aq->lock, flags); + dev_err(dev, "active queue empty\n"); + return; + } + + list_for_each_entry_reverse(ib, &aq->active, head) { + struct ipu7_isys_video_buffer *ivb; + struct vb2_v4l2_buffer *vvb; + dma_addr_t addr; + + vb = ipu7_isys_buffer_to_vb2_buffer(ib); + vvb = to_vb2_v4l2_buffer(vb); + ivb = vb2_buffer_to_ipu7_isys_video_buffer(vvb); + addr = ivb->dma_addr; + + if (info->pin.addr != addr) { + if (first) + dev_err(dev, "Unexpected buffer address %pad\n", + &addr); + + first = false; + continue; + } + + dev_dbg(dev, "buffer: found buffer %pad\n", &addr); + + buf = to_vb2_v4l2_buffer(vb); + buf->field = V4L2_FIELD_NONE; + + list_del(&ib->head); + spin_unlock_irqrestore(&aq->lock, flags); + + ipu7_isys_buf_calc_sequence_time(ib, time); + + ipu7_isys_queue_buf_done(ib); + + return; + } + + dev_err(dev, "Failed to find a matching video buffer\n"); + + spin_unlock_irqrestore(&aq->lock, flags); +} + +static const struct vb2_ops ipu7_isys_queue_ops = { + .queue_setup = ipu7_isys_queue_setup, + .buf_init = ipu7_isys_buf_init, + .buf_prepare = ipu7_isys_buf_prepare, + .buf_cleanup = ipu7_isys_buf_cleanup, + .start_streaming = start_streaming, + .stop_streaming = stop_streaming, + .buf_queue = buf_queue, +}; + +int ipu7_isys_queue_init(struct ipu7_isys_queue *aq) +{ + struct ipu7_isys *isys = ipu7_isys_queue_to_video(aq)->isys; + struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq); + struct ipu7_bus_device *adev = isys->adev; + int ret; + + if (!aq->vbq.io_modes) + aq->vbq.io_modes = VB2_MMAP | VB2_DMABUF; + + aq->vbq.drv_priv = isys; + aq->vbq.ops = &ipu7_isys_queue_ops; + aq->vbq.lock = &av->mutex; + aq->vbq.mem_ops = &vb2_dma_sg_memops; + aq->vbq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + aq->vbq.min_queued_buffers = 1; + aq->vbq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + + ret = vb2_queue_init(&aq->vbq); + if (ret) + return ret; + + aq->dev = &adev->auxdev.dev; + aq->vbq.dev = &adev->isp->pdev->dev; + spin_lock_init(&aq->lock); + INIT_LIST_HEAD(&aq->active); + INIT_LIST_HEAD(&aq->incoming); + + return 0; +} diff --git a/drivers/staging/media/ipu7/ipu7-isys-queue.h b/drivers/staging/media/ipu7/ipu7-isys-queue.h new file mode 100644 index 000000000000..0cb08a38f756 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys-queue.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_ISYS_QUEUE_H +#define IPU7_ISYS_QUEUE_H + +#include <linux/atomic.h> +#include <linux/container_of.h> +#include <linux/list.h> +#include <linux/spinlock_types.h> + +#include <media/videobuf2-v4l2.h> + +struct device; +struct ipu7_isys_stream; +struct ipu7_insys_resp; +struct ipu7_insys_buffset; + +struct ipu7_isys_queue { + struct vb2_queue vbq; + struct list_head node; + struct device *dev; + spinlock_t lock; + struct list_head active; + struct list_head incoming; + unsigned int fw_output; +}; + +struct ipu7_isys_buffer { + struct list_head head; + atomic_t str2mmio_flag; +}; + +struct ipu7_isys_video_buffer { + struct vb2_v4l2_buffer vb_v4l2; + struct ipu7_isys_buffer ib; + dma_addr_t dma_addr; +}; + +#define IPU_ISYS_BUFFER_LIST_FL_INCOMING BIT(0) +#define IPU_ISYS_BUFFER_LIST_FL_ACTIVE BIT(1) +#define IPU_ISYS_BUFFER_LIST_FL_SET_STATE BIT(2) + +struct ipu7_isys_buffer_list { + struct list_head head; + unsigned int nbufs; +}; + +#define vb2_queue_to_isys_queue(__vb2) \ + container_of(__vb2, struct ipu7_isys_queue, vbq) + +#define ipu7_isys_to_isys_video_buffer(__ib) \ + container_of(__ib, struct ipu7_isys_video_buffer, ib) + +#define vb2_buffer_to_ipu7_isys_video_buffer(__vvb) \ + container_of(__vvb, struct ipu7_isys_video_buffer, vb_v4l2) + +#define ipu7_isys_buffer_to_vb2_buffer(__ib) \ + (&ipu7_isys_to_isys_video_buffer(__ib)->vb_v4l2.vb2_buf) + +void ipu7_isys_buffer_list_queue(struct ipu7_isys_buffer_list *bl, + unsigned long op_flags, + enum vb2_buffer_state state); +void ipu7_isys_buffer_to_fw_frame_buff(struct ipu7_insys_buffset *set, + struct ipu7_isys_stream *stream, + struct ipu7_isys_buffer_list *bl); +void ipu7_isys_queue_buf_ready(struct ipu7_isys_stream *stream, + struct ipu7_insys_resp *info); +int ipu7_isys_queue_init(struct ipu7_isys_queue *aq); +#endif /* IPU7_ISYS_QUEUE_H */ diff --git a/drivers/staging/media/ipu7/ipu7-isys-subdev.c b/drivers/staging/media/ipu7/ipu7-isys-subdev.c new file mode 100644 index 000000000000..98b6ef6a2f21 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys-subdev.c @@ -0,0 +1,348 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <linux/bug.h> +#include <linux/device.h> +#include <linux/minmax.h> +#include <linux/types.h> + +#include <media/media-entity.h> +#include <media/mipi-csi2.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-subdev.h> + +#include <uapi/linux/media-bus-format.h> + +#include "ipu7-bus.h" +#include "ipu7-isys.h" +#include "ipu7-isys-subdev.h" + +unsigned int ipu7_isys_mbus_code_to_mipi(u32 code) +{ + switch (code) { + case MEDIA_BUS_FMT_RGB565_1X16: + return MIPI_CSI2_DT_RGB565; + case MEDIA_BUS_FMT_RGB888_1X24: + return MIPI_CSI2_DT_RGB888; + case MEDIA_BUS_FMT_YUYV10_1X20: + return MIPI_CSI2_DT_YUV422_10B; + case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: + return MIPI_CSI2_DT_YUV422_8B; + case MEDIA_BUS_FMT_SBGGR12_1X12: + case MEDIA_BUS_FMT_SGBRG12_1X12: + case MEDIA_BUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SRGGB12_1X12: + return MIPI_CSI2_DT_RAW12; + case MEDIA_BUS_FMT_Y10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SRGGB10_1X10: + return MIPI_CSI2_DT_RAW10; + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SRGGB8_1X8: + return MIPI_CSI2_DT_RAW8; + default: + WARN_ON(1); + return 0xff; + } +} + +bool ipu7_isys_is_bayer_format(u32 code) +{ + switch (ipu7_isys_mbus_code_to_mipi(code)) { + case MIPI_CSI2_DT_RAW8: + case MIPI_CSI2_DT_RAW10: + case MIPI_CSI2_DT_RAW12: + case MIPI_CSI2_DT_RAW14: + case MIPI_CSI2_DT_RAW16: + case MIPI_CSI2_DT_RAW20: + case MIPI_CSI2_DT_RAW24: + case MIPI_CSI2_DT_RAW28: + return true; + default: + return false; + } +} + +u32 ipu7_isys_convert_bayer_order(u32 code, int x, int y) +{ + static const u32 code_map[] = { + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SBGGR12_1X12, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(code_map); i++) + if (code_map[i] == code) + break; + + if (WARN_ON(i == ARRAY_SIZE(code_map))) + return code; + + return code_map[i ^ ((((u32)y & 1U) << 1U) | ((u32)x & 1U))]; +} + +int ipu7_isys_subdev_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *format) +{ + struct ipu7_isys_subdev *asd = to_ipu7_isys_subdev(sd); + u32 code = asd->supported_codes[0]; + struct v4l2_mbus_framefmt *fmt; + u32 other_pad, other_stream; + struct v4l2_rect *crop; + unsigned int i; + int ret; + + /* No transcoding, source and sink formats must match. */ + if ((sd->entity.pads[format->pad].flags & MEDIA_PAD_FL_SOURCE) && + sd->entity.num_pads > 1) + return v4l2_subdev_get_fmt(sd, state, format); + + format->format.width = clamp(format->format.width, IPU_ISYS_MIN_WIDTH, + IPU_ISYS_MAX_WIDTH); + format->format.height = clamp(format->format.height, + IPU_ISYS_MIN_HEIGHT, + IPU_ISYS_MAX_HEIGHT); + + for (i = 0; asd->supported_codes[i]; i++) { + if (asd->supported_codes[i] == format->format.code) { + code = asd->supported_codes[i]; + break; + } + } + format->format.code = code; + format->format.field = V4L2_FIELD_NONE; + + /* Store the format and propagate it to the source pad. */ + fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream); + if (!fmt) + return -EINVAL; + + *fmt = format->format; + + if (!(sd->entity.pads[format->pad].flags & MEDIA_PAD_FL_SINK)) + return 0; + + /* propagate format to following source pad */ + fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad, + format->stream); + if (!fmt) + return -EINVAL; + + *fmt = format->format; + + ret = v4l2_subdev_routing_find_opposite_end(&state->routing, + format->pad, + format->stream, + &other_pad, + &other_stream); + if (ret) + return -EINVAL; + + crop = v4l2_subdev_state_get_crop(state, other_pad, other_stream); + /* reset crop */ + crop->left = 0; + crop->top = 0; + crop->width = fmt->width; + crop->height = fmt->height; + + return 0; +} + +int ipu7_isys_subdev_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct ipu7_isys_subdev *asd = to_ipu7_isys_subdev(sd); + const u32 *supported_codes = asd->supported_codes; + u32 index; + + for (index = 0; supported_codes[index]; index++) { + if (index == code->index) { + code->code = supported_codes[index]; + return 0; + } + } + + return -EINVAL; +} + +static int subdev_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_krouting *routing) +{ + static const struct v4l2_mbus_framefmt fmt = { + .width = 4096, + .height = 3072, + .code = MEDIA_BUS_FMT_SGRBG10_1X10, + .field = V4L2_FIELD_NONE, + }; + int ret; + + ret = v4l2_subdev_routing_validate(sd, routing, + V4L2_SUBDEV_ROUTING_ONLY_1_TO_1); + if (ret) + return ret; + + return v4l2_subdev_set_routing_with_fmt(sd, state, routing, &fmt); +} + +int ipu7_isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream, + struct v4l2_mbus_framefmt *format) +{ + struct v4l2_subdev_state *state; + struct v4l2_mbus_framefmt *fmt; + + if (!sd || !format) + return -EINVAL; + + state = v4l2_subdev_lock_and_get_active_state(sd); + fmt = v4l2_subdev_state_get_format(state, pad, stream); + if (fmt) + *format = *fmt; + v4l2_subdev_unlock_state(state); + + return fmt ? 0 : -EINVAL; +} + +u32 ipu7_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad) +{ + struct v4l2_subdev_state *state; + struct v4l2_subdev_route *routes; + u32 source_stream = 0; + unsigned int i; + + state = v4l2_subdev_lock_and_get_active_state(sd); + if (!state) + return 0; + + routes = state->routing.routes; + for (i = 0; i < state->routing.num_routes; i++) { + if (routes[i].source_pad == pad) { + source_stream = routes[i].source_stream; + break; + } + } + + v4l2_subdev_unlock_state(state); + + return source_stream; +} + +static int ipu7_isys_subdev_init_state(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + struct v4l2_subdev_route route = { + .sink_pad = 0, + .sink_stream = 0, + .source_pad = 1, + .source_stream = 0, + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, + }; + struct v4l2_subdev_krouting routing = { + .num_routes = 1, + .routes = &route, + }; + + return subdev_set_routing(sd, state, &routing); +} + +int ipu7_isys_subdev_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + enum v4l2_subdev_format_whence which, + struct v4l2_subdev_krouting *routing) +{ + return subdev_set_routing(sd, state, routing); +} + +static const struct v4l2_subdev_internal_ops ipu7_isys_subdev_internal_ops = { + .init_state = ipu7_isys_subdev_init_state, +}; + +int ipu7_isys_subdev_init(struct ipu7_isys_subdev *asd, + const struct v4l2_subdev_ops *ops, + unsigned int nr_ctrls, + unsigned int num_sink_pads, + unsigned int num_source_pads) +{ + unsigned int num_pads = num_sink_pads + num_source_pads; + unsigned int i; + int ret; + + v4l2_subdev_init(&asd->sd, ops); + + asd->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | + V4L2_SUBDEV_FL_HAS_EVENTS | + V4L2_SUBDEV_FL_STREAMS; + asd->sd.owner = THIS_MODULE; + asd->sd.dev = &asd->isys->adev->auxdev.dev; + asd->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + asd->sd.internal_ops = &ipu7_isys_subdev_internal_ops; + + asd->pad = devm_kcalloc(&asd->isys->adev->auxdev.dev, num_pads, + sizeof(*asd->pad), GFP_KERNEL); + if (!asd->pad) + return -ENOMEM; + + for (i = 0; i < num_sink_pads; i++) + asd->pad[i].flags = MEDIA_PAD_FL_SINK | + MEDIA_PAD_FL_MUST_CONNECT; + + for (i = num_sink_pads; i < num_pads; i++) + asd->pad[i].flags = MEDIA_PAD_FL_SOURCE; + + ret = media_entity_pads_init(&asd->sd.entity, num_pads, asd->pad); + if (ret) { + pr_err("isys subdev init failed %d.\n", ret); + return ret; + } + + if (asd->ctrl_init) { + ret = v4l2_ctrl_handler_init(&asd->ctrl_handler, nr_ctrls); + if (ret) + goto out_media_entity_cleanup; + + asd->ctrl_init(&asd->sd); + if (asd->ctrl_handler.error) { + ret = asd->ctrl_handler.error; + goto out_v4l2_ctrl_handler_free; + } + + asd->sd.ctrl_handler = &asd->ctrl_handler; + } + + asd->source = -1; + + return 0; + +out_v4l2_ctrl_handler_free: + v4l2_ctrl_handler_free(&asd->ctrl_handler); + +out_media_entity_cleanup: + media_entity_cleanup(&asd->sd.entity); + + return ret; +} + +void ipu7_isys_subdev_cleanup(struct ipu7_isys_subdev *asd) +{ + media_entity_cleanup(&asd->sd.entity); + v4l2_ctrl_handler_free(&asd->ctrl_handler); +} diff --git a/drivers/staging/media/ipu7/ipu7-isys-subdev.h b/drivers/staging/media/ipu7/ipu7-isys-subdev.h new file mode 100644 index 000000000000..1057ec39ae39 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys-subdev.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_ISYS_SUBDEV_H +#define IPU7_ISYS_SUBDEV_H + +#include <linux/container_of.h> + +#include <media/media-entity.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-subdev.h> + +struct ipu7_isys; + +struct ipu7_isys_subdev { + struct v4l2_subdev sd; + struct ipu7_isys *isys; + u32 const *supported_codes; + struct media_pad *pad; + struct v4l2_ctrl_handler ctrl_handler; + void (*ctrl_init)(struct v4l2_subdev *sd); + int source; /* SSI stream source; -1 if unset */ +}; + +#define to_ipu7_isys_subdev(__sd) \ + container_of(__sd, struct ipu7_isys_subdev, sd) +unsigned int ipu7_isys_mbus_code_to_mipi(u32 code); +bool ipu7_isys_is_bayer_format(u32 code); +u32 ipu7_isys_convert_bayer_order(u32 code, int x, int y); + +int ipu7_isys_subdev_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *format); +int ipu7_isys_subdev_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_mbus_code_enum + *code); +u32 ipu7_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad); +int ipu7_isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream, + struct v4l2_mbus_framefmt *format); +int ipu7_isys_subdev_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + enum v4l2_subdev_format_whence which, + struct v4l2_subdev_krouting *routing); +int ipu7_isys_subdev_init(struct ipu7_isys_subdev *asd, + const struct v4l2_subdev_ops *ops, + unsigned int nr_ctrls, + unsigned int num_sink_pads, + unsigned int num_source_pads); +void ipu7_isys_subdev_cleanup(struct ipu7_isys_subdev *asd); +#endif /* IPU7_ISYS_SUBDEV_H */ diff --git a/drivers/staging/media/ipu7/ipu7-isys-video.c b/drivers/staging/media/ipu7/ipu7-isys-video.c new file mode 100644 index 000000000000..8756da3a8fb0 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys-video.c @@ -0,0 +1,1112 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <linux/align.h> +#include <linux/bits.h> +#include <linux/bug.h> +#include <linux/completion.h> +#include <linux/container_of.h> +#include <linux/compat.h> +#include <linux/device.h> +#include <linux/iopoll.h> +#include <linux/list.h> +#include <linux/minmax.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/pm_runtime.h> +#include <linux/spinlock.h> +#include <linux/string.h> + +#include <media/media-entity.h> +#include <media/v4l2-dev.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-ioctl.h> +#include <media/v4l2-mc.h> +#include <media/v4l2-subdev.h> +#include <media/videobuf2-v4l2.h> + +#include "abi/ipu7_fw_isys_abi.h" + +#include "ipu7.h" +#include "ipu7-bus.h" +#include "ipu7-buttress-regs.h" +#include "ipu7-fw-isys.h" +#include "ipu7-isys.h" +#include "ipu7-isys-video.h" +#include "ipu7-platform-regs.h" + +const struct ipu7_isys_pixelformat ipu7_isys_pfmts[] = { + {V4L2_PIX_FMT_SBGGR12, 16, 12, MEDIA_BUS_FMT_SBGGR12_1X12, + IPU_INSYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGBRG12, 16, 12, MEDIA_BUS_FMT_SGBRG12_1X12, + IPU_INSYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGRBG12, 16, 12, MEDIA_BUS_FMT_SGRBG12_1X12, + IPU_INSYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SRGGB12, 16, 12, MEDIA_BUS_FMT_SRGGB12_1X12, + IPU_INSYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SBGGR10, 16, 10, MEDIA_BUS_FMT_SBGGR10_1X10, + IPU_INSYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGBRG10, 16, 10, MEDIA_BUS_FMT_SGBRG10_1X10, + IPU_INSYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGRBG10, 16, 10, MEDIA_BUS_FMT_SGRBG10_1X10, + IPU_INSYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SRGGB10, 16, 10, MEDIA_BUS_FMT_SRGGB10_1X10, + IPU_INSYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SBGGR8, 8, 8, MEDIA_BUS_FMT_SBGGR8_1X8, + IPU_INSYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SGBRG8, 8, 8, MEDIA_BUS_FMT_SGBRG8_1X8, + IPU_INSYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SGRBG8, 8, 8, MEDIA_BUS_FMT_SGRBG8_1X8, + IPU_INSYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SRGGB8, 8, 8, MEDIA_BUS_FMT_SRGGB8_1X8, + IPU_INSYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SBGGR12P, 12, 12, MEDIA_BUS_FMT_SBGGR12_1X12, + IPU_INSYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SGBRG12P, 12, 12, MEDIA_BUS_FMT_SGBRG12_1X12, + IPU_INSYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SGRBG12P, 12, 12, MEDIA_BUS_FMT_SGRBG12_1X12, + IPU_INSYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SRGGB12P, 12, 12, MEDIA_BUS_FMT_SRGGB12_1X12, + IPU_INSYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SBGGR10P, 10, 10, MEDIA_BUS_FMT_SBGGR10_1X10, + IPU_INSYS_FRAME_FORMAT_RAW10}, + {V4L2_PIX_FMT_SGBRG10P, 10, 10, MEDIA_BUS_FMT_SGBRG10_1X10, + IPU_INSYS_FRAME_FORMAT_RAW10}, + {V4L2_PIX_FMT_SGRBG10P, 10, 10, MEDIA_BUS_FMT_SGRBG10_1X10, + IPU_INSYS_FRAME_FORMAT_RAW10}, + {V4L2_PIX_FMT_SRGGB10P, 10, 10, MEDIA_BUS_FMT_SRGGB10_1X10, + IPU_INSYS_FRAME_FORMAT_RAW10}, + {V4L2_PIX_FMT_UYVY, 16, 16, MEDIA_BUS_FMT_UYVY8_1X16, + IPU_INSYS_FRAME_FORMAT_UYVY}, + {V4L2_PIX_FMT_YUYV, 16, 16, MEDIA_BUS_FMT_YUYV8_1X16, + IPU_INSYS_FRAME_FORMAT_YUYV}, + {V4L2_PIX_FMT_RGB565, 16, 16, MEDIA_BUS_FMT_RGB565_1X16, + IPU_INSYS_FRAME_FORMAT_RGB565}, + {V4L2_PIX_FMT_BGR24, 24, 24, MEDIA_BUS_FMT_RGB888_1X24, + IPU_INSYS_FRAME_FORMAT_RGBA888}, +}; + +static int video_open(struct file *file) +{ + return v4l2_fh_open(file); +} + +const struct ipu7_isys_pixelformat *ipu7_isys_get_isys_format(u32 pixelformat) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(ipu7_isys_pfmts); i++) { + const struct ipu7_isys_pixelformat *pfmt = &ipu7_isys_pfmts[i]; + + if (pfmt->pixelformat == pixelformat) + return pfmt; + } + + return &ipu7_isys_pfmts[0]; +} + +static int ipu7_isys_vidioc_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) +{ + struct ipu7_isys_video *av = video_drvdata(file); + + strscpy(cap->driver, IPU_ISYS_NAME, sizeof(cap->driver)); + strscpy(cap->card, av->isys->media_dev.model, sizeof(cap->card)); + + return 0; +} + +static int ipu7_isys_vidioc_enum_fmt(struct file *file, void *fh, + struct v4l2_fmtdesc *f) +{ + unsigned int i, num_found; + + for (i = 0, num_found = 0; i < ARRAY_SIZE(ipu7_isys_pfmts); i++) { + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + continue; + + if (f->mbus_code && f->mbus_code != ipu7_isys_pfmts[i].code) + continue; + + if (num_found < f->index) { + num_found++; + continue; + } + + f->flags = 0; + f->pixelformat = ipu7_isys_pfmts[i].pixelformat; + + return 0; + } + + return -EINVAL; +} + +static int ipu7_isys_vidioc_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + unsigned int i; + + if (fsize->index > 0) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(ipu7_isys_pfmts); i++) { + if (fsize->pixel_format != ipu7_isys_pfmts[i].pixelformat) + continue; + + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; + fsize->stepwise.min_width = IPU_ISYS_MIN_WIDTH; + fsize->stepwise.max_width = IPU_ISYS_MAX_WIDTH; + fsize->stepwise.min_height = IPU_ISYS_MIN_HEIGHT; + fsize->stepwise.max_height = IPU_ISYS_MAX_HEIGHT; + fsize->stepwise.step_width = 2; + fsize->stepwise.step_height = 2; + + return 0; + } + + return -EINVAL; +} + +static int ipu7_isys_vidioc_g_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct ipu7_isys_video *av = video_drvdata(file); + + f->fmt.pix = av->pix_fmt; + + return 0; +} + +static void ipu7_isys_try_fmt_cap(struct ipu7_isys_video *av, u32 type, + u32 *format, u32 *width, u32 *height, + u32 *bytesperline, u32 *sizeimage) +{ + const struct ipu7_isys_pixelformat *pfmt = + ipu7_isys_get_isys_format(*format); + + *format = pfmt->pixelformat; + *width = clamp(*width, IPU_ISYS_MIN_WIDTH, IPU_ISYS_MAX_WIDTH); + *height = clamp(*height, IPU_ISYS_MIN_HEIGHT, IPU_ISYS_MAX_HEIGHT); + + if (pfmt->bpp != pfmt->bpp_packed) + *bytesperline = *width * DIV_ROUND_UP(pfmt->bpp, BITS_PER_BYTE); + else + *bytesperline = DIV_ROUND_UP(*width * pfmt->bpp, BITS_PER_BYTE); + + *bytesperline = ALIGN(*bytesperline, 64U); + + /* + * (height + 1) * bytesperline due to a hardware issue: the DMA unit + * is a power of two, and a line should be transferred as few units + * as possible. The result is that up to line length more data than + * the image size may be transferred to memory after the image. + * Another limitation is the GDA allocation unit size. For low + * resolution it gives a bigger number. Use larger one to avoid + * memory corruption. + */ + *sizeimage = *bytesperline * *height + + max(*bytesperline, + av->isys->pdata->ipdata->isys_dma_overshoot); +} + +static void __ipu_isys_vidioc_try_fmt_vid_cap(struct ipu7_isys_video *av, + struct v4l2_format *f) +{ + ipu7_isys_try_fmt_cap(av, f->type, &f->fmt.pix.pixelformat, + &f->fmt.pix.width, &f->fmt.pix.height, + &f->fmt.pix.bytesperline, &f->fmt.pix.sizeimage); + + f->fmt.pix.field = V4L2_FIELD_NONE; + f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; + f->fmt.pix.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + f->fmt.pix.quantization = V4L2_QUANTIZATION_DEFAULT; + f->fmt.pix.xfer_func = V4L2_XFER_FUNC_DEFAULT; +} + +static int ipu7_isys_vidioc_try_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct ipu7_isys_video *av = video_drvdata(file); + + if (vb2_is_busy(&av->aq.vbq)) + return -EBUSY; + + __ipu_isys_vidioc_try_fmt_vid_cap(av, f); + + return 0; +} + +static int ipu7_isys_vidioc_s_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct ipu7_isys_video *av = video_drvdata(file); + + ipu7_isys_vidioc_try_fmt_vid_cap(file, fh, f); + av->pix_fmt = f->fmt.pix; + + return 0; +} + +static int ipu7_isys_vidioc_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *p) +{ + struct ipu7_isys_video *av = video_drvdata(file); + int ret; + + av->aq.vbq.is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(p->type); + av->aq.vbq.is_output = V4L2_TYPE_IS_OUTPUT(p->type); + + ret = vb2_queue_change_type(&av->aq.vbq, p->type); + if (ret) + return ret; + + return vb2_ioctl_reqbufs(file, priv, p); +} + +static int ipu7_isys_vidioc_create_bufs(struct file *file, void *priv, + struct v4l2_create_buffers *p) +{ + struct ipu7_isys_video *av = video_drvdata(file); + int ret; + + av->aq.vbq.is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(p->format.type); + av->aq.vbq.is_output = V4L2_TYPE_IS_OUTPUT(p->format.type); + + ret = vb2_queue_change_type(&av->aq.vbq, p->format.type); + if (ret) + return ret; + + return vb2_ioctl_create_bufs(file, priv, p); +} + +static int link_validate(struct media_link *link) +{ + struct ipu7_isys_video *av = + container_of(link->sink, struct ipu7_isys_video, pad); + struct device *dev = &av->isys->adev->auxdev.dev; + struct v4l2_subdev_state *s_state; + struct v4l2_mbus_framefmt *s_fmt; + struct v4l2_subdev *s_sd; + struct media_pad *s_pad; + u32 s_stream, code; + int ret = -EPIPE; + + if (!link->source->entity) + return ret; + + s_sd = media_entity_to_v4l2_subdev(link->source->entity); + s_state = v4l2_subdev_get_unlocked_active_state(s_sd); + if (!s_state) + return ret; + + dev_dbg(dev, "validating link \"%s\":%u -> \"%s\"\n", + link->source->entity->name, link->source->index, + link->sink->entity->name); + + s_pad = media_pad_remote_pad_first(&av->pad); + s_stream = ipu7_isys_get_src_stream_by_src_pad(s_sd, s_pad->index); + + v4l2_subdev_lock_state(s_state); + + s_fmt = v4l2_subdev_state_get_format(s_state, s_pad->index, s_stream); + if (!s_fmt) { + dev_err(dev, "failed to get source pad format\n"); + goto unlock; + } + + code = ipu7_isys_get_isys_format(av->pix_fmt.pixelformat)->code; + + if (s_fmt->width != av->pix_fmt.width || + s_fmt->height != av->pix_fmt.height || s_fmt->code != code) { + dev_dbg(dev, "format mismatch %dx%d,%x != %dx%d,%x\n", + s_fmt->width, s_fmt->height, s_fmt->code, + av->pix_fmt.width, av->pix_fmt.height, code); + goto unlock; + } + + v4l2_subdev_unlock_state(s_state); + + return 0; +unlock: + v4l2_subdev_unlock_state(s_state); + + return ret; +} + +static void get_stream_opened(struct ipu7_isys_video *av) +{ + unsigned long flags; + + spin_lock_irqsave(&av->isys->streams_lock, flags); + av->isys->stream_opened++; + spin_unlock_irqrestore(&av->isys->streams_lock, flags); +} + +static void put_stream_opened(struct ipu7_isys_video *av) +{ + unsigned long flags; + + spin_lock_irqsave(&av->isys->streams_lock, flags); + av->isys->stream_opened--; + spin_unlock_irqrestore(&av->isys->streams_lock, flags); +} + +static int ipu7_isys_fw_pin_cfg(struct ipu7_isys_video *av, + struct ipu7_insys_stream_cfg *cfg) +{ + struct media_pad *src_pad = media_pad_remote_pad_first(&av->pad); + struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(src_pad->entity); + struct ipu7_isys_stream *stream = av->stream; + const struct ipu7_isys_pixelformat *pfmt = + ipu7_isys_get_isys_format(av->pix_fmt.pixelformat); + struct ipu7_insys_output_pin *output_pin; + struct ipu7_insys_input_pin *input_pin; + int input_pins = cfg->nof_input_pins++; + struct ipu7_isys_queue *aq = &av->aq; + struct ipu7_isys *isys = av->isys; + struct device *dev = &isys->adev->auxdev.dev; + struct v4l2_mbus_framefmt fmt; + int output_pins; + u32 src_stream; + int ret; + + src_stream = ipu7_isys_get_src_stream_by_src_pad(sd, src_pad->index); + ret = ipu7_isys_get_stream_pad_fmt(sd, src_pad->index, src_stream, + &fmt); + if (ret < 0) { + dev_err(dev, "can't get stream format (%d)\n", ret); + return ret; + } + + input_pin = &cfg->input_pins[input_pins]; + input_pin->input_res.width = fmt.width; + input_pin->input_res.height = fmt.height; + input_pin->dt = av->dt; + input_pin->disable_mipi_unpacking = 0; + pfmt = ipu7_isys_get_isys_format(av->pix_fmt.pixelformat); + if (pfmt->bpp == pfmt->bpp_packed && pfmt->bpp % BITS_PER_BYTE) + input_pin->disable_mipi_unpacking = 1; + input_pin->mapped_dt = N_IPU_INSYS_MIPI_DATA_TYPE; + input_pin->dt_rename_mode = IPU_INSYS_MIPI_DT_NO_RENAME; + /* if enable polling isys interrupt, the follow values maybe set */ + input_pin->sync_msg_map = IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_SOF | + IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_SOF_DISCARDED | + IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_SOF | + IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_SOF_DISCARDED; + + output_pins = cfg->nof_output_pins++; + aq->fw_output = output_pins; + stream->output_pins[output_pins].pin_ready = ipu7_isys_queue_buf_ready; + stream->output_pins[output_pins].aq = aq; + + output_pin = &cfg->output_pins[output_pins]; + /* output pin msg link */ + output_pin->link.buffer_lines = 0; + output_pin->link.foreign_key = IPU_MSG_LINK_FOREIGN_KEY_NONE; + output_pin->link.granularity_pointer_update = 0; + output_pin->link.msg_link_streaming_mode = + IA_GOFO_MSG_LINK_STREAMING_MODE_SOFF; + + output_pin->link.pbk_id = IPU_MSG_LINK_PBK_ID_DONT_CARE; + output_pin->link.pbk_slot_id = IPU_MSG_LINK_PBK_SLOT_ID_DONT_CARE; + output_pin->link.dest = IPU_INSYS_OUTPUT_LINK_DEST_MEM; + output_pin->link.use_sw_managed = 1; + /* TODO: set the snoop bit for metadata capture */ + output_pin->link.is_snoop = 0; + + /* output pin crop */ + output_pin->crop.line_top = 0; + output_pin->crop.line_bottom = 0; + + /* output de-compression */ + output_pin->dpcm.enable = 0; + + /* frame format type */ + pfmt = ipu7_isys_get_isys_format(av->pix_fmt.pixelformat); + output_pin->ft = (u16)pfmt->css_pixelformat; + + /* stride in bytes */ + output_pin->stride = av->pix_fmt.bytesperline; + output_pin->send_irq = 1; + output_pin->early_ack_en = 0; + + /* input pin id */ + output_pin->input_pin_id = input_pins; + + return 0; +} + +/* Create stream and start it using the CSS FW ABI. */ +static int start_stream_firmware(struct ipu7_isys_video *av, + struct ipu7_isys_buffer_list *bl) +{ + struct device *dev = &av->isys->adev->auxdev.dev; + struct ipu7_isys_stream *stream = av->stream; + struct ipu7_insys_stream_cfg *stream_cfg; + struct ipu7_insys_buffset *buf = NULL; + struct isys_fw_msgs *msg = NULL; + struct ipu7_isys_queue *aq; + int ret, retout, tout; + u16 send_type; + + if (WARN_ON(!bl)) + return -EIO; + + msg = ipu7_get_fw_msg_buf(stream); + if (!msg) + return -ENOMEM; + + stream_cfg = &msg->fw_msg.stream; + stream_cfg->port_id = stream->stream_source; + stream_cfg->vc = stream->vc; + stream_cfg->stream_msg_map = IPU_INSYS_STREAM_ENABLE_MSG_SEND_RESP | + IPU_INSYS_STREAM_ENABLE_MSG_SEND_IRQ; + + list_for_each_entry(aq, &stream->queues, node) { + struct ipu7_isys_video *__av = ipu7_isys_queue_to_video(aq); + + ret = ipu7_isys_fw_pin_cfg(__av, stream_cfg); + if (ret < 0) { + ipu7_put_fw_msg_buf(av->isys, (uintptr_t)stream_cfg); + return ret; + } + } + + ipu7_fw_isys_dump_stream_cfg(dev, stream_cfg); + + stream->nr_output_pins = stream_cfg->nof_output_pins; + + reinit_completion(&stream->stream_open_completion); + + ret = ipu7_fw_isys_complex_cmd(av->isys, stream->stream_handle, + stream_cfg, msg->dma_addr, + sizeof(*stream_cfg), + IPU_INSYS_SEND_TYPE_STREAM_OPEN); + if (ret < 0) { + dev_err(dev, "can't open stream (%d)\n", ret); + ipu7_put_fw_msg_buf(av->isys, (uintptr_t)stream_cfg); + return ret; + } + + get_stream_opened(av); + + tout = wait_for_completion_timeout(&stream->stream_open_completion, + FW_CALL_TIMEOUT_JIFFIES); + + ipu7_put_fw_msg_buf(av->isys, (uintptr_t)stream_cfg); + + if (!tout) { + dev_err(dev, "stream open time out\n"); + ret = -ETIMEDOUT; + goto out_put_stream_opened; + } + if (stream->error) { + dev_err(dev, "stream open error: %d\n", stream->error); + ret = -EIO; + goto out_put_stream_opened; + } + dev_dbg(dev, "start stream: open complete\n"); + + msg = ipu7_get_fw_msg_buf(stream); + if (!msg) { + ret = -ENOMEM; + goto out_put_stream_opened; + } + buf = &msg->fw_msg.frame; + + ipu7_isys_buffer_to_fw_frame_buff(buf, stream, bl); + ipu7_isys_buffer_list_queue(bl, IPU_ISYS_BUFFER_LIST_FL_ACTIVE, 0); + + reinit_completion(&stream->stream_start_completion); + + send_type = IPU_INSYS_SEND_TYPE_STREAM_START_AND_CAPTURE; + ipu7_fw_isys_dump_frame_buff_set(dev, buf, + stream_cfg->nof_output_pins); + ret = ipu7_fw_isys_complex_cmd(av->isys, stream->stream_handle, buf, + msg->dma_addr, sizeof(*buf), + send_type); + if (ret < 0) { + dev_err(dev, "can't start streaming (%d)\n", ret); + goto out_stream_close; + } + + tout = wait_for_completion_timeout(&stream->stream_start_completion, + FW_CALL_TIMEOUT_JIFFIES); + if (!tout) { + dev_err(dev, "stream start time out\n"); + ret = -ETIMEDOUT; + goto out_stream_close; + } + if (stream->error) { + dev_err(dev, "stream start error: %d\n", stream->error); + ret = -EIO; + goto out_stream_close; + } + dev_dbg(dev, "start stream: complete\n"); + + return 0; + +out_stream_close: + reinit_completion(&stream->stream_close_completion); + + retout = ipu7_fw_isys_simple_cmd(av->isys, stream->stream_handle, + IPU_INSYS_SEND_TYPE_STREAM_CLOSE); + if (retout < 0) { + dev_dbg(dev, "can't close stream (%d)\n", retout); + goto out_put_stream_opened; + } + + tout = wait_for_completion_timeout(&stream->stream_close_completion, + FW_CALL_TIMEOUT_JIFFIES); + if (!tout) + dev_err(dev, "stream close time out with error %d\n", + stream->error); + else + dev_dbg(dev, "stream close complete\n"); + +out_put_stream_opened: + put_stream_opened(av); + + return ret; +} + +static void stop_streaming_firmware(struct ipu7_isys_video *av) +{ + struct device *dev = &av->isys->adev->auxdev.dev; + struct ipu7_isys_stream *stream = av->stream; + int ret, tout; + + reinit_completion(&stream->stream_stop_completion); + + ret = ipu7_fw_isys_simple_cmd(av->isys, stream->stream_handle, + IPU_INSYS_SEND_TYPE_STREAM_FLUSH); + if (ret < 0) { + dev_err(dev, "can't stop stream (%d)\n", ret); + return; + } + + tout = wait_for_completion_timeout(&stream->stream_stop_completion, + FW_CALL_TIMEOUT_JIFFIES); + if (!tout) + dev_warn(dev, "stream stop time out\n"); + else if (stream->error) + dev_warn(dev, "stream stop error: %d\n", stream->error); + else + dev_dbg(dev, "stop stream: complete\n"); +} + +static void close_streaming_firmware(struct ipu7_isys_video *av) +{ + struct device *dev = &av->isys->adev->auxdev.dev; + struct ipu7_isys_stream *stream = av->stream; + int ret, tout; + + reinit_completion(&stream->stream_close_completion); + + ret = ipu7_fw_isys_simple_cmd(av->isys, stream->stream_handle, + IPU_INSYS_SEND_TYPE_STREAM_CLOSE); + if (ret < 0) { + dev_err(dev, "can't close stream (%d)\n", ret); + return; + } + + tout = wait_for_completion_timeout(&stream->stream_close_completion, + FW_CALL_TIMEOUT_JIFFIES); + if (!tout) + dev_warn(dev, "stream close time out\n"); + else if (stream->error) + dev_warn(dev, "stream close error: %d\n", stream->error); + else + dev_dbg(dev, "close stream: complete\n"); + + put_stream_opened(av); +} + +int ipu7_isys_video_prepare_stream(struct ipu7_isys_video *av, + struct media_entity *source_entity, + int nr_queues) +{ + struct ipu7_isys_stream *stream = av->stream; + struct ipu7_isys_csi2 *csi2; + + if (WARN_ON(stream->nr_streaming)) + return -EINVAL; + + stream->nr_queues = nr_queues; + atomic_set(&stream->sequence, 0); + atomic_set(&stream->buf_id, 0); + + stream->seq_index = 0; + memset(stream->seq, 0, sizeof(stream->seq)); + + if (WARN_ON(!list_empty(&stream->queues))) + return -EINVAL; + + stream->stream_source = stream->asd->source; + + csi2 = ipu7_isys_subdev_to_csi2(stream->asd); + csi2->receiver_errors = 0; + stream->source_entity = source_entity; + + dev_dbg(&av->isys->adev->auxdev.dev, + "prepare stream: external entity %s\n", + stream->source_entity->name); + + return 0; +} + +void ipu7_isys_put_stream(struct ipu7_isys_stream *stream) +{ + unsigned long flags; + struct device *dev; + unsigned int i; + + if (!stream) { + pr_err("ipu7-isys: no available stream\n"); + return; + } + + dev = &stream->isys->adev->auxdev.dev; + + spin_lock_irqsave(&stream->isys->streams_lock, flags); + for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) { + if (&stream->isys->streams[i] == stream) { + if (stream->isys->streams_ref_count[i] > 0) + stream->isys->streams_ref_count[i]--; + else + dev_warn(dev, "invalid stream %d\n", i); + + break; + } + } + spin_unlock_irqrestore(&stream->isys->streams_lock, flags); +} + +static struct ipu7_isys_stream * +ipu7_isys_get_stream(struct ipu7_isys_video *av, struct ipu7_isys_subdev *asd) +{ + struct ipu7_isys_stream *stream = NULL; + struct ipu7_isys *isys = av->isys; + unsigned long flags; + unsigned int i; + u8 vc = av->vc; + + if (!isys) + return NULL; + + spin_lock_irqsave(&isys->streams_lock, flags); + for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) { + if (isys->streams_ref_count[i] && isys->streams[i].vc == vc && + isys->streams[i].asd == asd) { + isys->streams_ref_count[i]++; + stream = &isys->streams[i]; + break; + } + } + + if (!stream) { + for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) { + if (!isys->streams_ref_count[i]) { + isys->streams_ref_count[i]++; + stream = &isys->streams[i]; + stream->vc = vc; + stream->asd = asd; + break; + } + } + } + spin_unlock_irqrestore(&isys->streams_lock, flags); + + return stream; +} + +struct ipu7_isys_stream * +ipu7_isys_query_stream_by_handle(struct ipu7_isys *isys, u8 stream_handle) +{ + unsigned long flags; + struct ipu7_isys_stream *stream = NULL; + + if (!isys) + return NULL; + + if (stream_handle >= IPU_ISYS_MAX_STREAMS) { + dev_err(&isys->adev->auxdev.dev, + "stream_handle %d is invalid\n", stream_handle); + return NULL; + } + + spin_lock_irqsave(&isys->streams_lock, flags); + if (isys->streams_ref_count[stream_handle] > 0) { + isys->streams_ref_count[stream_handle]++; + stream = &isys->streams[stream_handle]; + } + spin_unlock_irqrestore(&isys->streams_lock, flags); + + return stream; +} + +struct ipu7_isys_stream * +ipu7_isys_query_stream_by_source(struct ipu7_isys *isys, int source, u8 vc) +{ + struct ipu7_isys_stream *stream = NULL; + unsigned long flags; + unsigned int i; + + if (!isys) + return NULL; + + if (source < 0) { + dev_err(&isys->adev->auxdev.dev, + "query stream with invalid port number\n"); + return NULL; + } + + spin_lock_irqsave(&isys->streams_lock, flags); + for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) { + if (!isys->streams_ref_count[i]) + continue; + + if (isys->streams[i].stream_source == source && + isys->streams[i].vc == vc) { + stream = &isys->streams[i]; + isys->streams_ref_count[i]++; + break; + } + } + spin_unlock_irqrestore(&isys->streams_lock, flags); + + return stream; +} + +static u32 get_remote_pad_stream(struct media_pad *r_pad) +{ + struct v4l2_subdev_state *state; + struct v4l2_subdev *sd; + u32 stream_id = 0; + unsigned int i; + + sd = media_entity_to_v4l2_subdev(r_pad->entity); + state = v4l2_subdev_lock_and_get_active_state(sd); + if (!state) + return 0; + + for (i = 0; i < state->stream_configs.num_configs; i++) { + struct v4l2_subdev_stream_config *cfg = + &state->stream_configs.configs[i]; + if (cfg->pad == r_pad->index) { + stream_id = cfg->stream; + break; + } + } + + v4l2_subdev_unlock_state(state); + + return stream_id; +} + +int ipu7_isys_video_set_streaming(struct ipu7_isys_video *av, int state, + struct ipu7_isys_buffer_list *bl) +{ + struct ipu7_isys_stream *stream = av->stream; + struct device *dev = &av->isys->adev->auxdev.dev; + struct media_pad *r_pad; + struct v4l2_subdev *sd; + u32 r_stream; + int ret = 0; + + dev_dbg(dev, "set stream: %d\n", state); + + if (WARN(!stream->source_entity, "No source entity for stream\n")) + return -ENODEV; + + sd = &stream->asd->sd; + r_pad = media_pad_remote_pad_first(&av->pad); + r_stream = get_remote_pad_stream(r_pad); + if (!state) { + stop_streaming_firmware(av); + + /* stop sub-device which connects with video */ + dev_dbg(dev, "disable streams %s pad:%d mask:0x%llx\n", + sd->name, r_pad->index, BIT_ULL(r_stream)); + ret = v4l2_subdev_disable_streams(sd, r_pad->index, + BIT_ULL(r_stream)); + if (ret) { + dev_err(dev, "disable streams %s failed with %d\n", + sd->name, ret); + return ret; + } + + close_streaming_firmware(av); + } else { + ret = start_stream_firmware(av, bl); + if (ret) { + dev_err(dev, "start stream of firmware failed\n"); + return ret; + } + + /* start sub-device which connects with video */ + dev_dbg(dev, "enable streams %s pad: %d mask:0x%llx\n", + sd->name, r_pad->index, BIT_ULL(r_stream)); + ret = v4l2_subdev_enable_streams(sd, r_pad->index, + BIT_ULL(r_stream)); + if (ret) { + dev_err(dev, "enable streams %s failed with %d\n", + sd->name, ret); + goto out_media_entity_stop_streaming_firmware; + } + } + + av->streaming = state; + + return 0; + +out_media_entity_stop_streaming_firmware: + stop_streaming_firmware(av); + + return ret; +} + +static const struct v4l2_ioctl_ops ipu7_v4l2_ioctl_ops = { + .vidioc_querycap = ipu7_isys_vidioc_querycap, + .vidioc_enum_fmt_vid_cap = ipu7_isys_vidioc_enum_fmt, + .vidioc_enum_framesizes = ipu7_isys_vidioc_enum_framesizes, + .vidioc_g_fmt_vid_cap = ipu7_isys_vidioc_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = ipu7_isys_vidioc_s_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = ipu7_isys_vidioc_try_fmt_vid_cap, + .vidioc_reqbufs = ipu7_isys_vidioc_reqbufs, + .vidioc_create_bufs = ipu7_isys_vidioc_create_bufs, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_expbuf = vb2_ioctl_expbuf, +}; + +static const struct media_entity_operations entity_ops = { + .link_validate = link_validate, +}; + +static const struct v4l2_file_operations isys_fops = { + .owner = THIS_MODULE, + .poll = vb2_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = vb2_fop_mmap, + .open = video_open, + .release = vb2_fop_release, +}; + +int ipu7_isys_fw_open(struct ipu7_isys *isys) +{ + struct ipu7_bus_device *adev = isys->adev; + int ret; + + ret = pm_runtime_resume_and_get(&adev->auxdev.dev); + if (ret < 0) + return ret; + + mutex_lock(&isys->mutex); + + if (isys->ref_count++) + goto unlock; + + /* + * Buffers could have been left to wrong queue at last closure. + * Move them now back to empty buffer queue. + */ + ipu7_cleanup_fw_msg_bufs(isys); + + ret = ipu7_fw_isys_open(isys); + if (ret < 0) + goto out; + +unlock: + mutex_unlock(&isys->mutex); + + return 0; +out: + isys->ref_count--; + mutex_unlock(&isys->mutex); + pm_runtime_put(&adev->auxdev.dev); + + return ret; +} + +void ipu7_isys_fw_close(struct ipu7_isys *isys) +{ + mutex_lock(&isys->mutex); + + isys->ref_count--; + + if (!isys->ref_count) + ipu7_fw_isys_close(isys); + + mutex_unlock(&isys->mutex); +} + +int ipu7_isys_setup_video(struct ipu7_isys_video *av, + struct media_entity **source_entity, int *nr_queues) +{ + const struct ipu7_isys_pixelformat *pfmt = + ipu7_isys_get_isys_format(av->pix_fmt.pixelformat); + struct device *dev = &av->isys->adev->auxdev.dev; + struct media_pad *source_pad, *remote_pad; + struct v4l2_mbus_frame_desc_entry entry; + struct v4l2_subdev_route *route = NULL; + struct v4l2_subdev_route *r; + struct v4l2_subdev_state *state; + struct ipu7_isys_subdev *asd; + struct v4l2_subdev *remote_sd; + struct media_pipeline *pipeline; + int ret = -EINVAL; + + *nr_queues = 0; + + remote_pad = media_pad_remote_pad_unique(&av->pad); + if (IS_ERR(remote_pad)) { + dev_dbg(dev, "failed to get remote pad\n"); + return PTR_ERR(remote_pad); + } + + remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity); + asd = to_ipu7_isys_subdev(remote_sd); + + source_pad = media_pad_remote_pad_first(&remote_pad->entity->pads[0]); + if (!source_pad) { + dev_dbg(dev, "No external source entity\n"); + return -ENODEV; + } + + *source_entity = source_pad->entity; + + state = v4l2_subdev_lock_and_get_active_state(remote_sd); + for_each_active_route(&state->routing, r) { + if (r->source_pad == remote_pad->index) + route = r; + } + + if (!route) { + v4l2_subdev_unlock_state(state); + dev_dbg(dev, "Failed to find route\n"); + return -ENODEV; + } + + v4l2_subdev_unlock_state(state); + + ret = ipu7_isys_csi2_get_remote_desc(route->sink_stream, + to_ipu7_isys_csi2(asd), + *source_entity, &entry, + nr_queues); + if (ret == -ENOIOCTLCMD) { + av->vc = 0; + av->dt = ipu7_isys_mbus_code_to_mipi(pfmt->code); + if (av->dt == 0xff) + return -EINVAL; + *nr_queues = 1; + } else if (*nr_queues && !ret) { + dev_dbg(dev, "Framedesc: stream %u, len %u, vc %u, dt %#x\n", + entry.stream, entry.length, entry.bus.csi2.vc, + entry.bus.csi2.dt); + + av->vc = entry.bus.csi2.vc; + av->dt = entry.bus.csi2.dt; + } else { + dev_err(dev, "failed to get remote frame desc\n"); + return ret; + } + + pipeline = media_entity_pipeline(&av->vdev.entity); + if (!pipeline) + ret = video_device_pipeline_alloc_start(&av->vdev); + else + ret = video_device_pipeline_start(&av->vdev, pipeline); + if (ret < 0) { + dev_dbg(dev, "media pipeline start failed\n"); + return ret; + } + + av->stream = ipu7_isys_get_stream(av, asd); + if (!av->stream) { + video_device_pipeline_stop(&av->vdev); + dev_err(dev, "no available stream for firmware\n"); + return -EINVAL; + } + + return 0; +} + +/* + * Do everything that's needed to initialise things related to video + * buffer queue, video node, and the related media entity. The caller + * is expected to assign isys field and set the name of the video + * device. + */ +int ipu7_isys_video_init(struct ipu7_isys_video *av) +{ + struct v4l2_format format = { + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + .fmt.pix = { + .width = 1920, + .height = 1080, + }, + }; + int ret; + + mutex_init(&av->mutex); + av->vdev.device_caps = V4L2_CAP_STREAMING | V4L2_CAP_IO_MC | + V4L2_CAP_VIDEO_CAPTURE; + av->vdev.vfl_dir = VFL_DIR_RX; + + ret = ipu7_isys_queue_init(&av->aq); + if (ret) + goto out_mutex_destroy; + + av->pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; + ret = media_entity_pads_init(&av->vdev.entity, 1, &av->pad); + if (ret) + goto out_vb2_queue_cleanup; + + av->vdev.entity.ops = &entity_ops; + av->vdev.release = video_device_release_empty; + av->vdev.fops = &isys_fops; + av->vdev.v4l2_dev = &av->isys->v4l2_dev; + av->vdev.dev_parent = &av->isys->adev->isp->pdev->dev; + av->vdev.ioctl_ops = &ipu7_v4l2_ioctl_ops; + av->vdev.queue = &av->aq.vbq; + av->vdev.lock = &av->mutex; + + __ipu_isys_vidioc_try_fmt_vid_cap(av, &format); + av->pix_fmt = format.fmt.pix; + + set_bit(V4L2_FL_USES_V4L2_FH, &av->vdev.flags); + video_set_drvdata(&av->vdev, av); + + ret = video_register_device(&av->vdev, VFL_TYPE_VIDEO, -1); + if (ret) + goto out_media_entity_cleanup; + + return ret; + +out_media_entity_cleanup: + vb2_video_unregister_device(&av->vdev); + media_entity_cleanup(&av->vdev.entity); + +out_vb2_queue_cleanup: + vb2_queue_release(&av->aq.vbq); + +out_mutex_destroy: + mutex_destroy(&av->mutex); + + return ret; +} + +void ipu7_isys_video_cleanup(struct ipu7_isys_video *av) +{ + vb2_video_unregister_device(&av->vdev); + media_entity_cleanup(&av->vdev.entity); + mutex_destroy(&av->mutex); +} diff --git a/drivers/staging/media/ipu7/ipu7-isys-video.h b/drivers/staging/media/ipu7/ipu7-isys-video.h new file mode 100644 index 000000000000..1ac1787fabef --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys-video.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_ISYS_VIDEO_H +#define IPU7_ISYS_VIDEO_H + +#include <linux/atomic.h> +#include <linux/completion.h> +#include <linux/container_of.h> +#include <linux/list.h> +#include <linux/mutex.h> + +#include <media/media-entity.h> +#include <media/v4l2-dev.h> + +#include "ipu7-isys-queue.h" + +#define IPU_INSYS_OUTPUT_PINS 11U +#define IPU_ISYS_MAX_PARALLEL_SOF 2U + +struct file; +struct ipu7_isys; +struct ipu7_isys_csi2; +struct ipu7_insys_stream_cfg; +struct ipu7_isys_subdev; + +struct ipu7_isys_pixelformat { + u32 pixelformat; + u32 bpp; + u32 bpp_packed; + u32 code; + u32 css_pixelformat; +}; + +struct sequence_info { + unsigned int sequence; + u64 timestamp; +}; + +struct output_pin_data { + void (*pin_ready)(struct ipu7_isys_stream *stream, + struct ipu7_insys_resp *info); + struct ipu7_isys_queue *aq; +}; + +/* + * Align with firmware stream. Each stream represents a CSI virtual channel. + * May map to multiple video devices + */ +struct ipu7_isys_stream { + struct mutex mutex; + struct media_entity *source_entity; + atomic_t sequence; + atomic_t buf_id; + unsigned int seq_index; + struct sequence_info seq[IPU_ISYS_MAX_PARALLEL_SOF]; + int stream_source; + int stream_handle; + unsigned int nr_output_pins; + struct ipu7_isys_subdev *asd; + + int nr_queues; /* Number of capture queues */ + int nr_streaming; + int streaming; + struct list_head queues; + struct completion stream_open_completion; + struct completion stream_close_completion; + struct completion stream_start_completion; + struct completion stream_stop_completion; + struct ipu7_isys *isys; + + struct output_pin_data output_pins[IPU_INSYS_OUTPUT_PINS]; + int error; + u8 vc; +}; + +struct ipu7_isys_video { + struct ipu7_isys_queue aq; + /* Serialise access to other fields in the struct. */ + struct mutex mutex; + struct media_pad pad; + struct video_device vdev; + struct v4l2_pix_format pix_fmt; + struct ipu7_isys *isys; + struct ipu7_isys_csi2 *csi2; + struct ipu7_isys_stream *stream; + unsigned int streaming; + u8 vc; + u8 dt; +}; + +#define ipu7_isys_queue_to_video(__aq) \ + container_of(__aq, struct ipu7_isys_video, aq) + +extern const struct ipu7_isys_pixelformat ipu7_isys_pfmts[]; + +const struct ipu7_isys_pixelformat *ipu7_isys_get_isys_format(u32 pixelformat); +int ipu7_isys_video_prepare_stream(struct ipu7_isys_video *av, + struct media_entity *source_entity, + int nr_queues); +int ipu7_isys_video_set_streaming(struct ipu7_isys_video *av, int state, + struct ipu7_isys_buffer_list *bl); +int ipu7_isys_fw_open(struct ipu7_isys *isys); +void ipu7_isys_fw_close(struct ipu7_isys *isys); +int ipu7_isys_setup_video(struct ipu7_isys_video *av, + struct media_entity **source_entity, int *nr_queues); +int ipu7_isys_video_init(struct ipu7_isys_video *av); +void ipu7_isys_video_cleanup(struct ipu7_isys_video *av); +void ipu7_isys_put_stream(struct ipu7_isys_stream *stream); +struct ipu7_isys_stream * +ipu7_isys_query_stream_by_handle(struct ipu7_isys *isys, + u8 stream_handle); +struct ipu7_isys_stream * +ipu7_isys_query_stream_by_source(struct ipu7_isys *isys, int source, u8 vc); +#endif /* IPU7_ISYS_VIDEO_H */ diff --git a/drivers/staging/media/ipu7/ipu7-isys.c b/drivers/staging/media/ipu7/ipu7-isys.c new file mode 100644 index 000000000000..cb2f49f3e0fa --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys.c @@ -0,0 +1,1166 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <linux/auxiliary_bus.h> +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/bug.h> +#include <linux/completion.h> +#include <linux/container_of.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/err.h> +#include <linux/firmware.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/pci.h> +#include <linux/pm_runtime.h> +#include <linux/pm_qos.h> +#include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/types.h> + +#include <media/ipu-bridge.h> +#include <media/media-entity.h> +#include <media/v4l2-async.h> +#include <media/v4l2-device.h> +#include <media/v4l2-fwnode.h> +#include <media/v4l2-subdev.h> + +#include "abi/ipu7_fw_isys_abi.h" + +#include "ipu7-bus.h" +#include "ipu7-buttress-regs.h" +#include "ipu7-cpd.h" +#include "ipu7-dma.h" +#include "ipu7-fw-isys.h" +#include "ipu7-mmu.h" +#include "ipu7-isys.h" +#include "ipu7-isys-csi2.h" +#include "ipu7-isys-csi-phy.h" +#include "ipu7-isys-csi2-regs.h" +#include "ipu7-isys-video.h" +#include "ipu7-platform-regs.h" + +#define ISYS_PM_QOS_VALUE 300 + +static int +isys_complete_ext_device_registration(struct ipu7_isys *isys, + struct v4l2_subdev *sd, + struct ipu7_isys_csi2_config *csi2) +{ + struct device *dev = &isys->adev->auxdev.dev; + unsigned int i; + int ret; + + v4l2_set_subdev_hostdata(sd, csi2); + + for (i = 0; i < sd->entity.num_pads; i++) { + if (sd->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE) + break; + } + + if (i == sd->entity.num_pads) { + dev_warn(dev, "no source pad in external entity\n"); + ret = -ENOENT; + goto skip_unregister_subdev; + } + + ret = media_create_pad_link(&sd->entity, i, + &isys->csi2[csi2->port].asd.sd.entity, + 0, MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); + if (ret) { + dev_warn(dev, "can't create link\n"); + goto skip_unregister_subdev; + } + + isys->csi2[csi2->port].nlanes = csi2->nlanes; + if (csi2->bus_type == V4L2_MBUS_CSI2_DPHY) + isys->csi2[csi2->port].phy_mode = PHY_MODE_DPHY; + else + isys->csi2[csi2->port].phy_mode = PHY_MODE_CPHY; + + return 0; + +skip_unregister_subdev: + v4l2_device_unregister_subdev(sd); + return ret; +} + +static void isys_stream_init(struct ipu7_isys *isys) +{ + unsigned int i; + + for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) { + mutex_init(&isys->streams[i].mutex); + init_completion(&isys->streams[i].stream_open_completion); + init_completion(&isys->streams[i].stream_close_completion); + init_completion(&isys->streams[i].stream_start_completion); + init_completion(&isys->streams[i].stream_stop_completion); + INIT_LIST_HEAD(&isys->streams[i].queues); + isys->streams[i].isys = isys; + isys->streams[i].stream_handle = i; + isys->streams[i].vc = INVALID_VC_ID; + } +} + +static int isys_fw_log_init(struct ipu7_isys *isys) +{ + struct device *dev = &isys->adev->auxdev.dev; + struct isys_fw_log *fw_log; + void *log_buf; + + if (isys->fw_log) + return 0; + + fw_log = devm_kzalloc(dev, sizeof(*fw_log), GFP_KERNEL); + if (!fw_log) + return -ENOMEM; + + mutex_init(&fw_log->mutex); + + log_buf = devm_kzalloc(dev, FW_LOG_BUF_SIZE, GFP_KERNEL); + if (!log_buf) + return -ENOMEM; + + fw_log->head = log_buf; + fw_log->addr = log_buf; + fw_log->count = 0; + fw_log->size = 0; + + isys->fw_log = fw_log; + + return 0; +} + +/* The .bound() notifier callback when a match is found */ +static int isys_notifier_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd, + struct v4l2_async_connection *asc) +{ + struct ipu7_isys *isys = container_of(notifier, + struct ipu7_isys, notifier); + struct sensor_async_sd *s_asd = + container_of(asc, struct sensor_async_sd, asc); + struct device *dev = &isys->adev->auxdev.dev; + int ret; + + ret = ipu_bridge_instantiate_vcm(sd->dev); + if (ret) { + dev_err(dev, "instantiate vcm failed\n"); + return ret; + } + + dev_info(dev, "bind %s nlanes is %d port is %d\n", + sd->name, s_asd->csi2.nlanes, s_asd->csi2.port); + isys_complete_ext_device_registration(isys, sd, &s_asd->csi2); + + return v4l2_device_register_subdev_nodes(&isys->v4l2_dev); +} + +static int isys_notifier_complete(struct v4l2_async_notifier *notifier) +{ + struct ipu7_isys *isys = container_of(notifier, + struct ipu7_isys, notifier); + + dev_info(&isys->adev->auxdev.dev, + "All sensor registration completed.\n"); + + return v4l2_device_register_subdev_nodes(&isys->v4l2_dev); +} + +static const struct v4l2_async_notifier_operations isys_async_ops = { + .bound = isys_notifier_bound, + .complete = isys_notifier_complete, +}; + +static int isys_notifier_init(struct ipu7_isys *isys) +{ + const struct ipu7_isys_internal_csi2_pdata *csi2 = + &isys->pdata->ipdata->csi2; + struct ipu7_device *isp = isys->adev->isp; + struct device *dev = &isp->pdev->dev; + unsigned int i; + int ret; + + v4l2_async_nf_init(&isys->notifier, &isys->v4l2_dev); + + for (i = 0; i < csi2->nports; i++) { + struct v4l2_fwnode_endpoint vep = { + .bus_type = V4L2_MBUS_UNKNOWN + }; + struct sensor_async_sd *s_asd; + struct fwnode_handle *ep; + + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), i, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); + if (!ep) + continue; + + ret = v4l2_fwnode_endpoint_parse(ep, &vep); + if (ret) + goto err_parse; + + if (vep.bus_type != V4L2_MBUS_CSI2_DPHY && + vep.bus_type != V4L2_MBUS_CSI2_CPHY) { + ret = -EINVAL; + dev_err(dev, "unsupported bus type %d!\n", + vep.bus_type); + goto err_parse; + } + + s_asd = v4l2_async_nf_add_fwnode_remote(&isys->notifier, ep, + struct + sensor_async_sd); + if (IS_ERR(s_asd)) { + ret = PTR_ERR(s_asd); + goto err_parse; + } + + s_asd->csi2.port = vep.base.port; + s_asd->csi2.nlanes = vep.bus.mipi_csi2.num_data_lanes; + s_asd->csi2.bus_type = vep.bus_type; + + fwnode_handle_put(ep); + + continue; + +err_parse: + fwnode_handle_put(ep); + return ret; + } + + if (list_empty(&isys->notifier.waiting_list)) { + /* isys probe could continue with async subdevs missing */ + dev_warn(dev, "no subdev found in graph\n"); + return 0; + } + + isys->notifier.ops = &isys_async_ops; + ret = v4l2_async_nf_register(&isys->notifier); + if (ret) { + dev_err(dev, "failed to register async notifier(%d)\n", ret); + v4l2_async_nf_cleanup(&isys->notifier); + } + + return ret; +} + +static void isys_notifier_cleanup(struct ipu7_isys *isys) +{ + v4l2_async_nf_unregister(&isys->notifier); + v4l2_async_nf_cleanup(&isys->notifier); +} + +static void isys_unregister_video_devices(struct ipu7_isys *isys) +{ + const struct ipu7_isys_internal_csi2_pdata *csi2_pdata = + &isys->pdata->ipdata->csi2; + unsigned int i, j; + + for (i = 0; i < csi2_pdata->nports; i++) + for (j = 0; j < IPU7_NR_OF_CSI2_SRC_PADS; j++) + ipu7_isys_video_cleanup(&isys->csi2[i].av[j]); +} + +static int isys_register_video_devices(struct ipu7_isys *isys) +{ + const struct ipu7_isys_internal_csi2_pdata *csi2_pdata = + &isys->pdata->ipdata->csi2; + unsigned int i, j; + int ret; + + for (i = 0; i < csi2_pdata->nports; i++) { + for (j = 0; j < IPU7_NR_OF_CSI2_SRC_PADS; j++) { + struct ipu7_isys_video *av = &isys->csi2[i].av[j]; + + snprintf(av->vdev.name, sizeof(av->vdev.name), + IPU_ISYS_ENTITY_PREFIX " ISYS Capture %u", + i * IPU7_NR_OF_CSI2_SRC_PADS + j); + av->isys = isys; + av->aq.vbq.buf_struct_size = + sizeof(struct ipu7_isys_video_buffer); + + ret = ipu7_isys_video_init(av); + if (ret) + goto fail; + } + } + + return 0; + +fail: + i = i + 1U; + while (i--) { + while (j--) + ipu7_isys_video_cleanup(&isys->csi2[i].av[j]); + j = IPU7_NR_OF_CSI2_SRC_PADS; + } + + return ret; +} + +static void isys_csi2_unregister_subdevices(struct ipu7_isys *isys) +{ + const struct ipu7_isys_internal_csi2_pdata *csi2 = + &isys->pdata->ipdata->csi2; + unsigned int i; + + for (i = 0; i < csi2->nports; i++) + ipu7_isys_csi2_cleanup(&isys->csi2[i]); +} + +static int isys_csi2_register_subdevices(struct ipu7_isys *isys) +{ + const struct ipu7_isys_internal_csi2_pdata *csi2_pdata = + &isys->pdata->ipdata->csi2; + unsigned int i; + int ret; + + for (i = 0; i < csi2_pdata->nports; i++) { + ret = ipu7_isys_csi2_init(&isys->csi2[i], isys, + isys->pdata->base + + csi2_pdata->offsets[i], i); + if (ret) + goto fail; + } + + isys->isr_csi2_mask = IPU7_CSI_RX_LEGACY_IRQ_MASK; + + return 0; + +fail: + while (i--) + ipu7_isys_csi2_cleanup(&isys->csi2[i]); + + return ret; +} + +static int isys_csi2_create_media_links(struct ipu7_isys *isys) +{ + const struct ipu7_isys_internal_csi2_pdata *csi2_pdata = + &isys->pdata->ipdata->csi2; + struct device *dev = &isys->adev->auxdev.dev; + struct media_entity *sd; + unsigned int i, j; + int ret; + + for (i = 0; i < csi2_pdata->nports; i++) { + sd = &isys->csi2[i].asd.sd.entity; + + for (j = 0; j < IPU7_NR_OF_CSI2_SRC_PADS; j++) { + struct ipu7_isys_video *av = &isys->csi2[i].av[j]; + + ret = media_create_pad_link(sd, IPU7_CSI2_PAD_SRC + j, + &av->vdev.entity, 0, 0); + if (ret) { + dev_err(dev, "CSI2 can't create link\n"); + return ret; + } + + av->csi2 = &isys->csi2[i]; + } + } + + return 0; +} + +static int isys_register_devices(struct ipu7_isys *isys) +{ + struct device *dev = &isys->adev->auxdev.dev; + struct pci_dev *pdev = isys->adev->isp->pdev; + int ret; + + media_device_pci_init(&isys->media_dev, + pdev, IPU_MEDIA_DEV_MODEL_NAME); + + strscpy(isys->v4l2_dev.name, isys->media_dev.model, + sizeof(isys->v4l2_dev.name)); + + ret = media_device_register(&isys->media_dev); + if (ret < 0) + goto out_media_device_unregister; + + isys->v4l2_dev.mdev = &isys->media_dev; + isys->v4l2_dev.ctrl_handler = NULL; + + ret = v4l2_device_register(dev, &isys->v4l2_dev); + if (ret < 0) + goto out_media_device_unregister; + + ret = isys_register_video_devices(isys); + if (ret) + goto out_v4l2_device_unregister; + + ret = isys_csi2_register_subdevices(isys); + if (ret) + goto out_video_unregister_device; + + ret = isys_csi2_create_media_links(isys); + if (ret) + goto out_csi2_unregister_subdevices; + + ret = isys_notifier_init(isys); + if (ret) + goto out_csi2_unregister_subdevices; + + return 0; + +out_csi2_unregister_subdevices: + isys_csi2_unregister_subdevices(isys); + +out_video_unregister_device: + isys_unregister_video_devices(isys); + +out_v4l2_device_unregister: + v4l2_device_unregister(&isys->v4l2_dev); + +out_media_device_unregister: + media_device_unregister(&isys->media_dev); + media_device_cleanup(&isys->media_dev); + + dev_err(dev, "failed to register isys devices\n"); + + return ret; +} + +static void isys_unregister_devices(struct ipu7_isys *isys) +{ + isys_unregister_video_devices(isys); + isys_csi2_unregister_subdevices(isys); + v4l2_device_unregister(&isys->v4l2_dev); + media_device_unregister(&isys->media_dev); + media_device_cleanup(&isys->media_dev); +} + +static void enable_csi2_legacy_irq(struct ipu7_isys *isys, bool enable) +{ + u32 offset = IS_IO_CSI2_LEGACY_IRQ_CTRL_BASE; + void __iomem *base = isys->pdata->base; + u32 mask = isys->isr_csi2_mask; + + if (!enable) { + writel(mask, base + offset + IRQ_CTL_CLEAR); + writel(0, base + offset + IRQ_CTL_ENABLE); + return; + } + + writel(mask, base + offset + IRQ_CTL_EDGE); + writel(mask, base + offset + IRQ_CTL_CLEAR); + writel(mask, base + offset + IRQ_CTL_MASK); + writel(mask, base + offset + IRQ_CTL_ENABLE); +} + +static void enable_to_sw_irq(struct ipu7_isys *isys, bool enable) +{ + void __iomem *base = isys->pdata->base; + u32 mask = IS_UC_TO_SW_IRQ_MASK; + u32 offset = IS_UC_CTRL_BASE; + + if (!enable) { + writel(0, base + offset + TO_SW_IRQ_CNTL_ENABLE); + return; + } + + writel(mask, base + offset + TO_SW_IRQ_CNTL_CLEAR); + writel(mask, base + offset + TO_SW_IRQ_CNTL_MASK_N); + writel(mask, base + offset + TO_SW_IRQ_CNTL_ENABLE); +} + +void ipu7_isys_setup_hw(struct ipu7_isys *isys) +{ + u32 offset; + void __iomem *base = isys->pdata->base; + + /* soft reset */ + offset = IS_IO_GPREGS_BASE; + + writel(0x0, base + offset + CLK_EN_TXCLKESC); + /* Update if ISYS freq updated (0: 400/1, 1:400/2, 63:400/64) */ + writel(0x0, base + offset + CLK_DIV_FACTOR_IS_CLK); + /* correct the initial printf configuration */ + writel(0x200, base + IS_UC_CTRL_BASE + PRINTF_AXI_CNTL); + + enable_to_sw_irq(isys, 1); + enable_csi2_legacy_irq(isys, 1); +} + +static void isys_cleanup_hw(struct ipu7_isys *isys) +{ + enable_csi2_legacy_irq(isys, 0); + enable_to_sw_irq(isys, 0); +} + +static int isys_runtime_pm_resume(struct device *dev) +{ + struct ipu7_bus_device *adev = to_ipu7_bus_device(dev); + struct ipu7_isys *isys = ipu7_bus_get_drvdata(adev); + struct ipu7_device *isp = adev->isp; + unsigned long flags; + int ret; + + if (!isys) + return 0; + + ret = ipu7_mmu_hw_init(adev->mmu); + if (ret) + return ret; + + cpu_latency_qos_update_request(&isys->pm_qos, ISYS_PM_QOS_VALUE); + + ret = ipu_buttress_start_tsc_sync(isp); + if (ret) + return ret; + + spin_lock_irqsave(&isys->power_lock, flags); + isys->power = 1; + spin_unlock_irqrestore(&isys->power_lock, flags); + + return 0; +} + +static int isys_runtime_pm_suspend(struct device *dev) +{ + struct ipu7_bus_device *adev = to_ipu7_bus_device(dev); + struct ipu7_isys *isys = ipu7_bus_get_drvdata(adev); + unsigned long flags; + + if (!isys) + return 0; + + isys_cleanup_hw(isys); + + spin_lock_irqsave(&isys->power_lock, flags); + isys->power = 0; + spin_unlock_irqrestore(&isys->power_lock, flags); + + cpu_latency_qos_update_request(&isys->pm_qos, PM_QOS_DEFAULT_VALUE); + + ipu7_mmu_hw_cleanup(adev->mmu); + + return 0; +} + +static int isys_suspend(struct device *dev) +{ + struct ipu7_isys *isys = dev_get_drvdata(dev); + + /* If stream is open, refuse to suspend */ + if (isys->stream_opened) + return -EBUSY; + + return 0; +} + +static int isys_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops isys_pm_ops = { + .runtime_suspend = isys_runtime_pm_suspend, + .runtime_resume = isys_runtime_pm_resume, + .suspend = isys_suspend, + .resume = isys_resume, +}; + +static void isys_remove(struct auxiliary_device *auxdev) +{ + struct ipu7_isys *isys = dev_get_drvdata(&auxdev->dev); + struct isys_fw_msgs *fwmsg, *safe; + struct ipu7_bus_device *adev = auxdev_to_adev(auxdev); + + for (int i = 0; i < IPU_ISYS_MAX_STREAMS; i++) + mutex_destroy(&isys->streams[i].mutex); + + list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist, head) + ipu7_dma_free(adev, sizeof(struct isys_fw_msgs), + fwmsg, fwmsg->dma_addr, 0); + + list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist_fw, head) + ipu7_dma_free(adev, sizeof(struct isys_fw_msgs), + fwmsg, fwmsg->dma_addr, 0); + + isys_notifier_cleanup(isys); + isys_unregister_devices(isys); + + cpu_latency_qos_remove_request(&isys->pm_qos); + + mutex_destroy(&isys->stream_mutex); + mutex_destroy(&isys->mutex); +} + +static int alloc_fw_msg_bufs(struct ipu7_isys *isys, int amount) +{ + struct ipu7_bus_device *adev = isys->adev; + struct isys_fw_msgs *addr; + dma_addr_t dma_addr; + unsigned long flags; + unsigned int i; + + for (i = 0; i < amount; i++) { + addr = ipu7_dma_alloc(adev, sizeof(struct isys_fw_msgs), + &dma_addr, GFP_KERNEL, 0); + if (!addr) + break; + addr->dma_addr = dma_addr; + + spin_lock_irqsave(&isys->listlock, flags); + list_add(&addr->head, &isys->framebuflist); + spin_unlock_irqrestore(&isys->listlock, flags); + } + + if (i == amount) + return 0; + + spin_lock_irqsave(&isys->listlock, flags); + while (!list_empty(&isys->framebuflist)) { + addr = list_first_entry(&isys->framebuflist, + struct isys_fw_msgs, head); + list_del(&addr->head); + spin_unlock_irqrestore(&isys->listlock, flags); + ipu7_dma_free(adev, sizeof(struct isys_fw_msgs), + addr, addr->dma_addr, 0); + spin_lock_irqsave(&isys->listlock, flags); + } + spin_unlock_irqrestore(&isys->listlock, flags); + + return -ENOMEM; +} + +struct isys_fw_msgs *ipu7_get_fw_msg_buf(struct ipu7_isys_stream *stream) +{ + struct device *dev = &stream->isys->adev->auxdev.dev; + struct ipu7_isys *isys = stream->isys; + struct isys_fw_msgs *msg; + unsigned long flags; + int ret; + + spin_lock_irqsave(&isys->listlock, flags); + if (list_empty(&isys->framebuflist)) { + spin_unlock_irqrestore(&isys->listlock, flags); + dev_dbg(dev, "Frame buffer list empty\n"); + + ret = alloc_fw_msg_bufs(isys, 5); + if (ret < 0) + return NULL; + + spin_lock_irqsave(&isys->listlock, flags); + if (list_empty(&isys->framebuflist)) { + spin_unlock_irqrestore(&isys->listlock, flags); + dev_err(dev, "Frame list empty\n"); + return NULL; + } + } + msg = list_last_entry(&isys->framebuflist, struct isys_fw_msgs, head); + list_move(&msg->head, &isys->framebuflist_fw); + spin_unlock_irqrestore(&isys->listlock, flags); + memset(&msg->fw_msg, 0, sizeof(msg->fw_msg)); + + return msg; +} + +void ipu7_cleanup_fw_msg_bufs(struct ipu7_isys *isys) +{ + struct isys_fw_msgs *fwmsg, *fwmsg0; + unsigned long flags; + + spin_lock_irqsave(&isys->listlock, flags); + list_for_each_entry_safe(fwmsg, fwmsg0, &isys->framebuflist_fw, head) + list_move(&fwmsg->head, &isys->framebuflist); + spin_unlock_irqrestore(&isys->listlock, flags); +} + +void ipu7_put_fw_msg_buf(struct ipu7_isys *isys, uintptr_t data) +{ + struct isys_fw_msgs *msg; + void *ptr = (void *)data; + unsigned long flags; + + if (WARN_ON_ONCE(!ptr)) + return; + + spin_lock_irqsave(&isys->listlock, flags); + msg = container_of(ptr, struct isys_fw_msgs, fw_msg.dummy); + list_move(&msg->head, &isys->framebuflist); + spin_unlock_irqrestore(&isys->listlock, flags); +} + +static int isys_probe(struct auxiliary_device *auxdev, + const struct auxiliary_device_id *auxdev_id) +{ + const struct ipu7_isys_internal_csi2_pdata *csi2_pdata; + struct ipu7_bus_device *adev = auxdev_to_adev(auxdev); + struct ipu7_device *isp = adev->isp; + struct ipu7_isys *isys; + int ret = 0; + + if (!isp->ipu7_bus_ready_to_probe) + return -EPROBE_DEFER; + + isys = devm_kzalloc(&auxdev->dev, sizeof(*isys), GFP_KERNEL); + if (!isys) + return -ENOMEM; + + ret = pm_runtime_resume_and_get(&auxdev->dev); + if (ret < 0) + return ret; + + adev->auxdrv_data = + (const struct ipu7_auxdrv_data *)auxdev_id->driver_data; + adev->auxdrv = to_auxiliary_drv(auxdev->dev.driver); + isys->adev = adev; + isys->pdata = adev->pdata; + + INIT_LIST_HEAD(&isys->requests); + csi2_pdata = &isys->pdata->ipdata->csi2; + + isys->csi2 = devm_kcalloc(&auxdev->dev, csi2_pdata->nports, + sizeof(*isys->csi2), GFP_KERNEL); + if (!isys->csi2) { + ret = -ENOMEM; + goto out_runtime_put; + } + + ret = ipu7_mmu_hw_init(adev->mmu); + if (ret) + goto out_runtime_put; + + spin_lock_init(&isys->streams_lock); + spin_lock_init(&isys->power_lock); + isys->power = 0; + + mutex_init(&isys->mutex); + mutex_init(&isys->stream_mutex); + + spin_lock_init(&isys->listlock); + INIT_LIST_HEAD(&isys->framebuflist); + INIT_LIST_HEAD(&isys->framebuflist_fw); + + dev_set_drvdata(&auxdev->dev, isys); + + isys->icache_prefetch = 0; + isys->phy_rext_cal = 0; + + isys_stream_init(isys); + + cpu_latency_qos_add_request(&isys->pm_qos, PM_QOS_DEFAULT_VALUE); + ret = alloc_fw_msg_bufs(isys, 20); + if (ret < 0) + goto out_cleanup_isys; + + ret = ipu7_fw_isys_init(isys); + if (ret) + goto out_cleanup_isys; + + ret = isys_register_devices(isys); + if (ret) + goto out_cleanup_fw; + + ret = isys_fw_log_init(isys); + if (ret) + goto out_cleanup; + + ipu7_mmu_hw_cleanup(adev->mmu); + pm_runtime_put(&auxdev->dev); + + return 0; + +out_cleanup: + isys_unregister_devices(isys); +out_cleanup_fw: + ipu7_fw_isys_release(isys); +out_cleanup_isys: + cpu_latency_qos_remove_request(&isys->pm_qos); + + for (unsigned int i = 0; i < IPU_ISYS_MAX_STREAMS; i++) + mutex_destroy(&isys->streams[i].mutex); + + mutex_destroy(&isys->mutex); + mutex_destroy(&isys->stream_mutex); + + ipu7_mmu_hw_cleanup(adev->mmu); + +out_runtime_put: + pm_runtime_put(&auxdev->dev); + + return ret; +} + +struct ipu7_csi2_error { + const char *error_string; + bool is_info_only; +}; + +/* + * Strings corresponding to CSI-2 receiver errors are here. + * Corresponding macros are defined in the header file. + */ +static const struct ipu7_csi2_error dphy_rx_errors[] = { + { "Error handler FIFO full", false }, + { "Reserved Short Packet encoding detected", true }, + { "Reserved Long Packet encoding detected", true }, + { "Received packet is too short", false}, + { "Received packet is too long", false}, + { "Short packet discarded due to errors", false }, + { "Long packet discarded due to errors", false }, + { "CSI Combo Rx interrupt", false }, + { "IDI CDC FIFO overflow(remaining bits are reserved as 0)", false }, + { "Received NULL packet", true }, + { "Received blanking packet", true }, + { "Tie to 0", true }, + { } +}; + +static void ipu7_isys_register_errors(struct ipu7_isys_csi2 *csi2) +{ + u32 offset = IS_IO_CSI2_ERR_LEGACY_IRQ_CTL_BASE(csi2->port); + u32 status = readl(csi2->base + offset + IRQ_CTL_STATUS); + u32 mask = IPU7_CSI_RX_ERROR_IRQ_MASK; + + if (!status) + return; + + dev_dbg(&csi2->isys->adev->auxdev.dev, "csi2-%u error status 0x%08x\n", + csi2->port, status); + + writel(status & mask, csi2->base + offset + IRQ_CTL_CLEAR); + csi2->receiver_errors |= status & mask; +} + +static void ipu7_isys_csi2_error(struct ipu7_isys_csi2 *csi2) +{ + struct ipu7_csi2_error const *errors; + unsigned int i; + u32 status; + + /* Register errors once more in case of error interrupts are disabled */ + ipu7_isys_register_errors(csi2); + status = csi2->receiver_errors; + csi2->receiver_errors = 0; + errors = dphy_rx_errors; + + for (i = 0; i < CSI_RX_NUM_ERRORS_IN_IRQ; i++) { + if (status & BIT(i)) + dev_err_ratelimited(&csi2->isys->adev->auxdev.dev, + "csi2-%i error: %s\n", + csi2->port, + errors[i].error_string); + } +} + +struct resp_to_msg { + enum ipu7_insys_resp_type type; + const char *msg; +}; + +static const struct resp_to_msg is_fw_msg[] = { + {IPU_INSYS_RESP_TYPE_STREAM_OPEN_DONE, + "IPU_INSYS_RESP_TYPE_STREAM_OPEN_DONE"}, + {IPU_INSYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK, + "IPU_INSYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK"}, + {IPU_INSYS_RESP_TYPE_STREAM_CAPTURE_ACK, + "IPU_INSYS_RESP_TYPE_STREAM_CAPTURE_ACK"}, + {IPU_INSYS_RESP_TYPE_STREAM_ABORT_ACK, + "IPU_INSYS_RESP_TYPE_STREAM_ABORT_ACK"}, + {IPU_INSYS_RESP_TYPE_STREAM_FLUSH_ACK, + "IPU_INSYS_RESP_TYPE_STREAM_FLUSH_ACK"}, + {IPU_INSYS_RESP_TYPE_STREAM_CLOSE_ACK, + "IPU_INSYS_RESP_TYPE_STREAM_CLOSE_ACK"}, + {IPU_INSYS_RESP_TYPE_PIN_DATA_READY, + "IPU_INSYS_RESP_TYPE_PIN_DATA_READY"}, + {IPU_INSYS_RESP_TYPE_FRAME_SOF, "IPU_INSYS_RESP_TYPE_FRAME_SOF"}, + {IPU_INSYS_RESP_TYPE_FRAME_EOF, "IPU_INSYS_RESP_TYPE_FRAME_EOF"}, + {IPU_INSYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE, + "IPU_INSYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE"}, + {IPU_INSYS_RESP_TYPE_STREAM_CAPTURE_DONE, + "IPU_INSYS_RESP_TYPE_STREAM_CAPTURE_DONE"}, + {N_IPU_INSYS_RESP_TYPE, "N_IPU_INSYS_RESP_TYPE"}, +}; + +int isys_isr_one(struct ipu7_bus_device *adev) +{ + struct ipu7_isys *isys = ipu7_bus_get_drvdata(adev); + struct ipu7_isys_stream *stream = NULL; + struct device *dev = &adev->auxdev.dev; + struct ipu7_isys_csi2 *csi2 = NULL; + struct ia_gofo_msg_err err_info; + struct ipu7_insys_resp *resp; + u64 ts; + + if (!isys->adev->syscom) + return 1; + + resp = ipu7_fw_isys_get_resp(isys); + if (!resp) + return 1; + if (resp->type >= N_IPU_INSYS_RESP_TYPE) { + dev_err(dev, "Unknown response type %u stream %u\n", + resp->type, resp->stream_id); + ipu7_fw_isys_put_resp(isys); + return 1; + } + + err_info = resp->error_info; + ts = ((u64)resp->timestamp[1] << 32) | resp->timestamp[0]; + if (err_info.err_group == INSYS_MSG_ERR_GROUP_CAPTURE && + err_info.err_code == INSYS_MSG_ERR_CAPTURE_SYNC_FRAME_DROP) { + /* receive a sp w/o command, firmware drop it */ + dev_dbg(dev, "FRAME DROP: %02u %s stream %u\n", + resp->type, is_fw_msg[resp->type].msg, + resp->stream_id); + dev_dbg(dev, "\tpin %u buf_id %llx frame %u\n", + resp->pin_id, resp->buf_id, resp->frame_id); + dev_dbg(dev, "\terror group %u code %u details [%u %u]\n", + err_info.err_group, err_info.err_code, + err_info.err_detail[0], err_info.err_detail[1]); + } else if (!IA_GOFO_MSG_ERR_IS_OK(err_info)) { + dev_err(dev, "%02u %s stream %u pin %u buf_id %llx frame %u\n", + resp->type, is_fw_msg[resp->type].msg, resp->stream_id, + resp->pin_id, resp->buf_id, resp->frame_id); + dev_err(dev, "\terror group %u code %u details [%u %u]\n", + err_info.err_group, err_info.err_code, + err_info.err_detail[0], err_info.err_detail[1]); + } else { + dev_dbg(dev, "%02u %s stream %u pin %u buf_id %llx frame %u\n", + resp->type, is_fw_msg[resp->type].msg, resp->stream_id, + resp->pin_id, resp->buf_id, resp->frame_id); + dev_dbg(dev, "\tts %llu\n", ts); + } + + if (resp->stream_id >= IPU_ISYS_MAX_STREAMS) { + dev_err(dev, "bad stream handle %u\n", + resp->stream_id); + goto leave; + } + + stream = ipu7_isys_query_stream_by_handle(isys, resp->stream_id); + if (!stream) { + dev_err(dev, "stream of stream_handle %u is unused\n", + resp->stream_id); + goto leave; + } + + stream->error = err_info.err_code; + + if (stream->asd) + csi2 = ipu7_isys_subdev_to_csi2(stream->asd); + + switch (resp->type) { + case IPU_INSYS_RESP_TYPE_STREAM_OPEN_DONE: + complete(&stream->stream_open_completion); + break; + case IPU_INSYS_RESP_TYPE_STREAM_CLOSE_ACK: + complete(&stream->stream_close_completion); + break; + case IPU_INSYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK: + complete(&stream->stream_start_completion); + break; + case IPU_INSYS_RESP_TYPE_STREAM_ABORT_ACK: + complete(&stream->stream_stop_completion); + break; + case IPU_INSYS_RESP_TYPE_STREAM_FLUSH_ACK: + complete(&stream->stream_stop_completion); + break; + case IPU_INSYS_RESP_TYPE_PIN_DATA_READY: + /* + * firmware only release the capture msg until software + * get pin_data_ready event + */ + ipu7_put_fw_msg_buf(ipu7_bus_get_drvdata(adev), resp->buf_id); + if (resp->pin_id < IPU_INSYS_OUTPUT_PINS && + stream->output_pins[resp->pin_id].pin_ready) + stream->output_pins[resp->pin_id].pin_ready(stream, + resp); + else + dev_err(dev, "No handler for pin %u ready\n", + resp->pin_id); + if (csi2) + ipu7_isys_csi2_error(csi2); + + break; + case IPU_INSYS_RESP_TYPE_STREAM_CAPTURE_ACK: + break; + case IPU_INSYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE: + case IPU_INSYS_RESP_TYPE_STREAM_CAPTURE_DONE: + break; + case IPU_INSYS_RESP_TYPE_FRAME_SOF: + if (csi2) + ipu7_isys_csi2_sof_event_by_stream(stream); + + stream->seq[stream->seq_index].sequence = + atomic_read(&stream->sequence) - 1U; + stream->seq[stream->seq_index].timestamp = ts; + dev_dbg(dev, + "SOF: stream %u frame %u (index %u), ts 0x%16.16llx\n", + resp->stream_id, resp->frame_id, + stream->seq[stream->seq_index].sequence, ts); + stream->seq_index = (stream->seq_index + 1U) + % IPU_ISYS_MAX_PARALLEL_SOF; + break; + case IPU_INSYS_RESP_TYPE_FRAME_EOF: + if (csi2) + ipu7_isys_csi2_eof_event_by_stream(stream); + + dev_dbg(dev, "eof: stream %d(index %u) ts 0x%16.16llx\n", + resp->stream_id, + stream->seq[stream->seq_index].sequence, ts); + break; + default: + dev_err(dev, "Unknown response type %u stream %u\n", + resp->type, resp->stream_id); + break; + } + + ipu7_isys_put_stream(stream); +leave: + ipu7_fw_isys_put_resp(isys); + + return 0; +} + +static void ipu7_isys_csi2_isr(struct ipu7_isys_csi2 *csi2) +{ + struct device *dev = &csi2->isys->adev->auxdev.dev; + struct ipu7_device *isp = csi2->isys->adev->isp; + struct ipu7_isys_stream *s; + u32 sync, offset; + u32 fe = 0; + u8 vc; + + ipu7_isys_register_errors(csi2); + + offset = IS_IO_CSI2_SYNC_LEGACY_IRQ_CTL_BASE(csi2->port); + sync = readl(csi2->base + offset + IRQ_CTL_STATUS); + writel(sync, csi2->base + offset + IRQ_CTL_CLEAR); + dev_dbg(dev, "csi2-%u sync status 0x%08x\n", csi2->port, sync); + + if (!is_ipu7(isp->hw_ver)) { + fe = readl(csi2->base + offset + IRQ1_CTL_STATUS); + writel(fe, csi2->base + offset + IRQ1_CTL_CLEAR); + dev_dbg(dev, "csi2-%u FE status 0x%08x\n", csi2->port, fe); + } + + for (vc = 0; vc < IPU7_NR_OF_CSI2_VC && (sync || fe); vc++) { + s = ipu7_isys_query_stream_by_source(csi2->isys, + csi2->asd.source, vc); + if (!s) + continue; + + if (!is_ipu7(isp->hw_ver)) { + if (sync & IPU7P5_CSI_RX_SYNC_FS_VC & (1U << vc)) + ipu7_isys_csi2_sof_event_by_stream(s); + + if (fe & IPU7P5_CSI_RX_SYNC_FE_VC & (1U << vc)) + ipu7_isys_csi2_eof_event_by_stream(s); + } else { + if (sync & IPU7_CSI_RX_SYNC_FS_VC & (1U << (vc * 2))) + ipu7_isys_csi2_sof_event_by_stream(s); + + if (sync & IPU7_CSI_RX_SYNC_FE_VC & (2U << (vc * 2))) + ipu7_isys_csi2_eof_event_by_stream(s); + } + } +} + +static irqreturn_t isys_isr(struct ipu7_bus_device *adev) +{ + struct ipu7_isys *isys = ipu7_bus_get_drvdata(adev); + u32 status_csi, status_sw, csi_offset, sw_offset; + struct device *dev = &isys->adev->auxdev.dev; + void __iomem *base = isys->pdata->base; + + spin_lock(&isys->power_lock); + if (!isys->power) { + spin_unlock(&isys->power_lock); + return IRQ_NONE; + } + + csi_offset = IS_IO_CSI2_LEGACY_IRQ_CTRL_BASE; + sw_offset = IS_BASE; + + status_csi = readl(base + csi_offset + IRQ_CTL_STATUS); + status_sw = readl(base + sw_offset + TO_SW_IRQ_CNTL_STATUS); + if (!status_csi && !status_sw) { + spin_unlock(&isys->power_lock); + return IRQ_NONE; + } + + if (status_csi) + dev_dbg(dev, "status csi 0x%08x\n", status_csi); + if (status_sw) + dev_dbg(dev, "status to_sw 0x%08x\n", status_sw); + + do { + writel(status_sw, base + sw_offset + TO_SW_IRQ_CNTL_CLEAR); + writel(status_csi, base + csi_offset + IRQ_CTL_CLEAR); + + if (isys->isr_csi2_mask & status_csi) { + unsigned int i; + + for (i = 0; i < isys->pdata->ipdata->csi2.nports; i++) { + /* irq from not enabled port */ + if (!isys->csi2[i].base) + continue; + if (status_csi & isys->csi2[i].legacy_irq_mask) + ipu7_isys_csi2_isr(&isys->csi2[i]); + } + } + + if (!isys_isr_one(adev)) + status_sw = TO_SW_IRQ_FW; + else + status_sw = 0; + + status_csi = readl(base + csi_offset + IRQ_CTL_STATUS); + status_sw |= readl(base + sw_offset + TO_SW_IRQ_CNTL_STATUS); + } while ((status_csi & isys->isr_csi2_mask) || + (status_sw & TO_SW_IRQ_FW)); + + writel(TO_SW_IRQ_MASK, base + sw_offset + TO_SW_IRQ_CNTL_MASK_N); + + spin_unlock(&isys->power_lock); + + return IRQ_HANDLED; +} + +static const struct ipu7_auxdrv_data ipu7_isys_auxdrv_data = { + .isr = isys_isr, + .isr_threaded = NULL, + .wake_isr_thread = false, +}; + +static const struct auxiliary_device_id ipu7_isys_id_table[] = { + { + .name = "intel_ipu7.isys", + .driver_data = (kernel_ulong_t)&ipu7_isys_auxdrv_data, + }, + { } +}; +MODULE_DEVICE_TABLE(auxiliary, ipu7_isys_id_table); + +static struct auxiliary_driver isys_driver = { + .name = IPU_ISYS_NAME, + .probe = isys_probe, + .remove = isys_remove, + .id_table = ipu7_isys_id_table, + .driver = { + .pm = &isys_pm_ops, + }, +}; + +module_auxiliary_driver(isys_driver); + +MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>"); +MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>"); +MODULE_AUTHOR("Qingwu Zhang <qingwu.zhang@intel.com>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu7 input system driver"); +MODULE_IMPORT_NS("INTEL_IPU7"); +MODULE_IMPORT_NS("INTEL_IPU_BRIDGE"); diff --git a/drivers/staging/media/ipu7/ipu7-isys.h b/drivers/staging/media/ipu7/ipu7-isys.h new file mode 100644 index 000000000000..ef1ab1b42f6c --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-isys.h @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_ISYS_H +#define IPU7_ISYS_H + +#include <linux/irqreturn.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/pm_qos.h> +#include <linux/spinlock_types.h> +#include <linux/types.h> + +#include <media/media-device.h> +#include <media/v4l2-async.h> +#include <media/v4l2-device.h> +#include <media/v4l2-mediabus.h> + +#include "abi/ipu7_fw_msg_abi.h" +#include "abi/ipu7_fw_isys_abi.h" + +#include "ipu7.h" +#include "ipu7-isys-csi2.h" +#include "ipu7-isys-video.h" + +#define IPU_ISYS_ENTITY_PREFIX "Intel IPU7" + +/* FW support max 16 streams */ +#define IPU_ISYS_MAX_STREAMS 16U + +/* + * Current message queue configuration. These must be big enough + * so that they never gets full. Queues are located in system memory + */ +#define IPU_ISYS_SIZE_RECV_QUEUE 40U +#define IPU_ISYS_SIZE_LOG_QUEUE 256U +#define IPU_ISYS_SIZE_SEND_QUEUE 40U +#define IPU_ISYS_NUM_RECV_QUEUE 1U + +#define IPU_ISYS_MIN_WIDTH 2U +#define IPU_ISYS_MIN_HEIGHT 2U +#define IPU_ISYS_MAX_WIDTH 8160U +#define IPU_ISYS_MAX_HEIGHT 8190U + +#define FW_CALL_TIMEOUT_JIFFIES \ + msecs_to_jiffies(IPU_LIB_CALL_TIMEOUT_MS) + +struct isys_fw_log { + struct mutex mutex; /* protect whole struct */ + void *head; + void *addr; + u32 count; /* running counter of log */ + u32 size; /* actual size of log content, in bits */ +}; + +/* + * struct ipu7_isys + * + * @media_dev: Media device + * @v4l2_dev: V4L2 device + * @adev: ISYS bus device + * @power: Is ISYS powered on or not? + * @isr_bits: Which bits does the ISR handle? + * @power_lock: Serialise access to power (power state in general) + * @csi2_rx_ctrl_cached: cached shared value between all CSI2 receivers + * @streams_lock: serialise access to streams + * @streams: streams per firmware stream ID + * @syscom: fw communication layer context + * @ref_count: total number of callers fw open + * @mutex: serialise access isys video open/release related operations + * @stream_mutex: serialise stream start and stop, queueing requests + * @pdata: platform data pointer + * @csi2: CSI-2 receivers + */ +struct ipu7_isys { + struct media_device media_dev; + struct v4l2_device v4l2_dev; + struct ipu7_bus_device *adev; + + int power; + spinlock_t power_lock; /* Serialise access to power */ + u32 isr_csi2_mask; + u32 csi2_rx_ctrl_cached; + spinlock_t streams_lock; + struct ipu7_isys_stream streams[IPU_ISYS_MAX_STREAMS]; + int streams_ref_count[IPU_ISYS_MAX_STREAMS]; + u32 phy_rext_cal; + bool icache_prefetch; + bool csi2_cse_ipc_not_supported; + unsigned int ref_count; + unsigned int stream_opened; + + struct mutex mutex; /* Serialise isys video open/release related */ + struct mutex stream_mutex; /* Stream start, stop, queueing reqs */ + + struct ipu7_isys_pdata *pdata; + + struct ipu7_isys_csi2 *csi2; + struct isys_fw_log *fw_log; + + struct list_head requests; + struct pm_qos_request pm_qos; + spinlock_t listlock; /* Protect framebuflist */ + struct list_head framebuflist; + struct list_head framebuflist_fw; + struct v4l2_async_notifier notifier; + + struct ipu7_insys_config *subsys_config; + dma_addr_t subsys_config_dma_addr; +}; + +struct isys_fw_msgs { + union { + u64 dummy; + struct ipu7_insys_buffset frame; + struct ipu7_insys_stream_cfg stream; + } fw_msg; + struct list_head head; + dma_addr_t dma_addr; +}; + +struct ipu7_isys_csi2_config { + unsigned int nlanes; + unsigned int port; + enum v4l2_mbus_type bus_type; +}; + +struct sensor_async_sd { + struct v4l2_async_connection asc; + struct ipu7_isys_csi2_config csi2; +}; + +struct isys_fw_msgs *ipu7_get_fw_msg_buf(struct ipu7_isys_stream *stream); +void ipu7_put_fw_msg_buf(struct ipu7_isys *isys, uintptr_t data); +void ipu7_cleanup_fw_msg_bufs(struct ipu7_isys *isys); +int isys_isr_one(struct ipu7_bus_device *adev); +void ipu7_isys_setup_hw(struct ipu7_isys *isys); +#endif /* IPU7_ISYS_H */ diff --git a/drivers/staging/media/ipu7/ipu7-mmu.c b/drivers/staging/media/ipu7/ipu7-mmu.c new file mode 100644 index 000000000000..ded1986eb8ba --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-mmu.c @@ -0,0 +1,853 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <asm/barrier.h> + +#include <linux/align.h> +#include <linux/atomic.h> +#include <linux/bitops.h> +#include <linux/bits.h> +#include <linux/bug.h> +#include <linux/cacheflush.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/err.h> +#include <linux/gfp.h> +#include <linux/iopoll.h> +#include <linux/iova.h> +#include <linux/math.h> +#include <linux/minmax.h> +#include <linux/pci.h> +#include <linux/pfn.h> +#include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/types.h> +#include <linux/vmalloc.h> + +#include "ipu7.h" +#include "ipu7-dma.h" +#include "ipu7-mmu.h" +#include "ipu7-platform-regs.h" + +#define ISP_PAGE_SHIFT 12 +#define ISP_PAGE_SIZE BIT(ISP_PAGE_SHIFT) +#define ISP_PAGE_MASK (~(ISP_PAGE_SIZE - 1U)) + +#define ISP_L1PT_SHIFT 22 +#define ISP_L1PT_MASK (~((1U << ISP_L1PT_SHIFT) - 1)) + +#define ISP_L2PT_SHIFT 12 +#define ISP_L2PT_MASK (~(ISP_L1PT_MASK | (~(ISP_PAGE_MASK)))) + +#define ISP_L1PT_PTES 1024U +#define ISP_L2PT_PTES 1024U + +#define ISP_PADDR_SHIFT 12 + +#define REG_L1_PHYS 0x0004 /* 27-bit pfn */ +#define REG_INFO 0x0008 + +#define TBL_PHYS_ADDR(a) ((phys_addr_t)(a) << ISP_PADDR_SHIFT) + +#define MMU_TLB_INVALIDATE_TIMEOUT 2000 + +static __maybe_unused void mmu_irq_handler(struct ipu7_mmu *mmu) +{ + unsigned int i; + u32 irq_cause; + + for (i = 0; i < mmu->nr_mmus; i++) { + irq_cause = readl(mmu->mmu_hw[i].base + MMU_REG_IRQ_CAUSE); + pr_info("mmu %s irq_cause = 0x%x", mmu->mmu_hw[i].name, + irq_cause); + writel(0x1ffff, mmu->mmu_hw[i].base + MMU_REG_IRQ_CLEAR); + } +} + +static void tlb_invalidate(struct ipu7_mmu *mmu) +{ + unsigned long flags; + unsigned int i; + int ret; + u32 val; + + spin_lock_irqsave(&mmu->ready_lock, flags); + if (!mmu->ready) { + spin_unlock_irqrestore(&mmu->ready_lock, flags); + return; + } + + for (i = 0; i < mmu->nr_mmus; i++) { + writel(0xffffffffU, mmu->mmu_hw[i].base + + MMU_REG_INVALIDATE_0); + + /* Need check with HW, use l1streams or l2streams */ + if (mmu->mmu_hw[i].nr_l2streams > 32) + writel(0xffffffffU, mmu->mmu_hw[i].base + + MMU_REG_INVALIDATE_1); + + /* + * The TLB invalidation is a "single cycle" (IOMMU clock cycles) + * When the actual MMIO write reaches the IPU TLB Invalidate + * register, wmb() will force the TLB invalidate out if the CPU + * attempts to update the IOMMU page table (or sooner). + */ + wmb(); + + /* wait invalidation done */ + ret = readl_poll_timeout_atomic(mmu->mmu_hw[i].base + + MMU_REG_INVALIDATION_STATUS, + val, !(val & 0x1U), 500, + MMU_TLB_INVALIDATE_TIMEOUT); + if (ret) + dev_err(mmu->dev, "MMU[%u] TLB invalidate failed\n", i); + } + + spin_unlock_irqrestore(&mmu->ready_lock, flags); +} + +static dma_addr_t map_single(struct ipu7_mmu_info *mmu_info, void *ptr) +{ + dma_addr_t dma; + + dma = dma_map_single(mmu_info->dev, ptr, PAGE_SIZE, DMA_BIDIRECTIONAL); + if (dma_mapping_error(mmu_info->dev, dma)) + return 0; + + return dma; +} + +static int get_dummy_page(struct ipu7_mmu_info *mmu_info) +{ + void *pt = (void *)get_zeroed_page(GFP_ATOMIC | GFP_DMA32); + dma_addr_t dma; + + if (!pt) + return -ENOMEM; + + dev_dbg(mmu_info->dev, "dummy_page: get_zeroed_page() == %p\n", pt); + + dma = map_single(mmu_info, pt); + if (!dma) { + dev_err(mmu_info->dev, "Failed to map dummy page\n"); + goto err_free_page; + } + + mmu_info->dummy_page = pt; + mmu_info->dummy_page_pteval = dma >> ISP_PAGE_SHIFT; + + return 0; + +err_free_page: + free_page((unsigned long)pt); + return -ENOMEM; +} + +static void free_dummy_page(struct ipu7_mmu_info *mmu_info) +{ + dma_unmap_single(mmu_info->dev, + TBL_PHYS_ADDR(mmu_info->dummy_page_pteval), + PAGE_SIZE, DMA_BIDIRECTIONAL); + free_page((unsigned long)mmu_info->dummy_page); +} + +static int alloc_dummy_l2_pt(struct ipu7_mmu_info *mmu_info) +{ + u32 *pt = (u32 *)get_zeroed_page(GFP_ATOMIC | GFP_DMA32); + dma_addr_t dma; + unsigned int i; + + if (!pt) + return -ENOMEM; + + dev_dbg(mmu_info->dev, "dummy_l2: get_zeroed_page() = %p\n", pt); + + dma = map_single(mmu_info, pt); + if (!dma) { + dev_err(mmu_info->dev, "Failed to map l2pt page\n"); + goto err_free_page; + } + + for (i = 0; i < ISP_L2PT_PTES; i++) + pt[i] = mmu_info->dummy_page_pteval; + + mmu_info->dummy_l2_pt = pt; + mmu_info->dummy_l2_pteval = dma >> ISP_PAGE_SHIFT; + + return 0; + +err_free_page: + free_page((unsigned long)pt); + return -ENOMEM; +} + +static void free_dummy_l2_pt(struct ipu7_mmu_info *mmu_info) +{ + dma_unmap_single(mmu_info->dev, + TBL_PHYS_ADDR(mmu_info->dummy_l2_pteval), + PAGE_SIZE, DMA_BIDIRECTIONAL); + free_page((unsigned long)mmu_info->dummy_l2_pt); +} + +static u32 *alloc_l1_pt(struct ipu7_mmu_info *mmu_info) +{ + u32 *pt = (u32 *)get_zeroed_page(GFP_ATOMIC | GFP_DMA32); + dma_addr_t dma; + unsigned int i; + + if (!pt) + return NULL; + + dev_dbg(mmu_info->dev, "alloc_l1: get_zeroed_page() = %p\n", pt); + + for (i = 0; i < ISP_L1PT_PTES; i++) + pt[i] = mmu_info->dummy_l2_pteval; + + dma = map_single(mmu_info, pt); + if (!dma) { + dev_err(mmu_info->dev, "Failed to map l1pt page\n"); + goto err_free_page; + } + + mmu_info->l1_pt_dma = dma >> ISP_PADDR_SHIFT; + dev_dbg(mmu_info->dev, "l1 pt %p mapped at %pad\n", pt, &dma); + + return pt; + +err_free_page: + free_page((unsigned long)pt); + return NULL; +} + +static u32 *alloc_l2_pt(struct ipu7_mmu_info *mmu_info) +{ + u32 *pt = (u32 *)get_zeroed_page(GFP_ATOMIC | GFP_DMA32); + unsigned int i; + + if (!pt) + return NULL; + + dev_dbg(mmu_info->dev, "alloc_l2: get_zeroed_page() = %p\n", pt); + + for (i = 0; i < ISP_L1PT_PTES; i++) + pt[i] = mmu_info->dummy_page_pteval; + + return pt; +} + +static void l2_unmap(struct ipu7_mmu_info *mmu_info, unsigned long iova, + phys_addr_t dummy, size_t size) +{ + unsigned int l2_entries; + unsigned int l2_idx; + unsigned long flags; + u32 l1_idx; + u32 *l2_pt; + + spin_lock_irqsave(&mmu_info->lock, flags); + for (l1_idx = iova >> ISP_L1PT_SHIFT; + size > 0U && l1_idx < ISP_L1PT_PTES; l1_idx++) { + dev_dbg(mmu_info->dev, + "unmapping l2 pgtable (l1 index %u (iova 0x%8.8lx))\n", + l1_idx, iova); + + if (mmu_info->l1_pt[l1_idx] == mmu_info->dummy_l2_pteval) { + dev_err(mmu_info->dev, + "unmap not mapped iova 0x%8.8lx l1 index %u\n", + iova, l1_idx); + continue; + } + l2_pt = mmu_info->l2_pts[l1_idx]; + + l2_entries = 0; + for (l2_idx = (iova & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT; + size > 0U && l2_idx < ISP_L2PT_PTES; l2_idx++) { + phys_addr_t pteval = TBL_PHYS_ADDR(l2_pt[l2_idx]); + + dev_dbg(mmu_info->dev, + "unmap l2 index %u with pteval 0x%p\n", + l2_idx, &pteval); + l2_pt[l2_idx] = mmu_info->dummy_page_pteval; + + iova += ISP_PAGE_SIZE; + size -= ISP_PAGE_SIZE; + + l2_entries++; + } + + WARN_ON_ONCE(!l2_entries); + clflush_cache_range(&l2_pt[l2_idx - l2_entries], + sizeof(l2_pt[0]) * l2_entries); + } + + WARN_ON_ONCE(size); + spin_unlock_irqrestore(&mmu_info->lock, flags); +} + +static int l2_map(struct ipu7_mmu_info *mmu_info, unsigned long iova, + phys_addr_t paddr, size_t size) +{ + struct device *dev = mmu_info->dev; + unsigned int l2_entries; + u32 *l2_pt, *l2_virt; + unsigned int l2_idx; + unsigned long flags; + size_t mapped = 0; + dma_addr_t dma; + u32 l1_entry; + u32 l1_idx; + int err = 0; + + spin_lock_irqsave(&mmu_info->lock, flags); + + paddr = ALIGN(paddr, ISP_PAGE_SIZE); + for (l1_idx = iova >> ISP_L1PT_SHIFT; + size && l1_idx < ISP_L1PT_PTES; l1_idx++) { + dev_dbg(dev, + "mapping l2 page table for l1 index %u (iova %8.8x)\n", + l1_idx, (u32)iova); + + l1_entry = mmu_info->l1_pt[l1_idx]; + if (l1_entry == mmu_info->dummy_l2_pteval) { + l2_virt = mmu_info->l2_pts[l1_idx]; + if (likely(!l2_virt)) { + l2_virt = alloc_l2_pt(mmu_info); + if (!l2_virt) { + err = -ENOMEM; + goto error; + } + } + + dma = map_single(mmu_info, l2_virt); + if (!dma) { + dev_err(dev, "Failed to map l2pt page\n"); + free_page((unsigned long)l2_virt); + err = -EINVAL; + goto error; + } + + l1_entry = dma >> ISP_PADDR_SHIFT; + + dev_dbg(dev, "page for l1_idx %u %p allocated\n", + l1_idx, l2_virt); + mmu_info->l1_pt[l1_idx] = l1_entry; + mmu_info->l2_pts[l1_idx] = l2_virt; + + clflush_cache_range(&mmu_info->l1_pt[l1_idx], + sizeof(mmu_info->l1_pt[l1_idx])); + } + + l2_pt = mmu_info->l2_pts[l1_idx]; + l2_entries = 0; + + for (l2_idx = (iova & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT; + size && l2_idx < ISP_L2PT_PTES; l2_idx++) { + l2_pt[l2_idx] = paddr >> ISP_PADDR_SHIFT; + + dev_dbg(dev, "l2 index %u mapped as 0x%8.8x\n", l2_idx, + l2_pt[l2_idx]); + + iova += ISP_PAGE_SIZE; + paddr += ISP_PAGE_SIZE; + mapped += ISP_PAGE_SIZE; + size -= ISP_PAGE_SIZE; + + l2_entries++; + } + + WARN_ON_ONCE(!l2_entries); + clflush_cache_range(&l2_pt[l2_idx - l2_entries], + sizeof(l2_pt[0]) * l2_entries); + } + + spin_unlock_irqrestore(&mmu_info->lock, flags); + + return 0; + +error: + spin_unlock_irqrestore(&mmu_info->lock, flags); + /* unroll mapping in case something went wrong */ + if (mapped) + l2_unmap(mmu_info, iova - mapped, paddr - mapped, mapped); + + return err; +} + +static int __ipu7_mmu_map(struct ipu7_mmu_info *mmu_info, unsigned long iova, + phys_addr_t paddr, size_t size) +{ + u32 iova_start = round_down(iova, ISP_PAGE_SIZE); + u32 iova_end = ALIGN(iova + size, ISP_PAGE_SIZE); + + dev_dbg(mmu_info->dev, + "mapping iova 0x%8.8x--0x%8.8x, size %zu at paddr %pap\n", + iova_start, iova_end, size, &paddr); + + return l2_map(mmu_info, iova_start, paddr, size); +} + +static void __ipu7_mmu_unmap(struct ipu7_mmu_info *mmu_info, + unsigned long iova, size_t size) +{ + l2_unmap(mmu_info, iova, 0, size); +} + +static int allocate_trash_buffer(struct ipu7_mmu *mmu) +{ + unsigned int n_pages = PFN_UP(IPU_MMUV2_TRASH_RANGE); + unsigned long iova_addr; + struct iova *iova; + unsigned int i; + dma_addr_t dma; + int ret; + + /* Allocate 8MB in iova range */ + iova = alloc_iova(&mmu->dmap->iovad, n_pages, + PHYS_PFN(mmu->dmap->mmu_info->aperture_end), 0); + if (!iova) { + dev_err(mmu->dev, "cannot allocate iova range for trash\n"); + return -ENOMEM; + } + + dma = dma_map_page(mmu->dmap->mmu_info->dev, mmu->trash_page, 0, + PAGE_SIZE, DMA_BIDIRECTIONAL); + if (dma_mapping_error(mmu->dmap->mmu_info->dev, dma)) { + dev_err(mmu->dmap->mmu_info->dev, "Failed to map trash page\n"); + ret = -ENOMEM; + goto out_free_iova; + } + + mmu->pci_trash_page = dma; + + /* + * Map the 8MB iova address range to the same physical trash page + * mmu->trash_page which is already reserved at the probe + */ + iova_addr = iova->pfn_lo; + for (i = 0; i < n_pages; i++) { + ret = ipu7_mmu_map(mmu->dmap->mmu_info, PFN_PHYS(iova_addr), + mmu->pci_trash_page, PAGE_SIZE); + if (ret) { + dev_err(mmu->dev, + "mapping trash buffer range failed\n"); + goto out_unmap; + } + + iova_addr++; + } + + mmu->iova_trash_page = PFN_PHYS(iova->pfn_lo); + dev_dbg(mmu->dev, "iova trash buffer for MMUID: %d is %u\n", + mmu->mmid, (unsigned int)mmu->iova_trash_page); + return 0; + +out_unmap: + ipu7_mmu_unmap(mmu->dmap->mmu_info, PFN_PHYS(iova->pfn_lo), + PFN_PHYS(iova_size(iova))); + dma_unmap_page(mmu->dmap->mmu_info->dev, mmu->pci_trash_page, + PAGE_SIZE, DMA_BIDIRECTIONAL); +out_free_iova: + __free_iova(&mmu->dmap->iovad, iova); + return ret; +} + +static void __mmu_at_init(struct ipu7_mmu *mmu) +{ + struct ipu7_mmu_info *mmu_info; + unsigned int i; + + mmu_info = mmu->dmap->mmu_info; + for (i = 0; i < mmu->nr_mmus; i++) { + struct ipu7_mmu_hw *mmu_hw = &mmu->mmu_hw[i]; + unsigned int j; + + /* Write page table address per MMU */ + writel((phys_addr_t)mmu_info->l1_pt_dma, + mmu_hw->base + MMU_REG_PAGE_TABLE_BASE_ADDR); + dev_dbg(mmu->dev, "mmu %s base was set as %x\n", mmu_hw->name, + readl(mmu_hw->base + MMU_REG_PAGE_TABLE_BASE_ADDR)); + + /* Set info bits and axi_refill per MMU */ + writel(mmu_hw->info_bits, + mmu_hw->base + MMU_REG_USER_INFO_BITS); + writel(mmu_hw->refill, mmu_hw->base + MMU_REG_AXI_REFILL_IF_ID); + writel(mmu_hw->collapse_en_bitmap, + mmu_hw->base + MMU_REG_COLLAPSE_ENABLE_BITMAP); + + dev_dbg(mmu->dev, "mmu %s info_bits was set as %x\n", + mmu_hw->name, + readl(mmu_hw->base + MMU_REG_USER_INFO_BITS)); + + if (mmu_hw->at_sp_arb_cfg) + writel(mmu_hw->at_sp_arb_cfg, + mmu_hw->base + MMU_REG_AT_SP_ARB_CFG); + + /* default irq configuration */ + writel(0x3ff, mmu_hw->base + MMU_REG_IRQ_MASK); + writel(0x3ff, mmu_hw->base + MMU_REG_IRQ_ENABLE); + + /* Configure MMU TLB stream configuration for L1/L2 */ + for (j = 0; j < mmu_hw->nr_l1streams; j++) { + writel(mmu_hw->l1_block_sz[j], mmu_hw->base + + mmu_hw->l1_block + 4U * j); + } + + for (j = 0; j < mmu_hw->nr_l2streams; j++) { + writel(mmu_hw->l2_block_sz[j], mmu_hw->base + + mmu_hw->l2_block + 4U * j); + } + + for (j = 0; j < mmu_hw->uao_p_num; j++) { + if (!mmu_hw->uao_p2tlb[j]) + continue; + writel(mmu_hw->uao_p2tlb[j], mmu_hw->uao_base + 4U * j); + } + } +} + +static void __mmu_zlx_init(struct ipu7_mmu *mmu) +{ + unsigned int i; + + dev_dbg(mmu->dev, "mmu zlx init\n"); + + for (i = 0; i < mmu->nr_mmus; i++) { + struct ipu7_mmu_hw *mmu_hw = &mmu->mmu_hw[i]; + unsigned int j; + + dev_dbg(mmu->dev, "mmu %s zlx init\n", mmu_hw->name); + for (j = 0; j < IPU_ZLX_POOL_NUM; j++) { + if (!mmu_hw->zlx_axi_pool[j]) + continue; + writel(mmu_hw->zlx_axi_pool[j], + mmu_hw->zlx_base + ZLX_REG_AXI_POOL + j * 0x4U); + } + + for (j = 0; j < mmu_hw->zlx_nr; j++) { + if (!mmu_hw->zlx_conf[j]) + continue; + + writel(mmu_hw->zlx_conf[j], + mmu_hw->zlx_base + ZLX_REG_CONF + j * 0x8U); + } + + for (j = 0; j < mmu_hw->zlx_nr; j++) { + if (!mmu_hw->zlx_en[j]) + continue; + + writel(mmu_hw->zlx_en[j], + mmu_hw->zlx_base + ZLX_REG_EN + j * 0x8U); + } + } +} + +int ipu7_mmu_hw_init(struct ipu7_mmu *mmu) +{ + unsigned long flags; + + dev_dbg(mmu->dev, "IPU mmu hardware init\n"); + + /* Initialise the each MMU and ZLX */ + __mmu_at_init(mmu); + __mmu_zlx_init(mmu); + + if (!mmu->trash_page) { + int ret; + + mmu->trash_page = alloc_page(GFP_KERNEL); + if (!mmu->trash_page) { + dev_err(mmu->dev, "insufficient memory for trash buffer\n"); + return -ENOMEM; + } + + ret = allocate_trash_buffer(mmu); + if (ret) { + __free_page(mmu->trash_page); + mmu->trash_page = NULL; + dev_err(mmu->dev, "trash buffer allocation failed\n"); + return ret; + } + } + + spin_lock_irqsave(&mmu->ready_lock, flags); + mmu->ready = true; + spin_unlock_irqrestore(&mmu->ready_lock, flags); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ipu7_mmu_hw_init, "INTEL_IPU7"); + +static struct ipu7_mmu_info *ipu7_mmu_alloc(struct ipu7_device *isp) +{ + struct ipu7_mmu_info *mmu_info; + int ret; + + mmu_info = kzalloc(sizeof(*mmu_info), GFP_KERNEL); + if (!mmu_info) + return NULL; + + if (isp->secure_mode) { + mmu_info->aperture_start = IPU_FW_CODE_REGION_END; + mmu_info->aperture_end = + (dma_addr_t)DMA_BIT_MASK(IPU_MMU_ADDR_BITS); + } else { + mmu_info->aperture_start = IPU_FW_CODE_REGION_START; + mmu_info->aperture_end = + (dma_addr_t)DMA_BIT_MASK(IPU_MMU_ADDR_BITS_NON_SECURE); + } + + mmu_info->pgsize_bitmap = SZ_4K; + mmu_info->dev = &isp->pdev->dev; + + ret = get_dummy_page(mmu_info); + if (ret) + goto err_free_info; + + ret = alloc_dummy_l2_pt(mmu_info); + if (ret) + goto err_free_dummy_page; + + mmu_info->l2_pts = vzalloc(ISP_L2PT_PTES * sizeof(*mmu_info->l2_pts)); + if (!mmu_info->l2_pts) + goto err_free_dummy_l2_pt; + + /* + * We always map the L1 page table (a single page as well as + * the L2 page tables). + */ + mmu_info->l1_pt = alloc_l1_pt(mmu_info); + if (!mmu_info->l1_pt) + goto err_free_l2_pts; + + spin_lock_init(&mmu_info->lock); + + dev_dbg(mmu_info->dev, "domain initialised\n"); + + return mmu_info; + +err_free_l2_pts: + vfree(mmu_info->l2_pts); +err_free_dummy_l2_pt: + free_dummy_l2_pt(mmu_info); +err_free_dummy_page: + free_dummy_page(mmu_info); +err_free_info: + kfree(mmu_info); + + return NULL; +} + +void ipu7_mmu_hw_cleanup(struct ipu7_mmu *mmu) +{ + unsigned long flags; + + spin_lock_irqsave(&mmu->ready_lock, flags); + mmu->ready = false; + spin_unlock_irqrestore(&mmu->ready_lock, flags); +} +EXPORT_SYMBOL_NS_GPL(ipu7_mmu_hw_cleanup, "INTEL_IPU7"); + +static struct ipu7_dma_mapping *alloc_dma_mapping(struct ipu7_device *isp) +{ + struct ipu7_dma_mapping *dmap; + unsigned long base_pfn; + + dmap = kzalloc(sizeof(*dmap), GFP_KERNEL); + if (!dmap) + return NULL; + + dmap->mmu_info = ipu7_mmu_alloc(isp); + if (!dmap->mmu_info) { + kfree(dmap); + return NULL; + } + + /* 0~64M is forbidden for uctile controller */ + base_pfn = max_t(unsigned long, 1, + PFN_DOWN(dmap->mmu_info->aperture_start)); + init_iova_domain(&dmap->iovad, SZ_4K, base_pfn); + dmap->mmu_info->dmap = dmap; + + dev_dbg(&isp->pdev->dev, "alloc mapping\n"); + + iova_cache_get(); + + return dmap; +} + +phys_addr_t ipu7_mmu_iova_to_phys(struct ipu7_mmu_info *mmu_info, + dma_addr_t iova) +{ + phys_addr_t phy_addr; + unsigned long flags; + u32 *l2_pt; + + spin_lock_irqsave(&mmu_info->lock, flags); + l2_pt = mmu_info->l2_pts[iova >> ISP_L1PT_SHIFT]; + phy_addr = (phys_addr_t)l2_pt[(iova & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT]; + phy_addr <<= ISP_PAGE_SHIFT; + spin_unlock_irqrestore(&mmu_info->lock, flags); + + return phy_addr; +} + +void ipu7_mmu_unmap(struct ipu7_mmu_info *mmu_info, unsigned long iova, + size_t size) +{ + unsigned int min_pagesz; + + dev_dbg(mmu_info->dev, "unmapping iova 0x%lx size 0x%zx\n", iova, size); + + /* find out the minimum page size supported */ + min_pagesz = 1U << __ffs(mmu_info->pgsize_bitmap); + + /* + * The virtual address and the size of the mapping must be + * aligned (at least) to the size of the smallest page supported + * by the hardware + */ + if (!IS_ALIGNED(iova | size, min_pagesz)) { + dev_err(mmu_info->dev, + "unaligned: iova 0x%lx size 0x%zx min_pagesz 0x%x\n", + iova, size, min_pagesz); + return; + } + + __ipu7_mmu_unmap(mmu_info, iova, size); +} + +int ipu7_mmu_map(struct ipu7_mmu_info *mmu_info, unsigned long iova, + phys_addr_t paddr, size_t size) +{ + unsigned int min_pagesz; + + if (mmu_info->pgsize_bitmap == 0UL) + return -ENODEV; + + /* find out the minimum page size supported */ + min_pagesz = 1U << __ffs(mmu_info->pgsize_bitmap); + + /* + * both the virtual address and the physical one, as well as + * the size of the mapping, must be aligned (at least) to the + * size of the smallest page supported by the hardware + */ + if (!IS_ALIGNED(iova | paddr | size, min_pagesz)) { + dev_err(mmu_info->dev, + "unaligned: iova %lx pa %pa size %zx min_pagesz %x\n", + iova, &paddr, size, min_pagesz); + return -EINVAL; + } + + dev_dbg(mmu_info->dev, "map: iova 0x%lx pa %pa size 0x%zx\n", + iova, &paddr, size); + + return __ipu7_mmu_map(mmu_info, iova, paddr, size); +} + +static void ipu7_mmu_destroy(struct ipu7_mmu *mmu) +{ + struct ipu7_dma_mapping *dmap = mmu->dmap; + struct ipu7_mmu_info *mmu_info = dmap->mmu_info; + struct iova *iova; + u32 l1_idx; + + if (mmu->iova_trash_page) { + iova = find_iova(&dmap->iovad, PHYS_PFN(mmu->iova_trash_page)); + if (iova) { + /* unmap and free the trash buffer iova */ + ipu7_mmu_unmap(mmu_info, PFN_PHYS(iova->pfn_lo), + PFN_PHYS(iova_size(iova))); + __free_iova(&dmap->iovad, iova); + } else { + dev_err(mmu->dev, "trash buffer iova not found.\n"); + } + + mmu->iova_trash_page = 0; + dma_unmap_page(mmu_info->dev, mmu->pci_trash_page, + PAGE_SIZE, DMA_BIDIRECTIONAL); + mmu->pci_trash_page = 0; + __free_page(mmu->trash_page); + } + + for (l1_idx = 0; l1_idx < ISP_L1PT_PTES; l1_idx++) { + if (mmu_info->l1_pt[l1_idx] != mmu_info->dummy_l2_pteval) { + dma_unmap_single(mmu_info->dev, + TBL_PHYS_ADDR(mmu_info->l1_pt[l1_idx]), + PAGE_SIZE, DMA_BIDIRECTIONAL); + free_page((unsigned long)mmu_info->l2_pts[l1_idx]); + } + } + + vfree(mmu_info->l2_pts); + free_dummy_page(mmu_info); + dma_unmap_single(mmu_info->dev, TBL_PHYS_ADDR(mmu_info->l1_pt_dma), + PAGE_SIZE, DMA_BIDIRECTIONAL); + free_page((unsigned long)mmu_info->dummy_l2_pt); + free_page((unsigned long)mmu_info->l1_pt); + kfree(mmu_info); +} + +struct ipu7_mmu *ipu7_mmu_init(struct device *dev, + void __iomem *base, int mmid, + const struct ipu7_hw_variants *hw) +{ + struct ipu7_device *isp = pci_get_drvdata(to_pci_dev(dev)); + struct ipu7_mmu_pdata *pdata; + struct ipu7_mmu *mmu; + unsigned int i; + + if (hw->nr_mmus > IPU_MMU_MAX_NUM) + return ERR_PTR(-EINVAL); + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < hw->nr_mmus; i++) { + struct ipu7_mmu_hw *pdata_mmu = &pdata->mmu_hw[i]; + const struct ipu7_mmu_hw *src_mmu = &hw->mmu_hw[i]; + + if (src_mmu->nr_l1streams > IPU_MMU_MAX_TLB_L1_STREAMS || + src_mmu->nr_l2streams > IPU_MMU_MAX_TLB_L2_STREAMS) + return ERR_PTR(-EINVAL); + + *pdata_mmu = *src_mmu; + pdata_mmu->base = base + src_mmu->offset; + pdata_mmu->zlx_base = base + src_mmu->zlx_offset; + pdata_mmu->uao_base = base + src_mmu->uao_offset; + } + + mmu = devm_kzalloc(dev, sizeof(*mmu), GFP_KERNEL); + if (!mmu) + return ERR_PTR(-ENOMEM); + + mmu->mmid = mmid; + mmu->mmu_hw = pdata->mmu_hw; + mmu->nr_mmus = hw->nr_mmus; + mmu->tlb_invalidate = tlb_invalidate; + mmu->ready = false; + INIT_LIST_HEAD(&mmu->vma_list); + spin_lock_init(&mmu->ready_lock); + + mmu->dmap = alloc_dma_mapping(isp); + if (!mmu->dmap) { + dev_err(dev, "can't alloc dma mapping\n"); + return ERR_PTR(-ENOMEM); + } + + return mmu; +} + +void ipu7_mmu_cleanup(struct ipu7_mmu *mmu) +{ + struct ipu7_dma_mapping *dmap = mmu->dmap; + + ipu7_mmu_destroy(mmu); + mmu->dmap = NULL; + iova_cache_put(); + put_iova_domain(&dmap->iovad); + kfree(dmap); +} diff --git a/drivers/staging/media/ipu7/ipu7-mmu.h b/drivers/staging/media/ipu7/ipu7-mmu.h new file mode 100644 index 000000000000..d85bb8ffc711 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-mmu.h @@ -0,0 +1,414 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_MMU_H +#define IPU7_MMU_H + +#include <linux/dma-mapping.h> +#include <linux/list.h> +#include <linux/spinlock_types.h> +#include <linux/types.h> + +struct device; +struct page; +struct ipu7_hw_variants; +struct ipu7_mmu; +struct ipu7_mmu_info; + +#define ISYS_MMID 0x1 +#define PSYS_MMID 0x0 + +/* IPU7 for LNL */ +/* IS MMU Cmd RD */ +#define IPU7_IS_MMU_FW_RD_OFFSET 0x274000 +#define IPU7_IS_MMU_FW_RD_STREAM_NUM 3 +#define IPU7_IS_MMU_FW_RD_L1_BLOCKNR_REG 0x54 +#define IPU7_IS_MMU_FW_RD_L2_BLOCKNR_REG 0x60 + +/* IS MMU Cmd WR */ +#define IPU7_IS_MMU_FW_WR_OFFSET 0x275000 +#define IPU7_IS_MMU_FW_WR_STREAM_NUM 3 +#define IPU7_IS_MMU_FW_WR_L1_BLOCKNR_REG 0x54 +#define IPU7_IS_MMU_FW_WR_L2_BLOCKNR_REG 0x60 + +/* IS MMU Data WR Snoop */ +#define IPU7_IS_MMU_M0_OFFSET 0x276000 +#define IPU7_IS_MMU_M0_STREAM_NUM 8 +#define IPU7_IS_MMU_M0_L1_BLOCKNR_REG 0x54 +#define IPU7_IS_MMU_M0_L2_BLOCKNR_REG 0x74 + +/* IS MMU Data WR ISOC */ +#define IPU7_IS_MMU_M1_OFFSET 0x277000 +#define IPU7_IS_MMU_M1_STREAM_NUM 16 +#define IPU7_IS_MMU_M1_L1_BLOCKNR_REG 0x54 +#define IPU7_IS_MMU_M1_L2_BLOCKNR_REG 0x94 + +/* PS MMU FW RD */ +#define IPU7_PS_MMU_FW_RD_OFFSET 0x148000 +#define IPU7_PS_MMU_FW_RD_STREAM_NUM 20 +#define IPU7_PS_MMU_FW_RD_L1_BLOCKNR_REG 0x54 +#define IPU7_PS_MMU_FW_RD_L2_BLOCKNR_REG 0xa4 + +/* PS MMU FW WR */ +#define IPU7_PS_MMU_FW_WR_OFFSET 0x149000 +#define IPU7_PS_MMU_FW_WR_STREAM_NUM 10 +#define IPU7_PS_MMU_FW_WR_L1_BLOCKNR_REG 0x54 +#define IPU7_PS_MMU_FW_WR_L2_BLOCKNR_REG 0x7c + +/* PS MMU FW Data RD VC0 */ +#define IPU7_PS_MMU_SRT_RD_OFFSET 0x14a000 +#define IPU7_PS_MMU_SRT_RD_STREAM_NUM 40 +#define IPU7_PS_MMU_SRT_RD_L1_BLOCKNR_REG 0x54 +#define IPU7_PS_MMU_SRT_RD_L2_BLOCKNR_REG 0xf4 + +/* PS MMU FW Data WR VC0 */ +#define IPU7_PS_MMU_SRT_WR_OFFSET 0x14b000 +#define IPU7_PS_MMU_SRT_WR_STREAM_NUM 40 +#define IPU7_PS_MMU_SRT_WR_L1_BLOCKNR_REG 0x54 +#define IPU7_PS_MMU_SRT_WR_L2_BLOCKNR_REG 0xf4 + +/* IS UAO UC RD */ +#define IPU7_IS_UAO_UC_RD_OFFSET 0x27c000 +#define IPU7_IS_UAO_UC_RD_PLANENUM 4 + +/* IS UAO UC WR */ +#define IPU7_IS_UAO_UC_WR_OFFSET 0x27d000 +#define IPU7_IS_UAO_UC_WR_PLANENUM 4 + +/* IS UAO M0 WR */ +#define IPU7_IS_UAO_M0_WR_OFFSET 0x27e000 +#define IPU7_IS_UAO_M0_WR_PLANENUM 8 + +/* IS UAO M1 WR */ +#define IPU7_IS_UAO_M1_WR_OFFSET 0x27f000 +#define IPU7_IS_UAO_M1_WR_PLANENUM 16 + +/* PS UAO FW RD */ +#define IPU7_PS_UAO_FW_RD_OFFSET 0x156000 +#define IPU7_PS_UAO_FW_RD_PLANENUM 20 + +/* PS UAO FW WR */ +#define IPU7_PS_UAO_FW_WR_OFFSET 0x157000 +#define IPU7_PS_UAO_FW_WR_PLANENUM 16 + +/* PS UAO SRT RD */ +#define IPU7_PS_UAO_SRT_RD_OFFSET 0x154000 +#define IPU7_PS_UAO_SRT_RD_PLANENUM 40 + +/* PS UAO SRT WR */ +#define IPU7_PS_UAO_SRT_WR_OFFSET 0x155000 +#define IPU7_PS_UAO_SRT_WR_PLANENUM 40 + +#define IPU7_IS_ZLX_UC_RD_OFFSET 0x278000 +#define IPU7_IS_ZLX_UC_WR_OFFSET 0x279000 +#define IPU7_IS_ZLX_M0_OFFSET 0x27a000 +#define IPU7_IS_ZLX_M1_OFFSET 0x27b000 +#define IPU7_IS_ZLX_UC_RD_NUM 4 +#define IPU7_IS_ZLX_UC_WR_NUM 4 +#define IPU7_IS_ZLX_M0_NUM 8 +#define IPU7_IS_ZLX_M1_NUM 16 + +#define IPU7_PS_ZLX_DATA_RD_OFFSET 0x14e000 +#define IPU7_PS_ZLX_DATA_WR_OFFSET 0x14f000 +#define IPU7_PS_ZLX_FW_RD_OFFSET 0x150000 +#define IPU7_PS_ZLX_FW_WR_OFFSET 0x151000 +#define IPU7_PS_ZLX_DATA_RD_NUM 32 +#define IPU7_PS_ZLX_DATA_WR_NUM 32 +#define IPU7_PS_ZLX_FW_RD_NUM 16 +#define IPU7_PS_ZLX_FW_WR_NUM 10 + +/* IPU7P5 for PTL */ +/* IS MMU Cmd RD */ +#define IPU7P5_IS_MMU_FW_RD_OFFSET 0x274000 +#define IPU7P5_IS_MMU_FW_RD_STREAM_NUM 3 +#define IPU7P5_IS_MMU_FW_RD_L1_BLOCKNR_REG 0x54 +#define IPU7P5_IS_MMU_FW_RD_L2_BLOCKNR_REG 0x60 + +/* IS MMU Cmd WR */ +#define IPU7P5_IS_MMU_FW_WR_OFFSET 0x275000 +#define IPU7P5_IS_MMU_FW_WR_STREAM_NUM 3 +#define IPU7P5_IS_MMU_FW_WR_L1_BLOCKNR_REG 0x54 +#define IPU7P5_IS_MMU_FW_WR_L2_BLOCKNR_REG 0x60 + +/* IS MMU Data WR Snoop */ +#define IPU7P5_IS_MMU_M0_OFFSET 0x276000 +#define IPU7P5_IS_MMU_M0_STREAM_NUM 16 +#define IPU7P5_IS_MMU_M0_L1_BLOCKNR_REG 0x54 +#define IPU7P5_IS_MMU_M0_L2_BLOCKNR_REG 0x94 + +/* IS MMU Data WR ISOC */ +#define IPU7P5_IS_MMU_M1_OFFSET 0x277000 +#define IPU7P5_IS_MMU_M1_STREAM_NUM 16 +#define IPU7P5_IS_MMU_M1_L1_BLOCKNR_REG 0x54 +#define IPU7P5_IS_MMU_M1_L2_BLOCKNR_REG 0x94 + +/* PS MMU FW RD */ +#define IPU7P5_PS_MMU_FW_RD_OFFSET 0x148000 +#define IPU7P5_PS_MMU_FW_RD_STREAM_NUM 16 +#define IPU7P5_PS_MMU_FW_RD_L1_BLOCKNR_REG 0x54 +#define IPU7P5_PS_MMU_FW_RD_L2_BLOCKNR_REG 0x94 + +/* PS MMU FW WR */ +#define IPU7P5_PS_MMU_FW_WR_OFFSET 0x149000 +#define IPU7P5_PS_MMU_FW_WR_STREAM_NUM 10 +#define IPU7P5_PS_MMU_FW_WR_L1_BLOCKNR_REG 0x54 +#define IPU7P5_PS_MMU_FW_WR_L2_BLOCKNR_REG 0x7c + +/* PS MMU FW Data RD VC0 */ +#define IPU7P5_PS_MMU_SRT_RD_OFFSET 0x14a000 +#define IPU7P5_PS_MMU_SRT_RD_STREAM_NUM 22 +#define IPU7P5_PS_MMU_SRT_RD_L1_BLOCKNR_REG 0x54 +#define IPU7P5_PS_MMU_SRT_RD_L2_BLOCKNR_REG 0xac + +/* PS MMU FW Data WR VC0 */ +#define IPU7P5_PS_MMU_SRT_WR_OFFSET 0x14b000 +#define IPU7P5_PS_MMU_SRT_WR_STREAM_NUM 32 +#define IPU7P5_PS_MMU_SRT_WR_L1_BLOCKNR_REG 0x54 +#define IPU7P5_PS_MMU_SRT_WR_L2_BLOCKNR_REG 0xd4 + +/* IS UAO UC RD */ +#define IPU7P5_IS_UAO_UC_RD_OFFSET 0x27c000 +#define IPU7P5_IS_UAO_UC_RD_PLANENUM 4 + +/* IS UAO UC WR */ +#define IPU7P5_IS_UAO_UC_WR_OFFSET 0x27d000 +#define IPU7P5_IS_UAO_UC_WR_PLANENUM 4 + +/* IS UAO M0 WR */ +#define IPU7P5_IS_UAO_M0_WR_OFFSET 0x27e000 +#define IPU7P5_IS_UAO_M0_WR_PLANENUM 16 + +/* IS UAO M1 WR */ +#define IPU7P5_IS_UAO_M1_WR_OFFSET 0x27f000 +#define IPU7P5_IS_UAO_M1_WR_PLANENUM 16 + +/* PS UAO FW RD */ +#define IPU7P5_PS_UAO_FW_RD_OFFSET 0x156000 +#define IPU7P5_PS_UAO_FW_RD_PLANENUM 16 + +/* PS UAO FW WR */ +#define IPU7P5_PS_UAO_FW_WR_OFFSET 0x157000 +#define IPU7P5_PS_UAO_FW_WR_PLANENUM 10 + +/* PS UAO SRT RD */ +#define IPU7P5_PS_UAO_SRT_RD_OFFSET 0x154000 +#define IPU7P5_PS_UAO_SRT_RD_PLANENUM 22 + +/* PS UAO SRT WR */ +#define IPU7P5_PS_UAO_SRT_WR_OFFSET 0x155000 +#define IPU7P5_PS_UAO_SRT_WR_PLANENUM 32 + +#define IPU7P5_IS_ZLX_UC_RD_OFFSET 0x278000 +#define IPU7P5_IS_ZLX_UC_WR_OFFSET 0x279000 +#define IPU7P5_IS_ZLX_M0_OFFSET 0x27a000 +#define IPU7P5_IS_ZLX_M1_OFFSET 0x27b000 +#define IPU7P5_IS_ZLX_UC_RD_NUM 4 +#define IPU7P5_IS_ZLX_UC_WR_NUM 4 +#define IPU7P5_IS_ZLX_M0_NUM 16 +#define IPU7P5_IS_ZLX_M1_NUM 16 + +#define IPU7P5_PS_ZLX_DATA_RD_OFFSET 0x14e000 +#define IPU7P5_PS_ZLX_DATA_WR_OFFSET 0x14f000 +#define IPU7P5_PS_ZLX_FW_RD_OFFSET 0x150000 +#define IPU7P5_PS_ZLX_FW_WR_OFFSET 0x151000 +#define IPU7P5_PS_ZLX_DATA_RD_NUM 22 +#define IPU7P5_PS_ZLX_DATA_WR_NUM 32 +#define IPU7P5_PS_ZLX_FW_RD_NUM 16 +#define IPU7P5_PS_ZLX_FW_WR_NUM 10 + +/* IS MMU Cmd RD */ +#define IPU8_IS_MMU_FW_RD_OFFSET 0x270000 +#define IPU8_IS_MMU_FW_RD_STREAM_NUM 3 +#define IPU8_IS_MMU_FW_RD_L1_BLOCKNR_REG 0x54 +#define IPU8_IS_MMU_FW_RD_L2_BLOCKNR_REG 0x60 + +/* IS MMU Cmd WR */ +#define IPU8_IS_MMU_FW_WR_OFFSET 0x271000 +#define IPU8_IS_MMU_FW_WR_STREAM_NUM 3 +#define IPU8_IS_MMU_FW_WR_L1_BLOCKNR_REG 0x54 +#define IPU8_IS_MMU_FW_WR_L2_BLOCKNR_REG 0x60 + +/* IS MMU Data WR Snoop */ +#define IPU8_IS_MMU_M0_OFFSET 0x272000 +#define IPU8_IS_MMU_M0_STREAM_NUM 16 +#define IPU8_IS_MMU_M0_L1_BLOCKNR_REG 0x54 +#define IPU8_IS_MMU_M0_L2_BLOCKNR_REG 0x94 + +/* IS MMU Data WR ISOC */ +#define IPU8_IS_MMU_M1_OFFSET 0x273000 +#define IPU8_IS_MMU_M1_STREAM_NUM 16 +#define IPU8_IS_MMU_M1_L1_BLOCKNR_REG 0x54 +#define IPU8_IS_MMU_M1_L2_BLOCKNR_REG 0x94 + +/* IS MMU UPIPE ISOC */ +#define IPU8_IS_MMU_UPIPE_OFFSET 0x274000 +#define IPU8_IS_MMU_UPIPE_STREAM_NUM 6 +#define IPU8_IS_MMU_UPIPE_L1_BLOCKNR_REG 0x54 +#define IPU8_IS_MMU_UPIPE_L2_BLOCKNR_REG 0x6c + +/* PS MMU FW RD */ +#define IPU8_PS_MMU_FW_RD_OFFSET 0x148000 +#define IPU8_PS_MMU_FW_RD_STREAM_NUM 12 +#define IPU8_PS_MMU_FW_RD_L1_BLOCKNR_REG 0x54 +#define IPU8_PS_MMU_FW_RD_L2_BLOCKNR_REG 0x84 + +/* PS MMU FW WR */ +#define IPU8_PS_MMU_FW_WR_OFFSET 0x149000 +#define IPU8_PS_MMU_FW_WR_STREAM_NUM 8 +#define IPU8_PS_MMU_FW_WR_L1_BLOCKNR_REG 0x54 +#define IPU8_PS_MMU_FW_WR_L2_BLOCKNR_REG 0x74 + +/* PS MMU FW Data RD VC0 */ +#define IPU8_PS_MMU_SRT_RD_OFFSET 0x14a000 +#define IPU8_PS_MMU_SRT_RD_STREAM_NUM 26 +#define IPU8_PS_MMU_SRT_RD_L1_BLOCKNR_REG 0x54 +#define IPU8_PS_MMU_SRT_RD_L2_BLOCKNR_REG 0xbc + +/* PS MMU FW Data WR VC0 */ +#define IPU8_PS_MMU_SRT_WR_OFFSET 0x14b000 +#define IPU8_PS_MMU_SRT_WR_STREAM_NUM 26 +#define IPU8_PS_MMU_SRT_WR_L1_BLOCKNR_REG 0x54 +#define IPU8_PS_MMU_SRT_WR_L2_BLOCKNR_REG 0xbc + +/* IS UAO UC RD */ +#define IPU8_IS_UAO_UC_RD_OFFSET 0x27a000 +#define IPU8_IS_UAO_UC_RD_PLANENUM 4 + +/* IS UAO UC WR */ +#define IPU8_IS_UAO_UC_WR_OFFSET 0x27b000 +#define IPU8_IS_UAO_UC_WR_PLANENUM 4 + +/* IS UAO M0 WR */ +#define IPU8_IS_UAO_M0_WR_OFFSET 0x27c000 +#define IPU8_IS_UAO_M0_WR_PLANENUM 16 + +/* IS UAO M1 WR */ +#define IPU8_IS_UAO_M1_WR_OFFSET 0x27d000 +#define IPU8_IS_UAO_M1_WR_PLANENUM 16 + +/* IS UAO UPIPE */ +#define IPU8_IS_UAO_UPIPE_OFFSET 0x27e000 +#define IPU8_IS_UAO_UPIPE_PLANENUM 6 + +/* PS UAO FW RD */ +#define IPU8_PS_UAO_FW_RD_OFFSET 0x156000 +#define IPU8_PS_UAO_FW_RD_PLANENUM 12 + +/* PS UAO FW WR */ +#define IPU8_PS_UAO_FW_WR_OFFSET 0x157000 +#define IPU8_PS_UAO_FW_WR_PLANENUM 8 + +/* PS UAO SRT RD */ +#define IPU8_PS_UAO_SRT_RD_OFFSET 0x154000 +#define IPU8_PS_UAO_SRT_RD_PLANENUM 26 + +/* PS UAO SRT WR */ +#define IPU8_PS_UAO_SRT_WR_OFFSET 0x155000 +#define IPU8_PS_UAO_SRT_WR_PLANENUM 26 + +#define IPU8_IS_ZLX_UC_RD_OFFSET 0x275000 +#define IPU8_IS_ZLX_UC_WR_OFFSET 0x276000 +#define IPU8_IS_ZLX_M0_OFFSET 0x277000 +#define IPU8_IS_ZLX_M1_OFFSET 0x278000 +#define IPU8_IS_ZLX_UPIPE_OFFSET 0x279000 +#define IPU8_IS_ZLX_UC_RD_NUM 4 +#define IPU8_IS_ZLX_UC_WR_NUM 4 +#define IPU8_IS_ZLX_M0_NUM 16 +#define IPU8_IS_ZLX_M1_NUM 16 +#define IPU8_IS_ZLX_UPIPE_NUM 6 + +#define IPU8_PS_ZLX_DATA_RD_OFFSET 0x14e000 +#define IPU8_PS_ZLX_DATA_WR_OFFSET 0x14f000 +#define IPU8_PS_ZLX_FW_RD_OFFSET 0x150000 +#define IPU8_PS_ZLX_FW_WR_OFFSET 0x151000 +#define IPU8_PS_ZLX_DATA_RD_NUM 26 +#define IPU8_PS_ZLX_DATA_WR_NUM 26 +#define IPU8_PS_ZLX_FW_RD_NUM 12 +#define IPU8_PS_ZLX_FW_WR_NUM 8 + +#define MMU_REG_INVALIDATE_0 0x00 +#define MMU_REG_INVALIDATE_1 0x04 +#define MMU_REG_PAGE_TABLE_BASE_ADDR 0x08 +#define MMU_REG_USER_INFO_BITS 0x0c +#define MMU_REG_AXI_REFILL_IF_ID 0x10 +#define MMU_REG_PW_EN_BITMAP 0x14 +#define MMU_REG_COLLAPSE_ENABLE_BITMAP 0x18 +#define MMU_REG_GENERAL_REG 0x1c +#define MMU_REG_AT_SP_ARB_CFG 0x20 +#define MMU_REG_INVALIDATION_STATUS 0x24 +#define MMU_REG_IRQ_LEVEL_NO_PULSE 0x28 +#define MMU_REG_IRQ_MASK 0x2c +#define MMU_REG_IRQ_ENABLE 0x30 +#define MMU_REG_IRQ_EDGE 0x34 +#define MMU_REG_IRQ_CLEAR 0x38 +#define MMU_REG_IRQ_CAUSE 0x3c +#define MMU_REG_CG_CTRL_BITS 0x40 +#define MMU_REG_RD_FIFOS_STATUS 0x44 +#define MMU_REG_WR_FIFOS_STATUS 0x48 +#define MMU_REG_COMMON_FIFOS_STATUS 0x4c +#define MMU_REG_FSM_STATUS 0x50 + +#define ZLX_REG_AXI_POOL 0x0 +#define ZLX_REG_EN 0x20 +#define ZLX_REG_CONF 0x24 +#define ZLX_REG_CG_CTRL 0x900 +#define ZLX_REG_FORCE_BYPASS 0x904 + +struct ipu7_mmu_info { + struct device *dev; + + u32 *l1_pt; + u32 l1_pt_dma; + u32 **l2_pts; + + u32 *dummy_l2_pt; + u32 dummy_l2_pteval; + void *dummy_page; + u32 dummy_page_pteval; + + dma_addr_t aperture_start; + dma_addr_t aperture_end; + unsigned long pgsize_bitmap; + + spinlock_t lock; /* Serialize access to users */ + struct ipu7_dma_mapping *dmap; +}; + +struct ipu7_mmu { + struct list_head node; + + struct ipu7_mmu_hw *mmu_hw; + unsigned int nr_mmus; + unsigned int mmid; + + phys_addr_t pgtbl; + struct device *dev; + + struct ipu7_dma_mapping *dmap; + struct list_head vma_list; + + struct page *trash_page; + dma_addr_t pci_trash_page; /* IOVA from PCI DMA services (parent) */ + dma_addr_t iova_trash_page; /* IOVA for IPU child nodes to use */ + + bool ready; + spinlock_t ready_lock; /* Serialize access to bool ready */ + + void (*tlb_invalidate)(struct ipu7_mmu *mmu); +}; + +struct ipu7_mmu *ipu7_mmu_init(struct device *dev, + void __iomem *base, int mmid, + const struct ipu7_hw_variants *hw); +void ipu7_mmu_cleanup(struct ipu7_mmu *mmu); +int ipu7_mmu_hw_init(struct ipu7_mmu *mmu); +void ipu7_mmu_hw_cleanup(struct ipu7_mmu *mmu); +int ipu7_mmu_map(struct ipu7_mmu_info *mmu_info, unsigned long iova, + phys_addr_t paddr, size_t size); +void ipu7_mmu_unmap(struct ipu7_mmu_info *mmu_info, unsigned long iova, + size_t size); +phys_addr_t ipu7_mmu_iova_to_phys(struct ipu7_mmu_info *mmu_info, + dma_addr_t iova); +#endif diff --git a/drivers/staging/media/ipu7/ipu7-platform-regs.h b/drivers/staging/media/ipu7/ipu7-platform-regs.h new file mode 100644 index 000000000000..eeadc886a8cf --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-platform-regs.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2018 - 2025 Intel Corporation + */ + +#ifndef IPU7_PLATFORM_REGS_H +#define IPU7_PLATFORM_REGS_H + +#define IS_BASE 0x230000 +#define IS_UC_CTRL_BASE (IS_BASE + 0x0) + +#define PS_BASE 0x130000 +#define PS_UC_CTRL_BASE (PS_BASE + 0x0) + +/* + * bit 0: IRQ from FW, + * bit 1, 2 and 3: IRQ from HW + */ +#define TO_SW_IRQ_MASK 0xf +#define TO_SW_IRQ_FW BIT(0) + +#define FW_CODE_BASE 0x0 +#define FW_DATA_BASE 0x4 +#define PRINTF_EN_THROUGH_TRACE 0x3004 +#define PRINTF_EN_DIRECTLY_TO_DDR 0x3008 +#define PRINTF_DDR_BASE_ADDR 0x300c +#define PRINTF_DDR_SIZE 0x3010 +#define PRINTF_DDR_NEXT_ADDR 0x3014 +#define PRINTF_STATUS 0x3018 +#define PRINTF_AXI_CNTL 0x301c +#define PRINTF_MSG_LENGTH 0x3020 +#define TO_SW_IRQ_CNTL_EDGE 0x4000 +#define TO_SW_IRQ_CNTL_MASK_N 0x4004 +#define TO_SW_IRQ_CNTL_STATUS 0x4008 +#define TO_SW_IRQ_CNTL_CLEAR 0x400c +#define TO_SW_IRQ_CNTL_ENABLE 0x4010 +#define TO_SW_IRQ_CNTL_LEVEL_NOT_PULSE 0x4014 +#define ERR_IRQ_CNTL_EDGE 0x4018 +#define ERR_IRQ_CNTL_MASK_N 0x401c +#define ERR_IRQ_CNTL_STATUS 0x4020 +#define ERR_IRQ_CNTL_CLEAR 0x4024 +#define ERR_IRQ_CNTL_ENABLE 0x4028 +#define ERR_IRQ_CNTL_LEVEL_NOT_PULSE 0x402c +#define LOCAL_DMEM_BASE_ADDR 0x1300000 + +/* + * IS_UC_TO_SW irqs + * bit 0: IRQ from local FW + * bit 1~3: IRQ from HW + */ +#define IS_UC_TO_SW_IRQ_MASK 0xf + +#define IPU_ISYS_SPC_OFFSET 0x210000 +#define IPU7_PSYS_SPC_OFFSET 0x118000 +#define IPU_ISYS_DMEM_OFFSET 0x200000 +#define IPU_PSYS_DMEM_OFFSET 0x100000 + +#define IPU7_ISYS_CSI_PORT_NUM 4 + +/* IRQ-related registers in PSYS */ +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_EDGE 0x134000 +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_MASK 0x134004 +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_STATUS 0x134008 +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_CLEAR 0x13400c +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_ENABLE 0x134010 +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_LEVEL_NOT_PULSE 0x134014 +#define IRQ_FROM_LOCAL_FW BIT(0) + +/* + * psys subdomains power request regs + */ +enum ipu7_device_buttress_psys_domain_pos { + IPU_PSYS_SUBDOMAIN_LB = 0, + IPU_PSYS_SUBDOMAIN_BB = 1, +}; + +#define IPU7_PSYS_DOMAIN_POWER_MASK (BIT(IPU_PSYS_SUBDOMAIN_LB) | \ + BIT(IPU_PSYS_SUBDOMAIN_BB)) +#define IPU8_PSYS_DOMAIN_POWER_MASK BIT(IPU_PSYS_SUBDOMAIN_LB) +#define IPU_PSYS_DOMAIN_POWER_IN_PROGRESS BIT(31) + +#endif /* IPU7_PLATFORM_REGS_H */ diff --git a/drivers/staging/media/ipu7/ipu7-syscom.c b/drivers/staging/media/ipu7/ipu7-syscom.c new file mode 100644 index 000000000000..3f9f9c5c3cce --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-syscom.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <linux/export.h> +#include <linux/io.h> + +#include "abi/ipu7_fw_syscom_abi.h" + +#include "ipu7.h" +#include "ipu7-syscom.h" + +static void __iomem *ipu7_syscom_get_indices(struct ipu7_syscom_context *ctx, + u32 q) +{ + return ctx->queue_indices + (q * sizeof(struct syscom_queue_indices_s)); +} + +void *ipu7_syscom_get_token(struct ipu7_syscom_context *ctx, int q) +{ + struct syscom_queue_config *queue_params = &ctx->queue_configs[q]; + void __iomem *queue_indices = ipu7_syscom_get_indices(ctx, q); + u32 write_index = readl(queue_indices + + offsetof(struct syscom_queue_indices_s, + write_index)); + u32 read_index = readl(queue_indices + + offsetof(struct syscom_queue_indices_s, + read_index)); + void *token = NULL; + + if (q < ctx->num_output_queues) { + /* Output queue */ + bool empty = (write_index == read_index); + + if (!empty) + token = queue_params->token_array_mem + + read_index * + queue_params->token_size_in_bytes; + } else { + /* Input queue */ + bool full = (read_index == ((write_index + 1U) % + (u32)queue_params->max_capacity)); + + if (!full) + token = queue_params->token_array_mem + + write_index * queue_params->token_size_in_bytes; + } + return token; +} +EXPORT_SYMBOL_NS_GPL(ipu7_syscom_get_token, "INTEL_IPU7"); + +void ipu7_syscom_put_token(struct ipu7_syscom_context *ctx, int q) +{ + struct syscom_queue_config *queue_params = &ctx->queue_configs[q]; + void __iomem *queue_indices = ipu7_syscom_get_indices(ctx, q); + u32 offset, index; + + if (q < ctx->num_output_queues) + /* Output queue */ + offset = offsetof(struct syscom_queue_indices_s, read_index); + + else + /* Input queue */ + offset = offsetof(struct syscom_queue_indices_s, write_index); + + index = readl(queue_indices + offset); + writel((index + 1U) % queue_params->max_capacity, + queue_indices + offset); +} +EXPORT_SYMBOL_NS_GPL(ipu7_syscom_put_token, "INTEL_IPU7"); + +struct syscom_queue_params_config * +ipu7_syscom_get_queue_config(struct syscom_config_s *config) +{ + return (struct syscom_queue_params_config *)(&config[1]); +} +EXPORT_SYMBOL_NS_GPL(ipu7_syscom_get_queue_config, "INTEL_IPU7"); diff --git a/drivers/staging/media/ipu7/ipu7-syscom.h b/drivers/staging/media/ipu7/ipu7-syscom.h new file mode 100644 index 000000000000..e1fbe3b7914e --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7-syscom.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_SYSCOM_H +#define IPU7_SYSCOM_H + +#include <linux/types.h> + +struct syscom_config_s; +struct syscom_queue_params_config; + +struct syscom_queue_config { + void *token_array_mem; + u32 queue_size; + u16 token_size_in_bytes; + u16 max_capacity; +}; + +struct ipu7_syscom_context { + u16 num_input_queues; + u16 num_output_queues; + struct syscom_queue_config *queue_configs; + void __iomem *queue_indices; + dma_addr_t queue_mem_dma_addr; + void *queue_mem; + u32 queue_mem_size; +}; + +void ipu7_syscom_put_token(struct ipu7_syscom_context *ctx, int q); +void *ipu7_syscom_get_token(struct ipu7_syscom_context *ctx, int q); +struct syscom_queue_params_config * +ipu7_syscom_get_queue_config(struct syscom_config_s *config); +#endif diff --git a/drivers/staging/media/ipu7/ipu7.c b/drivers/staging/media/ipu7/ipu7.c new file mode 100644 index 000000000000..1b4f01db13ca --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7.c @@ -0,0 +1,2783 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#include <linux/acpi.h> +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/bug.h> +#include <linux/dma-mapping.h> +#include <linux/err.h> +#include <linux/firmware.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/pm_runtime.h> +#include <linux/property.h> +#include <linux/scatterlist.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/vmalloc.h> +#include <linux/version.h> + +#include <media/ipu-bridge.h> + +#include "abi/ipu7_fw_common_abi.h" + +#include "ipu7.h" +#include "ipu7-bus.h" +#include "ipu7-buttress.h" +#include "ipu7-buttress-regs.h" +#include "ipu7-cpd.h" +#include "ipu7-dma.h" +#include "ipu7-isys-csi2-regs.h" +#include "ipu7-mmu.h" +#include "ipu7-platform-regs.h" + +#define IPU_PCI_BAR 0 +#define IPU_PCI_PBBAR 4 + +static const unsigned int ipu7_csi_offsets[] = { + IPU_CSI_PORT_A_ADDR_OFFSET, + IPU_CSI_PORT_B_ADDR_OFFSET, + IPU_CSI_PORT_C_ADDR_OFFSET, + IPU_CSI_PORT_D_ADDR_OFFSET, +}; + +static struct ipu_isys_internal_pdata ipu7p5_isys_ipdata = { + .csi2 = { + .gpreg = IS_IO_CSI2_GPREGS_BASE, + }, + .hw_variant = { + .offset = IPU_UNIFIED_OFFSET, + .nr_mmus = IPU7P5_IS_MMU_NUM, + .mmu_hw = { + { + .name = "IS_FW_RD", + .offset = IPU7P5_IS_MMU_FW_RD_OFFSET, + .zlx_offset = IPU7P5_IS_ZLX_UC_RD_OFFSET, + .uao_offset = IPU7P5_IS_UAO_UC_RD_OFFSET, + .info_bits = 0x20005101, + .refill = 0x00002726, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU7P5_IS_MMU_FW_RD_L1_BLOCKNR_REG, + .l2_block = IPU7P5_IS_MMU_FW_RD_L2_BLOCKNR_REG, + .nr_l1streams = IPU7P5_IS_MMU_FW_RD_STREAM_NUM, + .nr_l2streams = IPU7P5_IS_MMU_FW_RD_STREAM_NUM, + .l1_block_sz = { + 0x0, 0x8, 0xa, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, + }, + .zlx_nr = IPU7P5_IS_ZLX_UC_RD_NUM, + .zlx_axi_pool = { + 0x00000f30, + }, + .zlx_en = { + 0, 1, 0, 0 + }, + .zlx_conf = { + 0x0, + }, + .uao_p_num = IPU7P5_IS_UAO_UC_RD_PLANENUM, + .uao_p2tlb = { + 0x00000049, + 0x0000004c, + 0x0000004d, + 0x00000000, + }, + }, + { + .name = "IS_FW_WR", + .offset = IPU7P5_IS_MMU_FW_WR_OFFSET, + .zlx_offset = IPU7P5_IS_ZLX_UC_WR_OFFSET, + .uao_offset = IPU7P5_IS_UAO_UC_WR_OFFSET, + .info_bits = 0x20005001, + .refill = 0x00002524, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU7P5_IS_MMU_FW_WR_L1_BLOCKNR_REG, + .l2_block = IPU7P5_IS_MMU_FW_WR_L2_BLOCKNR_REG, + .nr_l1streams = IPU7P5_IS_MMU_FW_WR_STREAM_NUM, + .nr_l2streams = IPU7P5_IS_MMU_FW_WR_STREAM_NUM, + .l1_block_sz = { + 0x0, 0x8, 0xa, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, + }, + .zlx_nr = IPU7P5_IS_ZLX_UC_WR_NUM, + .zlx_axi_pool = { + 0x00000f20, + }, + .zlx_en = { + 0, 1, 1, 0, + }, + .zlx_conf = { + 0x0, + 0x00010101, + 0x00010101, + 0x0, + }, + .uao_p_num = IPU7P5_IS_UAO_UC_WR_PLANENUM, + .uao_p2tlb = { + 0x00000049, + 0x0000004a, + 0x0000004b, + 0x00000000, + }, + }, + { + .name = "IS_DATA_WR_ISOC", + .offset = IPU7P5_IS_MMU_M0_OFFSET, + .zlx_offset = IPU7P5_IS_ZLX_M0_OFFSET, + .uao_offset = IPU7P5_IS_UAO_M0_WR_OFFSET, + .info_bits = 0x20004e01, + .refill = 0x00002120, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU7P5_IS_MMU_M0_L1_BLOCKNR_REG, + .l2_block = IPU7P5_IS_MMU_M0_L2_BLOCKNR_REG, + .nr_l1streams = IPU7P5_IS_MMU_M0_STREAM_NUM, + .nr_l2streams = IPU7P5_IS_MMU_M0_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + }, + .zlx_nr = IPU7P5_IS_ZLX_M0_NUM, + .zlx_axi_pool = { + 0x00000f10, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }, + .zlx_conf = { + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + }, + .uao_p_num = IPU7P5_IS_UAO_M0_WR_PLANENUM, + .uao_p2tlb = { + 0x00000041, + 0x00000042, + 0x00000043, + 0x00000044, + 0x00000041, + 0x00000042, + 0x00000043, + 0x00000044, + 0x00000041, + 0x00000042, + 0x00000043, + 0x00000044, + 0x00000041, + 0x00000042, + 0x00000043, + 0x00000044, + }, + }, + { + .name = "IS_DATA_WR_SNOOP", + .offset = IPU7P5_IS_MMU_M1_OFFSET, + .zlx_offset = IPU7P5_IS_ZLX_M1_OFFSET, + .uao_offset = IPU7P5_IS_UAO_M1_WR_OFFSET, + .info_bits = 0x20004f01, + .refill = 0x00002322, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU7P5_IS_MMU_M1_L1_BLOCKNR_REG, + .l2_block = IPU7P5_IS_MMU_M1_L2_BLOCKNR_REG, + .nr_l1streams = IPU7P5_IS_MMU_M1_STREAM_NUM, + .nr_l2streams = IPU7P5_IS_MMU_M1_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + }, + .zlx_nr = IPU7P5_IS_ZLX_M1_NUM, + .zlx_axi_pool = { + 0x00000f20, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }, + .zlx_conf = { + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + }, + .uao_p_num = IPU7P5_IS_UAO_M1_WR_PLANENUM, + .uao_p2tlb = { + 0x00000045, + 0x00000046, + 0x00000047, + 0x00000048, + 0x00000045, + 0x00000046, + 0x00000047, + 0x00000048, + 0x00000045, + 0x00000046, + 0x00000047, + 0x00000048, + 0x00000045, + 0x00000046, + 0x00000047, + 0x00000048, + }, + }, + }, + .cdc_fifos = 3, + .cdc_fifo_threshold = {6, 8, 2}, + .dmem_offset = IPU_ISYS_DMEM_OFFSET, + .spc_offset = IPU_ISYS_SPC_OFFSET, + }, + .isys_dma_overshoot = IPU_ISYS_OVERALLOC_MIN, +}; + +static struct ipu_psys_internal_pdata ipu7p5_psys_ipdata = { + .hw_variant = { + .offset = IPU_UNIFIED_OFFSET, + .nr_mmus = IPU7P5_PS_MMU_NUM, + .mmu_hw = { + { + .name = "PS_FW_RD", + .offset = IPU7P5_PS_MMU_FW_RD_OFFSET, + .zlx_offset = IPU7P5_PS_ZLX_FW_RD_OFFSET, + .uao_offset = IPU7P5_PS_UAO_FW_RD_OFFSET, + .info_bits = 0x20004001, + .refill = 0x00002726, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU7P5_PS_MMU_FW_RD_L1_BLOCKNR_REG, + .l2_block = IPU7P5_PS_MMU_FW_RD_L2_BLOCKNR_REG, + .nr_l1streams = IPU7P5_PS_MMU_FW_RD_STREAM_NUM, + .nr_l2streams = IPU7P5_PS_MMU_FW_RD_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000d, + 0x0000000f, + 0x00000011, + 0x00000012, + 0x00000013, + 0x00000014, + 0x00000016, + 0x00000018, + 0x00000019, + 0x0000001a, + 0x0000001a, + 0x0000001a, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + }, + .zlx_nr = IPU7P5_PS_ZLX_FW_RD_NUM, + .zlx_axi_pool = { + 0x00000f30, + }, + .zlx_en = { + 0, 1, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + }, + .zlx_conf = { + 0x00000000, + 0x00010101, + 0x00000000, + 0x00000000, + 0x00010101, + 0x00010101, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00010101, + 0x00010101, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + }, + .uao_p_num = IPU7P5_PS_UAO_FW_RD_PLANENUM, + .uao_p2tlb = { + 0x0000002e, + 0x00000035, + 0x00000036, + 0x00000031, + 0x00000037, + 0x00000038, + 0x00000039, + 0x00000032, + 0x00000033, + 0x0000003a, + 0x0000003b, + 0x0000003c, + 0x00000034, + 0x0, + 0x0, + 0x0, + }, + }, + { + .name = "PS_FW_WR", + .offset = IPU7P5_PS_MMU_FW_WR_OFFSET, + .zlx_offset = IPU7P5_PS_ZLX_FW_WR_OFFSET, + .uao_offset = IPU7P5_PS_UAO_FW_WR_OFFSET, + .info_bits = 0x20003e01, + .refill = 0x00002322, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU7P5_PS_MMU_FW_WR_L1_BLOCKNR_REG, + .l2_block = IPU7P5_PS_MMU_FW_WR_L2_BLOCKNR_REG, + .nr_l1streams = IPU7P5_PS_MMU_FW_WR_STREAM_NUM, + .nr_l2streams = IPU7P5_PS_MMU_FW_WR_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000d, + 0x0000000e, + 0x0000000f, + 0x00000010, + 0x00000010, + 0x00000010, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + }, + .zlx_nr = IPU7P5_PS_ZLX_FW_WR_NUM, + .zlx_axi_pool = { + 0x00000f20, + }, + .zlx_en = { + 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, + }, + .zlx_conf = { + 0x00000000, + 0x00010101, + 0x00010101, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + }, + .uao_p_num = IPU7P5_PS_UAO_FW_WR_PLANENUM, + .uao_p2tlb = { + 0x0000002e, + 0x0000002f, + 0x00000030, + 0x00000031, + 0x00000032, + 0x00000033, + 0x00000034, + 0x0, + 0x0, + 0x0, + }, + }, + { + .name = "PS_DATA_RD", + .offset = IPU7P5_PS_MMU_SRT_RD_OFFSET, + .zlx_offset = IPU7P5_PS_ZLX_DATA_RD_OFFSET, + .uao_offset = IPU7P5_PS_UAO_SRT_RD_OFFSET, + .info_bits = 0x20003f01, + .refill = 0x00002524, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU7P5_PS_MMU_SRT_RD_L1_BLOCKNR_REG, + .l2_block = IPU7P5_PS_MMU_SRT_RD_L2_BLOCKNR_REG, + .nr_l1streams = IPU7P5_PS_MMU_SRT_RD_STREAM_NUM, + .nr_l2streams = IPU7P5_PS_MMU_SRT_RD_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000b, + 0x0000000d, + 0x0000000f, + 0x00000013, + 0x00000017, + 0x00000019, + 0x0000001b, + 0x0000001d, + 0x0000001f, + 0x0000002b, + 0x00000033, + 0x0000003f, + 0x00000047, + 0x00000049, + 0x0000004b, + 0x0000004c, + 0x0000004d, + 0x0000004e, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + 0x00000020, + 0x00000022, + 0x00000024, + 0x00000026, + 0x00000028, + 0x0000002a, + }, + .zlx_nr = IPU7P5_PS_ZLX_DATA_RD_NUM, + .zlx_axi_pool = { + 0x00000f30, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, + }, + .zlx_conf = { + 0x00030303, + 0x00010101, + 0x00010101, + 0x00030202, + 0x00010101, + 0x00010101, + 0x00030303, + 0x00030303, + 0x00010101, + 0x00030800, + 0x00030500, + 0x00020101, + 0x00042000, + 0x00031000, + 0x00042000, + 0x00031000, + 0x00020400, + 0x00010101, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + }, + .uao_p_num = IPU7P5_PS_UAO_SRT_RD_PLANENUM, + .uao_p2tlb = { + 0x0000001c, + 0x0000001d, + 0x0000001e, + 0x0000001f, + 0x00000020, + 0x00000021, + 0x00000022, + 0x00000023, + 0x00000024, + 0x00000025, + 0x00000026, + 0x00000027, + 0x00000028, + 0x00000029, + 0x0000002a, + 0x0000002b, + 0x0000002c, + 0x0000002d, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + }, + }, + { + .name = "PS_DATA_WR", + .offset = IPU7P5_PS_MMU_SRT_WR_OFFSET, + .zlx_offset = IPU7P5_PS_ZLX_DATA_WR_OFFSET, + .uao_offset = IPU7P5_PS_UAO_SRT_WR_OFFSET, + .info_bits = 0x20003d01, + .refill = 0x00002120, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU7P5_PS_MMU_SRT_WR_L1_BLOCKNR_REG, + .l2_block = IPU7P5_PS_MMU_SRT_WR_L2_BLOCKNR_REG, + .nr_l1streams = IPU7P5_PS_MMU_SRT_WR_STREAM_NUM, + .nr_l2streams = IPU7P5_PS_MMU_SRT_WR_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000002, + 0x00000006, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + 0x00000020, + 0x00000022, + 0x00000024, + 0x00000028, + 0x0000002a, + 0x00000036, + 0x0000003e, + 0x00000040, + 0x00000042, + 0x0000004e, + 0x00000056, + 0x0000005c, + 0x00000068, + 0x00000070, + 0x00000076, + 0x00000077, + 0x00000078, + 0x00000079, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000006, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + 0x00000020, + 0x00000022, + 0x00000024, + 0x00000028, + 0x0000002a, + 0x00000036, + 0x0000003e, + 0x00000040, + 0x00000042, + 0x0000004e, + 0x00000056, + 0x0000005c, + 0x00000068, + 0x00000070, + 0x00000076, + 0x00000077, + 0x00000078, + 0x00000079, + }, + .zlx_nr = IPU7P5_PS_ZLX_DATA_WR_NUM, + .zlx_axi_pool = { + 0x00000f50, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, + }, + .zlx_conf = { + 0x00010102, + 0x00030103, + 0x00030103, + 0x00010101, + 0x00010101, + 0x00030101, + 0x00010101, + 0x38010101, + 0x00000000, + 0x00000000, + 0x38010101, + 0x38010101, + 0x38010101, + 0x38010101, + 0x38010101, + 0x38010101, + 0x00030303, + 0x00010101, + 0x00042000, + 0x00031000, + 0x00010101, + 0x00010101, + 0x00042000, + 0x00031000, + 0x00031000, + 0x00042000, + 0x00031000, + 0x00031000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + }, + .uao_p_num = IPU7P5_PS_UAO_SRT_WR_PLANENUM, + .uao_p2tlb = { + 0x00000000, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00000007, + 0x00000008, + 0x00000009, + 0x0000000a, + 0x0000000b, + 0x0000000c, + 0x0000000d, + 0x0000000e, + 0x0000000f, + 0x00000010, + 0x00000011, + 0x00000012, + 0x00000013, + 0x00000014, + 0x00000015, + 0x00000016, + 0x00000017, + 0x00000018, + 0x00000019, + 0x0000001a, + 0x0000001b, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + }, + }, + }, + .dmem_offset = IPU_PSYS_DMEM_OFFSET, + }, +}; + +static struct ipu_isys_internal_pdata ipu7_isys_ipdata = { + .csi2 = { + .gpreg = IS_IO_CSI2_GPREGS_BASE, + }, + .hw_variant = { + .offset = IPU_UNIFIED_OFFSET, + .nr_mmus = IPU7_IS_MMU_NUM, + .mmu_hw = { + { + .name = "IS_FW_RD", + .offset = IPU7_IS_MMU_FW_RD_OFFSET, + .zlx_offset = IPU7_IS_ZLX_UC_RD_OFFSET, + .uao_offset = IPU7_IS_UAO_UC_RD_OFFSET, + .info_bits = 0x20006701, + .refill = 0x00002726, + .collapse_en_bitmap = 0x0, + .l1_block = IPU7_IS_MMU_FW_RD_L1_BLOCKNR_REG, + .l2_block = IPU7_IS_MMU_FW_RD_L2_BLOCKNR_REG, + .nr_l1streams = IPU7_IS_MMU_FW_RD_STREAM_NUM, + .nr_l2streams = IPU7_IS_MMU_FW_RD_STREAM_NUM, + .l1_block_sz = { + 0x0, 0x8, 0xa, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, + }, + .zlx_nr = IPU7_IS_ZLX_UC_RD_NUM, + .zlx_axi_pool = { + 0x00000f30, + }, + .zlx_en = { + 0, 0, 0, 0 + }, + .zlx_conf = { + 0x0, 0x0, 0x0, 0x0, + }, + .uao_p_num = IPU7_IS_UAO_UC_RD_PLANENUM, + .uao_p2tlb = { + 0x00000061, + 0x00000064, + 0x00000065, + }, + }, + { + .name = "IS_FW_WR", + .offset = IPU7_IS_MMU_FW_WR_OFFSET, + .zlx_offset = IPU7_IS_ZLX_UC_WR_OFFSET, + .uao_offset = IPU7_IS_UAO_UC_WR_OFFSET, + .info_bits = 0x20006801, + .refill = 0x00002524, + .collapse_en_bitmap = 0x0, + .l1_block = IPU7_IS_MMU_FW_WR_L1_BLOCKNR_REG, + .l2_block = IPU7_IS_MMU_FW_WR_L2_BLOCKNR_REG, + .nr_l1streams = IPU7_IS_MMU_FW_WR_STREAM_NUM, + .nr_l2streams = IPU7_IS_MMU_FW_WR_STREAM_NUM, + .l1_block_sz = { + 0x0, 0x8, 0xa, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, + }, + .zlx_nr = IPU7_IS_ZLX_UC_WR_NUM, + .zlx_axi_pool = { + 0x00000f20, + }, + .zlx_en = { + 0, 1, 1, 0, + }, + .zlx_conf = { + 0x0, + 0x00010101, + 0x00010101, + }, + .uao_p_num = IPU7_IS_UAO_UC_WR_PLANENUM, + .uao_p2tlb = { + 0x00000061, + 0x00000062, + 0x00000063, + }, + }, + { + .name = "IS_DATA_WR_ISOC", + .offset = IPU7_IS_MMU_M0_OFFSET, + .zlx_offset = IPU7_IS_ZLX_M0_OFFSET, + .uao_offset = IPU7_IS_UAO_M0_WR_OFFSET, + .info_bits = 0x20006601, + .refill = 0x00002120, + .collapse_en_bitmap = 0x0, + .l1_block = IPU7_IS_MMU_M0_L1_BLOCKNR_REG, + .l2_block = IPU7_IS_MMU_M0_L2_BLOCKNR_REG, + .nr_l1streams = IPU7_IS_MMU_M0_STREAM_NUM, + .nr_l2streams = IPU7_IS_MMU_M0_STREAM_NUM, + .l1_block_sz = { + 0x0, 0x3, 0x6, 0x8, 0xa, 0xc, 0xe, 0x10, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe, + }, + .zlx_nr = IPU7_IS_ZLX_M0_NUM, + .zlx_axi_pool = { + 0x00000f10, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, 1, 1, + }, + .zlx_conf = { + 0x00010103, + 0x00010103, + 0x00010101, + 0x00010101, + 0x00010101, + 0x00010101, + 0x00010101, + 0x00010101, + }, + .uao_p_num = IPU7_IS_UAO_M0_WR_PLANENUM, + .uao_p2tlb = { + 0x00000049, + 0x0000004a, + 0x0000004b, + 0x0000004c, + 0x0000004d, + 0x0000004e, + 0x0000004f, + 0x00000050, + }, + }, + { + .name = "IS_DATA_WR_SNOOP", + .offset = IPU7_IS_MMU_M1_OFFSET, + .zlx_offset = IPU7_IS_ZLX_M1_OFFSET, + .uao_offset = IPU7_IS_UAO_M1_WR_OFFSET, + .info_bits = 0x20006901, + .refill = 0x00002322, + .collapse_en_bitmap = 0x0, + .l1_block = IPU7_IS_MMU_M1_L1_BLOCKNR_REG, + .l2_block = IPU7_IS_MMU_M1_L2_BLOCKNR_REG, + .nr_l1streams = IPU7_IS_MMU_M1_STREAM_NUM, + .nr_l2streams = IPU7_IS_MMU_M1_STREAM_NUM, + .l1_block_sz = { + 0x0, 0x3, 0x6, 0x9, 0xc, + 0xe, 0x10, 0x12, 0x14, 0x16, + 0x18, 0x1a, 0x1c, 0x1e, 0x20, + 0x22, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, 0x6, 0x8, + 0xa, 0xc, 0xe, 0x10, 0x12, + 0x14, 0x16, 0x18, 0x1a, 0x1c, + 0x1e, + }, + .zlx_nr = IPU7_IS_ZLX_M1_NUM, + .zlx_axi_pool = { + 0x00000f20, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }, + .zlx_conf = { + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010103, + 0x00010101, + 0x00010101, + 0x00010101, + 0x00010101, + 0x00010101, + 0x00010101, + 0x00010101, + 0x00010101, + }, + .uao_p_num = IPU7_IS_UAO_M1_WR_PLANENUM, + .uao_p2tlb = { + 0x00000051, + 0x00000052, + 0x00000053, + 0x00000054, + 0x00000055, + 0x00000056, + 0x00000057, + 0x00000058, + 0x00000059, + 0x0000005a, + 0x0000005b, + 0x0000005c, + 0x0000005d, + 0x0000005e, + 0x0000005f, + 0x00000060, + }, + }, + }, + .cdc_fifos = 3, + .cdc_fifo_threshold = {6, 8, 2}, + .dmem_offset = IPU_ISYS_DMEM_OFFSET, + .spc_offset = IPU_ISYS_SPC_OFFSET, + }, + .isys_dma_overshoot = IPU_ISYS_OVERALLOC_MIN, +}; + +static struct ipu_psys_internal_pdata ipu7_psys_ipdata = { + .hw_variant = { + .offset = IPU_UNIFIED_OFFSET, + .nr_mmus = IPU7_PS_MMU_NUM, + .mmu_hw = { + { + .name = "PS_FW_RD", + .offset = IPU7_PS_MMU_FW_RD_OFFSET, + .zlx_offset = IPU7_PS_ZLX_FW_RD_OFFSET, + .uao_offset = IPU7_PS_UAO_FW_RD_OFFSET, + .info_bits = 0x20004801, + .refill = 0x00002726, + .collapse_en_bitmap = 0x0, + .l1_block = IPU7_PS_MMU_FW_RD_L1_BLOCKNR_REG, + .l2_block = IPU7_PS_MMU_FW_RD_L2_BLOCKNR_REG, + .nr_l1streams = IPU7_PS_MMU_FW_RD_STREAM_NUM, + .nr_l2streams = IPU7_PS_MMU_FW_RD_STREAM_NUM, + .l1_block_sz = { + 0, 0x8, 0xa, 0xc, 0xd, + 0xf, 0x11, 0x12, 0x13, 0x14, + 0x16, 0x18, 0x19, 0x1a, 0x1a, + 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, 0x6, 0x8, + 0xa, 0xc, 0xe, 0x10, 0x12, + 0x14, 0x16, 0x18, 0x1a, 0x1c, + 0x1e, 0x20, 0x22, 0x24, 0x26, + }, + .zlx_nr = IPU7_PS_ZLX_FW_RD_NUM, + .zlx_axi_pool = { + 0x00000f30, + }, + .zlx_en = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, + .zlx_conf = { + 0x0, + }, + .uao_p_num = IPU7_PS_UAO_FW_RD_PLANENUM, + .uao_p2tlb = { + 0x00000036, + 0x0000003d, + 0x0000003e, + 0x00000039, + 0x0000003f, + 0x00000040, + 0x00000041, + 0x0000003a, + 0x0000003b, + 0x00000042, + 0x00000043, + 0x00000044, + 0x0000003c, + }, + }, + { + .name = "PS_FW_WR", + .offset = IPU7_PS_MMU_FW_WR_OFFSET, + .zlx_offset = IPU7_PS_ZLX_FW_WR_OFFSET, + .uao_offset = IPU7_PS_UAO_FW_WR_OFFSET, + .info_bits = 0x20004601, + .refill = 0x00002322, + .collapse_en_bitmap = 0x0, + .l1_block = IPU7_PS_MMU_FW_WR_L1_BLOCKNR_REG, + .l2_block = IPU7_PS_MMU_FW_WR_L2_BLOCKNR_REG, + .nr_l1streams = IPU7_PS_MMU_FW_WR_STREAM_NUM, + .nr_l2streams = IPU7_PS_MMU_FW_WR_STREAM_NUM, + .l1_block_sz = { + 0, 0x8, 0xa, 0xc, 0xd, + 0xe, 0xf, 0x10, 0x10, 0x10, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, 0x6, 0x8, + 0xa, 0xc, 0xe, 0x10, 0x12, + }, + .zlx_nr = IPU7_PS_ZLX_FW_WR_NUM, + .zlx_axi_pool = { + 0x00000f20, + }, + .zlx_en = { + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, + }, + .zlx_conf = { + 0x0, + 0x00010101, + 0x00010101, + }, + .uao_p_num = IPU7_PS_UAO_FW_WR_PLANENUM, + .uao_p2tlb = { + 0x00000036, + 0x00000037, + 0x00000038, + 0x00000039, + 0x0000003a, + 0x0000003b, + 0x0000003c, + }, + }, + { + .name = "PS_DATA_RD", + .offset = IPU7_PS_MMU_SRT_RD_OFFSET, + .zlx_offset = IPU7_PS_ZLX_DATA_RD_OFFSET, + .uao_offset = IPU7_PS_UAO_SRT_RD_OFFSET, + .info_bits = 0x20004701, + .refill = 0x00002120, + .collapse_en_bitmap = 0x0, + .l1_block = IPU7_PS_MMU_SRT_RD_L1_BLOCKNR_REG, + .l2_block = IPU7_PS_MMU_SRT_RD_L2_BLOCKNR_REG, + .nr_l1streams = IPU7_PS_MMU_SRT_RD_STREAM_NUM, + .nr_l2streams = IPU7_PS_MMU_SRT_RD_STREAM_NUM, + .l1_block_sz = { + 0x0, 0x4, 0x6, 0x8, 0xb, + 0xd, 0xf, 0x11, 0x13, 0x15, + 0x17, 0x23, 0x2b, 0x37, 0x3f, + 0x41, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0x53, 0x55, 0x57, + 0x59, 0x5b, 0x5d, 0x5f, 0x61, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, 0x6, 0x8, + 0xa, 0xc, 0xe, 0x10, 0x12, + 0x14, 0x16, 0x18, 0x1a, 0x1c, + 0x1e, 0x20, 0x22, 0x24, 0x26, + 0x28, 0x2a, 0x2c, 0x2e, 0x30, + 0x32, 0x34, 0x36, 0x38, 0x3a, + 0x3c, 0x3e, 0x40, 0x42, 0x44, + 0x46, 0x48, 0x4a, 0x4c, 0x4e, + }, + .zlx_nr = IPU7_PS_ZLX_DATA_RD_NUM, + .zlx_axi_pool = { + 0x00000f30, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, + .zlx_conf = { + 0x00030303, + 0x00010101, + 0x00010101, + 0x00030202, + 0x00010101, + 0x00010101, + 0x00010101, + 0x00030800, + 0x00030500, + 0x00020101, + 0x00042000, + 0x00031000, + 0x00042000, + 0x00031000, + 0x00020400, + 0x00010101, + }, + .uao_p_num = IPU7_PS_UAO_SRT_RD_PLANENUM, + .uao_p2tlb = { + 0x00000022, + 0x00000023, + 0x00000024, + 0x00000025, + 0x00000026, + 0x00000027, + 0x00000028, + 0x00000029, + 0x0000002a, + 0x0000002b, + 0x0000002c, + 0x0000002d, + 0x0000002e, + 0x0000002f, + 0x00000030, + 0x00000031, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0000001e, + 0x0000001f, + 0x00000020, + 0x00000021, + 0x00000032, + 0x00000033, + 0x00000034, + 0x00000035, + }, + }, + { + .name = "PS_DATA_WR", + .offset = IPU7_PS_MMU_SRT_WR_OFFSET, + .zlx_offset = IPU7_PS_ZLX_DATA_WR_OFFSET, + .uao_offset = IPU7_PS_UAO_SRT_WR_OFFSET, + .info_bits = 0x20004501, + .refill = 0x00002120, + .collapse_en_bitmap = 0x0, + .l1_block = IPU7_PS_MMU_SRT_WR_L1_BLOCKNR_REG, + .l2_block = IPU7_PS_MMU_SRT_WR_L2_BLOCKNR_REG, + .nr_l1streams = IPU7_PS_MMU_SRT_WR_STREAM_NUM, + .nr_l2streams = IPU7_PS_MMU_SRT_WR_STREAM_NUM, + .l1_block_sz = { + 0x0, 0x2, 0x6, 0xa, 0xc, + 0xe, 0x10, 0x12, 0x14, 0x16, + 0x18, 0x1a, 0x1c, 0x1e, 0x20, + 0x22, 0x24, 0x26, 0x32, 0x3a, + 0x3c, 0x3e, 0x4a, 0x52, 0x58, + 0x64, 0x6c, 0x72, 0x7e, 0x86, + 0x8c, 0x8d, 0x8e, 0x8f, 0x90, + 0x91, 0x92, 0x94, 0x96, 0x98, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, 0x6, 0x8, + 0xa, 0xc, 0xe, 0x10, 0x12, + 0x14, 0x16, 0x18, 0x1a, 0x1c, + 0x1e, 0x20, 0x22, 0x24, 0x26, + 0x28, 0x2a, 0x2c, 0x2e, 0x30, + 0x32, 0x34, 0x36, 0x38, 0x3a, + 0x3c, 0x3e, 0x40, 0x42, 0x44, + 0x46, 0x48, 0x4a, 0x4c, 0x4e, + }, + .zlx_nr = IPU7_PS_ZLX_DATA_WR_NUM, + .zlx_axi_pool = { + 0x00000f50, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + }, + .zlx_conf = { + 0x00010102, + 0x00030103, + 0x00030103, + 0x00010101, + 0x00010101, + 0x00030101, + 0x00010101, + 0x38010101, + 0x0, + 0x0, + 0x38010101, + 0x38010101, + 0x38010101, + 0x38010101, + 0x38010101, + 0x38010101, + 0x00010101, + 0x00042000, + 0x00031000, + 0x00010101, + 0x00010101, + 0x00042000, + 0x00031000, + 0x00031000, + 0x00042000, + 0x00031000, + 0x00031000, + 0x00042000, + 0x00031000, + 0x00031000, + 0x0, + 0x0, + }, + .uao_p_num = IPU7_PS_UAO_SRT_WR_PLANENUM, + .uao_p2tlb = { + 0x00000000, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00000007, + 0x00000008, + 0x00000009, + 0x0000000a, + 0x0000000b, + 0x0000000c, + 0x0000000d, + 0x0000000e, + 0x0000000f, + 0x00000010, + 0x00000011, + 0x00000012, + 0x00000013, + 0x00000014, + 0x00000015, + 0x00000016, + 0x00000017, + 0x00000018, + 0x00000019, + 0x0000001a, + 0x0000001b, + 0x0000001c, + 0x0000001d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0000001e, + 0x0000001f, + 0x00000020, + 0x00000021, + }, + }, + }, + .dmem_offset = IPU_PSYS_DMEM_OFFSET, + }, +}; + +static struct ipu_isys_internal_pdata ipu8_isys_ipdata = { + .csi2 = { + .gpreg = IPU8_IS_IO_CSI2_GPREGS_BASE, + }, + .hw_variant = { + .offset = IPU_UNIFIED_OFFSET, + .nr_mmus = IPU8_IS_MMU_NUM, + .mmu_hw = { + { + .name = "IS_FW_RD", + .offset = IPU8_IS_MMU_FW_RD_OFFSET, + .zlx_offset = IPU8_IS_ZLX_UC_RD_OFFSET, + .uao_offset = IPU8_IS_UAO_UC_RD_OFFSET, + .info_bits = 0x20005101, + .refill = 0x00002726, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU8_IS_MMU_FW_RD_L1_BLOCKNR_REG, + .l2_block = IPU8_IS_MMU_FW_RD_L2_BLOCKNR_REG, + .nr_l1streams = IPU8_IS_MMU_FW_RD_STREAM_NUM, + .nr_l2streams = IPU8_IS_MMU_FW_RD_STREAM_NUM, + .l1_block_sz = { + 0x0, 0x8, 0xa, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, + }, + .zlx_nr = IPU8_IS_ZLX_UC_RD_NUM, + .zlx_axi_pool = { + 0x00000f30, + }, + .zlx_en = { + 0, 1, 0, 0 + }, + .zlx_conf = { + 0, 2, 0, 0 + }, + .uao_p_num = IPU8_IS_UAO_UC_RD_PLANENUM, + .uao_p2tlb = { + 0x00000049, + 0x0000004c, + 0x0000004d, + 0x00000000, + }, + }, + { + .name = "IS_FW_WR", + .offset = IPU8_IS_MMU_FW_WR_OFFSET, + .zlx_offset = IPU8_IS_ZLX_UC_WR_OFFSET, + .uao_offset = IPU8_IS_UAO_UC_WR_OFFSET, + .info_bits = 0x20005001, + .refill = 0x00002524, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU8_IS_MMU_FW_WR_L1_BLOCKNR_REG, + .l2_block = IPU8_IS_MMU_FW_WR_L2_BLOCKNR_REG, + .nr_l1streams = IPU8_IS_MMU_FW_WR_STREAM_NUM, + .nr_l2streams = IPU8_IS_MMU_FW_WR_STREAM_NUM, + .l1_block_sz = { + 0x0, 0x8, 0xa, + }, + .l2_block_sz = { + 0x0, 0x2, 0x4, + }, + .zlx_nr = IPU8_IS_ZLX_UC_WR_NUM, + .zlx_axi_pool = { + 0x00000f20, + }, + .zlx_en = { + 0, 1, 1, 0, + }, + .zlx_conf = { + 0x0, + 0x2, + 0x2, + 0x0, + }, + .uao_p_num = IPU8_IS_UAO_UC_WR_PLANENUM, + .uao_p2tlb = { + 0x00000049, + 0x0000004a, + 0x0000004b, + 0x00000000, + }, + }, + { + .name = "IS_DATA_WR_ISOC", + .offset = IPU8_IS_MMU_M0_OFFSET, + .zlx_offset = IPU8_IS_ZLX_M0_OFFSET, + .uao_offset = IPU8_IS_UAO_M0_WR_OFFSET, + .info_bits = 0x20004e01, + .refill = 0x00002120, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU8_IS_MMU_M0_L1_BLOCKNR_REG, + .l2_block = IPU8_IS_MMU_M0_L2_BLOCKNR_REG, + .nr_l1streams = IPU8_IS_MMU_M0_STREAM_NUM, + .nr_l2streams = IPU8_IS_MMU_M0_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + }, + .zlx_nr = IPU8_IS_ZLX_M0_NUM, + .zlx_axi_pool = { + 0x00000f10, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }, + .zlx_conf = { + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + }, + .uao_p_num = IPU8_IS_UAO_M0_WR_PLANENUM, + .uao_p2tlb = { + 0x0000003b, + 0x0000003c, + 0x0000003d, + 0x0000003e, + 0x0000003b, + 0x0000003c, + 0x0000003d, + 0x0000003e, + 0x0000003b, + 0x0000003c, + 0x0000003d, + 0x0000003e, + 0x0000003b, + 0x0000003c, + 0x0000003d, + 0x0000003e, + }, + }, + { + .name = "IS_DATA_WR_SNOOP", + .offset = IPU8_IS_MMU_M1_OFFSET, + .zlx_offset = IPU8_IS_ZLX_M1_OFFSET, + .uao_offset = IPU8_IS_UAO_M1_WR_OFFSET, + .info_bits = 0x20004f01, + .refill = 0x00002322, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU8_IS_MMU_M1_L1_BLOCKNR_REG, + .l2_block = IPU8_IS_MMU_M1_L2_BLOCKNR_REG, + .nr_l1streams = IPU8_IS_MMU_M1_STREAM_NUM, + .nr_l2streams = IPU8_IS_MMU_M1_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + }, + .zlx_nr = IPU8_IS_ZLX_M1_NUM, + .zlx_axi_pool = { + 0x00000f20, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }, + .zlx_conf = { + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + }, + .uao_p_num = IPU8_IS_UAO_M1_WR_PLANENUM, + .uao_p2tlb = { + 0x0000003f, + 0x00000040, + 0x00000041, + 0x00000042, + 0x0000003f, + 0x00000040, + 0x00000041, + 0x00000042, + 0x0000003f, + 0x00000040, + 0x00000041, + 0x00000042, + 0x0000003f, + 0x00000040, + 0x00000041, + 0x00000042, + }, + }, + { + .name = "IS_UPIPE", + .offset = IPU8_IS_MMU_UPIPE_OFFSET, + .zlx_offset = IPU8_IS_ZLX_UPIPE_OFFSET, + .uao_offset = IPU8_IS_UAO_UPIPE_OFFSET, + .info_bits = 0x20005201, + .refill = 0x00002928, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU8_IS_MMU_UPIPE_L1_BLOCKNR_REG, + .l2_block = IPU8_IS_MMU_UPIPE_L2_BLOCKNR_REG, + .nr_l1streams = IPU8_IS_MMU_UPIPE_STREAM_NUM, + .nr_l2streams = IPU8_IS_MMU_UPIPE_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + }, + .zlx_nr = IPU8_IS_ZLX_UPIPE_NUM, + .zlx_axi_pool = { + 0x00000f20, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, + }, + .zlx_conf = { + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + 0x3, + }, + .uao_p_num = IPU8_IS_UAO_UPIPE_PLANENUM, + .uao_p2tlb = { + 0x00000043, + 0x00000044, + 0x00000045, + 0x00000046, + 0x00000047, + 0x00000048, + }, + }, + }, + .cdc_fifos = 3, + .cdc_fifo_threshold = {6, 8, 2}, + .dmem_offset = IPU_ISYS_DMEM_OFFSET, + .spc_offset = IPU_ISYS_SPC_OFFSET, + }, + .isys_dma_overshoot = IPU_ISYS_OVERALLOC_MIN, +}; + +static struct ipu_psys_internal_pdata ipu8_psys_ipdata = { + .hw_variant = { + .offset = IPU_UNIFIED_OFFSET, + .nr_mmus = IPU8_PS_MMU_NUM, + .mmu_hw = { + { + .name = "PS_FW_RD", + .offset = IPU8_PS_MMU_FW_RD_OFFSET, + .zlx_offset = IPU8_PS_ZLX_FW_RD_OFFSET, + .uao_offset = IPU8_PS_UAO_FW_RD_OFFSET, + .info_bits = 0x20003a01, + .refill = 0x00002726, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU8_PS_MMU_FW_RD_L1_BLOCKNR_REG, + .l2_block = IPU8_PS_MMU_FW_RD_L2_BLOCKNR_REG, + .nr_l1streams = IPU8_PS_MMU_FW_RD_STREAM_NUM, + .nr_l2streams = IPU8_PS_MMU_FW_RD_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000008, + 0x0000000a, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x00000018, + 0x00000018, + 0x00000018, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + }, + .zlx_nr = IPU8_PS_ZLX_FW_RD_NUM, + .zlx_axi_pool = { + 0x00000f30, + }, + .zlx_en = { + 0, 1, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, + }, + .zlx_conf = { + 0x0, + 0x2, + 0x0, + 0x0, + 0x2, + 0x2, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + }, + .uao_p_num = IPU8_PS_UAO_FW_RD_PLANENUM, + .uao_p2tlb = { + 0x0000002d, + 0x00000032, + 0x00000033, + 0x00000030, + 0x00000034, + 0x00000035, + 0x00000036, + 0x00000031, + 0x0, + 0x0, + 0x0, + 0x0, + }, + }, + { + .name = "PS_FW_WR", + .offset = IPU8_PS_MMU_FW_WR_OFFSET, + .zlx_offset = IPU8_PS_ZLX_FW_WR_OFFSET, + .uao_offset = IPU8_PS_UAO_FW_WR_OFFSET, + .info_bits = 0x20003901, + .refill = 0x00002524, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU8_PS_MMU_FW_WR_L1_BLOCKNR_REG, + .l2_block = IPU8_PS_MMU_FW_WR_L2_BLOCKNR_REG, + .nr_l1streams = IPU8_PS_MMU_FW_WR_STREAM_NUM, + .nr_l2streams = IPU8_PS_MMU_FW_WR_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000010, + 0x00000010, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + }, + .zlx_nr = IPU8_PS_ZLX_FW_WR_NUM, + .zlx_axi_pool = { + 0x00000f20, + }, + .zlx_en = { + 0, 1, 1, 0, 0, 0, 0, 0, + }, + .zlx_conf = { + 0x0, 0x2, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, + }, + .uao_p_num = IPU8_PS_UAO_FW_WR_PLANENUM, + .uao_p2tlb = { + 0x0000002d, + 0x0000002e, + 0x0000002f, + 0x00000030, + 0x00000031, + 0x0, + 0x0, + 0x0, + }, + }, + { + .name = "PS_DATA_RD", + .offset = IPU8_PS_MMU_SRT_RD_OFFSET, + .zlx_offset = IPU8_PS_ZLX_DATA_RD_OFFSET, + .uao_offset = IPU8_PS_UAO_SRT_RD_OFFSET, + .info_bits = 0x20003801, + .refill = 0x00002322, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU8_PS_MMU_SRT_RD_L1_BLOCKNR_REG, + .l2_block = IPU8_PS_MMU_SRT_RD_L2_BLOCKNR_REG, + .nr_l1streams = IPU8_PS_MMU_SRT_RD_STREAM_NUM, + .nr_l2streams = IPU8_PS_MMU_SRT_RD_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000014, + 0x00000018, + 0x0000001c, + 0x0000001e, + 0x00000022, + 0x00000024, + 0x00000026, + 0x00000028, + 0x0000002a, + 0x0000002c, + 0x0000002e, + 0x00000030, + 0x00000032, + 0x00000036, + 0x0000003a, + 0x0000003c, + 0x0000003c, + 0x0000003c, + 0x0000003c, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + 0x00000020, + 0x00000022, + 0x00000024, + 0x00000026, + 0x00000028, + 0x0000002a, + 0x0000002c, + 0x0000002e, + 0x00000030, + 0x00000032, + }, + .zlx_nr = IPU8_PS_ZLX_DATA_RD_NUM, + .zlx_axi_pool = { + 0x00000f30, + }, + .zlx_en = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, + }, + .zlx_conf = { + 0x6, 0x3, 0x3, 0x6, + 0x2, 0x2, 0x6, 0x6, + 0x6, 0x3, 0x6, 0x3, + 0x3, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x6, + 0x6, 0x3, 0x0, 0x0, + 0x0, 0x0, + }, + .uao_p_num = IPU8_PS_UAO_SRT_RD_PLANENUM, + .uao_p2tlb = { + 0x00000017, + 0x00000018, + 0x00000019, + 0x0000001a, + 0x0000001b, + 0x0000001c, + 0x0000001d, + 0x0000001e, + 0x0000001f, + 0x00000020, + 0x00000021, + 0x00000022, + 0x00000023, + 0x00000024, + 0x00000025, + 0x00000026, + 0x00000027, + 0x00000028, + 0x00000029, + 0x0000002a, + 0x0000002b, + 0x0000002c, + 0x0, + 0x0, + 0x0, + 0x0, + }, + }, + { + .name = "PS_DATA_WR", + .offset = IPU8_PS_MMU_SRT_WR_OFFSET, + .zlx_offset = IPU8_PS_ZLX_DATA_WR_OFFSET, + .uao_offset = IPU8_PS_UAO_SRT_WR_OFFSET, + .info_bits = 0x20003701, + .refill = 0x00002120, + .collapse_en_bitmap = 0x1, + .at_sp_arb_cfg = 0x1, + .l1_block = IPU8_PS_MMU_SRT_WR_L1_BLOCKNR_REG, + .l2_block = IPU8_PS_MMU_SRT_WR_L2_BLOCKNR_REG, + .nr_l1streams = IPU8_PS_MMU_SRT_WR_STREAM_NUM, + .nr_l2streams = IPU8_PS_MMU_SRT_WR_STREAM_NUM, + .l1_block_sz = { + 0x00000000, + 0x00000002, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001c, + 0x0000001e, + 0x00000022, + 0x00000024, + 0x00000028, + 0x0000002a, + 0x0000002e, + 0x00000030, + 0x00000032, + 0x00000036, + 0x00000038, + 0x0000003a, + 0x0000003a, + 0x0000003a, + }, + .l2_block_sz = { + 0x00000000, + 0x00000002, + 0x00000004, + 0x00000006, + 0x00000008, + 0x0000000a, + 0x0000000c, + 0x0000000e, + 0x00000010, + 0x00000012, + 0x00000014, + 0x00000016, + 0x00000018, + 0x0000001a, + 0x0000001c, + 0x0000001e, + 0x00000020, + 0x00000022, + 0x00000024, + 0x00000026, + 0x00000028, + 0x0000002a, + 0x0000002c, + 0x0000002e, + 0x00000030, + 0x00000032, + }, + .zlx_nr = IPU8_PS_ZLX_DATA_WR_NUM, + .zlx_axi_pool = { + 0x00000f50, + }, + .zlx_en = { + 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, + }, + .zlx_conf = { + 0x3, + 0x6, + 0x38000002, + 0x38000000, + 0x3, + 0x38000002, + 0x38000002, + 0x38000002, + 0x38000002, + 0x38000002, + 0x38000002, + 0x6, + 0x3, + 0x6, + 0x3, + 0x6, + 0x3, + 0x6, + 0x3, + 0x3, + 0x6, + 0x3, + 0x3, + 0x0, + 0x0, + 0x0, + }, + .uao_p_num = IPU8_PS_UAO_SRT_WR_PLANENUM, + .uao_p2tlb = { + 0x00000000, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00000007, + 0x00000008, + 0x00000009, + 0x0000000a, + 0x0000000b, + 0x0000000c, + 0x0000000d, + 0x0000000e, + 0x0000000f, + 0x00000010, + 0x00000011, + 0x00000012, + 0x00000013, + 0x00000014, + 0x00000015, + 0x00000016, + 0x00000000, + 0x00000000, + 0x00000000, + }, + }, + }, + .dmem_offset = IPU_PSYS_DMEM_OFFSET, + }, +}; + +static const struct ipu_buttress_ctrl ipu7_isys_buttress_ctrl = { + .subsys_id = IPU_IS, + .ratio = IPU7_IS_FREQ_CTL_DEFAULT_RATIO, + .ratio_shift = IPU_FREQ_CTL_RATIO_SHIFT, + .cdyn = IPU_FREQ_CTL_CDYN, + .cdyn_shift = IPU_FREQ_CTL_CDYN_SHIFT, + .freq_ctl = BUTTRESS_REG_IS_WORKPOINT_REQ, + .pwr_sts_shift = IPU_BUTTRESS_PWR_STATE_IS_PWR_SHIFT, + .pwr_sts_mask = IPU_BUTTRESS_PWR_STATE_IS_PWR_MASK, + .pwr_sts_on = IPU_BUTTRESS_PWR_STATE_UP_DONE, + .pwr_sts_off = IPU_BUTTRESS_PWR_STATE_DN_DONE, + .ovrd_clk = BUTTRESS_OVERRIDE_IS_CLK, + .own_clk_ack = BUTTRESS_OWN_ACK_IS_CLK, +}; + +static const struct ipu_buttress_ctrl ipu7_psys_buttress_ctrl = { + .subsys_id = IPU_PS, + .ratio = IPU7_PS_FREQ_CTL_DEFAULT_RATIO, + .ratio_shift = IPU_FREQ_CTL_RATIO_SHIFT, + .cdyn = IPU_FREQ_CTL_CDYN, + .cdyn_shift = IPU_FREQ_CTL_CDYN_SHIFT, + .freq_ctl = BUTTRESS_REG_PS_WORKPOINT_REQ, + .pwr_sts_shift = IPU_BUTTRESS_PWR_STATE_PS_PWR_SHIFT, + .pwr_sts_mask = IPU_BUTTRESS_PWR_STATE_PS_PWR_MASK, + .pwr_sts_on = IPU_BUTTRESS_PWR_STATE_UP_DONE, + .pwr_sts_off = IPU_BUTTRESS_PWR_STATE_DN_DONE, + .ovrd_clk = BUTTRESS_OVERRIDE_PS_CLK, + .own_clk_ack = BUTTRESS_OWN_ACK_PS_CLK, +}; + +static const struct ipu_buttress_ctrl ipu8_isys_buttress_ctrl = { + .subsys_id = IPU_IS, + .ratio = IPU8_IS_FREQ_CTL_DEFAULT_RATIO, + .ratio_shift = IPU_FREQ_CTL_RATIO_SHIFT, + .cdyn = IPU_FREQ_CTL_CDYN, + .cdyn_shift = IPU_FREQ_CTL_CDYN_SHIFT, + .freq_ctl = BUTTRESS_REG_IS_WORKPOINT_REQ, + .pwr_sts_shift = IPU_BUTTRESS_PWR_STATE_IS_PWR_SHIFT, + .pwr_sts_mask = IPU_BUTTRESS_PWR_STATE_IS_PWR_MASK, + .pwr_sts_on = IPU_BUTTRESS_PWR_STATE_UP_DONE, + .pwr_sts_off = IPU_BUTTRESS_PWR_STATE_DN_DONE, +}; + +static const struct ipu_buttress_ctrl ipu8_psys_buttress_ctrl = { + .subsys_id = IPU_PS, + .ratio = IPU8_PS_FREQ_CTL_DEFAULT_RATIO, + .ratio_shift = IPU_FREQ_CTL_RATIO_SHIFT, + .cdyn = IPU_FREQ_CTL_CDYN, + .cdyn_shift = IPU_FREQ_CTL_CDYN_SHIFT, + .freq_ctl = BUTTRESS_REG_PS_WORKPOINT_REQ, + .pwr_sts_shift = IPU_BUTTRESS_PWR_STATE_PS_PWR_SHIFT, + .pwr_sts_mask = IPU_BUTTRESS_PWR_STATE_PS_PWR_MASK, + .pwr_sts_on = IPU_BUTTRESS_PWR_STATE_UP_DONE, + .pwr_sts_off = IPU_BUTTRESS_PWR_STATE_DN_DONE, + .own_clk_ack = BUTTRESS_OWN_ACK_PS_PLL, +}; + +void ipu_internal_pdata_init(struct ipu_isys_internal_pdata *isys_ipdata, + struct ipu_psys_internal_pdata *psys_ipdata) +{ + isys_ipdata->csi2.nports = ARRAY_SIZE(ipu7_csi_offsets); + isys_ipdata->csi2.offsets = ipu7_csi_offsets; + isys_ipdata->num_parallel_streams = IPU7_ISYS_NUM_STREAMS; + psys_ipdata->hw_variant.spc_offset = IPU7_PSYS_SPC_OFFSET; +} + +static int ipu7_isys_check_fwnode_graph(struct fwnode_handle *fwnode) +{ + struct fwnode_handle *endpoint; + + if (IS_ERR_OR_NULL(fwnode)) + return -EINVAL; + + endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL); + if (endpoint) { + fwnode_handle_put(endpoint); + return 0; + } + + return ipu7_isys_check_fwnode_graph(fwnode->secondary); +} + +static struct ipu7_bus_device * +ipu7_isys_init(struct pci_dev *pdev, struct device *parent, + const struct ipu_buttress_ctrl *ctrl, void __iomem *base, + const struct ipu_isys_internal_pdata *ipdata, + unsigned int nr) +{ + struct fwnode_handle *fwnode = dev_fwnode(&pdev->dev); + struct ipu7_bus_device *isys_adev; + struct device *dev = &pdev->dev; + struct ipu7_isys_pdata *pdata; + int ret; + + ret = ipu7_isys_check_fwnode_graph(fwnode); + if (ret) { + if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary)) { + dev_err(dev, + "fwnode graph has no endpoints connection\n"); + return ERR_PTR(-EINVAL); + } + + ret = ipu_bridge_init(dev, ipu_bridge_parse_ssdb); + if (ret) { + dev_err_probe(dev, ret, "IPU bridge init failed\n"); + return ERR_PTR(ret); + } + } + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + pdata->base = base; + pdata->ipdata = ipdata; + + isys_adev = ipu7_bus_initialize_device(pdev, parent, pdata, ctrl, + IPU_ISYS_NAME); + if (IS_ERR(isys_adev)) { + dev_err_probe(dev, PTR_ERR(isys_adev), + "ipu7_bus_initialize_device isys failed\n"); + kfree(pdata); + return ERR_CAST(isys_adev); + } + + isys_adev->mmu = ipu7_mmu_init(dev, base, ISYS_MMID, + &ipdata->hw_variant); + if (IS_ERR(isys_adev->mmu)) { + dev_err_probe(dev, PTR_ERR(isys_adev->mmu), + "ipu7_mmu_init(isys_adev->mmu) failed\n"); + put_device(&isys_adev->auxdev.dev); + kfree(pdata); + return ERR_CAST(isys_adev->mmu); + } + + isys_adev->mmu->dev = &isys_adev->auxdev.dev; + isys_adev->subsys = IPU_IS; + + ret = ipu7_bus_add_device(isys_adev); + if (ret) { + kfree(pdata); + return ERR_PTR(ret); + } + + return isys_adev; +} + +static struct ipu7_bus_device * +ipu7_psys_init(struct pci_dev *pdev, struct device *parent, + const struct ipu_buttress_ctrl *ctrl, void __iomem *base, + const struct ipu_psys_internal_pdata *ipdata, unsigned int nr) +{ + struct ipu7_bus_device *psys_adev; + struct ipu7_psys_pdata *pdata; + int ret; + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + pdata->base = base; + pdata->ipdata = ipdata; + + psys_adev = ipu7_bus_initialize_device(pdev, parent, pdata, ctrl, + IPU_PSYS_NAME); + if (IS_ERR(psys_adev)) { + dev_err_probe(&pdev->dev, PTR_ERR(psys_adev), + "ipu7_bus_initialize_device psys failed\n"); + kfree(pdata); + return ERR_CAST(psys_adev); + } + + psys_adev->mmu = ipu7_mmu_init(&pdev->dev, base, PSYS_MMID, + &ipdata->hw_variant); + if (IS_ERR(psys_adev->mmu)) { + dev_err_probe(&pdev->dev, PTR_ERR(psys_adev->mmu), + "ipu7_mmu_init(psys_adev->mmu) failed\n"); + put_device(&psys_adev->auxdev.dev); + kfree(pdata); + return ERR_CAST(psys_adev->mmu); + } + + psys_adev->mmu->dev = &psys_adev->auxdev.dev; + psys_adev->subsys = IPU_PS; + + ret = ipu7_bus_add_device(psys_adev); + if (ret) { + kfree(pdata); + return ERR_PTR(ret); + } + + return psys_adev; +} + +static struct ia_gofo_msg_log_info_ts fw_error_log[IPU_SUBSYS_NUM]; +void ipu7_dump_fw_error_log(const struct ipu7_bus_device *adev) +{ + void __iomem *reg = adev->isp->base + ((adev->subsys == IPU_IS) ? + BUTTRESS_REG_FW_GP24 : + BUTTRESS_REG_FW_GP8); + + memcpy_fromio(&fw_error_log[adev->subsys], reg, + sizeof(fw_error_log[adev->subsys])); +} +EXPORT_SYMBOL_NS_GPL(ipu7_dump_fw_error_log, "INTEL_IPU7"); + +static int ipu7_pci_config_setup(struct pci_dev *dev) +{ + u16 pci_command; + int ret; + + pci_read_config_word(dev, PCI_COMMAND, &pci_command); + pci_command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + pci_write_config_word(dev, PCI_COMMAND, pci_command); + + ret = pci_enable_msi(dev); + if (ret) + dev_err(&dev->dev, "Failed to enable msi (%d)\n", ret); + + return ret; +} + +static int ipu7_map_fw_code_region(struct ipu7_bus_device *sys, + void *data, size_t size) +{ + struct device *dev = &sys->auxdev.dev; + struct ipu7_bus_device *adev = to_ipu7_bus_device(dev); + struct sg_table *sgt = &sys->fw_sgt; + struct ipu7_device *isp = adev->isp; + struct pci_dev *pdev = isp->pdev; + unsigned long n_pages, i; + unsigned long attr = 0; + struct page **pages; + int ret; + + n_pages = PFN_UP(size); + + pages = kmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL); + if (!pages) + return -ENOMEM; + + for (i = 0; i < n_pages; i++) { + struct page *p = vmalloc_to_page(data); + + if (!p) { + ret = -ENODEV; + goto out; + } + + pages[i] = p; + data += PAGE_SIZE; + } + + ret = sg_alloc_table_from_pages(sgt, pages, n_pages, 0, size, + GFP_KERNEL); + if (ret) { + ret = -ENOMEM; + goto out; + } + + if (!isp->secure_mode) + attr |= DMA_ATTR_RESERVE_REGION; + + ret = dma_map_sgtable(&pdev->dev, sgt, DMA_BIDIRECTIONAL, 0); + if (ret < 0) { + dev_err(dev, "map fw code[%lu pages %u nents] failed\n", + n_pages, sgt->nents); + ret = -ENOMEM; + sg_free_table(sgt); + goto out; + } + + ret = ipu7_dma_map_sgtable(sys, sgt, DMA_BIDIRECTIONAL, attr); + if (ret) { + dma_unmap_sgtable(&pdev->dev, sgt, DMA_BIDIRECTIONAL, 0); + sg_free_table(sgt); + goto out; + } + + ipu7_dma_sync_sgtable(sys, sgt); + + dev_dbg(dev, "fw code region mapped at 0x%pad entries %d\n", + &sgt->sgl->dma_address, sgt->nents); + +out: + kfree(pages); + + return ret; +} + +static void ipu7_unmap_fw_code_region(struct ipu7_bus_device *sys) +{ + struct pci_dev *pdev = sys->isp->pdev; + struct sg_table *sgt = &sys->fw_sgt; + + ipu7_dma_unmap_sgtable(sys, sgt, DMA_BIDIRECTIONAL, 0); + dma_unmap_sgtable(&pdev->dev, sgt, DMA_BIDIRECTIONAL, 0); + sg_free_table(sgt); +} + +static int ipu7_init_fw_code_region_by_sys(struct ipu7_bus_device *sys, + const char *sys_name) +{ + struct device *dev = &sys->auxdev.dev; + struct ipu7_device *isp = sys->isp; + int ret; + + /* Copy FW binaries to specific location. */ + ret = ipu7_cpd_copy_binary(isp->cpd_fw->data, sys_name, + isp->fw_code_region, &sys->fw_entry); + if (ret) { + dev_err(dev, "%s binary not found.\n", sys_name); + return ret; + } + + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + dev_err(dev, "Failed to get runtime PM\n"); + return ret; + } + + ret = ipu7_mmu_hw_init(sys->mmu); + if (ret) { + dev_err(dev, "Failed to set mmu hw\n"); + pm_runtime_put(dev); + return ret; + } + + /* Map code region. */ + ret = ipu7_map_fw_code_region(sys, isp->fw_code_region, + IPU_FW_CODE_REGION_SIZE); + if (ret) + dev_err(dev, "Failed to map fw code region for %s.\n", + sys_name); + + ipu7_mmu_hw_cleanup(sys->mmu); + pm_runtime_put(dev); + + return ret; +} + +static int ipu7_init_fw_code_region(struct ipu7_device *isp) +{ + int ret; + + /* + * Allocate and map memory for FW execution. + * Not required in secure mode, in which FW runs in IMR. + */ + isp->fw_code_region = vmalloc(IPU_FW_CODE_REGION_SIZE); + if (!isp->fw_code_region) + return -ENOMEM; + + ret = ipu7_init_fw_code_region_by_sys(isp->isys, "isys"); + if (ret) + goto fail_init; + + ret = ipu7_init_fw_code_region_by_sys(isp->psys, "psys"); + if (ret) + goto fail_init; + + return 0; + +fail_init: + vfree(isp->fw_code_region); + + return ret; +} + +static int ipu7_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct ipu_buttress_ctrl *isys_ctrl = NULL, *psys_ctrl = NULL; + struct fwnode_handle *fwnode = dev_fwnode(&pdev->dev); + const struct ipu_buttress_ctrl *isys_buttress_ctrl; + const struct ipu_buttress_ctrl *psys_buttress_ctrl; + struct ipu_isys_internal_pdata *isys_ipdata; + struct ipu_psys_internal_pdata *psys_ipdata; + unsigned int dma_mask = IPU_DMA_MASK; + struct device *dev = &pdev->dev; + void __iomem *isys_base = NULL; + void __iomem *psys_base = NULL; + phys_addr_t phys, pb_phys; + struct ipu7_device *isp; + u32 is_es; + int ret; + + if (!fwnode || fwnode_property_read_u32(fwnode, "is_es", &is_es)) + is_es = 0; + + isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL); + if (!isp) + return -ENOMEM; + + dev_set_name(dev, "intel-ipu7"); + isp->pdev = pdev; + INIT_LIST_HEAD(&isp->devices); + + ret = pcim_enable_device(pdev); + if (ret) + return dev_err_probe(dev, ret, "Enable PCI device failed\n"); + + dev_info(dev, "Device 0x%x (rev: 0x%x)\n", + pdev->device, pdev->revision); + + phys = pci_resource_start(pdev, IPU_PCI_BAR); + pb_phys = pci_resource_start(pdev, IPU_PCI_PBBAR); + dev_info(dev, "IPU7 PCI BAR0 base %pap BAR2 base %pap\n", + &phys, &pb_phys); + + isp->base = pcim_iomap_region(pdev, IPU_PCI_BAR, IPU_NAME); + if (IS_ERR(isp->base)) + return dev_err_probe(dev, PTR_ERR(isp->base), + "Failed to I/O memory remapping bar %u\n", + IPU_PCI_BAR); + + isp->pb_base = pcim_iomap_region(pdev, IPU_PCI_PBBAR, IPU_NAME); + if (IS_ERR(isp->pb_base)) + return dev_err_probe(dev, PTR_ERR(isp->pb_base), + "Failed to I/O memory remapping bar %u\n", + IPU_PCI_PBBAR); + + dev_info(dev, "IPU7 PCI BAR0 mapped at %p\n BAR2 mapped at %p\n", + isp->base, isp->pb_base); + + pci_set_drvdata(pdev, isp); + pci_set_master(pdev); + + switch (id->device) { + case IPU7_PCI_ID: + isp->hw_ver = IPU_VER_7; + isp->cpd_fw_name = IPU7_FIRMWARE_NAME; + isys_ipdata = &ipu7_isys_ipdata; + psys_ipdata = &ipu7_psys_ipdata; + isys_buttress_ctrl = &ipu7_isys_buttress_ctrl; + psys_buttress_ctrl = &ipu7_psys_buttress_ctrl; + break; + case IPU7P5_PCI_ID: + isp->hw_ver = IPU_VER_7P5; + isp->cpd_fw_name = IPU7P5_FIRMWARE_NAME; + isys_ipdata = &ipu7p5_isys_ipdata; + psys_ipdata = &ipu7p5_psys_ipdata; + isys_buttress_ctrl = &ipu7_isys_buttress_ctrl; + psys_buttress_ctrl = &ipu7_psys_buttress_ctrl; + break; + case IPU8_PCI_ID: + isp->hw_ver = IPU_VER_8; + isp->cpd_fw_name = IPU8_FIRMWARE_NAME; + isys_ipdata = &ipu8_isys_ipdata; + psys_ipdata = &ipu8_psys_ipdata; + isys_buttress_ctrl = &ipu8_isys_buttress_ctrl; + psys_buttress_ctrl = &ipu8_psys_buttress_ctrl; + break; + default: + WARN(1, "Unsupported IPU device"); + return -ENODEV; + } + + ipu_internal_pdata_init(isys_ipdata, psys_ipdata); + + isys_base = isp->base + isys_ipdata->hw_variant.offset; + psys_base = isp->base + psys_ipdata->hw_variant.offset; + + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(dma_mask)); + if (ret) + return dev_err_probe(dev, ret, "Failed to set DMA mask\n"); + + dma_set_max_seg_size(dev, UINT_MAX); + + ret = ipu7_pci_config_setup(pdev); + if (ret) + return ret; + + ret = ipu_buttress_init(isp); + if (ret) + return ret; + + dev_info(dev, "firmware cpd file: %s\n", isp->cpd_fw_name); + + ret = request_firmware(&isp->cpd_fw, isp->cpd_fw_name, dev); + if (ret) { + dev_err_probe(dev, ret, + "Requesting signed firmware %s failed\n", + isp->cpd_fw_name); + goto buttress_exit; + } + + ret = ipu7_cpd_validate_cpd_file(isp, isp->cpd_fw->data, + isp->cpd_fw->size); + if (ret) { + dev_err_probe(dev, ret, "Failed to validate cpd\n"); + goto out_ipu_bus_del_devices; + } + + isys_ctrl = devm_kmemdup(dev, isys_buttress_ctrl, + sizeof(*isys_buttress_ctrl), GFP_KERNEL); + if (!isys_ctrl) { + ret = -ENOMEM; + goto out_ipu_bus_del_devices; + } + + isp->isys = ipu7_isys_init(pdev, dev, isys_ctrl, isys_base, + isys_ipdata, 0); + if (IS_ERR(isp->isys)) { + ret = PTR_ERR(isp->isys); + goto out_ipu_bus_del_devices; + } + + psys_ctrl = devm_kmemdup(dev, psys_buttress_ctrl, + sizeof(*psys_buttress_ctrl), GFP_KERNEL); + if (!psys_ctrl) { + ret = -ENOMEM; + goto out_ipu_bus_del_devices; + } + + isp->psys = ipu7_psys_init(pdev, &isp->isys->auxdev.dev, + psys_ctrl, psys_base, + psys_ipdata, 0); + if (IS_ERR(isp->psys)) { + ret = PTR_ERR(isp->psys); + goto out_ipu_bus_del_devices; + } + + ret = devm_request_threaded_irq(dev, pdev->irq, + ipu_buttress_isr, + ipu_buttress_isr_threaded, + IRQF_SHARED, IPU_NAME, isp); + if (ret) + goto out_ipu_bus_del_devices; + + if (!isp->secure_mode) { + ret = ipu7_init_fw_code_region(isp); + if (ret) + goto out_ipu_bus_del_devices; + } else { + ret = pm_runtime_get_sync(&isp->psys->auxdev.dev); + if (ret < 0) { + dev_err(&isp->psys->auxdev.dev, + "Failed to get runtime PM\n"); + goto out_ipu_bus_del_devices; + } + + ret = ipu7_mmu_hw_init(isp->psys->mmu); + if (ret) { + dev_err_probe(&isp->pdev->dev, ret, + "Failed to init MMU hardware\n"); + goto out_ipu_bus_del_devices; + } + + ret = ipu7_map_fw_code_region(isp->psys, + (void *)isp->cpd_fw->data, + isp->cpd_fw->size); + if (ret) { + dev_err_probe(&isp->pdev->dev, ret, + "failed to map fw image\n"); + goto out_ipu_bus_del_devices; + } + + ret = ipu_buttress_authenticate(isp); + if (ret) { + dev_err_probe(&isp->pdev->dev, ret, + "FW authentication failed\n"); + goto out_ipu_bus_del_devices; + } + + ipu7_mmu_hw_cleanup(isp->psys->mmu); + pm_runtime_put(&isp->psys->auxdev.dev); + } + + pm_runtime_put_noidle(dev); + pm_runtime_allow(dev); + + isp->ipu7_bus_ready_to_probe = true; + + return 0; + +out_ipu_bus_del_devices: + if (!IS_ERR_OR_NULL(isp->isys) && isp->isys->fw_sgt.nents) + ipu7_unmap_fw_code_region(isp->isys); + if (!IS_ERR_OR_NULL(isp->psys) && isp->psys->fw_sgt.nents) + ipu7_unmap_fw_code_region(isp->psys); + if (!IS_ERR_OR_NULL(isp->psys) && !IS_ERR_OR_NULL(isp->psys->mmu)) + ipu7_mmu_cleanup(isp->psys->mmu); + if (!IS_ERR_OR_NULL(isp->isys) && !IS_ERR_OR_NULL(isp->isys->mmu)) + ipu7_mmu_cleanup(isp->isys->mmu); + if (!IS_ERR_OR_NULL(isp->psys)) + pm_runtime_put(&isp->psys->auxdev.dev); + ipu7_bus_del_devices(pdev); + release_firmware(isp->cpd_fw); +buttress_exit: + ipu_buttress_exit(isp); + + return ret; +} + +static void ipu7_pci_remove(struct pci_dev *pdev) +{ + struct ipu7_device *isp = pci_get_drvdata(pdev); + + if (!IS_ERR_OR_NULL(isp->isys) && isp->isys->fw_sgt.nents) + ipu7_unmap_fw_code_region(isp->isys); + if (!IS_ERR_OR_NULL(isp->psys) && isp->psys->fw_sgt.nents) + ipu7_unmap_fw_code_region(isp->psys); + + if (!IS_ERR_OR_NULL(isp->fw_code_region)) + vfree(isp->fw_code_region); + + ipu7_bus_del_devices(pdev); + + pm_runtime_forbid(&pdev->dev); + pm_runtime_get_noresume(&pdev->dev); + + ipu_buttress_exit(isp); + + release_firmware(isp->cpd_fw); + + ipu7_mmu_cleanup(isp->psys->mmu); + ipu7_mmu_cleanup(isp->isys->mmu); +} + +static void ipu7_pci_reset_prepare(struct pci_dev *pdev) +{ + struct ipu7_device *isp = pci_get_drvdata(pdev); + + dev_warn(&pdev->dev, "FLR prepare\n"); + pm_runtime_forbid(&isp->pdev->dev); +} + +static void ipu7_pci_reset_done(struct pci_dev *pdev) +{ + struct ipu7_device *isp = pci_get_drvdata(pdev); + + ipu_buttress_restore(isp); + if (isp->secure_mode) + ipu_buttress_reset_authentication(isp); + + isp->ipc_reinit = true; + pm_runtime_allow(&isp->pdev->dev); + + dev_warn(&pdev->dev, "FLR completed\n"); +} + +/* + * PCI base driver code requires driver to provide these to enable + * PCI device level PM state transitions (D0<->D3) + */ +static int ipu7_suspend(struct device *dev) +{ + return 0; +} + +static int ipu7_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct ipu7_device *isp = pci_get_drvdata(pdev); + struct ipu_buttress *b = &isp->buttress; + int ret; + + isp->secure_mode = ipu_buttress_get_secure_mode(isp); + dev_info(dev, "IPU7 in %s mode\n", + isp->secure_mode ? "secure" : "non-secure"); + + ipu_buttress_restore(isp); + + ret = ipu_buttress_ipc_reset(isp, &b->cse); + if (ret) + dev_err(dev, "IPC reset protocol failed!\n"); + + ret = pm_runtime_get_sync(&isp->psys->auxdev.dev); + if (ret < 0) { + dev_err(dev, "Failed to get runtime PM\n"); + return 0; + } + + ret = ipu_buttress_authenticate(isp); + if (ret) + dev_err(dev, "FW authentication failed(%d)\n", ret); + + pm_runtime_put(&isp->psys->auxdev.dev); + + return 0; +} + +static int ipu7_runtime_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct ipu7_device *isp = pci_get_drvdata(pdev); + int ret; + + ipu_buttress_restore(isp); + + if (isp->ipc_reinit) { + struct ipu_buttress *b = &isp->buttress; + + isp->ipc_reinit = false; + ret = ipu_buttress_ipc_reset(isp, &b->cse); + if (ret) + dev_err(dev, "IPC reset protocol failed!\n"); + } + + return 0; +} + +static const struct dev_pm_ops ipu7_pm_ops = { + SYSTEM_SLEEP_PM_OPS(&ipu7_suspend, &ipu7_resume) + RUNTIME_PM_OPS(&ipu7_suspend, &ipu7_runtime_resume, NULL) +}; + +static const struct pci_device_id ipu7_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU7_PCI_ID)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU7P5_PCI_ID)}, + {0,} +}; +MODULE_DEVICE_TABLE(pci, ipu7_pci_tbl); + +static const struct pci_error_handlers pci_err_handlers = { + .reset_prepare = ipu7_pci_reset_prepare, + .reset_done = ipu7_pci_reset_done, +}; + +static struct pci_driver ipu7_pci_driver = { + .name = IPU_NAME, + .id_table = ipu7_pci_tbl, + .probe = ipu7_pci_probe, + .remove = ipu7_pci_remove, + .driver = { + .pm = &ipu7_pm_ops, + }, + .err_handler = &pci_err_handlers, +}; + +module_pci_driver(ipu7_pci_driver); + +MODULE_IMPORT_NS("INTEL_IPU_BRIDGE"); +MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>"); +MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>"); +MODULE_AUTHOR("Qingwu Zhang <qingwu.zhang@intel.com>"); +MODULE_AUTHOR("Intel"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu7 pci driver"); diff --git a/drivers/staging/media/ipu7/ipu7.h b/drivers/staging/media/ipu7/ipu7.h new file mode 100644 index 000000000000..ac8ac0689468 --- /dev/null +++ b/drivers/staging/media/ipu7/ipu7.h @@ -0,0 +1,242 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 - 2025 Intel Corporation + */ + +#ifndef IPU7_H +#define IPU7_H + +#include <linux/list.h> +#include <linux/pci.h> +#include <linux/types.h> + +#include "ipu7-buttress.h" + +struct ipu7_bus_device; +struct pci_dev; +struct firmware; + +#define IPU_NAME "intel-ipu7" +#define IPU_MEDIA_DEV_MODEL_NAME "ipu7" + +#define IPU7_FIRMWARE_NAME "intel/ipu/ipu7_fw.bin" +#define IPU7P5_FIRMWARE_NAME "intel/ipu/ipu7ptl_fw.bin" +#define IPU8_FIRMWARE_NAME "intel/ipu/ipu8_fw.bin" + +#define IPU7_ISYS_NUM_STREAMS 12 + +#define IPU7_PCI_ID 0x645d +#define IPU7P5_PCI_ID 0xb05d +#define IPU8_PCI_ID 0xd719 + +#define FW_LOG_BUF_SIZE (2 * 1024 * 1024) + +enum ipu_version { + IPU_VER_INVALID = 0, + IPU_VER_7 = 1, + IPU_VER_7P5 = 2, + IPU_VER_8 = 3, +}; + +static inline bool is_ipu7p5(u8 hw_ver) +{ + return hw_ver == IPU_VER_7P5; +} + +static inline bool is_ipu7(u8 hw_ver) +{ + return hw_ver == IPU_VER_7; +} + +static inline bool is_ipu8(u8 hw_ver) +{ + return hw_ver == IPU_VER_8; +} + +#define IPU_UNIFIED_OFFSET 0 + +/* + * ISYS DMA can overshoot. For higher resolutions over allocation is one line + * but it must be at minimum 1024 bytes. Value could be different in + * different versions / generations thus provide it via platform data. + */ +#define IPU_ISYS_OVERALLOC_MIN 1024 + +#define IPU_FW_CODE_REGION_SIZE 0x1000000 /* 16MB */ +#define IPU_FW_CODE_REGION_START 0x4000000 /* 64MB */ +#define IPU_FW_CODE_REGION_END (IPU_FW_CODE_REGION_START + \ + IPU_FW_CODE_REGION_SIZE) /* 80MB */ + +struct ipu7_device { + struct pci_dev *pdev; + struct list_head devices; + struct ipu7_bus_device *isys; + struct ipu7_bus_device *psys; + struct ipu_buttress buttress; + + const struct firmware *cpd_fw; + const char *cpd_fw_name; + /* Only for non-secure mode. */ + void *fw_code_region; + + void __iomem *base; + void __iomem *pb_base; + u8 hw_ver; + bool ipc_reinit; + bool secure_mode; + bool ipu7_bus_ready_to_probe; +}; + +#define IPU_DMA_MASK 39 +#define IPU_LIB_CALL_TIMEOUT_MS 2000 +#define IPU_PSYS_CMD_TIMEOUT_MS 2000 +#define IPU_PSYS_OPEN_CLOSE_TIMEOUT_US 50 +#define IPU_PSYS_OPEN_CLOSE_RETRY (10000 / IPU_PSYS_OPEN_CLOSE_TIMEOUT_US) + +#define IPU_ISYS_NAME "isys" +#define IPU_PSYS_NAME "psys" + +#define IPU_MMU_ADDR_BITS 32 +/* FW is accessible within the first 2 GiB only in non-secure mode. */ +#define IPU_MMU_ADDR_BITS_NON_SECURE 31 + +#define IPU7_IS_MMU_NUM 4U +#define IPU7_PS_MMU_NUM 4U +#define IPU7P5_IS_MMU_NUM 4U +#define IPU7P5_PS_MMU_NUM 4U +#define IPU8_IS_MMU_NUM 5U +#define IPU8_PS_MMU_NUM 4U +#define IPU_MMU_MAX_NUM 5U /* max(IS, PS) */ +#define IPU_MMU_MAX_TLB_L1_STREAMS 40U +#define IPU_MMU_MAX_TLB_L2_STREAMS 40U +#define IPU_ZLX_MAX_NUM 32U +#define IPU_ZLX_POOL_NUM 8U +#define IPU_UAO_PLANE_MAX_NUM 64U + +/* + * To maximize the IOSF utlization, IPU need to send requests in bursts. + * At the DMA interface with the buttress, there are CDC FIFOs with burst + * collection capability. CDC FIFO burst collectors have a configurable + * threshold and is configured based on the outcome of performance measurements. + * + * isys has 3 ports with IOSF interface for VC0, VC1 and VC2 + * psys has 4 ports with IOSF interface for VC0, VC1w, VC1r and VC2 + * + * Threshold values are pre-defined and are arrived at after performance + * evaluations on a type of IPU + */ +#define IPU_MAX_VC_IOSF_PORTS 4 + +/* + * IPU must configure correct arbitration mechanism related to the IOSF VC + * requests. There are two options per VC0 and VC1 - > 0 means rearbitrate on + * stall and 1 means stall until the request is completed. + */ +#define IPU_BTRS_ARB_MODE_TYPE_REARB 0 +#define IPU_BTRS_ARB_MODE_TYPE_STALL 1 + +/* Currently chosen arbitration mechanism for VC0 */ +#define IPU_BTRS_ARB_STALL_MODE_VC0 IPU_BTRS_ARB_MODE_TYPE_REARB + +/* Currently chosen arbitration mechanism for VC1 */ +#define IPU_BTRS_ARB_STALL_MODE_VC1 IPU_BTRS_ARB_MODE_TYPE_REARB + +/* One L2 entry maps 1024 L1 entries and one L1 entry per page */ +#define IPU_MMUV2_L2_RANGE (1024 * PAGE_SIZE) +/* Max L2 blocks per stream */ +#define IPU_MMUV2_MAX_L2_BLOCKS 2 +/* Max L1 blocks per stream */ +#define IPU_MMUV2_MAX_L1_BLOCKS 16 +#define IPU_MMUV2_TRASH_RANGE (IPU_MMUV2_L2_RANGE * \ + IPU_MMUV2_MAX_L2_BLOCKS) +/* Entries per L1 block */ +#define MMUV2_ENTRIES_PER_L1_BLOCK 16 +#define MMUV2_TRASH_L1_BLOCK_OFFSET (MMUV2_ENTRIES_PER_L1_BLOCK * PAGE_SIZE) +#define MMUV2_TRASH_L2_BLOCK_OFFSET IPU_MMUV2_L2_RANGE + +struct ipu7_mmu_hw { + char name[32]; + + void __iomem *base; + void __iomem *zlx_base; + void __iomem *uao_base; + + u32 offset; + u32 zlx_offset; + u32 uao_offset; + + u32 info_bits; + u32 refill; + u32 collapse_en_bitmap; + u32 at_sp_arb_cfg; + + u32 l1_block; + u32 l2_block; + + u8 nr_l1streams; + u8 nr_l2streams; + u32 l1_block_sz[IPU_MMU_MAX_TLB_L1_STREAMS]; + u32 l2_block_sz[IPU_MMU_MAX_TLB_L2_STREAMS]; + + u8 zlx_nr; + u32 zlx_axi_pool[IPU_ZLX_POOL_NUM]; + u32 zlx_en[IPU_ZLX_MAX_NUM]; + u32 zlx_conf[IPU_ZLX_MAX_NUM]; + + u32 uao_p_num; + u32 uao_p2tlb[IPU_UAO_PLANE_MAX_NUM]; +}; + +struct ipu7_mmu_pdata { + u32 nr_mmus; + struct ipu7_mmu_hw mmu_hw[IPU_MMU_MAX_NUM]; + int mmid; +}; + +struct ipu7_isys_csi2_pdata { + void __iomem *base; +}; + +struct ipu7_isys_internal_csi2_pdata { + u32 nports; + u32 const *offsets; + u32 gpreg; +}; + +struct ipu7_hw_variants { + unsigned long offset; + u32 nr_mmus; + struct ipu7_mmu_hw mmu_hw[IPU_MMU_MAX_NUM]; + u8 cdc_fifos; + u8 cdc_fifo_threshold[IPU_MAX_VC_IOSF_PORTS]; + u32 dmem_offset; + u32 spc_offset; /* SPC offset from psys base */ +}; + +struct ipu_isys_internal_pdata { + struct ipu7_isys_internal_csi2_pdata csi2; + struct ipu7_hw_variants hw_variant; + u32 num_parallel_streams; + u32 isys_dma_overshoot; +}; + +struct ipu7_isys_pdata { + void __iomem *base; + const struct ipu_isys_internal_pdata *ipdata; +}; + +struct ipu_psys_internal_pdata { + struct ipu7_hw_variants hw_variant; +}; + +struct ipu7_psys_pdata { + void __iomem *base; + const struct ipu_psys_internal_pdata *ipdata; +}; + +int request_cpd_fw(const struct firmware **firmware_p, const char *name, + struct device *device); +void ipu_internal_pdata_init(struct ipu_isys_internal_pdata *isys_ipdata, + struct ipu_psys_internal_pdata *psys_ipdata); +void ipu7_dump_fw_error_log(const struct ipu7_bus_device *adev); +#endif /* IPU7_H */ diff --git a/drivers/staging/media/rkvdec/Kconfig b/drivers/staging/media/rkvdec/Kconfig deleted file mode 100644 index 5f3bdd848a2c..000000000000 --- a/drivers/staging/media/rkvdec/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config VIDEO_ROCKCHIP_VDEC - tristate "Rockchip Video Decoder driver" - depends on ARCH_ROCKCHIP || COMPILE_TEST - depends on VIDEO_DEV - select MEDIA_CONTROLLER - select VIDEOBUF2_DMA_CONTIG - select VIDEOBUF2_VMALLOC - select V4L2_MEM2MEM_DEV - select V4L2_H264 - select V4L2_VP9 - help - Support for the Rockchip Video Decoder IP present on Rockchip SoCs, - which accelerates video decoding. - To compile this driver as a module, choose M here: the module - will be called rockchip-vdec. diff --git a/drivers/staging/media/rkvdec/Makefile b/drivers/staging/media/rkvdec/Makefile deleted file mode 100644 index cb86b429cfaa..000000000000 --- a/drivers/staging/media/rkvdec/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rockchip-vdec.o - -rockchip-vdec-y += rkvdec.o rkvdec-h264.o rkvdec-vp9.o diff --git a/drivers/staging/media/rkvdec/TODO b/drivers/staging/media/rkvdec/TODO deleted file mode 100644 index 2c0779383276..000000000000 --- a/drivers/staging/media/rkvdec/TODO +++ /dev/null @@ -1,11 +0,0 @@ -* Support for HEVC is planned for this driver. - - Given the V4L controls for that CODEC will be part of - the uABI, it will be required to have the driver in staging. - - For this reason, we are keeping this driver in staging for now. - -* Evaluate introducing a helper to consolidate duplicated - code in rkvdec_request_validate and cedrus_request_validate. - The helper needs to the driver private data associated with - the videobuf2 queue, from a media request. diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c deleted file mode 100644 index 4fc167b42cf0..000000000000 --- a/drivers/staging/media/rkvdec/rkvdec-h264.c +++ /dev/null @@ -1,1192 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Rockchip Video Decoder H264 backend - * - * Copyright (C) 2019 Collabora, Ltd. - * Boris Brezillon <boris.brezillon@collabora.com> - * - * Copyright (C) 2016 Rockchip Electronics Co., Ltd. - * Jeffy Chen <jeffy.chen@rock-chips.com> - */ - -#include <media/v4l2-h264.h> -#include <media/v4l2-mem2mem.h> - -#include "rkvdec.h" -#include "rkvdec-regs.h" - -/* Size with u32 units. */ -#define RKV_CABAC_INIT_BUFFER_SIZE (3680 + 128) -#define RKV_RPS_SIZE ((128 + 128) / 4) -#define RKV_ERROR_INFO_SIZE (256 * 144 * 4) - -#define RKVDEC_NUM_REFLIST 3 - -struct rkvdec_h264_scaling_list { - u8 scaling_list_4x4[6][16]; - u8 scaling_list_8x8[6][64]; - u8 padding[128]; -}; - -struct rkvdec_sps_pps_packet { - u32 info[8]; -}; - -struct rkvdec_ps_field { - u16 offset; - u8 len; -}; - -#define PS_FIELD(_offset, _len) \ - ((struct rkvdec_ps_field){ _offset, _len }) - -#define SEQ_PARAMETER_SET_ID PS_FIELD(0, 4) -#define PROFILE_IDC PS_FIELD(4, 8) -#define CONSTRAINT_SET3_FLAG PS_FIELD(12, 1) -#define CHROMA_FORMAT_IDC PS_FIELD(13, 2) -#define BIT_DEPTH_LUMA PS_FIELD(15, 3) -#define BIT_DEPTH_CHROMA PS_FIELD(18, 3) -#define QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG PS_FIELD(21, 1) -#define LOG2_MAX_FRAME_NUM_MINUS4 PS_FIELD(22, 4) -#define MAX_NUM_REF_FRAMES PS_FIELD(26, 5) -#define PIC_ORDER_CNT_TYPE PS_FIELD(31, 2) -#define LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4 PS_FIELD(33, 4) -#define DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG PS_FIELD(37, 1) -#define PIC_WIDTH_IN_MBS PS_FIELD(38, 9) -#define PIC_HEIGHT_IN_MBS PS_FIELD(47, 9) -#define FRAME_MBS_ONLY_FLAG PS_FIELD(56, 1) -#define MB_ADAPTIVE_FRAME_FIELD_FLAG PS_FIELD(57, 1) -#define DIRECT_8X8_INFERENCE_FLAG PS_FIELD(58, 1) -#define MVC_EXTENSION_ENABLE PS_FIELD(59, 1) -#define NUM_VIEWS PS_FIELD(60, 2) -#define VIEW_ID(i) PS_FIELD(62 + ((i) * 10), 10) -#define NUM_ANCHOR_REFS_L(i) PS_FIELD(82 + ((i) * 11), 1) -#define ANCHOR_REF_L(i) PS_FIELD(83 + ((i) * 11), 10) -#define NUM_NON_ANCHOR_REFS_L(i) PS_FIELD(104 + ((i) * 11), 1) -#define NON_ANCHOR_REFS_L(i) PS_FIELD(105 + ((i) * 11), 10) -#define PIC_PARAMETER_SET_ID PS_FIELD(128, 8) -#define PPS_SEQ_PARAMETER_SET_ID PS_FIELD(136, 5) -#define ENTROPY_CODING_MODE_FLAG PS_FIELD(141, 1) -#define BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT_FLAG PS_FIELD(142, 1) -#define NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(i) PS_FIELD(143 + ((i) * 5), 5) -#define WEIGHTED_PRED_FLAG PS_FIELD(153, 1) -#define WEIGHTED_BIPRED_IDC PS_FIELD(154, 2) -#define PIC_INIT_QP_MINUS26 PS_FIELD(156, 7) -#define PIC_INIT_QS_MINUS26 PS_FIELD(163, 6) -#define CHROMA_QP_INDEX_OFFSET PS_FIELD(169, 5) -#define DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG PS_FIELD(174, 1) -#define CONSTRAINED_INTRA_PRED_FLAG PS_FIELD(175, 1) -#define REDUNDANT_PIC_CNT_PRESENT PS_FIELD(176, 1) -#define TRANSFORM_8X8_MODE_FLAG PS_FIELD(177, 1) -#define SECOND_CHROMA_QP_INDEX_OFFSET PS_FIELD(178, 5) -#define SCALING_LIST_ENABLE_FLAG PS_FIELD(183, 1) -#define SCALING_LIST_ADDRESS PS_FIELD(184, 32) -#define IS_LONG_TERM(i) PS_FIELD(216 + (i), 1) - -#define DPB_OFFS(i, j) (288 + ((j) * 32 * 7) + ((i) * 7)) -#define DPB_INFO(i, j) PS_FIELD(DPB_OFFS(i, j), 5) -#define BOTTOM_FLAG(i, j) PS_FIELD(DPB_OFFS(i, j) + 5, 1) -#define VIEW_INDEX_OFF(i, j) PS_FIELD(DPB_OFFS(i, j) + 6, 1) - -/* Data structure describing auxiliary buffer format. */ -struct rkvdec_h264_priv_tbl { - s8 cabac_table[4][464][2]; - struct rkvdec_h264_scaling_list scaling_list; - u32 rps[RKV_RPS_SIZE]; - struct rkvdec_sps_pps_packet param_set[256]; - u8 err_info[RKV_ERROR_INFO_SIZE]; -}; - -struct rkvdec_h264_reflists { - struct v4l2_h264_reference p[V4L2_H264_REF_LIST_LEN]; - struct v4l2_h264_reference b0[V4L2_H264_REF_LIST_LEN]; - struct v4l2_h264_reference b1[V4L2_H264_REF_LIST_LEN]; -}; - -struct rkvdec_h264_run { - struct rkvdec_run base; - const struct v4l2_ctrl_h264_decode_params *decode_params; - const struct v4l2_ctrl_h264_sps *sps; - const struct v4l2_ctrl_h264_pps *pps; - const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix; - struct vb2_buffer *ref_buf[V4L2_H264_NUM_DPB_ENTRIES]; -}; - -struct rkvdec_h264_ctx { - struct rkvdec_aux_buf priv_tbl; - struct rkvdec_h264_reflists reflists; -}; - -#define CABAC_ENTRY(ctxidx, idc0_m, idc0_n, idc1_m, idc1_n, \ - idc2_m, idc2_n, intra_m, intra_n) \ - [0][(ctxidx)] = {idc0_m, idc0_n}, \ - [1][(ctxidx)] = {idc1_m, idc1_n}, \ - [2][(ctxidx)] = {idc2_m, idc2_n}, \ - [3][(ctxidx)] = {intra_m, intra_n} - -/* - * Constant CABAC table. - * Built from the tables described in section '9.3.1.1 Initialisation process - * for context variables' of the H264 spec. - */ -static const s8 rkvdec_h264_cabac_table[4][464][2] = { - /* Table 9-12 – Values of variables m and n for ctxIdx from 0 to 10 */ - CABAC_ENTRY(0, 20, -15, 20, -15, 20, -15, 20, -15), - CABAC_ENTRY(1, 2, 54, 2, 54, 2, 54, 2, 54), - CABAC_ENTRY(2, 3, 74, 3, 74, 3, 74, 3, 74), - CABAC_ENTRY(3, 20, -15, 20, -15, 20, -15, 20, -15), - CABAC_ENTRY(4, 2, 54, 2, 54, 2, 54, 2, 54), - CABAC_ENTRY(5, 3, 74, 3, 74, 3, 74, 3, 74), - CABAC_ENTRY(6, -28, 127, -28, 127, -28, 127, -28, 127), - CABAC_ENTRY(7, -23, 104, -23, 104, -23, 104, -23, 104), - CABAC_ENTRY(8, -6, 53, -6, 53, -6, 53, -6, 53), - CABAC_ENTRY(9, -1, 54, -1, 54, -1, 54, -1, 54), - CABAC_ENTRY(10, 7, 51, 7, 51, 7, 51, 7, 51), - - /* Table 9-13 – Values of variables m and n for ctxIdx from 11 to 23 */ - CABAC_ENTRY(11, 23, 33, 22, 25, 29, 16, 0, 0), - CABAC_ENTRY(12, 23, 2, 34, 0, 25, 0, 0, 0), - CABAC_ENTRY(13, 21, 0, 16, 0, 14, 0, 0, 0), - CABAC_ENTRY(14, 1, 9, -2, 9, -10, 51, 0, 0), - CABAC_ENTRY(15, 0, 49, 4, 41, -3, 62, 0, 0), - CABAC_ENTRY(16, -37, 118, -29, 118, -27, 99, 0, 0), - CABAC_ENTRY(17, 5, 57, 2, 65, 26, 16, 0, 0), - CABAC_ENTRY(18, -13, 78, -6, 71, -4, 85, 0, 0), - CABAC_ENTRY(19, -11, 65, -13, 79, -24, 102, 0, 0), - CABAC_ENTRY(20, 1, 62, 5, 52, 5, 57, 0, 0), - CABAC_ENTRY(21, 12, 49, 9, 50, 6, 57, 0, 0), - CABAC_ENTRY(22, -4, 73, -3, 70, -17, 73, 0, 0), - CABAC_ENTRY(23, 17, 50, 10, 54, 14, 57, 0, 0), - - /* Table 9-14 – Values of variables m and n for ctxIdx from 24 to 39 */ - CABAC_ENTRY(24, 18, 64, 26, 34, 20, 40, 0, 0), - CABAC_ENTRY(25, 9, 43, 19, 22, 20, 10, 0, 0), - CABAC_ENTRY(26, 29, 0, 40, 0, 29, 0, 0, 0), - CABAC_ENTRY(27, 26, 67, 57, 2, 54, 0, 0, 0), - CABAC_ENTRY(28, 16, 90, 41, 36, 37, 42, 0, 0), - CABAC_ENTRY(29, 9, 104, 26, 69, 12, 97, 0, 0), - CABAC_ENTRY(30, -46, 127, -45, 127, -32, 127, 0, 0), - CABAC_ENTRY(31, -20, 104, -15, 101, -22, 117, 0, 0), - CABAC_ENTRY(32, 1, 67, -4, 76, -2, 74, 0, 0), - CABAC_ENTRY(33, -13, 78, -6, 71, -4, 85, 0, 0), - CABAC_ENTRY(34, -11, 65, -13, 79, -24, 102, 0, 0), - CABAC_ENTRY(35, 1, 62, 5, 52, 5, 57, 0, 0), - CABAC_ENTRY(36, -6, 86, 6, 69, -6, 93, 0, 0), - CABAC_ENTRY(37, -17, 95, -13, 90, -14, 88, 0, 0), - CABAC_ENTRY(38, -6, 61, 0, 52, -6, 44, 0, 0), - CABAC_ENTRY(39, 9, 45, 8, 43, 4, 55, 0, 0), - - /* Table 9-15 – Values of variables m and n for ctxIdx from 40 to 53 */ - CABAC_ENTRY(40, -3, 69, -2, 69, -11, 89, 0, 0), - CABAC_ENTRY(41, -6, 81, -5, 82, -15, 103, 0, 0), - CABAC_ENTRY(42, -11, 96, -10, 96, -21, 116, 0, 0), - CABAC_ENTRY(43, 6, 55, 2, 59, 19, 57, 0, 0), - CABAC_ENTRY(44, 7, 67, 2, 75, 20, 58, 0, 0), - CABAC_ENTRY(45, -5, 86, -3, 87, 4, 84, 0, 0), - CABAC_ENTRY(46, 2, 88, -3, 100, 6, 96, 0, 0), - CABAC_ENTRY(47, 0, 58, 1, 56, 1, 63, 0, 0), - CABAC_ENTRY(48, -3, 76, -3, 74, -5, 85, 0, 0), - CABAC_ENTRY(49, -10, 94, -6, 85, -13, 106, 0, 0), - CABAC_ENTRY(50, 5, 54, 0, 59, 5, 63, 0, 0), - CABAC_ENTRY(51, 4, 69, -3, 81, 6, 75, 0, 0), - CABAC_ENTRY(52, -3, 81, -7, 86, -3, 90, 0, 0), - CABAC_ENTRY(53, 0, 88, -5, 95, -1, 101, 0, 0), - - /* Table 9-16 – Values of variables m and n for ctxIdx from 54 to 59 */ - CABAC_ENTRY(54, -7, 67, -1, 66, 3, 55, 0, 0), - CABAC_ENTRY(55, -5, 74, -1, 77, -4, 79, 0, 0), - CABAC_ENTRY(56, -4, 74, 1, 70, -2, 75, 0, 0), - CABAC_ENTRY(57, -5, 80, -2, 86, -12, 97, 0, 0), - CABAC_ENTRY(58, -7, 72, -5, 72, -7, 50, 0, 0), - CABAC_ENTRY(59, 1, 58, 0, 61, 1, 60, 0, 0), - - /* Table 9-17 – Values of variables m and n for ctxIdx from 60 to 69 */ - CABAC_ENTRY(60, 0, 41, 0, 41, 0, 41, 0, 41), - CABAC_ENTRY(61, 0, 63, 0, 63, 0, 63, 0, 63), - CABAC_ENTRY(62, 0, 63, 0, 63, 0, 63, 0, 63), - CABAC_ENTRY(63, 0, 63, 0, 63, 0, 63, 0, 63), - CABAC_ENTRY(64, -9, 83, -9, 83, -9, 83, -9, 83), - CABAC_ENTRY(65, 4, 86, 4, 86, 4, 86, 4, 86), - CABAC_ENTRY(66, 0, 97, 0, 97, 0, 97, 0, 97), - CABAC_ENTRY(67, -7, 72, -7, 72, -7, 72, -7, 72), - CABAC_ENTRY(68, 13, 41, 13, 41, 13, 41, 13, 41), - CABAC_ENTRY(69, 3, 62, 3, 62, 3, 62, 3, 62), - - /* Table 9-18 – Values of variables m and n for ctxIdx from 70 to 104 */ - CABAC_ENTRY(70, 0, 45, 13, 15, 7, 34, 0, 11), - CABAC_ENTRY(71, -4, 78, 7, 51, -9, 88, 1, 55), - CABAC_ENTRY(72, -3, 96, 2, 80, -20, 127, 0, 69), - CABAC_ENTRY(73, -27, 126, -39, 127, -36, 127, -17, 127), - CABAC_ENTRY(74, -28, 98, -18, 91, -17, 91, -13, 102), - CABAC_ENTRY(75, -25, 101, -17, 96, -14, 95, 0, 82), - CABAC_ENTRY(76, -23, 67, -26, 81, -25, 84, -7, 74), - CABAC_ENTRY(77, -28, 82, -35, 98, -25, 86, -21, 107), - CABAC_ENTRY(78, -20, 94, -24, 102, -12, 89, -27, 127), - CABAC_ENTRY(79, -16, 83, -23, 97, -17, 91, -31, 127), - CABAC_ENTRY(80, -22, 110, -27, 119, -31, 127, -24, 127), - CABAC_ENTRY(81, -21, 91, -24, 99, -14, 76, -18, 95), - CABAC_ENTRY(82, -18, 102, -21, 110, -18, 103, -27, 127), - CABAC_ENTRY(83, -13, 93, -18, 102, -13, 90, -21, 114), - CABAC_ENTRY(84, -29, 127, -36, 127, -37, 127, -30, 127), - CABAC_ENTRY(85, -7, 92, 0, 80, 11, 80, -17, 123), - CABAC_ENTRY(86, -5, 89, -5, 89, 5, 76, -12, 115), - CABAC_ENTRY(87, -7, 96, -7, 94, 2, 84, -16, 122), - CABAC_ENTRY(88, -13, 108, -4, 92, 5, 78, -11, 115), - CABAC_ENTRY(89, -3, 46, 0, 39, -6, 55, -12, 63), - CABAC_ENTRY(90, -1, 65, 0, 65, 4, 61, -2, 68), - CABAC_ENTRY(91, -1, 57, -15, 84, -14, 83, -15, 84), - CABAC_ENTRY(92, -9, 93, -35, 127, -37, 127, -13, 104), - CABAC_ENTRY(93, -3, 74, -2, 73, -5, 79, -3, 70), - CABAC_ENTRY(94, -9, 92, -12, 104, -11, 104, -8, 93), - CABAC_ENTRY(95, -8, 87, -9, 91, -11, 91, -10, 90), - CABAC_ENTRY(96, -23, 126, -31, 127, -30, 127, -30, 127), - CABAC_ENTRY(97, 5, 54, 3, 55, 0, 65, -1, 74), - CABAC_ENTRY(98, 6, 60, 7, 56, -2, 79, -6, 97), - CABAC_ENTRY(99, 6, 59, 7, 55, 0, 72, -7, 91), - CABAC_ENTRY(100, 6, 69, 8, 61, -4, 92, -20, 127), - CABAC_ENTRY(101, -1, 48, -3, 53, -6, 56, -4, 56), - CABAC_ENTRY(102, 0, 68, 0, 68, 3, 68, -5, 82), - CABAC_ENTRY(103, -4, 69, -7, 74, -8, 71, -7, 76), - CABAC_ENTRY(104, -8, 88, -9, 88, -13, 98, -22, 125), - - /* Table 9-19 – Values of variables m and n for ctxIdx from 105 to 165 */ - CABAC_ENTRY(105, -2, 85, -13, 103, -4, 86, -7, 93), - CABAC_ENTRY(106, -6, 78, -13, 91, -12, 88, -11, 87), - CABAC_ENTRY(107, -1, 75, -9, 89, -5, 82, -3, 77), - CABAC_ENTRY(108, -7, 77, -14, 92, -3, 72, -5, 71), - CABAC_ENTRY(109, 2, 54, -8, 76, -4, 67, -4, 63), - CABAC_ENTRY(110, 5, 50, -12, 87, -8, 72, -4, 68), - CABAC_ENTRY(111, -3, 68, -23, 110, -16, 89, -12, 84), - CABAC_ENTRY(112, 1, 50, -24, 105, -9, 69, -7, 62), - CABAC_ENTRY(113, 6, 42, -10, 78, -1, 59, -7, 65), - CABAC_ENTRY(114, -4, 81, -20, 112, 5, 66, 8, 61), - CABAC_ENTRY(115, 1, 63, -17, 99, 4, 57, 5, 56), - CABAC_ENTRY(116, -4, 70, -78, 127, -4, 71, -2, 66), - CABAC_ENTRY(117, 0, 67, -70, 127, -2, 71, 1, 64), - CABAC_ENTRY(118, 2, 57, -50, 127, 2, 58, 0, 61), - CABAC_ENTRY(119, -2, 76, -46, 127, -1, 74, -2, 78), - CABAC_ENTRY(120, 11, 35, -4, 66, -4, 44, 1, 50), - CABAC_ENTRY(121, 4, 64, -5, 78, -1, 69, 7, 52), - CABAC_ENTRY(122, 1, 61, -4, 71, 0, 62, 10, 35), - CABAC_ENTRY(123, 11, 35, -8, 72, -7, 51, 0, 44), - CABAC_ENTRY(124, 18, 25, 2, 59, -4, 47, 11, 38), - CABAC_ENTRY(125, 12, 24, -1, 55, -6, 42, 1, 45), - CABAC_ENTRY(126, 13, 29, -7, 70, -3, 41, 0, 46), - CABAC_ENTRY(127, 13, 36, -6, 75, -6, 53, 5, 44), - CABAC_ENTRY(128, -10, 93, -8, 89, 8, 76, 31, 17), - CABAC_ENTRY(129, -7, 73, -34, 119, -9, 78, 1, 51), - CABAC_ENTRY(130, -2, 73, -3, 75, -11, 83, 7, 50), - CABAC_ENTRY(131, 13, 46, 32, 20, 9, 52, 28, 19), - CABAC_ENTRY(132, 9, 49, 30, 22, 0, 67, 16, 33), - CABAC_ENTRY(133, -7, 100, -44, 127, -5, 90, 14, 62), - CABAC_ENTRY(134, 9, 53, 0, 54, 1, 67, -13, 108), - CABAC_ENTRY(135, 2, 53, -5, 61, -15, 72, -15, 100), - CABAC_ENTRY(136, 5, 53, 0, 58, -5, 75, -13, 101), - CABAC_ENTRY(137, -2, 61, -1, 60, -8, 80, -13, 91), - CABAC_ENTRY(138, 0, 56, -3, 61, -21, 83, -12, 94), - CABAC_ENTRY(139, 0, 56, -8, 67, -21, 64, -10, 88), - CABAC_ENTRY(140, -13, 63, -25, 84, -13, 31, -16, 84), - CABAC_ENTRY(141, -5, 60, -14, 74, -25, 64, -10, 86), - CABAC_ENTRY(142, -1, 62, -5, 65, -29, 94, -7, 83), - CABAC_ENTRY(143, 4, 57, 5, 52, 9, 75, -13, 87), - CABAC_ENTRY(144, -6, 69, 2, 57, 17, 63, -19, 94), - CABAC_ENTRY(145, 4, 57, 0, 61, -8, 74, 1, 70), - CABAC_ENTRY(146, 14, 39, -9, 69, -5, 35, 0, 72), - CABAC_ENTRY(147, 4, 51, -11, 70, -2, 27, -5, 74), - CABAC_ENTRY(148, 13, 68, 18, 55, 13, 91, 18, 59), - CABAC_ENTRY(149, 3, 64, -4, 71, 3, 65, -8, 102), - CABAC_ENTRY(150, 1, 61, 0, 58, -7, 69, -15, 100), - CABAC_ENTRY(151, 9, 63, 7, 61, 8, 77, 0, 95), - CABAC_ENTRY(152, 7, 50, 9, 41, -10, 66, -4, 75), - CABAC_ENTRY(153, 16, 39, 18, 25, 3, 62, 2, 72), - CABAC_ENTRY(154, 5, 44, 9, 32, -3, 68, -11, 75), - CABAC_ENTRY(155, 4, 52, 5, 43, -20, 81, -3, 71), - CABAC_ENTRY(156, 11, 48, 9, 47, 0, 30, 15, 46), - CABAC_ENTRY(157, -5, 60, 0, 44, 1, 7, -13, 69), - CABAC_ENTRY(158, -1, 59, 0, 51, -3, 23, 0, 62), - CABAC_ENTRY(159, 0, 59, 2, 46, -21, 74, 0, 65), - CABAC_ENTRY(160, 22, 33, 19, 38, 16, 66, 21, 37), - CABAC_ENTRY(161, 5, 44, -4, 66, -23, 124, -15, 72), - CABAC_ENTRY(162, 14, 43, 15, 38, 17, 37, 9, 57), - CABAC_ENTRY(163, -1, 78, 12, 42, 44, -18, 16, 54), - CABAC_ENTRY(164, 0, 60, 9, 34, 50, -34, 0, 62), - CABAC_ENTRY(165, 9, 69, 0, 89, -22, 127, 12, 72), - - /* Table 9-20 – Values of variables m and n for ctxIdx from 166 to 226 */ - CABAC_ENTRY(166, 11, 28, 4, 45, 4, 39, 24, 0), - CABAC_ENTRY(167, 2, 40, 10, 28, 0, 42, 15, 9), - CABAC_ENTRY(168, 3, 44, 10, 31, 7, 34, 8, 25), - CABAC_ENTRY(169, 0, 49, 33, -11, 11, 29, 13, 18), - CABAC_ENTRY(170, 0, 46, 52, -43, 8, 31, 15, 9), - CABAC_ENTRY(171, 2, 44, 18, 15, 6, 37, 13, 19), - CABAC_ENTRY(172, 2, 51, 28, 0, 7, 42, 10, 37), - CABAC_ENTRY(173, 0, 47, 35, -22, 3, 40, 12, 18), - CABAC_ENTRY(174, 4, 39, 38, -25, 8, 33, 6, 29), - CABAC_ENTRY(175, 2, 62, 34, 0, 13, 43, 20, 33), - CABAC_ENTRY(176, 6, 46, 39, -18, 13, 36, 15, 30), - CABAC_ENTRY(177, 0, 54, 32, -12, 4, 47, 4, 45), - CABAC_ENTRY(178, 3, 54, 102, -94, 3, 55, 1, 58), - CABAC_ENTRY(179, 2, 58, 0, 0, 2, 58, 0, 62), - CABAC_ENTRY(180, 4, 63, 56, -15, 6, 60, 7, 61), - CABAC_ENTRY(181, 6, 51, 33, -4, 8, 44, 12, 38), - CABAC_ENTRY(182, 6, 57, 29, 10, 11, 44, 11, 45), - CABAC_ENTRY(183, 7, 53, 37, -5, 14, 42, 15, 39), - CABAC_ENTRY(184, 6, 52, 51, -29, 7, 48, 11, 42), - CABAC_ENTRY(185, 6, 55, 39, -9, 4, 56, 13, 44), - CABAC_ENTRY(186, 11, 45, 52, -34, 4, 52, 16, 45), - CABAC_ENTRY(187, 14, 36, 69, -58, 13, 37, 12, 41), - CABAC_ENTRY(188, 8, 53, 67, -63, 9, 49, 10, 49), - CABAC_ENTRY(189, -1, 82, 44, -5, 19, 58, 30, 34), - CABAC_ENTRY(190, 7, 55, 32, 7, 10, 48, 18, 42), - CABAC_ENTRY(191, -3, 78, 55, -29, 12, 45, 10, 55), - CABAC_ENTRY(192, 15, 46, 32, 1, 0, 69, 17, 51), - CABAC_ENTRY(193, 22, 31, 0, 0, 20, 33, 17, 46), - CABAC_ENTRY(194, -1, 84, 27, 36, 8, 63, 0, 89), - CABAC_ENTRY(195, 25, 7, 33, -25, 35, -18, 26, -19), - CABAC_ENTRY(196, 30, -7, 34, -30, 33, -25, 22, -17), - CABAC_ENTRY(197, 28, 3, 36, -28, 28, -3, 26, -17), - CABAC_ENTRY(198, 28, 4, 38, -28, 24, 10, 30, -25), - CABAC_ENTRY(199, 32, 0, 38, -27, 27, 0, 28, -20), - CABAC_ENTRY(200, 34, -1, 34, -18, 34, -14, 33, -23), - CABAC_ENTRY(201, 30, 6, 35, -16, 52, -44, 37, -27), - CABAC_ENTRY(202, 30, 6, 34, -14, 39, -24, 33, -23), - CABAC_ENTRY(203, 32, 9, 32, -8, 19, 17, 40, -28), - CABAC_ENTRY(204, 31, 19, 37, -6, 31, 25, 38, -17), - CABAC_ENTRY(205, 26, 27, 35, 0, 36, 29, 33, -11), - CABAC_ENTRY(206, 26, 30, 30, 10, 24, 33, 40, -15), - CABAC_ENTRY(207, 37, 20, 28, 18, 34, 15, 41, -6), - CABAC_ENTRY(208, 28, 34, 26, 25, 30, 20, 38, 1), - CABAC_ENTRY(209, 17, 70, 29, 41, 22, 73, 41, 17), - CABAC_ENTRY(210, 1, 67, 0, 75, 20, 34, 30, -6), - CABAC_ENTRY(211, 5, 59, 2, 72, 19, 31, 27, 3), - CABAC_ENTRY(212, 9, 67, 8, 77, 27, 44, 26, 22), - CABAC_ENTRY(213, 16, 30, 14, 35, 19, 16, 37, -16), - CABAC_ENTRY(214, 18, 32, 18, 31, 15, 36, 35, -4), - CABAC_ENTRY(215, 18, 35, 17, 35, 15, 36, 38, -8), - CABAC_ENTRY(216, 22, 29, 21, 30, 21, 28, 38, -3), - CABAC_ENTRY(217, 24, 31, 17, 45, 25, 21, 37, 3), - CABAC_ENTRY(218, 23, 38, 20, 42, 30, 20, 38, 5), - CABAC_ENTRY(219, 18, 43, 18, 45, 31, 12, 42, 0), - CABAC_ENTRY(220, 20, 41, 27, 26, 27, 16, 35, 16), - CABAC_ENTRY(221, 11, 63, 16, 54, 24, 42, 39, 22), - CABAC_ENTRY(222, 9, 59, 7, 66, 0, 93, 14, 48), - CABAC_ENTRY(223, 9, 64, 16, 56, 14, 56, 27, 37), - CABAC_ENTRY(224, -1, 94, 11, 73, 15, 57, 21, 60), - CABAC_ENTRY(225, -2, 89, 10, 67, 26, 38, 12, 68), - CABAC_ENTRY(226, -9, 108, -10, 116, -24, 127, 2, 97), - - /* Table 9-21 – Values of variables m and n for ctxIdx from 227 to 275 */ - CABAC_ENTRY(227, -6, 76, -23, 112, -24, 115, -3, 71), - CABAC_ENTRY(228, -2, 44, -15, 71, -22, 82, -6, 42), - CABAC_ENTRY(229, 0, 45, -7, 61, -9, 62, -5, 50), - CABAC_ENTRY(230, 0, 52, 0, 53, 0, 53, -3, 54), - CABAC_ENTRY(231, -3, 64, -5, 66, 0, 59, -2, 62), - CABAC_ENTRY(232, -2, 59, -11, 77, -14, 85, 0, 58), - CABAC_ENTRY(233, -4, 70, -9, 80, -13, 89, 1, 63), - CABAC_ENTRY(234, -4, 75, -9, 84, -13, 94, -2, 72), - CABAC_ENTRY(235, -8, 82, -10, 87, -11, 92, -1, 74), - CABAC_ENTRY(236, -17, 102, -34, 127, -29, 127, -9, 91), - CABAC_ENTRY(237, -9, 77, -21, 101, -21, 100, -5, 67), - CABAC_ENTRY(238, 3, 24, -3, 39, -14, 57, -5, 27), - CABAC_ENTRY(239, 0, 42, -5, 53, -12, 67, -3, 39), - CABAC_ENTRY(240, 0, 48, -7, 61, -11, 71, -2, 44), - CABAC_ENTRY(241, 0, 55, -11, 75, -10, 77, 0, 46), - CABAC_ENTRY(242, -6, 59, -15, 77, -21, 85, -16, 64), - CABAC_ENTRY(243, -7, 71, -17, 91, -16, 88, -8, 68), - CABAC_ENTRY(244, -12, 83, -25, 107, -23, 104, -10, 78), - CABAC_ENTRY(245, -11, 87, -25, 111, -15, 98, -6, 77), - CABAC_ENTRY(246, -30, 119, -28, 122, -37, 127, -10, 86), - CABAC_ENTRY(247, 1, 58, -11, 76, -10, 82, -12, 92), - CABAC_ENTRY(248, -3, 29, -10, 44, -8, 48, -15, 55), - CABAC_ENTRY(249, -1, 36, -10, 52, -8, 61, -10, 60), - CABAC_ENTRY(250, 1, 38, -10, 57, -8, 66, -6, 62), - CABAC_ENTRY(251, 2, 43, -9, 58, -7, 70, -4, 65), - CABAC_ENTRY(252, -6, 55, -16, 72, -14, 75, -12, 73), - CABAC_ENTRY(253, 0, 58, -7, 69, -10, 79, -8, 76), - CABAC_ENTRY(254, 0, 64, -4, 69, -9, 83, -7, 80), - CABAC_ENTRY(255, -3, 74, -5, 74, -12, 92, -9, 88), - CABAC_ENTRY(256, -10, 90, -9, 86, -18, 108, -17, 110), - CABAC_ENTRY(257, 0, 70, 2, 66, -4, 79, -11, 97), - CABAC_ENTRY(258, -4, 29, -9, 34, -22, 69, -20, 84), - CABAC_ENTRY(259, 5, 31, 1, 32, -16, 75, -11, 79), - CABAC_ENTRY(260, 7, 42, 11, 31, -2, 58, -6, 73), - CABAC_ENTRY(261, 1, 59, 5, 52, 1, 58, -4, 74), - CABAC_ENTRY(262, -2, 58, -2, 55, -13, 78, -13, 86), - CABAC_ENTRY(263, -3, 72, -2, 67, -9, 83, -13, 96), - CABAC_ENTRY(264, -3, 81, 0, 73, -4, 81, -11, 97), - CABAC_ENTRY(265, -11, 97, -8, 89, -13, 99, -19, 117), - CABAC_ENTRY(266, 0, 58, 3, 52, -13, 81, -8, 78), - CABAC_ENTRY(267, 8, 5, 7, 4, -6, 38, -5, 33), - CABAC_ENTRY(268, 10, 14, 10, 8, -13, 62, -4, 48), - CABAC_ENTRY(269, 14, 18, 17, 8, -6, 58, -2, 53), - CABAC_ENTRY(270, 13, 27, 16, 19, -2, 59, -3, 62), - CABAC_ENTRY(271, 2, 40, 3, 37, -16, 73, -13, 71), - CABAC_ENTRY(272, 0, 58, -1, 61, -10, 76, -10, 79), - CABAC_ENTRY(273, -3, 70, -5, 73, -13, 86, -12, 86), - CABAC_ENTRY(274, -6, 79, -1, 70, -9, 83, -13, 90), - CABAC_ENTRY(275, -8, 85, -4, 78, -10, 87, -14, 97), - - /* Table 9-22 – Values of variables m and n for ctxIdx from 277 to 337 */ - CABAC_ENTRY(277, -13, 106, -21, 126, -22, 127, -6, 93), - CABAC_ENTRY(278, -16, 106, -23, 124, -25, 127, -6, 84), - CABAC_ENTRY(279, -10, 87, -20, 110, -25, 120, -8, 79), - CABAC_ENTRY(280, -21, 114, -26, 126, -27, 127, 0, 66), - CABAC_ENTRY(281, -18, 110, -25, 124, -19, 114, -1, 71), - CABAC_ENTRY(282, -14, 98, -17, 105, -23, 117, 0, 62), - CABAC_ENTRY(283, -22, 110, -27, 121, -25, 118, -2, 60), - CABAC_ENTRY(284, -21, 106, -27, 117, -26, 117, -2, 59), - CABAC_ENTRY(285, -18, 103, -17, 102, -24, 113, -5, 75), - CABAC_ENTRY(286, -21, 107, -26, 117, -28, 118, -3, 62), - CABAC_ENTRY(287, -23, 108, -27, 116, -31, 120, -4, 58), - CABAC_ENTRY(288, -26, 112, -33, 122, -37, 124, -9, 66), - CABAC_ENTRY(289, -10, 96, -10, 95, -10, 94, -1, 79), - CABAC_ENTRY(290, -12, 95, -14, 100, -15, 102, 0, 71), - CABAC_ENTRY(291, -5, 91, -8, 95, -10, 99, 3, 68), - CABAC_ENTRY(292, -9, 93, -17, 111, -13, 106, 10, 44), - CABAC_ENTRY(293, -22, 94, -28, 114, -50, 127, -7, 62), - CABAC_ENTRY(294, -5, 86, -6, 89, -5, 92, 15, 36), - CABAC_ENTRY(295, 9, 67, -2, 80, 17, 57, 14, 40), - CABAC_ENTRY(296, -4, 80, -4, 82, -5, 86, 16, 27), - CABAC_ENTRY(297, -10, 85, -9, 85, -13, 94, 12, 29), - CABAC_ENTRY(298, -1, 70, -8, 81, -12, 91, 1, 44), - CABAC_ENTRY(299, 7, 60, -1, 72, -2, 77, 20, 36), - CABAC_ENTRY(300, 9, 58, 5, 64, 0, 71, 18, 32), - CABAC_ENTRY(301, 5, 61, 1, 67, -1, 73, 5, 42), - CABAC_ENTRY(302, 12, 50, 9, 56, 4, 64, 1, 48), - CABAC_ENTRY(303, 15, 50, 0, 69, -7, 81, 10, 62), - CABAC_ENTRY(304, 18, 49, 1, 69, 5, 64, 17, 46), - CABAC_ENTRY(305, 17, 54, 7, 69, 15, 57, 9, 64), - CABAC_ENTRY(306, 10, 41, -7, 69, 1, 67, -12, 104), - CABAC_ENTRY(307, 7, 46, -6, 67, 0, 68, -11, 97), - CABAC_ENTRY(308, -1, 51, -16, 77, -10, 67, -16, 96), - CABAC_ENTRY(309, 7, 49, -2, 64, 1, 68, -7, 88), - CABAC_ENTRY(310, 8, 52, 2, 61, 0, 77, -8, 85), - CABAC_ENTRY(311, 9, 41, -6, 67, 2, 64, -7, 85), - CABAC_ENTRY(312, 6, 47, -3, 64, 0, 68, -9, 85), - CABAC_ENTRY(313, 2, 55, 2, 57, -5, 78, -13, 88), - CABAC_ENTRY(314, 13, 41, -3, 65, 7, 55, 4, 66), - CABAC_ENTRY(315, 10, 44, -3, 66, 5, 59, -3, 77), - CABAC_ENTRY(316, 6, 50, 0, 62, 2, 65, -3, 76), - CABAC_ENTRY(317, 5, 53, 9, 51, 14, 54, -6, 76), - CABAC_ENTRY(318, 13, 49, -1, 66, 15, 44, 10, 58), - CABAC_ENTRY(319, 4, 63, -2, 71, 5, 60, -1, 76), - CABAC_ENTRY(320, 6, 64, -2, 75, 2, 70, -1, 83), - CABAC_ENTRY(321, -2, 69, -1, 70, -2, 76, -7, 99), - CABAC_ENTRY(322, -2, 59, -9, 72, -18, 86, -14, 95), - CABAC_ENTRY(323, 6, 70, 14, 60, 12, 70, 2, 95), - CABAC_ENTRY(324, 10, 44, 16, 37, 5, 64, 0, 76), - CABAC_ENTRY(325, 9, 31, 0, 47, -12, 70, -5, 74), - CABAC_ENTRY(326, 12, 43, 18, 35, 11, 55, 0, 70), - CABAC_ENTRY(327, 3, 53, 11, 37, 5, 56, -11, 75), - CABAC_ENTRY(328, 14, 34, 12, 41, 0, 69, 1, 68), - CABAC_ENTRY(329, 10, 38, 10, 41, 2, 65, 0, 65), - CABAC_ENTRY(330, -3, 52, 2, 48, -6, 74, -14, 73), - CABAC_ENTRY(331, 13, 40, 12, 41, 5, 54, 3, 62), - CABAC_ENTRY(332, 17, 32, 13, 41, 7, 54, 4, 62), - CABAC_ENTRY(333, 7, 44, 0, 59, -6, 76, -1, 68), - CABAC_ENTRY(334, 7, 38, 3, 50, -11, 82, -13, 75), - CABAC_ENTRY(335, 13, 50, 19, 40, -2, 77, 11, 55), - CABAC_ENTRY(336, 10, 57, 3, 66, -2, 77, 5, 64), - CABAC_ENTRY(337, 26, 43, 18, 50, 25, 42, 12, 70), - - /* Table 9-23 – Values of variables m and n for ctxIdx from 338 to 398 */ - CABAC_ENTRY(338, 14, 11, 19, -6, 17, -13, 15, 6), - CABAC_ENTRY(339, 11, 14, 18, -6, 16, -9, 6, 19), - CABAC_ENTRY(340, 9, 11, 14, 0, 17, -12, 7, 16), - CABAC_ENTRY(341, 18, 11, 26, -12, 27, -21, 12, 14), - CABAC_ENTRY(342, 21, 9, 31, -16, 37, -30, 18, 13), - CABAC_ENTRY(343, 23, -2, 33, -25, 41, -40, 13, 11), - CABAC_ENTRY(344, 32, -15, 33, -22, 42, -41, 13, 15), - CABAC_ENTRY(345, 32, -15, 37, -28, 48, -47, 15, 16), - CABAC_ENTRY(346, 34, -21, 39, -30, 39, -32, 12, 23), - CABAC_ENTRY(347, 39, -23, 42, -30, 46, -40, 13, 23), - CABAC_ENTRY(348, 42, -33, 47, -42, 52, -51, 15, 20), - CABAC_ENTRY(349, 41, -31, 45, -36, 46, -41, 14, 26), - CABAC_ENTRY(350, 46, -28, 49, -34, 52, -39, 14, 44), - CABAC_ENTRY(351, 38, -12, 41, -17, 43, -19, 17, 40), - CABAC_ENTRY(352, 21, 29, 32, 9, 32, 11, 17, 47), - CABAC_ENTRY(353, 45, -24, 69, -71, 61, -55, 24, 17), - CABAC_ENTRY(354, 53, -45, 63, -63, 56, -46, 21, 21), - CABAC_ENTRY(355, 48, -26, 66, -64, 62, -50, 25, 22), - CABAC_ENTRY(356, 65, -43, 77, -74, 81, -67, 31, 27), - CABAC_ENTRY(357, 43, -19, 54, -39, 45, -20, 22, 29), - CABAC_ENTRY(358, 39, -10, 52, -35, 35, -2, 19, 35), - CABAC_ENTRY(359, 30, 9, 41, -10, 28, 15, 14, 50), - CABAC_ENTRY(360, 18, 26, 36, 0, 34, 1, 10, 57), - CABAC_ENTRY(361, 20, 27, 40, -1, 39, 1, 7, 63), - CABAC_ENTRY(362, 0, 57, 30, 14, 30, 17, -2, 77), - CABAC_ENTRY(363, -14, 82, 28, 26, 20, 38, -4, 82), - CABAC_ENTRY(364, -5, 75, 23, 37, 18, 45, -3, 94), - CABAC_ENTRY(365, -19, 97, 12, 55, 15, 54, 9, 69), - CABAC_ENTRY(366, -35, 125, 11, 65, 0, 79, -12, 109), - CABAC_ENTRY(367, 27, 0, 37, -33, 36, -16, 36, -35), - CABAC_ENTRY(368, 28, 0, 39, -36, 37, -14, 36, -34), - CABAC_ENTRY(369, 31, -4, 40, -37, 37, -17, 32, -26), - CABAC_ENTRY(370, 27, 6, 38, -30, 32, 1, 37, -30), - CABAC_ENTRY(371, 34, 8, 46, -33, 34, 15, 44, -32), - CABAC_ENTRY(372, 30, 10, 42, -30, 29, 15, 34, -18), - CABAC_ENTRY(373, 24, 22, 40, -24, 24, 25, 34, -15), - CABAC_ENTRY(374, 33, 19, 49, -29, 34, 22, 40, -15), - CABAC_ENTRY(375, 22, 32, 38, -12, 31, 16, 33, -7), - CABAC_ENTRY(376, 26, 31, 40, -10, 35, 18, 35, -5), - CABAC_ENTRY(377, 21, 41, 38, -3, 31, 28, 33, 0), - CABAC_ENTRY(378, 26, 44, 46, -5, 33, 41, 38, 2), - CABAC_ENTRY(379, 23, 47, 31, 20, 36, 28, 33, 13), - CABAC_ENTRY(380, 16, 65, 29, 30, 27, 47, 23, 35), - CABAC_ENTRY(381, 14, 71, 25, 44, 21, 62, 13, 58), - CABAC_ENTRY(382, 8, 60, 12, 48, 18, 31, 29, -3), - CABAC_ENTRY(383, 6, 63, 11, 49, 19, 26, 26, 0), - CABAC_ENTRY(384, 17, 65, 26, 45, 36, 24, 22, 30), - CABAC_ENTRY(385, 21, 24, 22, 22, 24, 23, 31, -7), - CABAC_ENTRY(386, 23, 20, 23, 22, 27, 16, 35, -15), - CABAC_ENTRY(387, 26, 23, 27, 21, 24, 30, 34, -3), - CABAC_ENTRY(388, 27, 32, 33, 20, 31, 29, 34, 3), - CABAC_ENTRY(389, 28, 23, 26, 28, 22, 41, 36, -1), - CABAC_ENTRY(390, 28, 24, 30, 24, 22, 42, 34, 5), - CABAC_ENTRY(391, 23, 40, 27, 34, 16, 60, 32, 11), - CABAC_ENTRY(392, 24, 32, 18, 42, 15, 52, 35, 5), - CABAC_ENTRY(393, 28, 29, 25, 39, 14, 60, 34, 12), - CABAC_ENTRY(394, 23, 42, 18, 50, 3, 78, 39, 11), - CABAC_ENTRY(395, 19, 57, 12, 70, -16, 123, 30, 29), - CABAC_ENTRY(396, 22, 53, 21, 54, 21, 53, 34, 26), - CABAC_ENTRY(397, 22, 61, 14, 71, 22, 56, 29, 39), - CABAC_ENTRY(398, 11, 86, 11, 83, 25, 61, 19, 66), - - /* Values of variables m and n for ctxIdx from 399 to 463 (not documented) */ - CABAC_ENTRY(399, 12, 40, 25, 32, 21, 33, 31, 21), - CABAC_ENTRY(400, 11, 51, 21, 49, 19, 50, 31, 31), - CABAC_ENTRY(401, 14, 59, 21, 54, 17, 61, 25, 50), - CABAC_ENTRY(402, -4, 79, -5, 85, -3, 78, -17, 120), - CABAC_ENTRY(403, -7, 71, -6, 81, -8, 74, -20, 112), - CABAC_ENTRY(404, -5, 69, -10, 77, -9, 72, -18, 114), - CABAC_ENTRY(405, -9, 70, -7, 81, -10, 72, -11, 85), - CABAC_ENTRY(406, -8, 66, -17, 80, -18, 75, -15, 92), - CABAC_ENTRY(407, -10, 68, -18, 73, -12, 71, -14, 89), - CABAC_ENTRY(408, -19, 73, -4, 74, -11, 63, -26, 71), - CABAC_ENTRY(409, -12, 69, -10, 83, -5, 70, -15, 81), - CABAC_ENTRY(410, -16, 70, -9, 71, -17, 75, -14, 80), - CABAC_ENTRY(411, -15, 67, -9, 67, -14, 72, 0, 68), - CABAC_ENTRY(412, -20, 62, -1, 61, -16, 67, -14, 70), - CABAC_ENTRY(413, -19, 70, -8, 66, -8, 53, -24, 56), - CABAC_ENTRY(414, -16, 66, -14, 66, -14, 59, -23, 68), - CABAC_ENTRY(415, -22, 65, 0, 59, -9, 52, -24, 50), - CABAC_ENTRY(416, -20, 63, 2, 59, -11, 68, -11, 74), - CABAC_ENTRY(417, 9, -2, 17, -10, 9, -2, 23, -13), - CABAC_ENTRY(418, 26, -9, 32, -13, 30, -10, 26, -13), - CABAC_ENTRY(419, 33, -9, 42, -9, 31, -4, 40, -15), - CABAC_ENTRY(420, 39, -7, 49, -5, 33, -1, 49, -14), - CABAC_ENTRY(421, 41, -2, 53, 0, 33, 7, 44, 3), - CABAC_ENTRY(422, 45, 3, 64, 3, 31, 12, 45, 6), - CABAC_ENTRY(423, 49, 9, 68, 10, 37, 23, 44, 34), - CABAC_ENTRY(424, 45, 27, 66, 27, 31, 38, 33, 54), - CABAC_ENTRY(425, 36, 59, 47, 57, 20, 64, 19, 82), - CABAC_ENTRY(426, -6, 66, -5, 71, -9, 71, -3, 75), - CABAC_ENTRY(427, -7, 35, 0, 24, -7, 37, -1, 23), - CABAC_ENTRY(428, -7, 42, -1, 36, -8, 44, 1, 34), - CABAC_ENTRY(429, -8, 45, -2, 42, -11, 49, 1, 43), - CABAC_ENTRY(430, -5, 48, -2, 52, -10, 56, 0, 54), - CABAC_ENTRY(431, -12, 56, -9, 57, -12, 59, -2, 55), - CABAC_ENTRY(432, -6, 60, -6, 63, -8, 63, 0, 61), - CABAC_ENTRY(433, -5, 62, -4, 65, -9, 67, 1, 64), - CABAC_ENTRY(434, -8, 66, -4, 67, -6, 68, 0, 68), - CABAC_ENTRY(435, -8, 76, -7, 82, -10, 79, -9, 92), - CABAC_ENTRY(436, -5, 85, -3, 81, -3, 78, -14, 106), - CABAC_ENTRY(437, -6, 81, -3, 76, -8, 74, -13, 97), - CABAC_ENTRY(438, -10, 77, -7, 72, -9, 72, -15, 90), - CABAC_ENTRY(439, -7, 81, -6, 78, -10, 72, -12, 90), - CABAC_ENTRY(440, -17, 80, -12, 72, -18, 75, -18, 88), - CABAC_ENTRY(441, -18, 73, -14, 68, -12, 71, -10, 73), - CABAC_ENTRY(442, -4, 74, -3, 70, -11, 63, -9, 79), - CABAC_ENTRY(443, -10, 83, -6, 76, -5, 70, -14, 86), - CABAC_ENTRY(444, -9, 71, -5, 66, -17, 75, -10, 73), - CABAC_ENTRY(445, -9, 67, -5, 62, -14, 72, -10, 70), - CABAC_ENTRY(446, -1, 61, 0, 57, -16, 67, -10, 69), - CABAC_ENTRY(447, -8, 66, -4, 61, -8, 53, -5, 66), - CABAC_ENTRY(448, -14, 66, -9, 60, -14, 59, -9, 64), - CABAC_ENTRY(449, 0, 59, 1, 54, -9, 52, -5, 58), - CABAC_ENTRY(450, 2, 59, 2, 58, -11, 68, 2, 59), - CABAC_ENTRY(451, 21, -13, 17, -10, 9, -2, 21, -10), - CABAC_ENTRY(452, 33, -14, 32, -13, 30, -10, 24, -11), - CABAC_ENTRY(453, 39, -7, 42, -9, 31, -4, 28, -8), - CABAC_ENTRY(454, 46, -2, 49, -5, 33, -1, 28, -1), - CABAC_ENTRY(455, 51, 2, 53, 0, 33, 7, 29, 3), - CABAC_ENTRY(456, 60, 6, 64, 3, 31, 12, 29, 9), - CABAC_ENTRY(457, 61, 17, 68, 10, 37, 23, 35, 20), - CABAC_ENTRY(458, 55, 34, 66, 27, 31, 38, 29, 36), - CABAC_ENTRY(459, 42, 62, 47, 57, 20, 64, 14, 67), -}; - -static void set_ps_field(u32 *buf, struct rkvdec_ps_field field, u32 value) -{ - u8 bit = field.offset % 32, word = field.offset / 32; - u64 mask = GENMASK_ULL(bit + field.len - 1, bit); - u64 val = ((u64)value << bit) & mask; - - buf[word] &= ~mask; - buf[word] |= val; - if (bit + field.len > 32) { - buf[word + 1] &= ~(mask >> 32); - buf[word + 1] |= val >> 32; - } -} - -static void assemble_hw_pps(struct rkvdec_ctx *ctx, - struct rkvdec_h264_run *run) -{ - struct rkvdec_h264_ctx *h264_ctx = ctx->priv; - const struct v4l2_ctrl_h264_sps *sps = run->sps; - const struct v4l2_ctrl_h264_pps *pps = run->pps; - const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; - const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; - struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu; - struct rkvdec_sps_pps_packet *hw_ps; - dma_addr_t scaling_list_address; - u32 scaling_distance; - u32 i; - - /* - * HW read the SPS/PPS information from PPS packet index by PPS id. - * offset from the base can be calculated by PPS_id * 32 (size per PPS - * packet unit). so the driver copy SPS/PPS information to the exact PPS - * packet unit for HW accessing. - */ - hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id]; - memset(hw_ps, 0, sizeof(*hw_ps)); - -#define WRITE_PPS(value, field) set_ps_field(hw_ps->info, field, value) - /* write sps */ - WRITE_PPS(0xf, SEQ_PARAMETER_SET_ID); - WRITE_PPS(0xff, PROFILE_IDC); - WRITE_PPS(1, CONSTRAINT_SET3_FLAG); - WRITE_PPS(sps->chroma_format_idc, CHROMA_FORMAT_IDC); - WRITE_PPS(sps->bit_depth_luma_minus8, BIT_DEPTH_LUMA); - WRITE_PPS(sps->bit_depth_chroma_minus8, BIT_DEPTH_CHROMA); - WRITE_PPS(0, QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG); - WRITE_PPS(sps->log2_max_frame_num_minus4, LOG2_MAX_FRAME_NUM_MINUS4); - WRITE_PPS(sps->max_num_ref_frames, MAX_NUM_REF_FRAMES); - WRITE_PPS(sps->pic_order_cnt_type, PIC_ORDER_CNT_TYPE); - WRITE_PPS(sps->log2_max_pic_order_cnt_lsb_minus4, - LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4); - WRITE_PPS(!!(sps->flags & V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO), - DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG); - - /* - * Use the SPS values since they are already in macroblocks - * dimensions, height can be field height (halved) if - * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY is not set and also it allows - * decoding smaller images into larger allocation which can be used - * to implementing SVC spatial layer support. - */ - WRITE_PPS(sps->pic_width_in_mbs_minus1 + 1, PIC_WIDTH_IN_MBS); - WRITE_PPS(sps->pic_height_in_map_units_minus1 + 1, PIC_HEIGHT_IN_MBS); - - WRITE_PPS(!!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY), - FRAME_MBS_ONLY_FLAG); - WRITE_PPS(!!(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD), - MB_ADAPTIVE_FRAME_FIELD_FLAG); - WRITE_PPS(!!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE), - DIRECT_8X8_INFERENCE_FLAG); - - /* write pps */ - WRITE_PPS(0xff, PIC_PARAMETER_SET_ID); - WRITE_PPS(0x1f, PPS_SEQ_PARAMETER_SET_ID); - WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE), - ENTROPY_CODING_MODE_FLAG); - WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT), - BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT_FLAG); - WRITE_PPS(pps->num_ref_idx_l0_default_active_minus1, - NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(0)); - WRITE_PPS(pps->num_ref_idx_l1_default_active_minus1, - NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(1)); - WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED), - WEIGHTED_PRED_FLAG); - WRITE_PPS(pps->weighted_bipred_idc, WEIGHTED_BIPRED_IDC); - WRITE_PPS(pps->pic_init_qp_minus26, PIC_INIT_QP_MINUS26); - WRITE_PPS(pps->pic_init_qs_minus26, PIC_INIT_QS_MINUS26); - WRITE_PPS(pps->chroma_qp_index_offset, CHROMA_QP_INDEX_OFFSET); - WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT), - DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG); - WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED), - CONSTRAINED_INTRA_PRED_FLAG); - WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT), - REDUNDANT_PIC_CNT_PRESENT); - WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE), - TRANSFORM_8X8_MODE_FLAG); - WRITE_PPS(pps->second_chroma_qp_index_offset, - SECOND_CHROMA_QP_INDEX_OFFSET); - - WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT), - SCALING_LIST_ENABLE_FLAG); - /* To be on the safe side, program the scaling matrix address */ - scaling_distance = offsetof(struct rkvdec_h264_priv_tbl, scaling_list); - scaling_list_address = h264_ctx->priv_tbl.dma + scaling_distance; - WRITE_PPS(scaling_list_address, SCALING_LIST_ADDRESS); - - for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { - u32 is_longterm = 0; - - if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) - is_longterm = 1; - - WRITE_PPS(is_longterm, IS_LONG_TERM(i)); - } -} - -static void lookup_ref_buf_idx(struct rkvdec_ctx *ctx, - struct rkvdec_h264_run *run) -{ - const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; - u32 i; - - for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { - struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; - const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb; - struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q; - struct vb2_buffer *buf = NULL; - - if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) { - buf = vb2_find_buffer(cap_q, dpb[i].reference_ts); - if (!buf) - pr_debug("No buffer for reference_ts %llu", - dpb[i].reference_ts); - } - - run->ref_buf[i] = buf; - } -} - -static void assemble_hw_rps(struct rkvdec_ctx *ctx, - struct v4l2_h264_reflist_builder *builder, - struct rkvdec_h264_run *run) -{ - const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; - const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; - struct rkvdec_h264_ctx *h264_ctx = ctx->priv; - struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu; - - u32 *hw_rps = priv_tbl->rps; - u32 i, j; - u16 *p = (u16 *)hw_rps; - - memset(hw_rps, 0, sizeof(priv_tbl->rps)); - - /* - * Assign an invalid pic_num if DPB entry at that position is inactive. - * If we assign 0 in that position hardware will treat that as a real - * reference picture with pic_num 0, triggering output picture - * corruption. - */ - for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { - if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) - continue; - - p[i] = builder->refs[i].frame_num; - } - - for (j = 0; j < RKVDEC_NUM_REFLIST; j++) { - for (i = 0; i < builder->num_valid; i++) { - struct v4l2_h264_reference *ref; - bool dpb_valid; - bool bottom; - - switch (j) { - case 0: - ref = &h264_ctx->reflists.p[i]; - break; - case 1: - ref = &h264_ctx->reflists.b0[i]; - break; - case 2: - ref = &h264_ctx->reflists.b1[i]; - break; - } - - if (WARN_ON(ref->index >= ARRAY_SIZE(dec_params->dpb))) - continue; - - dpb_valid = run->ref_buf[ref->index] != NULL; - bottom = ref->fields == V4L2_H264_BOTTOM_FIELD_REF; - - set_ps_field(hw_rps, DPB_INFO(i, j), - ref->index | dpb_valid << 4); - set_ps_field(hw_rps, BOTTOM_FLAG(i, j), bottom); - } - } -} - -static void assemble_hw_scaling_list(struct rkvdec_ctx *ctx, - struct rkvdec_h264_run *run) -{ - const struct v4l2_ctrl_h264_scaling_matrix *scaling = run->scaling_matrix; - const struct v4l2_ctrl_h264_pps *pps = run->pps; - struct rkvdec_h264_ctx *h264_ctx = ctx->priv; - struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu; - - if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT)) - return; - - BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_4x4) != - sizeof(scaling->scaling_list_4x4)); - BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_8x8) != - sizeof(scaling->scaling_list_8x8)); - - memcpy(tbl->scaling_list.scaling_list_4x4, - scaling->scaling_list_4x4, - sizeof(scaling->scaling_list_4x4)); - - memcpy(tbl->scaling_list.scaling_list_8x8, - scaling->scaling_list_8x8, - sizeof(scaling->scaling_list_8x8)); -} - -/* - * dpb poc related registers table - */ -static const u32 poc_reg_tbl_top_field[16] = { - RKVDEC_REG_H264_POC_REFER0(0), - RKVDEC_REG_H264_POC_REFER0(2), - RKVDEC_REG_H264_POC_REFER0(4), - RKVDEC_REG_H264_POC_REFER0(6), - RKVDEC_REG_H264_POC_REFER0(8), - RKVDEC_REG_H264_POC_REFER0(10), - RKVDEC_REG_H264_POC_REFER0(12), - RKVDEC_REG_H264_POC_REFER0(14), - RKVDEC_REG_H264_POC_REFER1(1), - RKVDEC_REG_H264_POC_REFER1(3), - RKVDEC_REG_H264_POC_REFER1(5), - RKVDEC_REG_H264_POC_REFER1(7), - RKVDEC_REG_H264_POC_REFER1(9), - RKVDEC_REG_H264_POC_REFER1(11), - RKVDEC_REG_H264_POC_REFER1(13), - RKVDEC_REG_H264_POC_REFER2(0) -}; - -static const u32 poc_reg_tbl_bottom_field[16] = { - RKVDEC_REG_H264_POC_REFER0(1), - RKVDEC_REG_H264_POC_REFER0(3), - RKVDEC_REG_H264_POC_REFER0(5), - RKVDEC_REG_H264_POC_REFER0(7), - RKVDEC_REG_H264_POC_REFER0(9), - RKVDEC_REG_H264_POC_REFER0(11), - RKVDEC_REG_H264_POC_REFER0(13), - RKVDEC_REG_H264_POC_REFER1(0), - RKVDEC_REG_H264_POC_REFER1(2), - RKVDEC_REG_H264_POC_REFER1(4), - RKVDEC_REG_H264_POC_REFER1(6), - RKVDEC_REG_H264_POC_REFER1(8), - RKVDEC_REG_H264_POC_REFER1(10), - RKVDEC_REG_H264_POC_REFER1(12), - RKVDEC_REG_H264_POC_REFER1(14), - RKVDEC_REG_H264_POC_REFER2(1) -}; - -static void config_registers(struct rkvdec_ctx *ctx, - struct rkvdec_h264_run *run) -{ - struct rkvdec_dev *rkvdec = ctx->dev; - const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; - const struct v4l2_ctrl_h264_sps *sps = run->sps; - const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; - struct rkvdec_h264_ctx *h264_ctx = ctx->priv; - dma_addr_t priv_start_addr = h264_ctx->priv_tbl.dma; - const struct v4l2_pix_format_mplane *dst_fmt; - struct vb2_v4l2_buffer *src_buf = run->base.bufs.src; - struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst; - const struct v4l2_format *f; - dma_addr_t rlc_addr; - dma_addr_t refer_addr; - u32 rlc_len; - u32 hor_virstride = 0; - u32 ver_virstride = 0; - u32 y_virstride = 0; - u32 yuv_virstride = 0; - u32 offset; - dma_addr_t dst_addr; - u32 reg, i; - - reg = RKVDEC_MODE(RKVDEC_MODE_H264); - writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_SYSCTRL); - - f = &ctx->decoded_fmt; - dst_fmt = &f->fmt.pix_mp; - hor_virstride = (sps->bit_depth_luma_minus8 + 8) * dst_fmt->width / 8; - ver_virstride = round_up(dst_fmt->height, 16); - y_virstride = hor_virstride * ver_virstride; - - if (sps->chroma_format_idc == 0) - yuv_virstride = y_virstride; - else if (sps->chroma_format_idc == 1) - yuv_virstride += y_virstride + y_virstride / 2; - else if (sps->chroma_format_idc == 2) - yuv_virstride += 2 * y_virstride; - - reg = RKVDEC_Y_HOR_VIRSTRIDE(hor_virstride / 16) | - RKVDEC_UV_HOR_VIRSTRIDE(hor_virstride / 16) | - RKVDEC_SLICE_NUM_HIGHBIT | - RKVDEC_SLICE_NUM_LOWBITS(0x7ff); - writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_PICPAR); - - /* config rlc base address */ - rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); - writel_relaxed(rlc_addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE); - writel_relaxed(rlc_addr, rkvdec->regs + RKVDEC_REG_RLCWRITE_BASE); - - rlc_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0); - reg = RKVDEC_STRM_LEN(rlc_len); - writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_STRM_LEN); - - /* config cabac table */ - offset = offsetof(struct rkvdec_h264_priv_tbl, cabac_table); - writel_relaxed(priv_start_addr + offset, - rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE); - - /* config output base address */ - dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); - writel_relaxed(dst_addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE); - - reg = RKVDEC_Y_VIRSTRIDE(y_virstride / 16); - writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE); - - reg = RKVDEC_YUV_VIRSTRIDE(yuv_virstride / 16); - writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE); - - /* config ref pic address & poc */ - for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { - struct vb2_buffer *vb_buf = run->ref_buf[i]; - - /* - * If a DPB entry is unused or invalid, address of current destination - * buffer is returned. - */ - if (!vb_buf) - vb_buf = &dst_buf->vb2_buf; - refer_addr = vb2_dma_contig_plane_dma_addr(vb_buf, 0); - - if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) - refer_addr |= RKVDEC_COLMV_USED_FLAG_REF; - if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD) - refer_addr |= RKVDEC_FIELD_REF; - - if (dpb[i].fields & V4L2_H264_TOP_FIELD_REF) - refer_addr |= RKVDEC_TOPFIELD_USED_REF; - if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF) - refer_addr |= RKVDEC_BOTFIELD_USED_REF; - - writel_relaxed(dpb[i].top_field_order_cnt, - rkvdec->regs + poc_reg_tbl_top_field[i]); - writel_relaxed(dpb[i].bottom_field_order_cnt, - rkvdec->regs + poc_reg_tbl_bottom_field[i]); - - if (i < V4L2_H264_NUM_DPB_ENTRIES - 1) - writel_relaxed(refer_addr, - rkvdec->regs + RKVDEC_REG_H264_BASE_REFER(i)); - else - writel_relaxed(refer_addr, - rkvdec->regs + RKVDEC_REG_H264_BASE_REFER15); - } - - reg = RKVDEC_CUR_POC(dec_params->top_field_order_cnt); - writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC0); - - reg = RKVDEC_CUR_POC(dec_params->bottom_field_order_cnt); - writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC1); - - /* config hw pps address */ - offset = offsetof(struct rkvdec_h264_priv_tbl, param_set); - writel_relaxed(priv_start_addr + offset, - rkvdec->regs + RKVDEC_REG_PPS_BASE); - - /* config hw rps address */ - offset = offsetof(struct rkvdec_h264_priv_tbl, rps); - writel_relaxed(priv_start_addr + offset, - rkvdec->regs + RKVDEC_REG_RPS_BASE); - - reg = RKVDEC_AXI_DDR_RDATA(0); - writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_AXI_DDR_RDATA); - - reg = RKVDEC_AXI_DDR_WDATA(0); - writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_AXI_DDR_WDATA); - - offset = offsetof(struct rkvdec_h264_priv_tbl, err_info); - writel_relaxed(priv_start_addr + offset, - rkvdec->regs + RKVDEC_REG_H264_ERRINFO_BASE); -} - -#define RKVDEC_H264_MAX_DEPTH_IN_BYTES 2 - -static int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx, - struct v4l2_format *f) -{ - struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp; - - fmt->num_planes = 1; - if (!fmt->plane_fmt[0].sizeimage) - fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * - RKVDEC_H264_MAX_DEPTH_IN_BYTES; - return 0; -} - -static int rkvdec_h264_validate_sps(struct rkvdec_ctx *ctx, - const struct v4l2_ctrl_h264_sps *sps) -{ - unsigned int width, height; - - /* - * TODO: The hardware supports 10-bit and 4:2:2 profiles, - * but it's currently broken in the driver. - * Reject them for now, until it's fixed. - */ - if (sps->chroma_format_idc > 1) - /* Only 4:0:0 and 4:2:0 are supported */ - return -EINVAL; - if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) - /* Luma and chroma bit depth mismatch */ - return -EINVAL; - if (sps->bit_depth_luma_minus8 != 0) - /* Only 8-bit is supported */ - return -EINVAL; - - width = (sps->pic_width_in_mbs_minus1 + 1) * 16; - height = (sps->pic_height_in_map_units_minus1 + 1) * 16; - - /* - * When frame_mbs_only_flag is not set, this is field height, - * which is half the final height (see (7-18) in the - * specification) - */ - if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)) - height *= 2; - - if (width > ctx->coded_fmt.fmt.pix_mp.width || - height > ctx->coded_fmt.fmt.pix_mp.height) - return -EINVAL; - - return 0; -} - -static int rkvdec_h264_start(struct rkvdec_ctx *ctx) -{ - struct rkvdec_dev *rkvdec = ctx->dev; - struct rkvdec_h264_priv_tbl *priv_tbl; - struct rkvdec_h264_ctx *h264_ctx; - struct v4l2_ctrl *ctrl; - int ret; - - ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, - V4L2_CID_STATELESS_H264_SPS); - if (!ctrl) - return -EINVAL; - - ret = rkvdec_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps); - if (ret) - return ret; - - h264_ctx = kzalloc(sizeof(*h264_ctx), GFP_KERNEL); - if (!h264_ctx) - return -ENOMEM; - - priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl), - &h264_ctx->priv_tbl.dma, GFP_KERNEL); - if (!priv_tbl) { - ret = -ENOMEM; - goto err_free_ctx; - } - - h264_ctx->priv_tbl.size = sizeof(*priv_tbl); - h264_ctx->priv_tbl.cpu = priv_tbl; - memcpy(priv_tbl->cabac_table, rkvdec_h264_cabac_table, - sizeof(rkvdec_h264_cabac_table)); - - ctx->priv = h264_ctx; - return 0; - -err_free_ctx: - kfree(h264_ctx); - return ret; -} - -static void rkvdec_h264_stop(struct rkvdec_ctx *ctx) -{ - struct rkvdec_h264_ctx *h264_ctx = ctx->priv; - struct rkvdec_dev *rkvdec = ctx->dev; - - dma_free_coherent(rkvdec->dev, h264_ctx->priv_tbl.size, - h264_ctx->priv_tbl.cpu, h264_ctx->priv_tbl.dma); - kfree(h264_ctx); -} - -static void rkvdec_h264_run_preamble(struct rkvdec_ctx *ctx, - struct rkvdec_h264_run *run) -{ - struct v4l2_ctrl *ctrl; - - ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, - V4L2_CID_STATELESS_H264_DECODE_PARAMS); - run->decode_params = ctrl ? ctrl->p_cur.p : NULL; - ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, - V4L2_CID_STATELESS_H264_SPS); - run->sps = ctrl ? ctrl->p_cur.p : NULL; - ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, - V4L2_CID_STATELESS_H264_PPS); - run->pps = ctrl ? ctrl->p_cur.p : NULL; - ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, - V4L2_CID_STATELESS_H264_SCALING_MATRIX); - run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL; - - rkvdec_run_preamble(ctx, &run->base); -} - -static int rkvdec_h264_run(struct rkvdec_ctx *ctx) -{ - struct v4l2_h264_reflist_builder reflist_builder; - struct rkvdec_dev *rkvdec = ctx->dev; - struct rkvdec_h264_ctx *h264_ctx = ctx->priv; - struct rkvdec_h264_run run; - - rkvdec_h264_run_preamble(ctx, &run); - - /* Build the P/B{0,1} ref lists. */ - v4l2_h264_init_reflist_builder(&reflist_builder, run.decode_params, - run.sps, run.decode_params->dpb); - v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p); - v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0, - h264_ctx->reflists.b1); - - assemble_hw_scaling_list(ctx, &run); - assemble_hw_pps(ctx, &run); - lookup_ref_buf_idx(ctx, &run); - assemble_hw_rps(ctx, &reflist_builder, &run); - config_registers(ctx, &run); - - rkvdec_run_postamble(ctx, &run.base); - - schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000)); - - writel(0, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN); - writel(0, rkvdec->regs + RKVDEC_REG_H264_ERR_E); - writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND); - writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND); - - /* Start decoding! */ - writel(RKVDEC_INTERRUPT_DEC_E | RKVDEC_CONFIG_DEC_CLK_GATE_E | - RKVDEC_TIMEOUT_E | RKVDEC_BUF_EMPTY_E, - rkvdec->regs + RKVDEC_REG_INTERRUPT); - - return 0; -} - -static int rkvdec_h264_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl) -{ - if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) - return rkvdec_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps); - - return 0; -} - -const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops = { - .adjust_fmt = rkvdec_h264_adjust_fmt, - .start = rkvdec_h264_start, - .stop = rkvdec_h264_stop, - .run = rkvdec_h264_run, - .try_ctrl = rkvdec_h264_try_ctrl, -}; diff --git a/drivers/staging/media/rkvdec/rkvdec-regs.h b/drivers/staging/media/rkvdec/rkvdec-regs.h deleted file mode 100644 index 15b9bee92016..000000000000 --- a/drivers/staging/media/rkvdec/rkvdec-regs.h +++ /dev/null @@ -1,223 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#ifndef RKVDEC_REGS_H_ -#define RKVDEC_REGS_H_ - -/* rkvcodec registers */ -#define RKVDEC_REG_INTERRUPT 0x004 -#define RKVDEC_INTERRUPT_DEC_E BIT(0) -#define RKVDEC_CONFIG_DEC_CLK_GATE_E BIT(1) -#define RKVDEC_E_STRMD_CLKGATE_DIS BIT(2) -#define RKVDEC_TIMEOUT_MODE BIT(3) -#define RKVDEC_IRQ_DIS BIT(4) -#define RKVDEC_TIMEOUT_E BIT(5) -#define RKVDEC_BUF_EMPTY_E BIT(6) -#define RKVDEC_STRM_E_WAITDECFIFO_EMPTY BIT(7) -#define RKVDEC_IRQ BIT(8) -#define RKVDEC_IRQ_RAW BIT(9) -#define RKVDEC_E_REWRITE_VALID BIT(10) -#define RKVDEC_COMMONIRQ_MODE BIT(11) -#define RKVDEC_RDY_STA BIT(12) -#define RKVDEC_BUS_STA BIT(13) -#define RKVDEC_ERR_STA BIT(14) -#define RKVDEC_TIMEOUT_STA BIT(15) -#define RKVDEC_BUF_EMPTY_STA BIT(16) -#define RKVDEC_COLMV_REF_ERR_STA BIT(17) -#define RKVDEC_CABU_END_STA BIT(18) -#define RKVDEC_H264ORVP9_ERR_MODE BIT(19) -#define RKVDEC_SOFTRST_EN_P BIT(20) -#define RKVDEC_FORCE_SOFTRESET_VALID BIT(21) -#define RKVDEC_SOFTRESET_RDY BIT(22) - -#define RKVDEC_REG_SYSCTRL 0x008 -#define RKVDEC_IN_ENDIAN BIT(0) -#define RKVDEC_IN_SWAP32_E BIT(1) -#define RKVDEC_IN_SWAP64_E BIT(2) -#define RKVDEC_STR_ENDIAN BIT(3) -#define RKVDEC_STR_SWAP32_E BIT(4) -#define RKVDEC_STR_SWAP64_E BIT(5) -#define RKVDEC_OUT_ENDIAN BIT(6) -#define RKVDEC_OUT_SWAP32_E BIT(7) -#define RKVDEC_OUT_CBCR_SWAP BIT(8) -#define RKVDEC_RLC_MODE_DIRECT_WRITE BIT(10) -#define RKVDEC_RLC_MODE BIT(11) -#define RKVDEC_STRM_START_BIT(x) (((x) & 0x7f) << 12) -#define RKVDEC_MODE(x) (((x) & 0x03) << 20) -#define RKVDEC_MODE_H264 1 -#define RKVDEC_MODE_VP9 2 -#define RKVDEC_RPS_MODE BIT(24) -#define RKVDEC_STRM_MODE BIT(25) -#define RKVDEC_H264_STRM_LASTPKT BIT(26) -#define RKVDEC_H264_FIRSTSLICE_FLAG BIT(27) -#define RKVDEC_H264_FRAME_ORSLICE BIT(28) -#define RKVDEC_BUSPR_SLOT_DIS BIT(29) - -#define RKVDEC_REG_PICPAR 0x00C -#define RKVDEC_Y_HOR_VIRSTRIDE(x) ((x) & 0x1ff) -#define RKVDEC_SLICE_NUM_HIGHBIT BIT(11) -#define RKVDEC_UV_HOR_VIRSTRIDE(x) (((x) & 0x1ff) << 12) -#define RKVDEC_SLICE_NUM_LOWBITS(x) (((x) & 0x7ff) << 21) - -#define RKVDEC_REG_STRM_RLC_BASE 0x010 - -#define RKVDEC_REG_STRM_LEN 0x014 -#define RKVDEC_STRM_LEN(x) ((x) & 0x7ffffff) - -#define RKVDEC_REG_CABACTBL_PROB_BASE 0x018 -#define RKVDEC_REG_DECOUT_BASE 0x01C - -#define RKVDEC_REG_Y_VIRSTRIDE 0x020 -#define RKVDEC_Y_VIRSTRIDE(x) ((x) & 0xfffff) - -#define RKVDEC_REG_YUV_VIRSTRIDE 0x024 -#define RKVDEC_YUV_VIRSTRIDE(x) ((x) & 0x1fffff) -#define RKVDEC_REG_H264_BASE_REFER(i) (((i) * 0x04) + 0x028) - -#define RKVDEC_REG_H264_BASE_REFER15 0x0C0 -#define RKVDEC_FIELD_REF BIT(0) -#define RKVDEC_TOPFIELD_USED_REF BIT(1) -#define RKVDEC_BOTFIELD_USED_REF BIT(2) -#define RKVDEC_COLMV_USED_FLAG_REF BIT(3) - -#define RKVDEC_REG_VP9_LAST_FRAME_BASE 0x02c -#define RKVDEC_REG_VP9_GOLDEN_FRAME_BASE 0x030 -#define RKVDEC_REG_VP9_ALTREF_FRAME_BASE 0x034 - -#define RKVDEC_REG_VP9_CPRHEADER_OFFSET 0x028 -#define RKVDEC_VP9_CPRHEADER_OFFSET(x) ((x) & 0xffff) - -#define RKVDEC_REG_VP9_REFERLAST_BASE 0x02C -#define RKVDEC_REG_VP9_REFERGOLDEN_BASE 0x030 -#define RKVDEC_REG_VP9_REFERALFTER_BASE 0x034 - -#define RKVDEC_REG_VP9COUNT_BASE 0x038 -#define RKVDEC_VP9COUNT_UPDATE_EN BIT(0) - -#define RKVDEC_REG_VP9_SEGIDLAST_BASE 0x03C -#define RKVDEC_REG_VP9_SEGIDCUR_BASE 0x040 -#define RKVDEC_REG_VP9_FRAME_SIZE(i) ((i) * 0x04 + 0x044) -#define RKVDEC_VP9_FRAMEWIDTH(x) (((x) & 0xffff) << 0) -#define RKVDEC_VP9_FRAMEHEIGHT(x) (((x) & 0xffff) << 16) - -#define RKVDEC_VP9_SEGID_GRP(i) ((i) * 0x04 + 0x050) -#define RKVDEC_SEGID_ABS_DELTA(x) ((x) & 0x1) -#define RKVDEC_SEGID_FRAME_QP_DELTA_EN(x) (((x) & 0x1) << 1) -#define RKVDEC_SEGID_FRAME_QP_DELTA(x) (((x) & 0x1ff) << 2) -#define RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE_EN(x) (((x) & 0x1) << 11) -#define RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE(x) (((x) & 0x7f) << 12) -#define RKVDEC_SEGID_REFERINFO_EN(x) (((x) & 0x1) << 19) -#define RKVDEC_SEGID_REFERINFO(x) (((x) & 0x03) << 20) -#define RKVDEC_SEGID_FRAME_SKIP_EN(x) (((x) & 0x1) << 22) - -#define RKVDEC_VP9_CPRHEADER_CONFIG 0x070 -#define RKVDEC_VP9_TX_MODE(x) ((x) & 0x07) -#define RKVDEC_VP9_FRAME_REF_MODE(x) (((x) & 0x03) << 3) - -#define RKVDEC_VP9_REF_SCALE(i) ((i) * 0x04 + 0x074) -#define RKVDEC_VP9_REF_HOR_SCALE(x) ((x) & 0xffff) -#define RKVDEC_VP9_REF_VER_SCALE(x) (((x) & 0xffff) << 16) - -#define RKVDEC_VP9_REF_DELTAS_LASTFRAME 0x080 -#define RKVDEC_REF_DELTAS_LASTFRAME(pos, val) (((val) & 0x7f) << ((pos) * 7)) - -#define RKVDEC_VP9_INFO_LASTFRAME 0x084 -#define RKVDEC_MODE_DELTAS_LASTFRAME(pos, val) (((val) & 0x7f) << ((pos) * 7)) -#define RKVDEC_SEG_EN_LASTFRAME BIT(16) -#define RKVDEC_LAST_SHOW_FRAME BIT(17) -#define RKVDEC_LAST_INTRA_ONLY BIT(18) -#define RKVDEC_LAST_WIDHHEIGHT_EQCUR BIT(19) -#define RKVDEC_COLOR_SPACE_LASTKEYFRAME(x) (((x) & 0x07) << 20) - -#define RKVDEC_VP9_INTERCMD_BASE 0x088 - -#define RKVDEC_VP9_INTERCMD_NUM 0x08C -#define RKVDEC_INTERCMD_NUM(x) ((x) & 0xffffff) - -#define RKVDEC_VP9_LASTTILE_SIZE 0x090 -#define RKVDEC_LASTTILE_SIZE(x) ((x) & 0xffffff) - -#define RKVDEC_VP9_HOR_VIRSTRIDE(i) ((i) * 0x04 + 0x094) -#define RKVDEC_HOR_Y_VIRSTRIDE(x) ((x) & 0x1ff) -#define RKVDEC_HOR_UV_VIRSTRIDE(x) (((x) & 0x1ff) << 16) - -#define RKVDEC_REG_H264_POC_REFER0(i) (((i) * 0x04) + 0x064) -#define RKVDEC_REG_H264_POC_REFER1(i) (((i) * 0x04) + 0x0C4) -#define RKVDEC_REG_H264_POC_REFER2(i) (((i) * 0x04) + 0x120) -#define RKVDEC_POC_REFER(x) ((x) & 0xffffffff) - -#define RKVDEC_REG_CUR_POC0 0x0A0 -#define RKVDEC_REG_CUR_POC1 0x128 -#define RKVDEC_CUR_POC(x) ((x) & 0xffffffff) - -#define RKVDEC_REG_RLCWRITE_BASE 0x0A4 -#define RKVDEC_REG_PPS_BASE 0x0A8 -#define RKVDEC_REG_RPS_BASE 0x0AC - -#define RKVDEC_REG_STRMD_ERR_EN 0x0B0 -#define RKVDEC_STRMD_ERR_EN(x) ((x) & 0xffffffff) - -#define RKVDEC_REG_STRMD_ERR_STA 0x0B4 -#define RKVDEC_STRMD_ERR_STA(x) ((x) & 0xfffffff) -#define RKVDEC_COLMV_ERR_REF_PICIDX(x) (((x) & 0x0f) << 28) - -#define RKVDEC_REG_STRMD_ERR_CTU 0x0B8 -#define RKVDEC_STRMD_ERR_CTU(x) ((x) & 0xff) -#define RKVDEC_STRMD_ERR_CTU_YOFFSET(x) (((x) & 0xff) << 8) -#define RKVDEC_STRMFIFO_SPACE2FULL(x) (((x) & 0x7f) << 16) -#define RKVDEC_VP9_ERR_EN_CTU0 BIT(24) - -#define RKVDEC_REG_SAO_CTU_POS 0x0BC -#define RKVDEC_SAOWR_XOFFSET(x) ((x) & 0x1ff) -#define RKVDEC_SAOWR_YOFFSET(x) (((x) & 0x3ff) << 16) - -#define RKVDEC_VP9_LAST_FRAME_YSTRIDE 0x0C0 -#define RKVDEC_VP9_GOLDEN_FRAME_YSTRIDE 0x0C4 -#define RKVDEC_VP9_ALTREF_FRAME_YSTRIDE 0x0C8 -#define RKVDEC_VP9_REF_YSTRIDE(x) (((x) & 0xfffff) << 0) - -#define RKVDEC_VP9_LAST_FRAME_YUVSTRIDE 0x0CC -#define RKVDEC_VP9_REF_YUVSTRIDE(x) (((x) & 0x1fffff) << 0) - -#define RKVDEC_VP9_REF_COLMV_BASE 0x0D0 - -#define RKVDEC_REG_PERFORMANCE_CYCLE 0x100 -#define RKVDEC_PERFORMANCE_CYCLE(x) ((x) & 0xffffffff) - -#define RKVDEC_REG_AXI_DDR_RDATA 0x104 -#define RKVDEC_AXI_DDR_RDATA(x) ((x) & 0xffffffff) - -#define RKVDEC_REG_AXI_DDR_WDATA 0x108 -#define RKVDEC_AXI_DDR_WDATA(x) ((x) & 0xffffffff) - -#define RKVDEC_REG_FPGADEBUG_RESET 0x10C -#define RKVDEC_BUSIFD_RESETN BIT(0) -#define RKVDEC_CABAC_RESETN BIT(1) -#define RKVDEC_DEC_CTRL_RESETN BIT(2) -#define RKVDEC_TRANSD_RESETN BIT(3) -#define RKVDEC_INTRA_RESETN BIT(4) -#define RKVDEC_INTER_RESETN BIT(5) -#define RKVDEC_RECON_RESETN BIT(6) -#define RKVDEC_FILER_RESETN BIT(7) - -#define RKVDEC_REG_PERFORMANCE_SEL 0x110 -#define RKVDEC_PERF_SEL_CNT0(x) ((x) & 0x3f) -#define RKVDEC_PERF_SEL_CNT1(x) (((x) & 0x3f) << 8) -#define RKVDEC_PERF_SEL_CNT2(x) (((x) & 0x3f) << 16) - -#define RKVDEC_REG_PERFORMANCE_CNT(i) ((i) * 0x04 + 0x114) -#define RKVDEC_PERF_CNT(x) ((x) & 0xffffffff) - -#define RKVDEC_REG_H264_ERRINFO_BASE 0x12C - -#define RKVDEC_REG_H264_ERRINFO_NUM 0x130 -#define RKVDEC_SLICEDEC_NUM(x) ((x) & 0x3fff) -#define RKVDEC_STRMD_DECT_ERR_FLAG BIT(15) -#define RKVDEC_ERR_PKT_NUM(x) (((x) & 0x3fff) << 16) - -#define RKVDEC_REG_H264_ERR_E 0x134 -#define RKVDEC_H264_ERR_EN_HIGHBITS(x) ((x) & 0x3fffffff) - -#define RKVDEC_REG_PREF_LUMA_CACHE_COMMAND 0x410 -#define RKVDEC_REG_PREF_CHR_CACHE_COMMAND 0x450 - -#endif /* RKVDEC_REGS_H_ */ diff --git a/drivers/staging/media/rkvdec/rkvdec-vp9.c b/drivers/staging/media/rkvdec/rkvdec-vp9.c deleted file mode 100644 index 0e7e16f20eeb..000000000000 --- a/drivers/staging/media/rkvdec/rkvdec-vp9.c +++ /dev/null @@ -1,1072 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Rockchip Video Decoder VP9 backend - * - * Copyright (C) 2019 Collabora, Ltd. - * Boris Brezillon <boris.brezillon@collabora.com> - * Copyright (C) 2021 Collabora, Ltd. - * Andrzej Pietrasiewicz <andrzej.p@collabora.com> - * - * Copyright (C) 2016 Rockchip Electronics Co., Ltd. - * Alpha Lin <Alpha.Lin@rock-chips.com> - */ - -/* - * For following the vp9 spec please start reading this driver - * code from rkvdec_vp9_run() followed by rkvdec_vp9_done(). - */ - -#include <linux/kernel.h> -#include <linux/vmalloc.h> -#include <media/v4l2-mem2mem.h> -#include <media/v4l2-vp9.h> - -#include "rkvdec.h" -#include "rkvdec-regs.h" - -#define RKVDEC_VP9_PROBE_SIZE 4864 -#define RKVDEC_VP9_COUNT_SIZE 13232 -#define RKVDEC_VP9_MAX_SEGMAP_SIZE 73728 - -struct rkvdec_vp9_intra_mode_probs { - u8 y_mode[105]; - u8 uv_mode[23]; -}; - -struct rkvdec_vp9_intra_only_frame_probs { - u8 coef_intra[4][2][128]; - struct rkvdec_vp9_intra_mode_probs intra_mode[10]; -}; - -struct rkvdec_vp9_inter_frame_probs { - u8 y_mode[4][9]; - u8 comp_mode[5]; - u8 comp_ref[5]; - u8 single_ref[5][2]; - u8 inter_mode[7][3]; - u8 interp_filter[4][2]; - u8 padding0[11]; - u8 coef[2][4][2][128]; - u8 uv_mode_0_2[3][9]; - u8 padding1[5]; - u8 uv_mode_3_5[3][9]; - u8 padding2[5]; - u8 uv_mode_6_8[3][9]; - u8 padding3[5]; - u8 uv_mode_9[9]; - u8 padding4[7]; - u8 padding5[16]; - struct { - u8 joint[3]; - u8 sign[2]; - u8 classes[2][10]; - u8 class0_bit[2]; - u8 bits[2][10]; - u8 class0_fr[2][2][3]; - u8 fr[2][3]; - u8 class0_hp[2]; - u8 hp[2]; - } mv; -}; - -struct rkvdec_vp9_probs { - u8 partition[16][3]; - u8 pred[3]; - u8 tree[7]; - u8 skip[3]; - u8 tx32[2][3]; - u8 tx16[2][2]; - u8 tx8[2][1]; - u8 is_inter[4]; - /* 128 bit alignment */ - u8 padding0[3]; - union { - struct rkvdec_vp9_inter_frame_probs inter; - struct rkvdec_vp9_intra_only_frame_probs intra_only; - }; - /* 128 bit alignment */ - u8 padding1[11]; -}; - -/* Data structure describing auxiliary buffer format. */ -struct rkvdec_vp9_priv_tbl { - struct rkvdec_vp9_probs probs; - u8 segmap[2][RKVDEC_VP9_MAX_SEGMAP_SIZE]; -}; - -struct rkvdec_vp9_refs_counts { - u32 eob[2]; - u32 coeff[3]; -}; - -struct rkvdec_vp9_inter_frame_symbol_counts { - u32 partition[16][4]; - u32 skip[3][2]; - u32 inter[4][2]; - u32 tx32p[2][4]; - u32 tx16p[2][4]; - u32 tx8p[2][2]; - u32 y_mode[4][10]; - u32 uv_mode[10][10]; - u32 comp[5][2]; - u32 comp_ref[5][2]; - u32 single_ref[5][2][2]; - u32 mv_mode[7][4]; - u32 filter[4][3]; - u32 mv_joint[4]; - u32 sign[2][2]; - /* add 1 element for align */ - u32 classes[2][11 + 1]; - u32 class0[2][2]; - u32 bits[2][10][2]; - u32 class0_fp[2][2][4]; - u32 fp[2][4]; - u32 class0_hp[2][2]; - u32 hp[2][2]; - struct rkvdec_vp9_refs_counts ref_cnt[2][4][2][6][6]; -}; - -struct rkvdec_vp9_intra_frame_symbol_counts { - u32 partition[4][4][4]; - u32 skip[3][2]; - u32 intra[4][2]; - u32 tx32p[2][4]; - u32 tx16p[2][4]; - u32 tx8p[2][2]; - struct rkvdec_vp9_refs_counts ref_cnt[2][4][2][6][6]; -}; - -struct rkvdec_vp9_run { - struct rkvdec_run base; - const struct v4l2_ctrl_vp9_frame *decode_params; -}; - -struct rkvdec_vp9_frame_info { - u32 valid : 1; - u32 segmapid : 1; - u32 frame_context_idx : 2; - u32 reference_mode : 2; - u32 tx_mode : 3; - u32 interpolation_filter : 3; - u32 flags; - u64 timestamp; - struct v4l2_vp9_segmentation seg; - struct v4l2_vp9_loop_filter lf; -}; - -struct rkvdec_vp9_ctx { - struct rkvdec_aux_buf priv_tbl; - struct rkvdec_aux_buf count_tbl; - struct v4l2_vp9_frame_symbol_counts inter_cnts; - struct v4l2_vp9_frame_symbol_counts intra_cnts; - struct v4l2_vp9_frame_context probability_tables; - struct v4l2_vp9_frame_context frame_context[4]; - struct rkvdec_vp9_frame_info cur; - struct rkvdec_vp9_frame_info last; -}; - -static void write_coeff_plane(const u8 coef[6][6][3], u8 *coeff_plane) -{ - unsigned int idx = 0, byte_count = 0; - int k, m, n; - u8 p; - - for (k = 0; k < 6; k++) { - for (m = 0; m < 6; m++) { - for (n = 0; n < 3; n++) { - p = coef[k][m][n]; - coeff_plane[idx++] = p; - byte_count++; - if (byte_count == 27) { - idx += 5; - byte_count = 0; - } - } - } - } -} - -static void init_intra_only_probs(struct rkvdec_ctx *ctx, - const struct rkvdec_vp9_run *run) -{ - struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; - struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu; - struct rkvdec_vp9_intra_only_frame_probs *rkprobs; - const struct v4l2_vp9_frame_context *probs; - unsigned int i, j, k; - - rkprobs = &tbl->probs.intra_only; - probs = &vp9_ctx->probability_tables; - - /* - * intra only 149 x 128 bits ,aligned to 152 x 128 bits coeff related - * prob 64 x 128 bits - */ - for (i = 0; i < ARRAY_SIZE(probs->coef); i++) { - for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++) - write_coeff_plane(probs->coef[i][j][0], - rkprobs->coef_intra[i][j]); - } - - /* intra mode prob 80 x 128 bits */ - for (i = 0; i < ARRAY_SIZE(v4l2_vp9_kf_y_mode_prob); i++) { - unsigned int byte_count = 0; - int idx = 0; - - /* vp9_kf_y_mode_prob */ - for (j = 0; j < ARRAY_SIZE(v4l2_vp9_kf_y_mode_prob[0]); j++) { - for (k = 0; k < ARRAY_SIZE(v4l2_vp9_kf_y_mode_prob[0][0]); - k++) { - u8 val = v4l2_vp9_kf_y_mode_prob[i][j][k]; - - rkprobs->intra_mode[i].y_mode[idx++] = val; - byte_count++; - if (byte_count == 27) { - byte_count = 0; - idx += 5; - } - } - } - } - - for (i = 0; i < sizeof(v4l2_vp9_kf_uv_mode_prob); ++i) { - const u8 *ptr = (const u8 *)v4l2_vp9_kf_uv_mode_prob; - - rkprobs->intra_mode[i / 23].uv_mode[i % 23] = ptr[i]; - } -} - -static void init_inter_probs(struct rkvdec_ctx *ctx, - const struct rkvdec_vp9_run *run) -{ - struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; - struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu; - struct rkvdec_vp9_inter_frame_probs *rkprobs; - const struct v4l2_vp9_frame_context *probs; - unsigned int i, j, k; - - rkprobs = &tbl->probs.inter; - probs = &vp9_ctx->probability_tables; - - /* - * inter probs - * 151 x 128 bits, aligned to 152 x 128 bits - * inter only - * intra_y_mode & inter_block info 6 x 128 bits - */ - - memcpy(rkprobs->y_mode, probs->y_mode, sizeof(rkprobs->y_mode)); - memcpy(rkprobs->comp_mode, probs->comp_mode, - sizeof(rkprobs->comp_mode)); - memcpy(rkprobs->comp_ref, probs->comp_ref, - sizeof(rkprobs->comp_ref)); - memcpy(rkprobs->single_ref, probs->single_ref, - sizeof(rkprobs->single_ref)); - memcpy(rkprobs->inter_mode, probs->inter_mode, - sizeof(rkprobs->inter_mode)); - memcpy(rkprobs->interp_filter, probs->interp_filter, - sizeof(rkprobs->interp_filter)); - - /* 128 x 128 bits coeff related */ - for (i = 0; i < ARRAY_SIZE(probs->coef); i++) { - for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++) { - for (k = 0; k < ARRAY_SIZE(probs->coef[0][0]); k++) - write_coeff_plane(probs->coef[i][j][k], - rkprobs->coef[k][i][j]); - } - } - - /* intra uv mode 6 x 128 */ - memcpy(rkprobs->uv_mode_0_2, &probs->uv_mode[0], - sizeof(rkprobs->uv_mode_0_2)); - memcpy(rkprobs->uv_mode_3_5, &probs->uv_mode[3], - sizeof(rkprobs->uv_mode_3_5)); - memcpy(rkprobs->uv_mode_6_8, &probs->uv_mode[6], - sizeof(rkprobs->uv_mode_6_8)); - memcpy(rkprobs->uv_mode_9, &probs->uv_mode[9], - sizeof(rkprobs->uv_mode_9)); - - /* mv related 6 x 128 */ - memcpy(rkprobs->mv.joint, probs->mv.joint, - sizeof(rkprobs->mv.joint)); - memcpy(rkprobs->mv.sign, probs->mv.sign, - sizeof(rkprobs->mv.sign)); - memcpy(rkprobs->mv.classes, probs->mv.classes, - sizeof(rkprobs->mv.classes)); - memcpy(rkprobs->mv.class0_bit, probs->mv.class0_bit, - sizeof(rkprobs->mv.class0_bit)); - memcpy(rkprobs->mv.bits, probs->mv.bits, - sizeof(rkprobs->mv.bits)); - memcpy(rkprobs->mv.class0_fr, probs->mv.class0_fr, - sizeof(rkprobs->mv.class0_fr)); - memcpy(rkprobs->mv.fr, probs->mv.fr, - sizeof(rkprobs->mv.fr)); - memcpy(rkprobs->mv.class0_hp, probs->mv.class0_hp, - sizeof(rkprobs->mv.class0_hp)); - memcpy(rkprobs->mv.hp, probs->mv.hp, - sizeof(rkprobs->mv.hp)); -} - -static void init_probs(struct rkvdec_ctx *ctx, - const struct rkvdec_vp9_run *run) -{ - const struct v4l2_ctrl_vp9_frame *dec_params; - struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; - struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu; - struct rkvdec_vp9_probs *rkprobs = &tbl->probs; - const struct v4l2_vp9_segmentation *seg; - const struct v4l2_vp9_frame_context *probs; - bool intra_only; - - dec_params = run->decode_params; - probs = &vp9_ctx->probability_tables; - seg = &dec_params->seg; - - memset(rkprobs, 0, sizeof(*rkprobs)); - - intra_only = !!(dec_params->flags & - (V4L2_VP9_FRAME_FLAG_KEY_FRAME | - V4L2_VP9_FRAME_FLAG_INTRA_ONLY)); - - /* sb info 5 x 128 bit */ - memcpy(rkprobs->partition, - intra_only ? v4l2_vp9_kf_partition_probs : probs->partition, - sizeof(rkprobs->partition)); - - memcpy(rkprobs->pred, seg->pred_probs, sizeof(rkprobs->pred)); - memcpy(rkprobs->tree, seg->tree_probs, sizeof(rkprobs->tree)); - memcpy(rkprobs->skip, probs->skip, sizeof(rkprobs->skip)); - memcpy(rkprobs->tx32, probs->tx32, sizeof(rkprobs->tx32)); - memcpy(rkprobs->tx16, probs->tx16, sizeof(rkprobs->tx16)); - memcpy(rkprobs->tx8, probs->tx8, sizeof(rkprobs->tx8)); - memcpy(rkprobs->is_inter, probs->is_inter, sizeof(rkprobs->is_inter)); - - if (intra_only) - init_intra_only_probs(ctx, run); - else - init_inter_probs(ctx, run); -} - -struct rkvdec_vp9_ref_reg { - u32 reg_frm_size; - u32 reg_hor_stride; - u32 reg_y_stride; - u32 reg_yuv_stride; - u32 reg_ref_base; -}; - -static struct rkvdec_vp9_ref_reg ref_regs[] = { - { - .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(0), - .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(0), - .reg_y_stride = RKVDEC_VP9_LAST_FRAME_YSTRIDE, - .reg_yuv_stride = RKVDEC_VP9_LAST_FRAME_YUVSTRIDE, - .reg_ref_base = RKVDEC_REG_VP9_LAST_FRAME_BASE, - }, - { - .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(1), - .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(1), - .reg_y_stride = RKVDEC_VP9_GOLDEN_FRAME_YSTRIDE, - .reg_yuv_stride = 0, - .reg_ref_base = RKVDEC_REG_VP9_GOLDEN_FRAME_BASE, - }, - { - .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(2), - .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(2), - .reg_y_stride = RKVDEC_VP9_ALTREF_FRAME_YSTRIDE, - .reg_yuv_stride = 0, - .reg_ref_base = RKVDEC_REG_VP9_ALTREF_FRAME_BASE, - } -}; - -static struct rkvdec_decoded_buffer * -get_ref_buf(struct rkvdec_ctx *ctx, struct vb2_v4l2_buffer *dst, u64 timestamp) -{ - struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; - struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q; - struct vb2_buffer *buf; - - /* - * If a ref is unused or invalid, address of current destination - * buffer is returned. - */ - buf = vb2_find_buffer(cap_q, timestamp); - if (!buf) - buf = &dst->vb2_buf; - - return vb2_to_rkvdec_decoded_buf(buf); -} - -static dma_addr_t get_mv_base_addr(struct rkvdec_decoded_buffer *buf) -{ - unsigned int aligned_pitch, aligned_height, yuv_len; - - aligned_height = round_up(buf->vp9.height, 64); - aligned_pitch = round_up(buf->vp9.width * buf->vp9.bit_depth, 512) / 8; - yuv_len = (aligned_height * aligned_pitch * 3) / 2; - - return vb2_dma_contig_plane_dma_addr(&buf->base.vb.vb2_buf, 0) + - yuv_len; -} - -static void config_ref_registers(struct rkvdec_ctx *ctx, - const struct rkvdec_vp9_run *run, - struct rkvdec_decoded_buffer *ref_buf, - struct rkvdec_vp9_ref_reg *ref_reg) -{ - unsigned int aligned_pitch, aligned_height, y_len, yuv_len; - struct rkvdec_dev *rkvdec = ctx->dev; - - aligned_height = round_up(ref_buf->vp9.height, 64); - writel_relaxed(RKVDEC_VP9_FRAMEWIDTH(ref_buf->vp9.width) | - RKVDEC_VP9_FRAMEHEIGHT(ref_buf->vp9.height), - rkvdec->regs + ref_reg->reg_frm_size); - - writel_relaxed(vb2_dma_contig_plane_dma_addr(&ref_buf->base.vb.vb2_buf, 0), - rkvdec->regs + ref_reg->reg_ref_base); - - if (&ref_buf->base.vb == run->base.bufs.dst) - return; - - aligned_pitch = round_up(ref_buf->vp9.width * ref_buf->vp9.bit_depth, 512) / 8; - y_len = aligned_height * aligned_pitch; - yuv_len = (y_len * 3) / 2; - - writel_relaxed(RKVDEC_HOR_Y_VIRSTRIDE(aligned_pitch / 16) | - RKVDEC_HOR_UV_VIRSTRIDE(aligned_pitch / 16), - rkvdec->regs + ref_reg->reg_hor_stride); - writel_relaxed(RKVDEC_VP9_REF_YSTRIDE(y_len / 16), - rkvdec->regs + ref_reg->reg_y_stride); - - if (!ref_reg->reg_yuv_stride) - return; - - writel_relaxed(RKVDEC_VP9_REF_YUVSTRIDE(yuv_len / 16), - rkvdec->regs + ref_reg->reg_yuv_stride); -} - -static void config_seg_registers(struct rkvdec_ctx *ctx, unsigned int segid) -{ - struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; - const struct v4l2_vp9_segmentation *seg; - struct rkvdec_dev *rkvdec = ctx->dev; - s16 feature_val; - int feature_id; - u32 val = 0; - - seg = vp9_ctx->last.valid ? &vp9_ctx->last.seg : &vp9_ctx->cur.seg; - feature_id = V4L2_VP9_SEG_LVL_ALT_Q; - if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) { - feature_val = seg->feature_data[segid][feature_id]; - val |= RKVDEC_SEGID_FRAME_QP_DELTA_EN(1) | - RKVDEC_SEGID_FRAME_QP_DELTA(feature_val); - } - - feature_id = V4L2_VP9_SEG_LVL_ALT_L; - if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) { - feature_val = seg->feature_data[segid][feature_id]; - val |= RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE_EN(1) | - RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE(feature_val); - } - - feature_id = V4L2_VP9_SEG_LVL_REF_FRAME; - if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) { - feature_val = seg->feature_data[segid][feature_id]; - val |= RKVDEC_SEGID_REFERINFO_EN(1) | - RKVDEC_SEGID_REFERINFO(feature_val); - } - - feature_id = V4L2_VP9_SEG_LVL_SKIP; - if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) - val |= RKVDEC_SEGID_FRAME_SKIP_EN(1); - - if (!segid && - (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE)) - val |= RKVDEC_SEGID_ABS_DELTA(1); - - writel_relaxed(val, rkvdec->regs + RKVDEC_VP9_SEGID_GRP(segid)); -} - -static void update_dec_buf_info(struct rkvdec_decoded_buffer *buf, - const struct v4l2_ctrl_vp9_frame *dec_params) -{ - buf->vp9.width = dec_params->frame_width_minus_1 + 1; - buf->vp9.height = dec_params->frame_height_minus_1 + 1; - buf->vp9.bit_depth = dec_params->bit_depth; -} - -static void update_ctx_cur_info(struct rkvdec_vp9_ctx *vp9_ctx, - struct rkvdec_decoded_buffer *buf, - const struct v4l2_ctrl_vp9_frame *dec_params) -{ - vp9_ctx->cur.valid = true; - vp9_ctx->cur.reference_mode = dec_params->reference_mode; - vp9_ctx->cur.interpolation_filter = dec_params->interpolation_filter; - vp9_ctx->cur.flags = dec_params->flags; - vp9_ctx->cur.timestamp = buf->base.vb.vb2_buf.timestamp; - vp9_ctx->cur.seg = dec_params->seg; - vp9_ctx->cur.lf = dec_params->lf; -} - -static void update_ctx_last_info(struct rkvdec_vp9_ctx *vp9_ctx) -{ - vp9_ctx->last = vp9_ctx->cur; -} - -static void config_registers(struct rkvdec_ctx *ctx, - const struct rkvdec_vp9_run *run) -{ - unsigned int y_len, uv_len, yuv_len, bit_depth, aligned_height, aligned_pitch, stream_len; - const struct v4l2_ctrl_vp9_frame *dec_params; - struct rkvdec_decoded_buffer *ref_bufs[3]; - struct rkvdec_decoded_buffer *dst, *last, *mv_ref; - struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; - u32 val, last_frame_info = 0; - const struct v4l2_vp9_segmentation *seg; - struct rkvdec_dev *rkvdec = ctx->dev; - dma_addr_t addr; - bool intra_only; - unsigned int i; - - dec_params = run->decode_params; - dst = vb2_to_rkvdec_decoded_buf(&run->base.bufs.dst->vb2_buf); - ref_bufs[0] = get_ref_buf(ctx, &dst->base.vb, dec_params->last_frame_ts); - ref_bufs[1] = get_ref_buf(ctx, &dst->base.vb, dec_params->golden_frame_ts); - ref_bufs[2] = get_ref_buf(ctx, &dst->base.vb, dec_params->alt_frame_ts); - - if (vp9_ctx->last.valid) - last = get_ref_buf(ctx, &dst->base.vb, vp9_ctx->last.timestamp); - else - last = dst; - - update_dec_buf_info(dst, dec_params); - update_ctx_cur_info(vp9_ctx, dst, dec_params); - seg = &dec_params->seg; - - intra_only = !!(dec_params->flags & - (V4L2_VP9_FRAME_FLAG_KEY_FRAME | - V4L2_VP9_FRAME_FLAG_INTRA_ONLY)); - - writel_relaxed(RKVDEC_MODE(RKVDEC_MODE_VP9), - rkvdec->regs + RKVDEC_REG_SYSCTRL); - - bit_depth = dec_params->bit_depth; - aligned_height = round_up(ctx->decoded_fmt.fmt.pix_mp.height, 64); - - aligned_pitch = round_up(ctx->decoded_fmt.fmt.pix_mp.width * - bit_depth, - 512) / 8; - y_len = aligned_height * aligned_pitch; - uv_len = y_len / 2; - yuv_len = y_len + uv_len; - - writel_relaxed(RKVDEC_Y_HOR_VIRSTRIDE(aligned_pitch / 16) | - RKVDEC_UV_HOR_VIRSTRIDE(aligned_pitch / 16), - rkvdec->regs + RKVDEC_REG_PICPAR); - writel_relaxed(RKVDEC_Y_VIRSTRIDE(y_len / 16), - rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE); - writel_relaxed(RKVDEC_YUV_VIRSTRIDE(yuv_len / 16), - rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE); - - stream_len = vb2_get_plane_payload(&run->base.bufs.src->vb2_buf, 0); - writel_relaxed(RKVDEC_STRM_LEN(stream_len), - rkvdec->regs + RKVDEC_REG_STRM_LEN); - - /* - * Reset count buffer, because decoder only output intra related syntax - * counts when decoding intra frame, but update entropy need to update - * all the probabilities. - */ - if (intra_only) - memset(vp9_ctx->count_tbl.cpu, 0, vp9_ctx->count_tbl.size); - - vp9_ctx->cur.segmapid = vp9_ctx->last.segmapid; - if (!intra_only && - !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) && - (!(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED) || - (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP))) - vp9_ctx->cur.segmapid++; - - for (i = 0; i < ARRAY_SIZE(ref_bufs); i++) - config_ref_registers(ctx, run, ref_bufs[i], &ref_regs[i]); - - for (i = 0; i < 8; i++) - config_seg_registers(ctx, i); - - writel_relaxed(RKVDEC_VP9_TX_MODE(vp9_ctx->cur.tx_mode) | - RKVDEC_VP9_FRAME_REF_MODE(dec_params->reference_mode), - rkvdec->regs + RKVDEC_VP9_CPRHEADER_CONFIG); - - if (!intra_only) { - const struct v4l2_vp9_loop_filter *lf; - s8 delta; - - if (vp9_ctx->last.valid) - lf = &vp9_ctx->last.lf; - else - lf = &vp9_ctx->cur.lf; - - val = 0; - for (i = 0; i < ARRAY_SIZE(lf->ref_deltas); i++) { - delta = lf->ref_deltas[i]; - val |= RKVDEC_REF_DELTAS_LASTFRAME(i, delta); - } - - writel_relaxed(val, - rkvdec->regs + RKVDEC_VP9_REF_DELTAS_LASTFRAME); - - for (i = 0; i < ARRAY_SIZE(lf->mode_deltas); i++) { - delta = lf->mode_deltas[i]; - last_frame_info |= RKVDEC_MODE_DELTAS_LASTFRAME(i, - delta); - } - } - - if (vp9_ctx->last.valid && !intra_only && - vp9_ctx->last.seg.flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED) - last_frame_info |= RKVDEC_SEG_EN_LASTFRAME; - - if (vp9_ctx->last.valid && - vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_SHOW_FRAME) - last_frame_info |= RKVDEC_LAST_SHOW_FRAME; - - if (vp9_ctx->last.valid && - vp9_ctx->last.flags & - (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY)) - last_frame_info |= RKVDEC_LAST_INTRA_ONLY; - - if (vp9_ctx->last.valid && - last->vp9.width == dst->vp9.width && - last->vp9.height == dst->vp9.height) - last_frame_info |= RKVDEC_LAST_WIDHHEIGHT_EQCUR; - - writel_relaxed(last_frame_info, - rkvdec->regs + RKVDEC_VP9_INFO_LASTFRAME); - - writel_relaxed(stream_len - dec_params->compressed_header_size - - dec_params->uncompressed_header_size, - rkvdec->regs + RKVDEC_VP9_LASTTILE_SIZE); - - for (i = 0; !intra_only && i < ARRAY_SIZE(ref_bufs); i++) { - unsigned int refw = ref_bufs[i]->vp9.width; - unsigned int refh = ref_bufs[i]->vp9.height; - u32 hscale, vscale; - - hscale = (refw << 14) / dst->vp9.width; - vscale = (refh << 14) / dst->vp9.height; - writel_relaxed(RKVDEC_VP9_REF_HOR_SCALE(hscale) | - RKVDEC_VP9_REF_VER_SCALE(vscale), - rkvdec->regs + RKVDEC_VP9_REF_SCALE(i)); - } - - addr = vb2_dma_contig_plane_dma_addr(&dst->base.vb.vb2_buf, 0); - writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE); - addr = vb2_dma_contig_plane_dma_addr(&run->base.bufs.src->vb2_buf, 0); - writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE); - writel_relaxed(vp9_ctx->priv_tbl.dma + - offsetof(struct rkvdec_vp9_priv_tbl, probs), - rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE); - writel_relaxed(vp9_ctx->count_tbl.dma, - rkvdec->regs + RKVDEC_REG_VP9COUNT_BASE); - - writel_relaxed(vp9_ctx->priv_tbl.dma + - offsetof(struct rkvdec_vp9_priv_tbl, segmap) + - (RKVDEC_VP9_MAX_SEGMAP_SIZE * vp9_ctx->cur.segmapid), - rkvdec->regs + RKVDEC_REG_VP9_SEGIDCUR_BASE); - writel_relaxed(vp9_ctx->priv_tbl.dma + - offsetof(struct rkvdec_vp9_priv_tbl, segmap) + - (RKVDEC_VP9_MAX_SEGMAP_SIZE * (!vp9_ctx->cur.segmapid)), - rkvdec->regs + RKVDEC_REG_VP9_SEGIDLAST_BASE); - - if (!intra_only && - !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) && - vp9_ctx->last.valid) - mv_ref = last; - else - mv_ref = dst; - - writel_relaxed(get_mv_base_addr(mv_ref), - rkvdec->regs + RKVDEC_VP9_REF_COLMV_BASE); - - writel_relaxed(ctx->decoded_fmt.fmt.pix_mp.width | - (ctx->decoded_fmt.fmt.pix_mp.height << 16), - rkvdec->regs + RKVDEC_REG_PERFORMANCE_CYCLE); -} - -static int validate_dec_params(struct rkvdec_ctx *ctx, - const struct v4l2_ctrl_vp9_frame *dec_params) -{ - unsigned int aligned_width, aligned_height; - - /* We only support profile 0. */ - if (dec_params->profile != 0) { - dev_err(ctx->dev->dev, "unsupported profile %d\n", - dec_params->profile); - return -EINVAL; - } - - aligned_width = round_up(dec_params->frame_width_minus_1 + 1, 64); - aligned_height = round_up(dec_params->frame_height_minus_1 + 1, 64); - - /* - * Userspace should update the capture/decoded format when the - * resolution changes. - */ - if (aligned_width != ctx->decoded_fmt.fmt.pix_mp.width || - aligned_height != ctx->decoded_fmt.fmt.pix_mp.height) { - dev_err(ctx->dev->dev, - "unexpected bitstream resolution %dx%d\n", - dec_params->frame_width_minus_1 + 1, - dec_params->frame_height_minus_1 + 1); - return -EINVAL; - } - - return 0; -} - -static int rkvdec_vp9_run_preamble(struct rkvdec_ctx *ctx, - struct rkvdec_vp9_run *run) -{ - const struct v4l2_ctrl_vp9_frame *dec_params; - const struct v4l2_ctrl_vp9_compressed_hdr *prob_updates; - struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; - struct v4l2_ctrl *ctrl; - unsigned int fctx_idx; - int ret; - - /* v4l2-specific stuff */ - rkvdec_run_preamble(ctx, &run->base); - - ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, - V4L2_CID_STATELESS_VP9_FRAME); - if (WARN_ON(!ctrl)) - return -EINVAL; - dec_params = ctrl->p_cur.p; - - ret = validate_dec_params(ctx, dec_params); - if (ret) - return ret; - - run->decode_params = dec_params; - - ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, V4L2_CID_STATELESS_VP9_COMPRESSED_HDR); - if (WARN_ON(!ctrl)) - return -EINVAL; - prob_updates = ctrl->p_cur.p; - vp9_ctx->cur.tx_mode = prob_updates->tx_mode; - - /* - * vp9 stuff - * - * by this point the userspace has done all parts of 6.2 uncompressed_header() - * except this fragment: - * if ( FrameIsIntra || error_resilient_mode ) { - * setup_past_independence ( ) - * if ( frame_type == KEY_FRAME || error_resilient_mode == 1 || - * reset_frame_context == 3 ) { - * for ( i = 0; i < 4; i ++ ) { - * save_probs( i ) - * } - * } else if ( reset_frame_context == 2 ) { - * save_probs( frame_context_idx ) - * } - * frame_context_idx = 0 - * } - */ - fctx_idx = v4l2_vp9_reset_frame_ctx(dec_params, vp9_ctx->frame_context); - vp9_ctx->cur.frame_context_idx = fctx_idx; - - /* 6.1 frame(sz): load_probs() and load_probs2() */ - vp9_ctx->probability_tables = vp9_ctx->frame_context[fctx_idx]; - - /* - * The userspace has also performed 6.3 compressed_header(), but handling the - * probs in a special way. All probs which need updating, except MV-related, - * have been read from the bitstream and translated through inv_map_table[], - * but no 6.3.6 inv_recenter_nonneg(v, m) has been performed. The values passed - * by userspace are either translated values (there are no 0 values in - * inv_map_table[]), or zero to indicate no update. All MV-related probs which need - * updating have been read from the bitstream and (mv_prob << 1) | 1 has been - * performed. The values passed by userspace are either new values - * to replace old ones (the above mentioned shift and bitwise or never result in - * a zero) or zero to indicate no update. - * fw_update_probs() performs actual probs updates or leaves probs as-is - * for values for which a zero was passed from userspace. - */ - v4l2_vp9_fw_update_probs(&vp9_ctx->probability_tables, prob_updates, dec_params); - - return 0; -} - -static int rkvdec_vp9_run(struct rkvdec_ctx *ctx) -{ - struct rkvdec_dev *rkvdec = ctx->dev; - struct rkvdec_vp9_run run = { }; - int ret; - - ret = rkvdec_vp9_run_preamble(ctx, &run); - if (ret) { - rkvdec_run_postamble(ctx, &run.base); - return ret; - } - - /* Prepare probs. */ - init_probs(ctx, &run); - - /* Configure hardware registers. */ - config_registers(ctx, &run); - - rkvdec_run_postamble(ctx, &run.base); - - schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000)); - - writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND); - writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND); - - writel(0xe, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN); - /* Start decoding! */ - writel(RKVDEC_INTERRUPT_DEC_E | RKVDEC_CONFIG_DEC_CLK_GATE_E | - RKVDEC_TIMEOUT_E | RKVDEC_BUF_EMPTY_E, - rkvdec->regs + RKVDEC_REG_INTERRUPT); - - return 0; -} - -#define copy_tx_and_skip(p1, p2) \ -do { \ - memcpy((p1)->tx8, (p2)->tx8, sizeof((p1)->tx8)); \ - memcpy((p1)->tx16, (p2)->tx16, sizeof((p1)->tx16)); \ - memcpy((p1)->tx32, (p2)->tx32, sizeof((p1)->tx32)); \ - memcpy((p1)->skip, (p2)->skip, sizeof((p1)->skip)); \ -} while (0) - -static void rkvdec_vp9_done(struct rkvdec_ctx *ctx, - struct vb2_v4l2_buffer *src_buf, - struct vb2_v4l2_buffer *dst_buf, - enum vb2_buffer_state result) -{ - struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; - unsigned int fctx_idx; - - /* v4l2-specific stuff */ - if (result == VB2_BUF_STATE_ERROR) - goto out_update_last; - - /* - * vp9 stuff - * - * 6.1.2 refresh_probs() - * - * In the spec a complementary condition goes last in 6.1.2 refresh_probs(), - * but it makes no sense to perform all the activities from the first "if" - * there if we actually are not refreshing the frame context. On top of that, - * because of 6.2 uncompressed_header() whenever error_resilient_mode == 1, - * refresh_frame_context == 0. Consequently, if we don't jump to out_update_last - * it means error_resilient_mode must be 0. - */ - if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX)) - goto out_update_last; - - fctx_idx = vp9_ctx->cur.frame_context_idx; - - if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE)) { - /* error_resilient_mode == 0 && frame_parallel_decoding_mode == 0 */ - struct v4l2_vp9_frame_context *probs = &vp9_ctx->probability_tables; - bool frame_is_intra = vp9_ctx->cur.flags & - (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY); - struct tx_and_skip { - u8 tx8[2][1]; - u8 tx16[2][2]; - u8 tx32[2][3]; - u8 skip[3]; - } _tx_skip, *tx_skip = &_tx_skip; - struct v4l2_vp9_frame_symbol_counts *counts; - - /* buffer the forward-updated TX and skip probs */ - if (frame_is_intra) - copy_tx_and_skip(tx_skip, probs); - - /* 6.1.2 refresh_probs(): load_probs() and load_probs2() */ - *probs = vp9_ctx->frame_context[fctx_idx]; - - /* if FrameIsIntra then undo the effect of load_probs2() */ - if (frame_is_intra) - copy_tx_and_skip(probs, tx_skip); - - counts = frame_is_intra ? &vp9_ctx->intra_cnts : &vp9_ctx->inter_cnts; - v4l2_vp9_adapt_coef_probs(probs, counts, - !vp9_ctx->last.valid || - vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME, - frame_is_intra); - if (!frame_is_intra) { - const struct rkvdec_vp9_inter_frame_symbol_counts *inter_cnts; - u32 classes[2][11]; - int i; - - inter_cnts = vp9_ctx->count_tbl.cpu; - for (i = 0; i < ARRAY_SIZE(classes); ++i) - memcpy(classes[i], inter_cnts->classes[i], sizeof(classes[0])); - counts->classes = &classes; - - /* load_probs2() already done */ - v4l2_vp9_adapt_noncoef_probs(&vp9_ctx->probability_tables, counts, - vp9_ctx->cur.reference_mode, - vp9_ctx->cur.interpolation_filter, - vp9_ctx->cur.tx_mode, vp9_ctx->cur.flags); - } - } - - /* 6.1.2 refresh_probs(): save_probs(fctx_idx) */ - vp9_ctx->frame_context[fctx_idx] = vp9_ctx->probability_tables; - -out_update_last: - update_ctx_last_info(vp9_ctx); -} - -static void rkvdec_init_v4l2_vp9_count_tbl(struct rkvdec_ctx *ctx) -{ - struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; - struct rkvdec_vp9_intra_frame_symbol_counts *intra_cnts = vp9_ctx->count_tbl.cpu; - struct rkvdec_vp9_inter_frame_symbol_counts *inter_cnts = vp9_ctx->count_tbl.cpu; - int i, j, k, l, m; - - vp9_ctx->inter_cnts.partition = &inter_cnts->partition; - vp9_ctx->inter_cnts.skip = &inter_cnts->skip; - vp9_ctx->inter_cnts.intra_inter = &inter_cnts->inter; - vp9_ctx->inter_cnts.tx32p = &inter_cnts->tx32p; - vp9_ctx->inter_cnts.tx16p = &inter_cnts->tx16p; - vp9_ctx->inter_cnts.tx8p = &inter_cnts->tx8p; - - vp9_ctx->intra_cnts.partition = (u32 (*)[16][4])(&intra_cnts->partition); - vp9_ctx->intra_cnts.skip = &intra_cnts->skip; - vp9_ctx->intra_cnts.intra_inter = &intra_cnts->intra; - vp9_ctx->intra_cnts.tx32p = &intra_cnts->tx32p; - vp9_ctx->intra_cnts.tx16p = &intra_cnts->tx16p; - vp9_ctx->intra_cnts.tx8p = &intra_cnts->tx8p; - - vp9_ctx->inter_cnts.y_mode = &inter_cnts->y_mode; - vp9_ctx->inter_cnts.uv_mode = &inter_cnts->uv_mode; - vp9_ctx->inter_cnts.comp = &inter_cnts->comp; - vp9_ctx->inter_cnts.comp_ref = &inter_cnts->comp_ref; - vp9_ctx->inter_cnts.single_ref = &inter_cnts->single_ref; - vp9_ctx->inter_cnts.mv_mode = &inter_cnts->mv_mode; - vp9_ctx->inter_cnts.filter = &inter_cnts->filter; - vp9_ctx->inter_cnts.mv_joint = &inter_cnts->mv_joint; - vp9_ctx->inter_cnts.sign = &inter_cnts->sign; - /* - * rk hardware actually uses "u32 classes[2][11 + 1];" - * instead of "u32 classes[2][11];", so this must be explicitly - * copied into vp9_ctx->classes when passing the data to the - * vp9 library function - */ - vp9_ctx->inter_cnts.class0 = &inter_cnts->class0; - vp9_ctx->inter_cnts.bits = &inter_cnts->bits; - vp9_ctx->inter_cnts.class0_fp = &inter_cnts->class0_fp; - vp9_ctx->inter_cnts.fp = &inter_cnts->fp; - vp9_ctx->inter_cnts.class0_hp = &inter_cnts->class0_hp; - vp9_ctx->inter_cnts.hp = &inter_cnts->hp; - -#define INNERMOST_LOOP \ - do { \ - for (m = 0; m < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0][0][0][0]); ++m) {\ - vp9_ctx->inter_cnts.coeff[i][j][k][l][m] = \ - &inter_cnts->ref_cnt[k][i][j][l][m].coeff; \ - vp9_ctx->inter_cnts.eob[i][j][k][l][m][0] = \ - &inter_cnts->ref_cnt[k][i][j][l][m].eob[0]; \ - vp9_ctx->inter_cnts.eob[i][j][k][l][m][1] = \ - &inter_cnts->ref_cnt[k][i][j][l][m].eob[1]; \ - \ - vp9_ctx->intra_cnts.coeff[i][j][k][l][m] = \ - &intra_cnts->ref_cnt[k][i][j][l][m].coeff; \ - vp9_ctx->intra_cnts.eob[i][j][k][l][m][0] = \ - &intra_cnts->ref_cnt[k][i][j][l][m].eob[0]; \ - vp9_ctx->intra_cnts.eob[i][j][k][l][m][1] = \ - &intra_cnts->ref_cnt[k][i][j][l][m].eob[1]; \ - } \ - } while (0) - - for (i = 0; i < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff); ++i) - for (j = 0; j < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0]); ++j) - for (k = 0; k < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0][0]); ++k) - for (l = 0; l < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0][0][0]); ++l) - INNERMOST_LOOP; -#undef INNERMOST_LOOP -} - -static int rkvdec_vp9_start(struct rkvdec_ctx *ctx) -{ - struct rkvdec_dev *rkvdec = ctx->dev; - struct rkvdec_vp9_priv_tbl *priv_tbl; - struct rkvdec_vp9_ctx *vp9_ctx; - unsigned char *count_tbl; - int ret; - - vp9_ctx = kzalloc(sizeof(*vp9_ctx), GFP_KERNEL); - if (!vp9_ctx) - return -ENOMEM; - - ctx->priv = vp9_ctx; - - BUILD_BUG_ON(sizeof(priv_tbl->probs) % 16); /* ensure probs size is 128-bit aligned */ - priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl), - &vp9_ctx->priv_tbl.dma, GFP_KERNEL); - if (!priv_tbl) { - ret = -ENOMEM; - goto err_free_ctx; - } - - vp9_ctx->priv_tbl.size = sizeof(*priv_tbl); - vp9_ctx->priv_tbl.cpu = priv_tbl; - - count_tbl = dma_alloc_coherent(rkvdec->dev, RKVDEC_VP9_COUNT_SIZE, - &vp9_ctx->count_tbl.dma, GFP_KERNEL); - if (!count_tbl) { - ret = -ENOMEM; - goto err_free_priv_tbl; - } - - vp9_ctx->count_tbl.size = RKVDEC_VP9_COUNT_SIZE; - vp9_ctx->count_tbl.cpu = count_tbl; - rkvdec_init_v4l2_vp9_count_tbl(ctx); - - return 0; - -err_free_priv_tbl: - dma_free_coherent(rkvdec->dev, vp9_ctx->priv_tbl.size, - vp9_ctx->priv_tbl.cpu, vp9_ctx->priv_tbl.dma); - -err_free_ctx: - kfree(vp9_ctx); - return ret; -} - -static void rkvdec_vp9_stop(struct rkvdec_ctx *ctx) -{ - struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; - struct rkvdec_dev *rkvdec = ctx->dev; - - dma_free_coherent(rkvdec->dev, vp9_ctx->count_tbl.size, - vp9_ctx->count_tbl.cpu, vp9_ctx->count_tbl.dma); - dma_free_coherent(rkvdec->dev, vp9_ctx->priv_tbl.size, - vp9_ctx->priv_tbl.cpu, vp9_ctx->priv_tbl.dma); - kfree(vp9_ctx); -} - -static int rkvdec_vp9_adjust_fmt(struct rkvdec_ctx *ctx, - struct v4l2_format *f) -{ - struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp; - - fmt->num_planes = 1; - if (!fmt->plane_fmt[0].sizeimage) - fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * 2; - return 0; -} - -const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops = { - .adjust_fmt = rkvdec_vp9_adjust_fmt, - .start = rkvdec_vp9_start, - .stop = rkvdec_vp9_stop, - .run = rkvdec_vp9_run, - .done = rkvdec_vp9_done, -}; diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c deleted file mode 100644 index f9bef5173bf2..000000000000 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ /dev/null @@ -1,1115 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Rockchip Video Decoder driver - * - * Copyright (C) 2019 Collabora, Ltd. - * - * Based on rkvdec driver by Google LLC. (Tomasz Figa <tfiga@chromium.org>) - * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. - * Copyright (C) 2011 Samsung Electronics Co., Ltd. - */ - -#include <linux/clk.h> -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/of.h> -#include <linux/platform_device.h> -#include <linux/pm.h> -#include <linux/pm_runtime.h> -#include <linux/slab.h> -#include <linux/videodev2.h> -#include <linux/workqueue.h> -#include <media/v4l2-event.h> -#include <media/v4l2-mem2mem.h> -#include <media/videobuf2-core.h> -#include <media/videobuf2-vmalloc.h> - -#include "rkvdec.h" -#include "rkvdec-regs.h" - -static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) -{ - struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, ctrl_hdl); - const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc; - - if (desc->ops->try_ctrl) - return desc->ops->try_ctrl(ctx, ctrl); - - return 0; -} - -static const struct v4l2_ctrl_ops rkvdec_ctrl_ops = { - .try_ctrl = rkvdec_try_ctrl, -}; - -static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = { - { - .cfg.id = V4L2_CID_STATELESS_H264_DECODE_PARAMS, - }, - { - .cfg.id = V4L2_CID_STATELESS_H264_SPS, - .cfg.ops = &rkvdec_ctrl_ops, - }, - { - .cfg.id = V4L2_CID_STATELESS_H264_PPS, - }, - { - .cfg.id = V4L2_CID_STATELESS_H264_SCALING_MATRIX, - }, - { - .cfg.id = V4L2_CID_STATELESS_H264_DECODE_MODE, - .cfg.min = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED, - .cfg.max = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED, - .cfg.def = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED, - }, - { - .cfg.id = V4L2_CID_STATELESS_H264_START_CODE, - .cfg.min = V4L2_STATELESS_H264_START_CODE_ANNEX_B, - .cfg.def = V4L2_STATELESS_H264_START_CODE_ANNEX_B, - .cfg.max = V4L2_STATELESS_H264_START_CODE_ANNEX_B, - }, - { - .cfg.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE, - .cfg.min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, - .cfg.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, - .cfg.menu_skip_mask = - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED), - .cfg.def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN, - }, - { - .cfg.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, - .cfg.min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - .cfg.max = V4L2_MPEG_VIDEO_H264_LEVEL_5_1, - }, -}; - -static const struct rkvdec_ctrls rkvdec_h264_ctrls = { - .ctrls = rkvdec_h264_ctrl_descs, - .num_ctrls = ARRAY_SIZE(rkvdec_h264_ctrl_descs), -}; - -static const u32 rkvdec_h264_vp9_decoded_fmts[] = { - V4L2_PIX_FMT_NV12, -}; - -static const struct rkvdec_ctrl_desc rkvdec_vp9_ctrl_descs[] = { - { - .cfg.id = V4L2_CID_STATELESS_VP9_FRAME, - }, - { - .cfg.id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR, - }, - { - .cfg.id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE, - .cfg.min = V4L2_MPEG_VIDEO_VP9_PROFILE_0, - .cfg.max = V4L2_MPEG_VIDEO_VP9_PROFILE_0, - .cfg.def = V4L2_MPEG_VIDEO_VP9_PROFILE_0, - }, -}; - -static const struct rkvdec_ctrls rkvdec_vp9_ctrls = { - .ctrls = rkvdec_vp9_ctrl_descs, - .num_ctrls = ARRAY_SIZE(rkvdec_vp9_ctrl_descs), -}; - -static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { - { - .fourcc = V4L2_PIX_FMT_H264_SLICE, - .frmsize = { - .min_width = 48, - .max_width = 4096, - .step_width = 16, - .min_height = 48, - .max_height = 2560, - .step_height = 16, - }, - .ctrls = &rkvdec_h264_ctrls, - .ops = &rkvdec_h264_fmt_ops, - .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts), - .decoded_fmts = rkvdec_h264_vp9_decoded_fmts, - .subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF, - }, - { - .fourcc = V4L2_PIX_FMT_VP9_FRAME, - .frmsize = { - .min_width = 64, - .max_width = 4096, - .step_width = 64, - .min_height = 64, - .max_height = 2304, - .step_height = 64, - }, - .ctrls = &rkvdec_vp9_ctrls, - .ops = &rkvdec_vp9_fmt_ops, - .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts), - .decoded_fmts = rkvdec_h264_vp9_decoded_fmts, - } -}; - -static const struct rkvdec_coded_fmt_desc * -rkvdec_find_coded_fmt_desc(u32 fourcc) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) { - if (rkvdec_coded_fmts[i].fourcc == fourcc) - return &rkvdec_coded_fmts[i]; - } - - return NULL; -} - -static void rkvdec_reset_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f, - u32 fourcc) -{ - memset(f, 0, sizeof(*f)); - f->fmt.pix_mp.pixelformat = fourcc; - f->fmt.pix_mp.field = V4L2_FIELD_NONE; - f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709; - f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; - f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; - f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; -} - -static void rkvdec_reset_coded_fmt(struct rkvdec_ctx *ctx) -{ - struct v4l2_format *f = &ctx->coded_fmt; - - ctx->coded_fmt_desc = &rkvdec_coded_fmts[0]; - rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->fourcc); - - f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - f->fmt.pix_mp.width = ctx->coded_fmt_desc->frmsize.min_width; - f->fmt.pix_mp.height = ctx->coded_fmt_desc->frmsize.min_height; - - if (ctx->coded_fmt_desc->ops->adjust_fmt) - ctx->coded_fmt_desc->ops->adjust_fmt(ctx, f); -} - -static void rkvdec_reset_decoded_fmt(struct rkvdec_ctx *ctx) -{ - struct v4l2_format *f = &ctx->decoded_fmt; - - rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->decoded_fmts[0]); - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - v4l2_fill_pixfmt_mp(&f->fmt.pix_mp, - ctx->coded_fmt_desc->decoded_fmts[0], - ctx->coded_fmt.fmt.pix_mp.width, - ctx->coded_fmt.fmt.pix_mp.height); - f->fmt.pix_mp.plane_fmt[0].sizeimage += 128 * - DIV_ROUND_UP(f->fmt.pix_mp.width, 16) * - DIV_ROUND_UP(f->fmt.pix_mp.height, 16); -} - -static int rkvdec_enum_framesizes(struct file *file, void *priv, - struct v4l2_frmsizeenum *fsize) -{ - const struct rkvdec_coded_fmt_desc *fmt; - - if (fsize->index != 0) - return -EINVAL; - - fmt = rkvdec_find_coded_fmt_desc(fsize->pixel_format); - if (!fmt) - return -EINVAL; - - fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; - fsize->stepwise = fmt->frmsize; - return 0; -} - -static int rkvdec_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct rkvdec_dev *rkvdec = video_drvdata(file); - struct video_device *vdev = video_devdata(file); - - strscpy(cap->driver, rkvdec->dev->driver->name, - sizeof(cap->driver)); - strscpy(cap->card, vdev->name, sizeof(cap->card)); - snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", - rkvdec->dev->driver->name); - return 0; -} - -static int rkvdec_try_capture_fmt(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); - const struct rkvdec_coded_fmt_desc *coded_desc; - unsigned int i; - - /* - * The codec context should point to a coded format desc, if the format - * on the coded end has not been set yet, it should point to the - * default value. - */ - coded_desc = ctx->coded_fmt_desc; - if (WARN_ON(!coded_desc)) - return -EINVAL; - - for (i = 0; i < coded_desc->num_decoded_fmts; i++) { - if (coded_desc->decoded_fmts[i] == pix_mp->pixelformat) - break; - } - - if (i == coded_desc->num_decoded_fmts) - pix_mp->pixelformat = coded_desc->decoded_fmts[0]; - - /* Always apply the frmsize constraint of the coded end. */ - pix_mp->width = max(pix_mp->width, ctx->coded_fmt.fmt.pix_mp.width); - pix_mp->height = max(pix_mp->height, ctx->coded_fmt.fmt.pix_mp.height); - v4l2_apply_frmsize_constraints(&pix_mp->width, - &pix_mp->height, - &coded_desc->frmsize); - - v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, - pix_mp->width, pix_mp->height); - pix_mp->plane_fmt[0].sizeimage += - 128 * - DIV_ROUND_UP(pix_mp->width, 16) * - DIV_ROUND_UP(pix_mp->height, 16); - pix_mp->field = V4L2_FIELD_NONE; - - return 0; -} - -static int rkvdec_try_output_fmt(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); - const struct rkvdec_coded_fmt_desc *desc; - - desc = rkvdec_find_coded_fmt_desc(pix_mp->pixelformat); - if (!desc) { - pix_mp->pixelformat = rkvdec_coded_fmts[0].fourcc; - desc = &rkvdec_coded_fmts[0]; - } - - v4l2_apply_frmsize_constraints(&pix_mp->width, - &pix_mp->height, - &desc->frmsize); - - pix_mp->field = V4L2_FIELD_NONE; - /* All coded formats are considered single planar for now. */ - pix_mp->num_planes = 1; - - if (desc->ops->adjust_fmt) { - int ret; - - ret = desc->ops->adjust_fmt(ctx, f); - if (ret) - return ret; - } - - return 0; -} - -static int rkvdec_s_capture_fmt(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); - struct vb2_queue *vq; - int ret; - - /* Change not allowed if queue is busy */ - vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, - V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (vb2_is_busy(vq)) - return -EBUSY; - - ret = rkvdec_try_capture_fmt(file, priv, f); - if (ret) - return ret; - - ctx->decoded_fmt = *f; - return 0; -} - -static int rkvdec_s_output_fmt(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); - struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; - const struct rkvdec_coded_fmt_desc *desc; - struct v4l2_format *cap_fmt; - struct vb2_queue *peer_vq, *vq; - int ret; - - /* - * In order to support dynamic resolution change, the decoder admits - * a resolution change, as long as the pixelformat remains. Can't be - * done if streaming. - */ - vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); - if (vb2_is_streaming(vq) || - (vb2_is_busy(vq) && - f->fmt.pix_mp.pixelformat != ctx->coded_fmt.fmt.pix_mp.pixelformat)) - return -EBUSY; - - /* - * Since format change on the OUTPUT queue will reset the CAPTURE - * queue, we can't allow doing so when the CAPTURE queue has buffers - * allocated. - */ - peer_vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (vb2_is_busy(peer_vq)) - return -EBUSY; - - ret = rkvdec_try_output_fmt(file, priv, f); - if (ret) - return ret; - - desc = rkvdec_find_coded_fmt_desc(f->fmt.pix_mp.pixelformat); - if (!desc) - return -EINVAL; - ctx->coded_fmt_desc = desc; - ctx->coded_fmt = *f; - - /* - * Current decoded format might have become invalid with newly - * selected codec, so reset it to default just to be safe and - * keep internal driver state sane. User is mandated to set - * the decoded format again after we return, so we don't need - * anything smarter. - * - * Note that this will propagates any size changes to the decoded format. - */ - rkvdec_reset_decoded_fmt(ctx); - - /* Propagate colorspace information to capture. */ - cap_fmt = &ctx->decoded_fmt; - cap_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; - cap_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; - cap_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; - cap_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; - - /* Enable format specific queue features */ - vq->subsystem_flags |= desc->subsystem_flags; - - return 0; -} - -static int rkvdec_g_output_fmt(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); - - *f = ctx->coded_fmt; - return 0; -} - -static int rkvdec_g_capture_fmt(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); - - *f = ctx->decoded_fmt; - return 0; -} - -static int rkvdec_enum_output_fmt(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (f->index >= ARRAY_SIZE(rkvdec_coded_fmts)) - return -EINVAL; - - f->pixelformat = rkvdec_coded_fmts[f->index].fourcc; - return 0; -} - -static int rkvdec_enum_capture_fmt(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); - - if (WARN_ON(!ctx->coded_fmt_desc)) - return -EINVAL; - - if (f->index >= ctx->coded_fmt_desc->num_decoded_fmts) - return -EINVAL; - - f->pixelformat = ctx->coded_fmt_desc->decoded_fmts[f->index]; - return 0; -} - -static const struct v4l2_ioctl_ops rkvdec_ioctl_ops = { - .vidioc_querycap = rkvdec_querycap, - .vidioc_enum_framesizes = rkvdec_enum_framesizes, - - .vidioc_try_fmt_vid_cap_mplane = rkvdec_try_capture_fmt, - .vidioc_try_fmt_vid_out_mplane = rkvdec_try_output_fmt, - .vidioc_s_fmt_vid_out_mplane = rkvdec_s_output_fmt, - .vidioc_s_fmt_vid_cap_mplane = rkvdec_s_capture_fmt, - .vidioc_g_fmt_vid_out_mplane = rkvdec_g_output_fmt, - .vidioc_g_fmt_vid_cap_mplane = rkvdec_g_capture_fmt, - .vidioc_enum_fmt_vid_out = rkvdec_enum_output_fmt, - .vidioc_enum_fmt_vid_cap = rkvdec_enum_capture_fmt, - - .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, - .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, - .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, - .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, - .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, - .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, - .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, - - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, - - .vidioc_streamon = v4l2_m2m_ioctl_streamon, - .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, - - .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, - .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, -}; - -static int rkvdec_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, - unsigned int *num_planes, unsigned int sizes[], - struct device *alloc_devs[]) -{ - struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq); - struct v4l2_format *f; - unsigned int i; - - if (V4L2_TYPE_IS_OUTPUT(vq->type)) - f = &ctx->coded_fmt; - else - f = &ctx->decoded_fmt; - - if (*num_planes) { - if (*num_planes != f->fmt.pix_mp.num_planes) - return -EINVAL; - - for (i = 0; i < f->fmt.pix_mp.num_planes; i++) { - if (sizes[i] < f->fmt.pix_mp.plane_fmt[i].sizeimage) - return -EINVAL; - } - } else { - *num_planes = f->fmt.pix_mp.num_planes; - for (i = 0; i < f->fmt.pix_mp.num_planes; i++) - sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage; - } - - return 0; -} - -static int rkvdec_buf_prepare(struct vb2_buffer *vb) -{ - struct vb2_queue *vq = vb->vb2_queue; - struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq); - struct v4l2_format *f; - unsigned int i; - - if (V4L2_TYPE_IS_OUTPUT(vq->type)) - f = &ctx->coded_fmt; - else - f = &ctx->decoded_fmt; - - for (i = 0; i < f->fmt.pix_mp.num_planes; ++i) { - u32 sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage; - - if (vb2_plane_size(vb, i) < sizeimage) - return -EINVAL; - } - - /* - * Buffer's bytesused must be written by driver for CAPTURE buffers. - * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets - * it to buffer length). - */ - if (V4L2_TYPE_IS_CAPTURE(vq->type)) - vb2_set_plane_payload(vb, 0, f->fmt.pix_mp.plane_fmt[0].sizeimage); - - return 0; -} - -static void rkvdec_buf_queue(struct vb2_buffer *vb) -{ - struct rkvdec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); - - v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); -} - -static int rkvdec_buf_out_validate(struct vb2_buffer *vb) -{ - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); - - vbuf->field = V4L2_FIELD_NONE; - return 0; -} - -static void rkvdec_buf_request_complete(struct vb2_buffer *vb) -{ - struct rkvdec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - - v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_hdl); -} - -static int rkvdec_start_streaming(struct vb2_queue *q, unsigned int count) -{ - struct rkvdec_ctx *ctx = vb2_get_drv_priv(q); - const struct rkvdec_coded_fmt_desc *desc; - int ret; - - if (V4L2_TYPE_IS_CAPTURE(q->type)) - return 0; - - desc = ctx->coded_fmt_desc; - if (WARN_ON(!desc)) - return -EINVAL; - - if (desc->ops->start) { - ret = desc->ops->start(ctx); - if (ret) - return ret; - } - - return 0; -} - -static void rkvdec_queue_cleanup(struct vb2_queue *vq, u32 state) -{ - struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq); - - while (true) { - struct vb2_v4l2_buffer *vbuf; - - if (V4L2_TYPE_IS_OUTPUT(vq->type)) - vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - else - vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - - if (!vbuf) - break; - - v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, - &ctx->ctrl_hdl); - v4l2_m2m_buf_done(vbuf, state); - } -} - -static void rkvdec_stop_streaming(struct vb2_queue *q) -{ - struct rkvdec_ctx *ctx = vb2_get_drv_priv(q); - - if (V4L2_TYPE_IS_OUTPUT(q->type)) { - const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc; - - if (WARN_ON(!desc)) - return; - - if (desc->ops->stop) - desc->ops->stop(ctx); - } - - rkvdec_queue_cleanup(q, VB2_BUF_STATE_ERROR); -} - -static const struct vb2_ops rkvdec_queue_ops = { - .queue_setup = rkvdec_queue_setup, - .buf_prepare = rkvdec_buf_prepare, - .buf_queue = rkvdec_buf_queue, - .buf_out_validate = rkvdec_buf_out_validate, - .buf_request_complete = rkvdec_buf_request_complete, - .start_streaming = rkvdec_start_streaming, - .stop_streaming = rkvdec_stop_streaming, -}; - -static int rkvdec_request_validate(struct media_request *req) -{ - unsigned int count; - - count = vb2_request_buffer_cnt(req); - if (!count) - return -ENOENT; - else if (count > 1) - return -EINVAL; - - return vb2_request_validate(req); -} - -static const struct media_device_ops rkvdec_media_ops = { - .req_validate = rkvdec_request_validate, - .req_queue = v4l2_m2m_request_queue, -}; - -static void rkvdec_job_finish_no_pm(struct rkvdec_ctx *ctx, - enum vb2_buffer_state result) -{ - if (ctx->coded_fmt_desc->ops->done) { - struct vb2_v4l2_buffer *src_buf, *dst_buf; - - src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - ctx->coded_fmt_desc->ops->done(ctx, src_buf, dst_buf, result); - } - - v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx, - result); -} - -static void rkvdec_job_finish(struct rkvdec_ctx *ctx, - enum vb2_buffer_state result) -{ - struct rkvdec_dev *rkvdec = ctx->dev; - - pm_runtime_mark_last_busy(rkvdec->dev); - pm_runtime_put_autosuspend(rkvdec->dev); - rkvdec_job_finish_no_pm(ctx, result); -} - -void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run) -{ - struct media_request *src_req; - - memset(run, 0, sizeof(*run)); - - run->bufs.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - run->bufs.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - - /* Apply request(s) controls if needed. */ - src_req = run->bufs.src->vb2_buf.req_obj.req; - if (src_req) - v4l2_ctrl_request_setup(src_req, &ctx->ctrl_hdl); - - v4l2_m2m_buf_copy_metadata(run->bufs.src, run->bufs.dst, true); -} - -void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run) -{ - struct media_request *src_req = run->bufs.src->vb2_buf.req_obj.req; - - if (src_req) - v4l2_ctrl_request_complete(src_req, &ctx->ctrl_hdl); -} - -static void rkvdec_device_run(void *priv) -{ - struct rkvdec_ctx *ctx = priv; - struct rkvdec_dev *rkvdec = ctx->dev; - const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc; - int ret; - - if (WARN_ON(!desc)) - return; - - ret = pm_runtime_resume_and_get(rkvdec->dev); - if (ret < 0) { - rkvdec_job_finish_no_pm(ctx, VB2_BUF_STATE_ERROR); - return; - } - - ret = desc->ops->run(ctx); - if (ret) - rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR); -} - -static const struct v4l2_m2m_ops rkvdec_m2m_ops = { - .device_run = rkvdec_device_run, -}; - -static int rkvdec_queue_init(void *priv, - struct vb2_queue *src_vq, - struct vb2_queue *dst_vq) -{ - struct rkvdec_ctx *ctx = priv; - struct rkvdec_dev *rkvdec = ctx->dev; - int ret; - - src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - src_vq->io_modes = VB2_MMAP | VB2_DMABUF; - src_vq->drv_priv = ctx; - src_vq->ops = &rkvdec_queue_ops; - src_vq->mem_ops = &vb2_dma_contig_memops; - - /* - * Driver does mostly sequential access, so sacrifice TLB efficiency - * for faster allocation. Also, no CPU access on the source queue, - * so no kernel mapping needed. - */ - src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES | - DMA_ATTR_NO_KERNEL_MAPPING; - src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); - src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - src_vq->lock = &rkvdec->vdev_lock; - src_vq->dev = rkvdec->v4l2_dev.dev; - src_vq->supports_requests = true; - src_vq->requires_requests = true; - - ret = vb2_queue_init(src_vq); - if (ret) - return ret; - - dst_vq->bidirectional = true; - dst_vq->mem_ops = &vb2_dma_contig_memops; - dst_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES | - DMA_ATTR_NO_KERNEL_MAPPING; - dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; - dst_vq->drv_priv = ctx; - dst_vq->ops = &rkvdec_queue_ops; - dst_vq->buf_struct_size = sizeof(struct rkvdec_decoded_buffer); - dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - dst_vq->lock = &rkvdec->vdev_lock; - dst_vq->dev = rkvdec->v4l2_dev.dev; - - return vb2_queue_init(dst_vq); -} - -static int rkvdec_add_ctrls(struct rkvdec_ctx *ctx, - const struct rkvdec_ctrls *ctrls) -{ - unsigned int i; - - for (i = 0; i < ctrls->num_ctrls; i++) { - const struct v4l2_ctrl_config *cfg = &ctrls->ctrls[i].cfg; - - v4l2_ctrl_new_custom(&ctx->ctrl_hdl, cfg, ctx); - if (ctx->ctrl_hdl.error) - return ctx->ctrl_hdl.error; - } - - return 0; -} - -static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx) -{ - unsigned int i, nctrls = 0; - int ret; - - for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) - nctrls += rkvdec_coded_fmts[i].ctrls->num_ctrls; - - v4l2_ctrl_handler_init(&ctx->ctrl_hdl, nctrls); - - for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) { - ret = rkvdec_add_ctrls(ctx, rkvdec_coded_fmts[i].ctrls); - if (ret) - goto err_free_handler; - } - - ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); - if (ret) - goto err_free_handler; - - ctx->fh.ctrl_handler = &ctx->ctrl_hdl; - return 0; - -err_free_handler: - v4l2_ctrl_handler_free(&ctx->ctrl_hdl); - return ret; -} - -static int rkvdec_open(struct file *filp) -{ - struct rkvdec_dev *rkvdec = video_drvdata(filp); - struct rkvdec_ctx *ctx; - int ret; - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - ctx->dev = rkvdec; - rkvdec_reset_coded_fmt(ctx); - rkvdec_reset_decoded_fmt(ctx); - v4l2_fh_init(&ctx->fh, video_devdata(filp)); - - ret = rkvdec_init_ctrls(ctx); - if (ret) - goto err_free_ctx; - - ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(rkvdec->m2m_dev, ctx, - rkvdec_queue_init); - if (IS_ERR(ctx->fh.m2m_ctx)) { - ret = PTR_ERR(ctx->fh.m2m_ctx); - goto err_cleanup_ctrls; - } - - filp->private_data = &ctx->fh; - v4l2_fh_add(&ctx->fh); - - return 0; - -err_cleanup_ctrls: - v4l2_ctrl_handler_free(&ctx->ctrl_hdl); - -err_free_ctx: - kfree(ctx); - return ret; -} - -static int rkvdec_release(struct file *filp) -{ - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(filp->private_data); - - v4l2_fh_del(&ctx->fh); - v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); - v4l2_ctrl_handler_free(&ctx->ctrl_hdl); - v4l2_fh_exit(&ctx->fh); - kfree(ctx); - - return 0; -} - -static const struct v4l2_file_operations rkvdec_fops = { - .owner = THIS_MODULE, - .open = rkvdec_open, - .release = rkvdec_release, - .poll = v4l2_m2m_fop_poll, - .unlocked_ioctl = video_ioctl2, - .mmap = v4l2_m2m_fop_mmap, -}; - -static int rkvdec_v4l2_init(struct rkvdec_dev *rkvdec) -{ - int ret; - - ret = v4l2_device_register(rkvdec->dev, &rkvdec->v4l2_dev); - if (ret) { - dev_err(rkvdec->dev, "Failed to register V4L2 device\n"); - return ret; - } - - rkvdec->m2m_dev = v4l2_m2m_init(&rkvdec_m2m_ops); - if (IS_ERR(rkvdec->m2m_dev)) { - v4l2_err(&rkvdec->v4l2_dev, "Failed to init mem2mem device\n"); - ret = PTR_ERR(rkvdec->m2m_dev); - goto err_unregister_v4l2; - } - - rkvdec->mdev.dev = rkvdec->dev; - strscpy(rkvdec->mdev.model, "rkvdec", sizeof(rkvdec->mdev.model)); - strscpy(rkvdec->mdev.bus_info, "platform:rkvdec", - sizeof(rkvdec->mdev.bus_info)); - media_device_init(&rkvdec->mdev); - rkvdec->mdev.ops = &rkvdec_media_ops; - rkvdec->v4l2_dev.mdev = &rkvdec->mdev; - - rkvdec->vdev.lock = &rkvdec->vdev_lock; - rkvdec->vdev.v4l2_dev = &rkvdec->v4l2_dev; - rkvdec->vdev.fops = &rkvdec_fops; - rkvdec->vdev.release = video_device_release_empty; - rkvdec->vdev.vfl_dir = VFL_DIR_M2M; - rkvdec->vdev.device_caps = V4L2_CAP_STREAMING | - V4L2_CAP_VIDEO_M2M_MPLANE; - rkvdec->vdev.ioctl_ops = &rkvdec_ioctl_ops; - video_set_drvdata(&rkvdec->vdev, rkvdec); - strscpy(rkvdec->vdev.name, "rkvdec", sizeof(rkvdec->vdev.name)); - - ret = video_register_device(&rkvdec->vdev, VFL_TYPE_VIDEO, -1); - if (ret) { - v4l2_err(&rkvdec->v4l2_dev, "Failed to register video device\n"); - goto err_cleanup_mc; - } - - ret = v4l2_m2m_register_media_controller(rkvdec->m2m_dev, &rkvdec->vdev, - MEDIA_ENT_F_PROC_VIDEO_DECODER); - if (ret) { - v4l2_err(&rkvdec->v4l2_dev, - "Failed to initialize V4L2 M2M media controller\n"); - goto err_unregister_vdev; - } - - ret = media_device_register(&rkvdec->mdev); - if (ret) { - v4l2_err(&rkvdec->v4l2_dev, "Failed to register media device\n"); - goto err_unregister_mc; - } - - return 0; - -err_unregister_mc: - v4l2_m2m_unregister_media_controller(rkvdec->m2m_dev); - -err_unregister_vdev: - video_unregister_device(&rkvdec->vdev); - -err_cleanup_mc: - media_device_cleanup(&rkvdec->mdev); - v4l2_m2m_release(rkvdec->m2m_dev); - -err_unregister_v4l2: - v4l2_device_unregister(&rkvdec->v4l2_dev); - return ret; -} - -static void rkvdec_v4l2_cleanup(struct rkvdec_dev *rkvdec) -{ - media_device_unregister(&rkvdec->mdev); - v4l2_m2m_unregister_media_controller(rkvdec->m2m_dev); - video_unregister_device(&rkvdec->vdev); - media_device_cleanup(&rkvdec->mdev); - v4l2_m2m_release(rkvdec->m2m_dev); - v4l2_device_unregister(&rkvdec->v4l2_dev); -} - -static irqreturn_t rkvdec_irq_handler(int irq, void *priv) -{ - struct rkvdec_dev *rkvdec = priv; - enum vb2_buffer_state state; - u32 status; - - status = readl(rkvdec->regs + RKVDEC_REG_INTERRUPT); - state = (status & RKVDEC_RDY_STA) ? - VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; - - writel(0, rkvdec->regs + RKVDEC_REG_INTERRUPT); - if (cancel_delayed_work(&rkvdec->watchdog_work)) { - struct rkvdec_ctx *ctx; - - ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev); - rkvdec_job_finish(ctx, state); - } - - return IRQ_HANDLED; -} - -static void rkvdec_watchdog_func(struct work_struct *work) -{ - struct rkvdec_dev *rkvdec; - struct rkvdec_ctx *ctx; - - rkvdec = container_of(to_delayed_work(work), struct rkvdec_dev, - watchdog_work); - ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev); - if (ctx) { - dev_err(rkvdec->dev, "Frame processing timed out!\n"); - writel(RKVDEC_IRQ_DIS, rkvdec->regs + RKVDEC_REG_INTERRUPT); - writel(0, rkvdec->regs + RKVDEC_REG_SYSCTRL); - rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR); - } -} - -static const struct of_device_id of_rkvdec_match[] = { - { .compatible = "rockchip,rk3399-vdec" }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, of_rkvdec_match); - -static const char * const rkvdec_clk_names[] = { - "axi", "ahb", "cabac", "core" -}; - -static int rkvdec_probe(struct platform_device *pdev) -{ - struct rkvdec_dev *rkvdec; - unsigned int i; - int ret, irq; - - rkvdec = devm_kzalloc(&pdev->dev, sizeof(*rkvdec), GFP_KERNEL); - if (!rkvdec) - return -ENOMEM; - - platform_set_drvdata(pdev, rkvdec); - rkvdec->dev = &pdev->dev; - mutex_init(&rkvdec->vdev_lock); - INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func); - - rkvdec->clocks = devm_kcalloc(&pdev->dev, ARRAY_SIZE(rkvdec_clk_names), - sizeof(*rkvdec->clocks), GFP_KERNEL); - if (!rkvdec->clocks) - return -ENOMEM; - - for (i = 0; i < ARRAY_SIZE(rkvdec_clk_names); i++) - rkvdec->clocks[i].id = rkvdec_clk_names[i]; - - ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(rkvdec_clk_names), - rkvdec->clocks); - if (ret) - return ret; - - rkvdec->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(rkvdec->regs)) - return PTR_ERR(rkvdec->regs); - - ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (ret) { - dev_err(&pdev->dev, "Could not set DMA coherent mask.\n"); - return ret; - } - - vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); - - irq = platform_get_irq(pdev, 0); - if (irq <= 0) - return -ENXIO; - - ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, - rkvdec_irq_handler, IRQF_ONESHOT, - dev_name(&pdev->dev), rkvdec); - if (ret) { - dev_err(&pdev->dev, "Could not request vdec IRQ\n"); - return ret; - } - - pm_runtime_set_autosuspend_delay(&pdev->dev, 100); - pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_enable(&pdev->dev); - - ret = rkvdec_v4l2_init(rkvdec); - if (ret) - goto err_disable_runtime_pm; - - return 0; - -err_disable_runtime_pm: - pm_runtime_dont_use_autosuspend(&pdev->dev); - pm_runtime_disable(&pdev->dev); - return ret; -} - -static void rkvdec_remove(struct platform_device *pdev) -{ - struct rkvdec_dev *rkvdec = platform_get_drvdata(pdev); - - cancel_delayed_work_sync(&rkvdec->watchdog_work); - - rkvdec_v4l2_cleanup(rkvdec); - pm_runtime_disable(&pdev->dev); - pm_runtime_dont_use_autosuspend(&pdev->dev); -} - -#ifdef CONFIG_PM -static int rkvdec_runtime_resume(struct device *dev) -{ - struct rkvdec_dev *rkvdec = dev_get_drvdata(dev); - - return clk_bulk_prepare_enable(ARRAY_SIZE(rkvdec_clk_names), - rkvdec->clocks); -} - -static int rkvdec_runtime_suspend(struct device *dev) -{ - struct rkvdec_dev *rkvdec = dev_get_drvdata(dev); - - clk_bulk_disable_unprepare(ARRAY_SIZE(rkvdec_clk_names), - rkvdec->clocks); - return 0; -} -#endif - -static const struct dev_pm_ops rkvdec_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) - SET_RUNTIME_PM_OPS(rkvdec_runtime_suspend, rkvdec_runtime_resume, NULL) -}; - -static struct platform_driver rkvdec_driver = { - .probe = rkvdec_probe, - .remove = rkvdec_remove, - .driver = { - .name = "rkvdec", - .of_match_table = of_rkvdec_match, - .pm = &rkvdec_pm_ops, - }, -}; -module_platform_driver(rkvdec_driver); - -MODULE_AUTHOR("Boris Brezillon <boris.brezillon@collabora.com>"); -MODULE_DESCRIPTION("Rockchip Video Decoder driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h deleted file mode 100644 index 633335ebb9c4..000000000000 --- a/drivers/staging/media/rkvdec/rkvdec.h +++ /dev/null @@ -1,127 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Rockchip Video Decoder driver - * - * Copyright (C) 2019 Collabora, Ltd. - * - * Based on rkvdec driver by Google LLC. (Tomasz Figa <tfiga@chromium.org>) - * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. - * Copyright (C) 2011 Samsung Electronics Co., Ltd. - */ -#ifndef RKVDEC_H_ -#define RKVDEC_H_ - -#include <linux/platform_device.h> -#include <linux/videodev2.h> -#include <linux/wait.h> -#include <linux/clk.h> - -#include <media/v4l2-ctrls.h> -#include <media/v4l2-device.h> -#include <media/v4l2-ioctl.h> -#include <media/videobuf2-core.h> -#include <media/videobuf2-dma-contig.h> - -struct rkvdec_ctx; - -struct rkvdec_ctrl_desc { - struct v4l2_ctrl_config cfg; -}; - -struct rkvdec_ctrls { - const struct rkvdec_ctrl_desc *ctrls; - unsigned int num_ctrls; -}; - -struct rkvdec_run { - struct { - struct vb2_v4l2_buffer *src; - struct vb2_v4l2_buffer *dst; - } bufs; -}; - -struct rkvdec_vp9_decoded_buffer_info { - /* Info needed when the decoded frame serves as a reference frame. */ - unsigned short width; - unsigned short height; - unsigned int bit_depth : 4; -}; - -struct rkvdec_decoded_buffer { - /* Must be the first field in this struct. */ - struct v4l2_m2m_buffer base; - - union { - struct rkvdec_vp9_decoded_buffer_info vp9; - }; -}; - -static inline struct rkvdec_decoded_buffer * -vb2_to_rkvdec_decoded_buf(struct vb2_buffer *buf) -{ - return container_of(buf, struct rkvdec_decoded_buffer, - base.vb.vb2_buf); -} - -struct rkvdec_coded_fmt_ops { - int (*adjust_fmt)(struct rkvdec_ctx *ctx, - struct v4l2_format *f); - int (*start)(struct rkvdec_ctx *ctx); - void (*stop)(struct rkvdec_ctx *ctx); - int (*run)(struct rkvdec_ctx *ctx); - void (*done)(struct rkvdec_ctx *ctx, struct vb2_v4l2_buffer *src_buf, - struct vb2_v4l2_buffer *dst_buf, - enum vb2_buffer_state result); - int (*try_ctrl)(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl); -}; - -struct rkvdec_coded_fmt_desc { - u32 fourcc; - struct v4l2_frmsize_stepwise frmsize; - const struct rkvdec_ctrls *ctrls; - const struct rkvdec_coded_fmt_ops *ops; - unsigned int num_decoded_fmts; - const u32 *decoded_fmts; - u32 subsystem_flags; -}; - -struct rkvdec_dev { - struct v4l2_device v4l2_dev; - struct media_device mdev; - struct video_device vdev; - struct v4l2_m2m_dev *m2m_dev; - struct device *dev; - struct clk_bulk_data *clocks; - void __iomem *regs; - struct mutex vdev_lock; /* serializes ioctls */ - struct delayed_work watchdog_work; -}; - -struct rkvdec_ctx { - struct v4l2_fh fh; - struct v4l2_format coded_fmt; - struct v4l2_format decoded_fmt; - const struct rkvdec_coded_fmt_desc *coded_fmt_desc; - struct v4l2_ctrl_handler ctrl_hdl; - struct rkvdec_dev *dev; - void *priv; -}; - -static inline struct rkvdec_ctx *fh_to_rkvdec_ctx(struct v4l2_fh *fh) -{ - return container_of(fh, struct rkvdec_ctx, fh); -} - -struct rkvdec_aux_buf { - void *cpu; - dma_addr_t dma; - size_t size; -}; - -void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run); -void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run); - -extern const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops; -extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops; - -#endif /* RKVDEC_H_ */ diff --git a/drivers/staging/media/starfive/camss/stf-isp.c b/drivers/staging/media/starfive/camss/stf-isp.c index 4e6e26736852..df7a903fbb1b 100644 --- a/drivers/staging/media/starfive/camss/stf-isp.c +++ b/drivers/staging/media/starfive/camss/stf-isp.c @@ -278,7 +278,7 @@ static int isp_set_selection(struct v4l2_subdev *sd, isp_set_format(sd, state, &fmt); } - dev_dbg(isp_dev->stfcamss->dev, "pad: %d sel(%d,%d)/%dx%d\n", + dev_dbg(isp_dev->stfcamss->dev, "pad: %d sel(%d,%d)/%ux%u\n", sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height); return 0; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c index 32af0e96e762..444fb53878d1 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c @@ -86,9 +86,26 @@ void cedrus_dst_format_set(struct cedrus_dev *dev, switch (fmt->pixelformat) { case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: chroma_size = ALIGN(width, 16) * ALIGN(height, 16) / 2; - reg = VE_PRIMARY_OUT_FMT_NV12; + switch (fmt->pixelformat) { + case V4L2_PIX_FMT_NV12: + reg = VE_PRIMARY_OUT_FMT_NV12; + break; + case V4L2_PIX_FMT_NV21: + reg = VE_PRIMARY_OUT_FMT_NV21; + break; + case V4L2_PIX_FMT_YUV420: + reg = VE_PRIMARY_OUT_FMT_YU12; + break; + case V4L2_PIX_FMT_YVU420: + default: + reg = VE_PRIMARY_OUT_FMT_YV12; + break; + } cedrus_write(dev, VE_PRIMARY_OUT_FMT, reg); reg = chroma_size / 2; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c index 77f78266f406..9fae2c7493d0 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c @@ -64,6 +64,21 @@ static struct cedrus_format cedrus_formats[] = { .pixelformat = V4L2_PIX_FMT_NV12_32L32, .directions = CEDRUS_DECODE_DST, }, + { + .pixelformat = V4L2_PIX_FMT_NV21, + .directions = CEDRUS_DECODE_DST, + .capabilities = CEDRUS_CAPABILITY_UNTILED, + }, + { + .pixelformat = V4L2_PIX_FMT_YUV420, + .directions = CEDRUS_DECODE_DST, + .capabilities = CEDRUS_CAPABILITY_UNTILED, + }, + { + .pixelformat = V4L2_PIX_FMT_YVU420, + .directions = CEDRUS_DECODE_DST, + .capabilities = CEDRUS_CAPABILITY_UNTILED, + }, }; #define CEDRUS_FORMATS_COUNT ARRAY_SIZE(cedrus_formats) @@ -140,6 +155,9 @@ void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt) break; case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: /* 16-aligned stride. */ bytesperline = ALIGN(width, 16); diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index e0e67a3eb722..2faab9fdedef 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c @@ -194,7 +194,7 @@ static int nvec_power_bat_notifier(struct notifier_block *nb, break; case MANUFACTURER: memcpy(power->bat_manu, &res->plc, res->length - 2); - power->bat_model[res->length - 2] = '\0'; + power->bat_manu[res->length - 2] = '\0'; break; case MODEL: memcpy(power->bat_model, &res->plc, res->length - 2); diff --git a/drivers/staging/rtl8723bs/core/rtw_ap.c b/drivers/staging/rtl8723bs/core/rtw_ap.c index 50022bb5911e..b2e7e7267aa4 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ap.c +++ b/drivers/staging/rtl8723bs/core/rtw_ap.c @@ -389,7 +389,7 @@ void update_bmc_sta(struct adapter *padapter) psta->qos_option = 0; psta->htpriv.ht_option = false; - psta->ieee8021x_blocked = 0; + psta->ieee8021x_blocked = false; memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); @@ -741,13 +741,8 @@ void start_bss_network(struct adapter *padapter) if (p && ie_len) { pht_info = (struct HT_info_element *)(p + 2); - if (cur_channel > 14) { - if ((pregpriv->bw_mode & 0xf0) > 0) - cbw40_enable = 1; - } else { - if ((pregpriv->bw_mode & 0x0f) > 0) - cbw40_enable = 1; - } + if ((pregpriv->bw_mode & 0x0f) > 0) + cbw40_enable = 1; if ((cbw40_enable) && (pht_info->infos[0] & BIT(2))) { /* switch to the 40M Hz mode */ diff --git a/drivers/staging/rtl8723bs/core/rtw_btcoex.c b/drivers/staging/rtl8723bs/core/rtw_btcoex.c index d54095f50113..f4b19ef7b341 100644 --- a/drivers/staging/rtl8723bs/core/rtw_btcoex.c +++ b/drivers/staging/rtl8723bs/core/rtw_btcoex.c @@ -8,14 +8,14 @@ #include <rtw_btcoex.h> #include <hal_btcoex.h> -void rtw_btcoex_MediaStatusNotify(struct adapter *padapter, u8 mediaStatus) +void rtw_btcoex_MediaStatusNotify(struct adapter *padapter, u8 media_status) { - if ((mediaStatus == RT_MEDIA_CONNECT) + if ((media_status == RT_MEDIA_CONNECT) && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true)) { rtw_hal_set_hwreg(padapter, HW_VAR_DL_RSVD_PAGE, NULL); } - hal_btcoex_MediaStatusNotify(padapter, mediaStatus); + hal_btcoex_MediaStatusNotify(padapter, media_status); } void rtw_btcoex_HaltNotify(struct adapter *padapter) @@ -52,14 +52,14 @@ void rtw_btcoex_RejectApAggregatedPacket(struct adapter *padapter, u8 enable) void rtw_btcoex_LPS_Enter(struct adapter *padapter) { struct pwrctrl_priv *pwrpriv; - u8 lpsVal; + u8 lps_val; pwrpriv = adapter_to_pwrctl(padapter); pwrpriv->bpower_saving = true; - lpsVal = hal_btcoex_LpsVal(padapter); - rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, lpsVal, "BTCOEX"); + lps_val = hal_btcoex_LpsVal(padapter); + rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, lps_val, "BTCOEX"); } void rtw_btcoex_LPS_Leave(struct adapter *padapter) diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c index 1c9e8b01d9d8..ef2d92b5588a 100644 --- a/drivers/staging/rtl8723bs/core/rtw_cmd.c +++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c @@ -273,9 +273,9 @@ struct cmd_obj *_rtw_dequeue_cmd(struct __queue *queue) /* spin_lock_bh(&(queue->lock)); */ spin_lock_irqsave(&queue->lock, irqL); - if (list_empty(&queue->queue)) + if (list_empty(&queue->queue)) { obj = NULL; - else { + } else { obj = container_of(get_next(&queue->queue), struct cmd_obj, list); list_del_init(&obj->list); } @@ -695,7 +695,6 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) /* for ies is fix buf size */ t_len = sizeof(struct wlan_bssid_ex); - /* for hidden ap to set fw_state here */ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) != true) { switch (ndis_network_mode) { @@ -738,7 +737,6 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) psecnetwork->ie_length = rtw_restruct_sec_ie(padapter, &pnetwork->network.ies[0], &psecnetwork->ies[0], pnetwork->network.ie_length); - pqospriv->qos_option = 0; if (pregistrypriv->wmm_enable) { @@ -1032,7 +1030,6 @@ u8 rtw_reset_securitypriv_cmd(struct adapter *padapter) init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); - /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ res = rtw_enqueue_cmd(pcmdpriv, ph2c); exit: @@ -1099,7 +1096,6 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter) pdrvextra_cmd_parm->pbuf = NULL; init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); - /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ res = rtw_enqueue_cmd(pcmdpriv, ph2c); exit: @@ -1256,7 +1252,6 @@ static void dynamic_chk_wk_hdl(struct adapter *padapter) /* */ hal_btcoex_Handler(padapter); - /* always call rtw_ps_processor() at last one. */ rtw_ps_processor(padapter); } @@ -1322,9 +1317,6 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue) /* struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); */ u8 res = _SUCCESS; - /* if (!pwrctrlpriv->bLeisurePs) */ - /* return res; */ - if (enqueue) { ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); if (!ph2c) { @@ -1367,7 +1359,6 @@ u8 rtw_dm_in_lps_wk_cmd(struct adapter *padapter) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); if (!ph2c) { res = _FAIL; @@ -1850,7 +1841,6 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) spin_lock_bh(&pmlmepriv->lock); - if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->mac_address); if (!psta) { diff --git a/drivers/staging/rtl8723bs/core/rtw_efuse.c b/drivers/staging/rtl8723bs/core/rtw_efuse.c index 7a74b011dedc..208373113a62 100644 --- a/drivers/staging/rtl8723bs/core/rtw_efuse.c +++ b/drivers/staging/rtl8723bs/core/rtw_efuse.c @@ -70,7 +70,7 @@ Efuse_Write1ByteToFakeContent(u16 Offset, u8 Value) * When Who Remark * 11/17/2008 MHC Create Version 0. * - *---------------------------------------------------------------------------*/ + */ void Efuse_PowerSwitch( struct adapter *padapter, @@ -85,6 +85,7 @@ u8 Efuse_CalculateWordCnts(u8 word_en) { u8 word_cnts = 0; + if (!(word_en & BIT(0))) word_cnts++; /* 0 : write enable */ if (!(word_en & BIT(1))) @@ -163,7 +164,7 @@ EFUSE_GetEfuseDefinition( * When Who Remark * 09/23/2008 MHC Copy from WMAC. * - *---------------------------------------------------------------------------*/ + */ u8 EFUSE_Read1Byte( struct adapter *Adapter, @@ -286,18 +287,6 @@ u8 efuse_OneByteWrite(struct adapter *padapter, u16 addr, u8 data, bool bPseudoT return bResult; } -u8 -Efuse_WordEnableDataWrite(struct adapter *padapter, - u16 efuse_addr, - u8 word_en, - u8 *data, - bool bPseudoTest) -{ - return padapter->HalFunc.Efuse_WordEnableDataWrite(padapter, efuse_addr, - word_en, data, - bPseudoTest); -} - /*----------------------------------------------------------------------------- * Function: Efuse_ReadAllMap * @@ -313,7 +302,7 @@ Efuse_WordEnableDataWrite(struct adapter *padapter, * When Who Remark * 11/11/2008 MHC Create Version 0. * - *---------------------------------------------------------------------------*/ + */ void Efuse_ReadAllMap( struct adapter *padapter, @@ -350,7 +339,7 @@ void Efuse_ReadAllMap(struct adapter *padapter, u8 efuseType, u8 *Efuse, bool bP * When Who Remark * 11/12/2008 MHC Create Version 0. * - *---------------------------------------------------------------------------*/ + */ static void efuse_ShadowRead1Byte(struct adapter *padapter, u16 Offset, u8 *Value) { struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); @@ -396,7 +385,7 @@ static void efuse_ShadowRead4Byte(struct adapter *padapter, u16 Offset, u32 *Val * When Who Remark * 11/13/2008 MHC Create Version 0. * - *---------------------------------------------------------------------------*/ + */ void EFUSE_ShadowMapUpdate(struct adapter *padapter, u8 efuseType, bool bPseudoTest) { struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); @@ -429,7 +418,7 @@ void EFUSE_ShadowMapUpdate(struct adapter *padapter, u8 efuseType, bool bPseudoT * When Who Remark * 11/12/2008 MHC Create Version 0. * - *---------------------------------------------------------------------------*/ + */ void EFUSE_ShadowRead(struct adapter *padapter, u8 Type, u16 Offset, u32 *Value) { if (Type == 1) diff --git a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c index 0ed420f3d096..53d4c113b19c 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c @@ -988,11 +988,10 @@ void rtw_macaddr_cfg(struct device *dev, u8 *mac_addr) if (is_broadcast_ether_addr(mac) || is_zero_ether_addr(mac)) { addr = of_get_property(np, "local-mac-address", &len); - if (addr && len == ETH_ALEN) { + if (addr && len == ETH_ALEN) ether_addr_copy(mac_addr, addr); - } else { + else eth_random_addr(mac_addr); - } } } diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c index 58de0c2fdd68..692d0c2b766d 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c @@ -119,7 +119,7 @@ struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv) pnetwork = NULL; goto exit; } - plist = get_next(&(free_queue->queue)); + plist = get_next(&free_queue->queue); pnetwork = container_of(plist, struct wlan_network, list); @@ -141,7 +141,7 @@ void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwor { unsigned int delta_time; u32 lifetime = SCANQUEUE_LIFETIME; - struct __queue *free_queue = &(pmlmepriv->free_bss_pool); + struct __queue *free_queue = &pmlmepriv->free_bss_pool; if (!pnetwork) return; @@ -161,9 +161,9 @@ void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwor spin_lock_bh(&free_queue->lock); - list_del_init(&(pnetwork->list)); + list_del_init(&pnetwork->list); - list_add_tail(&(pnetwork->list), &(free_queue->queue)); + list_add_tail(&pnetwork->list, &free_queue->queue); spin_unlock_bh(&free_queue->lock); } @@ -171,7 +171,7 @@ void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwor void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork) { - struct __queue *free_queue = &(pmlmepriv->free_bss_pool); + struct __queue *free_queue = &pmlmepriv->free_bss_pool; if (!pnetwork) return; @@ -179,9 +179,9 @@ void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network * if (pnetwork->fixed) return; - list_del_init(&(pnetwork->list)); + list_del_init(&pnetwork->list); - list_add_tail(&(pnetwork->list), get_list_head(free_queue)); + list_add_tail(&pnetwork->list, get_list_head(free_queue)); } /* @@ -287,7 +287,7 @@ void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) void rtw_free_network_nolock(struct adapter *padapter, struct wlan_network *pnetwork); void rtw_free_network_nolock(struct adapter *padapter, struct wlan_network *pnetwork) { - _rtw_free_network_nolock(&(padapter->mlmepriv), pnetwork); + _rtw_free_network_nolock(&padapter->mlmepriv, pnetwork); rtw_cfg80211_unlink_bss(padapter, pnetwork); } @@ -404,7 +404,7 @@ void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, long rssi_final; /* The rule below is 1/5 for sample value, 4/5 for history value */ - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src, 0)) { + if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&padapter->mlmepriv.cur_network.network, src, 0)) { /* Take the recvpriv's value for the connected AP*/ ss_final = padapter->recvpriv.signal_strength; sq_final = padapter->recvpriv.signal_qual; @@ -440,15 +440,15 @@ void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork) { - struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - rtw_bug_check(&(pmlmepriv->cur_network.network), - &(pmlmepriv->cur_network.network), - &(pmlmepriv->cur_network.network), - &(pmlmepriv->cur_network.network)); + rtw_bug_check(&pmlmepriv->cur_network.network, + &pmlmepriv->cur_network.network, + &pmlmepriv->cur_network.network, + &pmlmepriv->cur_network.network); - if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork, 0))) { - update_network(&(pmlmepriv->cur_network.network), pnetwork, adapter, true); + if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) && (is_same_network(&pmlmepriv->cur_network.network, pnetwork, 0))) { + update_network(&pmlmepriv->cur_network.network, pnetwork, adapter, true); rtw_update_protection(adapter, (pmlmepriv->cur_network.network.ies) + sizeof(struct ndis_802_11_fix_ie), pmlmepriv->cur_network.network.ie_length); } @@ -461,8 +461,8 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t { struct list_head *plist, *phead; u32 bssid_ex_sz; - struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); - struct __queue *queue = &(pmlmepriv->scanned_queue); + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct __queue *queue = &pmlmepriv->scanned_queue; struct wlan_network *pnetwork = NULL; struct wlan_network *oldest = NULL; int target_find = 0; @@ -475,7 +475,7 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t rtw_bug_check(pnetwork, pnetwork, pnetwork, pnetwork); - if (is_same_network(&(pnetwork->network), target, feature)) { + if (is_same_network(&pnetwork->network, target, feature)) { target_find = 1; break; } @@ -499,7 +499,7 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t if (!pnetwork) goto exit; - memcpy(&(pnetwork->network), target, get_wlan_bssid_ex_sz(target)); + memcpy(&pnetwork->network, target, get_wlan_bssid_ex_sz(target)); /* variable initialize */ pnetwork->fixed = false; pnetwork->last_scanned = jiffies; @@ -521,7 +521,7 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t bssid_ex_sz = get_wlan_bssid_ex_sz(target); target->length = bssid_ex_sz; - memcpy(&(pnetwork->network), target, bssid_ex_sz); + memcpy(&pnetwork->network, target, bssid_ex_sz); pnetwork->last_scanned = jiffies; @@ -529,7 +529,7 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t if (pnetwork->network.phy_info.signal_quality == 101) pnetwork->network.phy_info.signal_quality = 0; - list_add_tail(&(pnetwork->list), &(queue->queue)); + list_add_tail(&pnetwork->list, &queue->queue); } } else { @@ -553,7 +553,7 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t update_ie = false; } - update_network(&(pnetwork->network), target, adapter, update_ie); + update_network(&pnetwork->network, target, adapter, update_ie); } exit: @@ -629,7 +629,7 @@ void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) { u32 len; struct wlan_bssid_ex *pnetwork; - struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; pnetwork = (struct wlan_bssid_ex *)pbuf; @@ -641,18 +641,18 @@ void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) /* update IBSS_network 's timestamp */ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) { - if (!memcmp(&(pmlmepriv->cur_network.network.mac_address), pnetwork->mac_address, ETH_ALEN)) { + if (!memcmp(&pmlmepriv->cur_network.network.mac_address, pnetwork->mac_address, ETH_ALEN)) { struct wlan_network *ibss_wlan = NULL; memcpy(pmlmepriv->cur_network.network.ies, pnetwork->ies, 8); - spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_lock_bh(&pmlmepriv->scanned_queue.lock); ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->mac_address); if (ibss_wlan) { memcpy(ibss_wlan->network.ies, pnetwork->ies, 8); - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_unlock_bh(&pmlmepriv->scanned_queue.lock); goto exit; } - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_unlock_bh(&pmlmepriv->scanned_queue.lock); } } @@ -670,7 +670,7 @@ exit: void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) { - struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; spin_lock_bh(&pmlmepriv->lock); if (pmlmepriv->wps_probe_req_ie) { @@ -697,7 +697,7 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); } else { u8 ret = _SUCCESS; - struct wlan_bssid_ex *pdev_network = &(adapter->registrypriv.dev_network); + struct wlan_bssid_ex *pdev_network = &adapter->registrypriv.dev_network; u8 *pibss = adapter->registrypriv.dev_network.mac_address; /* pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;because don't set assoc_timer */ @@ -922,8 +922,8 @@ inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted) void rtw_scan_abort(struct adapter *adapter) { unsigned long start; - struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); - struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; start = jiffies; pmlmeext->scan_abort = true; @@ -1029,8 +1029,8 @@ static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, str /* ptarget_wlan: found from scanned_queue */ static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network *pnetwork) { - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; /* why not use ptarget_wlan?? */ memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.length); @@ -1086,14 +1086,12 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) static u8 __maybe_unused retry; struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL; struct sta_priv *pstapriv = &adapter->stapriv; - struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; struct wlan_network *pnetwork = (struct wlan_network *)pbuf; - struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct wlan_network *cur_network = &pmlmepriv->cur_network; struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; unsigned int the_same_macaddr = false; - rtw_get_encrypt_decrypt_from_registrypriv(adapter); - the_same_macaddr = !memcmp(pnetwork->network.mac_address, cur_network->network.mac_address, ETH_ALEN); pnetwork->network.length = get_wlan_bssid_ex_sz(&pnetwork->network); @@ -1106,7 +1104,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0; if (pnetwork->join_res > 0) { - spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_lock_bh(&pmlmepriv->scanned_queue.lock); retry = 0; if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { /* s1. find ptarget_wlan */ @@ -1143,7 +1141,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) } else { netdev_dbg(adapter->pnetdev, "Can't find ptarget_wlan when joinbss_event callback\n"); - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_unlock_bh(&pmlmepriv->scanned_queue.lock); goto ignore_joinbss_callback; } @@ -1151,7 +1149,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork); if (!ptarget_sta) { - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_unlock_bh(&pmlmepriv->scanned_queue.lock); goto ignore_joinbss_callback; } } @@ -1169,7 +1167,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) timer_delete_sync(&pmlmepriv->assoc_timer); spin_lock_bh(&pmlmepriv->lock); } else { - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_unlock_bh(&pmlmepriv->scanned_queue.lock); } } else if (pnetwork->join_res == -4) { rtw_reset_securitypriv(adapter); @@ -1233,9 +1231,9 @@ void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta, u3 void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf) { struct sta_info *psta; - struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; - struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct wlan_network *cur_network = &pmlmepriv->cur_network; struct wlan_network *ptarget_wlan = NULL; if (rtw_access_ctrl(adapter, pstassoc->macaddr) == false) @@ -1306,12 +1304,12 @@ void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf) if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) || (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) { if (adapter->stapriv.asoc_sta_count == 2) { - spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_lock_bh(&pmlmepriv->scanned_queue.lock); ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.mac_address); pmlmepriv->cur_network_scanned = ptarget_wlan; if (ptarget_wlan) ptarget_wlan->fixed = true; - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_unlock_bh(&pmlmepriv->scanned_queue.lock); /* a sta + bc/mc_stainfo (not Ibss_stainfo) */ rtw_indicate_connect(adapter); } @@ -1329,11 +1327,11 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) struct wlan_network *pwlan = NULL; struct wlan_bssid_ex *pdev_network = NULL; u8 *pibss = NULL; - struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; struct stadel_event *pstadel = (struct stadel_event *)pbuf; - struct wlan_network *tgt_network = &(pmlmepriv->cur_network); + struct wlan_network *tgt_network = &pmlmepriv->cur_network; struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr); if (psta) @@ -1385,14 +1383,14 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) rtw_free_assoc_resources(adapter, 1); rtw_indicate_disconnect(adapter); - spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_lock_bh(&pmlmepriv->scanned_queue.lock); /* remove the network entry in scanned_queue */ pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address); if (pwlan) { pwlan->fixed = false; rtw_free_network_nolock(adapter, pwlan); } - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_unlock_bh(&pmlmepriv->scanned_queue.lock); _rtw_roaming(adapter, roam_target); } @@ -1404,16 +1402,16 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) if (adapter->stapriv.asoc_sta_count == 1) {/* a sta + bc/mc_stainfo (not Ibss_stainfo) */ u8 ret = _SUCCESS; - spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_lock_bh(&pmlmepriv->scanned_queue.lock); /* free old ibss network */ pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address); if (pwlan) { pwlan->fixed = false; rtw_free_network_nolock(adapter, pwlan); } - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_unlock_bh(&pmlmepriv->scanned_queue.lock); /* re-create ibss */ - pdev_network = &(adapter->registrypriv.dev_network); + pdev_network = &adapter->registrypriv.dev_network; pibss = adapter->registrypriv.dev_network.mac_address; memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network)); @@ -1460,8 +1458,8 @@ void rtw_wmm_event_callback(struct adapter *padapter, u8 *pbuf) */ void _rtw_join_timeout_handler(struct timer_list *t) { - struct adapter *adapter = from_timer(adapter, t, - mlmepriv.assoc_timer); + struct adapter *adapter = timer_container_of(adapter, t, + mlmepriv.assoc_timer); struct mlme_priv *pmlmepriv = &adapter->mlmepriv; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) @@ -1504,8 +1502,8 @@ void _rtw_join_timeout_handler(struct timer_list *t) */ void rtw_scan_timeout_handler(struct timer_list *t) { - struct adapter *adapter = from_timer(adapter, t, - mlmepriv.scan_to_timer); + struct adapter *adapter = timer_container_of(adapter, t, + mlmepriv.scan_to_timer); struct mlme_priv *pmlmepriv = &adapter->mlmepriv; spin_lock_bh(&pmlmepriv->lock); @@ -1521,7 +1519,7 @@ void rtw_mlme_reset_auto_scan_int(struct adapter *adapter) { struct mlme_priv *mlme = &adapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; if (pmlmeinfo->VHT_enable) /* disable auto scan when connect to 11AC AP */ mlme->auto_scan_int_ms = 0; @@ -1662,7 +1660,7 @@ int rtw_select_roaming_candidate(struct mlme_priv *mlme) { int ret = _FAIL; struct list_head *phead; - struct __queue *queue = &(mlme->scanned_queue); + struct __queue *queue = &mlme->scanned_queue; struct wlan_network *pnetwork = NULL; struct wlan_network *candidate = NULL; @@ -1671,7 +1669,7 @@ int rtw_select_roaming_candidate(struct mlme_priv *mlme) return ret; } - spin_lock_bh(&(mlme->scanned_queue.lock)); + spin_lock_bh(&mlme->scanned_queue.lock); phead = get_list_head(queue); list_for_each(mlme->pscanned, phead) { @@ -1695,7 +1693,7 @@ int rtw_select_roaming_candidate(struct mlme_priv *mlme) ret = _SUCCESS; exit: - spin_unlock_bh(&(mlme->scanned_queue.lock)); + spin_unlock_bh(&mlme->scanned_queue.lock); return ret; } @@ -1756,13 +1754,13 @@ int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv) int ret; struct list_head *phead; struct adapter *adapter; - struct __queue *queue = &(pmlmepriv->scanned_queue); + struct __queue *queue = &pmlmepriv->scanned_queue; struct wlan_network *pnetwork = NULL; struct wlan_network *candidate = NULL; adapter = (struct adapter *)pmlmepriv->nic_hdl; - spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_lock_bh(&pmlmepriv->scanned_queue.lock); if (pmlmepriv->roam_network) { candidate = pmlmepriv->roam_network; @@ -1800,7 +1798,7 @@ candidate_exist: ret = rtw_joinbss_cmd(adapter, candidate); exit: - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_unlock_bh(&pmlmepriv->scanned_queue.lock); return ret; } @@ -1808,7 +1806,7 @@ signed int rtw_set_auth(struct adapter *adapter, struct security_priv *psecurity { struct cmd_obj *pcmd; struct setauth_parm *psetauthparm; - struct cmd_priv *pcmdpriv = &(adapter->cmdpriv); + struct cmd_priv *pcmdpriv = &adapter->cmdpriv; signed int res = _SUCCESS; pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); @@ -1845,7 +1843,7 @@ signed int rtw_set_key(struct adapter *adapter, struct security_priv *psecurityp u8 keylen; struct cmd_obj *pcmd; struct setkey_parm *psetkeyparm; - struct cmd_priv *pcmdpriv = &(adapter->cmdpriv); + struct cmd_priv *pcmdpriv = &adapter->cmdpriv; signed int res = _SUCCESS; psetkeyparm = rtw_zmalloc(sizeof(struct setkey_parm)); @@ -1868,11 +1866,11 @@ signed int rtw_set_key(struct adapter *adapter, struct security_priv *psecurityp case _WEP40_: keylen = 5; - memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen); + memcpy(&psetkeyparm->key[0], &psecuritypriv->dot11DefKey[keyid].skey[0], keylen); break; case _WEP104_: keylen = 13; - memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen); + memcpy(&psetkeyparm->key[0], &psecuritypriv->dot11DefKey[keyid].skey[0], keylen); break; case _TKIP_: keylen = 16; @@ -2022,12 +2020,12 @@ signed int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, u } iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid); - if (iEntry < 0) { + if (iEntry < 0) return ielength; - } else { - if (authmode == WLAN_EID_RSN) - ielength = rtw_append_pmkid(adapter, iEntry, out_ie, ielength); - } + + if (authmode == WLAN_EID_RSN) + ielength = rtw_append_pmkid(adapter, iEntry, out_ie, ielength); + return ielength; } @@ -2095,10 +2093,6 @@ void rtw_update_registrypriv_dev_network(struct adapter *adapter) /* pdev_network->ie_length = cpu_to_le32(sz); */ } -void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter *adapter) -{ -} - /* the function is at passive_level */ void rtw_joinbss_reset(struct adapter *padapter) { @@ -2252,13 +2246,8 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ } /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */ - if (channel > 14) { - if ((pregistrypriv->bw_mode & 0xf0) > 0) - cbw40_enable = 1; - } else { - if ((pregistrypriv->bw_mode & 0x0f) > 0) - cbw40_enable = 1; - } + if ((pregistrypriv->bw_mode & 0x0f) > 0) + cbw40_enable = 1; if ((cbw40_enable == 1) && (operation_bw == CHANNEL_WIDTH_40)) { ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH); @@ -2335,7 +2324,7 @@ void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len, u8 channe struct ht_priv *phtpriv = &pmlmepriv->htpriv; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 cbw40_enable = 0; if (!phtpriv->ht_option) @@ -2366,13 +2355,8 @@ void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len, u8 channe /* todo: */ } - if (channel > 14) { - if ((pregistrypriv->bw_mode & 0xf0) > 0) - cbw40_enable = 1; - } else { - if ((pregistrypriv->bw_mode & 0x0f) > 0) - cbw40_enable = 1; - } + if ((pregistrypriv->bw_mode & 0x0f) > 0) + cbw40_enable = 1; /* update cur_bwmode & cur_ch_offset */ if ((cbw40_enable) && diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index 3d36b6f005e0..bc980d21d50e 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -3511,7 +3511,7 @@ void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned ch /* if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.mac_address)) != NULL) */ psta = rtw_get_stainfo(pstapriv, raddr); if (psta) { - start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1; + start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07] % 4096u) + 1; psta->BA_starting_seqctrl[status & 0x07] = start_seq; @@ -5088,7 +5088,7 @@ void linked_status_chk(struct adapter *padapter) void survey_timer_hdl(struct timer_list *t) { struct adapter *padapter = - from_timer(padapter, t, mlmeextpriv.survey_timer); + timer_container_of(padapter, t, mlmeextpriv.survey_timer); struct cmd_obj *ph2c; struct sitesurvey_parm *psurveyPara; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; @@ -5123,7 +5123,7 @@ void survey_timer_hdl(struct timer_list *t) void link_timer_hdl(struct timer_list *t) { struct adapter *padapter = - from_timer(padapter, t, mlmeextpriv.link_timer); + timer_container_of(padapter, t, mlmeextpriv.link_timer); /* static unsigned int rx_pkt = 0; */ /* static u64 tx_cnt = 0; */ /* struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); */ @@ -5161,7 +5161,7 @@ void link_timer_hdl(struct timer_list *t) void addba_timer_hdl(struct timer_list *t) { - struct sta_info *psta = from_timer(psta, t, addba_retry_timer); + struct sta_info *psta = timer_container_of(psta, t, addba_retry_timer); struct ht_priv *phtpriv; if (!psta) @@ -5179,7 +5179,7 @@ void addba_timer_hdl(struct timer_list *t) void sa_query_timer_hdl(struct timer_list *t) { struct adapter *padapter = - from_timer(padapter, t, mlmeextpriv.sa_query_timer); + timer_container_of(padapter, t, mlmeextpriv.sa_query_timer); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; /* disconnect */ spin_lock_bh(&pmlmepriv->lock); diff --git a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c index c60e179bb2e1..6a2583d0d3eb 100644 --- a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c @@ -8,7 +8,6 @@ #include <hal_data.h> #include <linux/jiffies.h> - void _ips_enter(struct adapter *padapter) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); @@ -56,9 +55,8 @@ int _ips_leave(struct adapter *padapter) pwrpriv->ips_leave_cnts++; result = rtw_ips_pwr_up(padapter); - if (result == _SUCCESS) { + if (result == _SUCCESS) pwrpriv->rf_pwrstate = rf_on; - } pwrpriv->bips_processing = false; pwrpriv->bkeepfwalive = false; @@ -177,7 +175,7 @@ exit: static void pwr_state_check_handler(struct timer_list *t) { struct pwrctrl_priv *pwrctrlpriv = - from_timer(pwrctrlpriv, t, pwr_state_check_timer); + timer_container_of(pwrctrlpriv, t, pwr_state_check_timer); struct adapter *padapter = pwrctrlpriv->adapter; rtw_ps_cmd(padapter); @@ -549,9 +547,8 @@ void LeaveAllPowerSaveMode(struct adapter *Adapter) LPS_Leave_check(Adapter); } else { - if (adapter_to_pwrctl(Adapter)->rf_pwrstate == rf_off) { + if (adapter_to_pwrctl(Adapter)->rf_pwrstate == rf_off) ips_leave(Adapter); - } } } @@ -677,7 +674,8 @@ exit: */ static void pwr_rpwm_timeout_handler(struct timer_list *t) { - struct pwrctrl_priv *pwrpriv = from_timer(pwrpriv, t, pwr_rpwm_timer); + struct pwrctrl_priv *pwrpriv = timer_container_of(pwrpriv, t, + pwr_rpwm_timer); if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) return; @@ -996,7 +994,6 @@ void rtw_init_pwrctrl_priv(struct adapter *padapter) pwrctrlpriv->wowlan_ap_mode = false; } - void rtw_free_pwrctrl_priv(struct adapter *adapter) { } diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c index 895116e9f4e7..8ae527b6e0d6 100644 --- a/drivers/staging/rtl8723bs/core/rtw_recv.c +++ b/drivers/staging/rtl8723bs/core/rtw_recv.c @@ -1641,7 +1641,7 @@ static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_n struct dvobj_priv *psdpriv = padapter->dvobj; struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; u8 wsize = preorder_ctrl->wsize_b; - u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) & 0xFFF;/* 4096; */ + u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) % 4096u; /* Rx Reorder initialize condition. */ if (preorder_ctrl->indicate_seq == 0xFFFF) @@ -1657,7 +1657,7 @@ static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_n /* 2. Incoming SeqNum is larger than the WinEnd => Window shift N */ /* */ if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) { - preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; + preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096u; } else if (SN_LESS(wend, seq_num)) { /* boundary situation, when seq_num cross 0xFFF */ @@ -1772,7 +1772,7 @@ static int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reor list_del_init(&(prframe->u.hdr.list)); if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num)) - preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; + preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096u; /* Set this as a lock to make sure that only one thread is indicating packet. */ /* pTS->RxIndicateState = RXTS_INDICATE_PROCESSING; */ @@ -1908,7 +1908,7 @@ _err_exit: void rtw_reordering_ctrl_timeout_handler(struct timer_list *t) { struct recv_reorder_ctrl *preorder_ctrl = - from_timer(preorder_ctrl, t, reordering_ctrl_timer); + timer_container_of(preorder_ctrl, t, reordering_ctrl_timer); struct adapter *padapter = preorder_ctrl->padapter; struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; @@ -2087,7 +2087,7 @@ _recv_entry_drop: static void rtw_signal_stat_timer_hdl(struct timer_list *t) { struct adapter *adapter = - from_timer(adapter, t, recvpriv.signal_stat_timer); + timer_container_of(adapter, t, recvpriv.signal_stat_timer); struct recv_priv *recvpriv = &adapter->recvpriv; u32 tmp_s, tmp_q; diff --git a/drivers/staging/rtl8723bs/core/rtw_security.c b/drivers/staging/rtl8723bs/core/rtw_security.c index 1e9eff01b1aa..e9f382c280d9 100644 --- a/drivers/staging/rtl8723bs/core/rtw_security.c +++ b/drivers/staging/rtl8723bs/core/rtw_security.c @@ -868,29 +868,21 @@ static signed int aes_cipher(u8 *key, uint hdrlen, num_blocks, payload_index; u8 pn_vector[6]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 ctr_preload[16]; + u8 mic_iv[16] = {}; + u8 mic_header1[16] = {}; + u8 mic_header2[16] = {}; + u8 ctr_preload[16] = {}; /* Intermediate Buffers */ - u8 chain_buffer[16]; - u8 aes_out[16]; - u8 padded_buffer[16]; + u8 chain_buffer[16] = {}; + u8 aes_out[16] = {}; + u8 padded_buffer[16] = {}; u8 mic[8]; uint frtype = GetFrameType(pframe); uint frsubtype = GetFrameSubType(pframe); frsubtype = frsubtype>>4; - memset((void *)mic_iv, 0, 16); - memset((void *)mic_header1, 0, 16); - memset((void *)mic_header2, 0, 16); - memset((void *)ctr_preload, 0, 16); - memset((void *)chain_buffer, 0, 16); - memset((void *)aes_out, 0, 16); - memset((void *)padded_buffer, 0, 16); - if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) a4_exists = 0; else @@ -1080,15 +1072,15 @@ static signed int aes_decipher(u8 *key, uint hdrlen, num_blocks, payload_index; signed int res = _SUCCESS; u8 pn_vector[6]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 ctr_preload[16]; + u8 mic_iv[16] = {}; + u8 mic_header1[16] = {}; + u8 mic_header2[16] = {}; + u8 ctr_preload[16] = {}; /* Intermediate Buffers */ - u8 chain_buffer[16]; - u8 aes_out[16]; - u8 padded_buffer[16]; + u8 chain_buffer[16] = {}; + u8 aes_out[16] = {}; + u8 padded_buffer[16] = {}; u8 mic[8]; uint frtype = GetFrameType(pframe); @@ -1096,14 +1088,6 @@ static signed int aes_decipher(u8 *key, uint hdrlen, frsubtype = frsubtype>>4; - memset((void *)mic_iv, 0, 16); - memset((void *)mic_header1, 0, 16); - memset((void *)mic_header2, 0, 16); - memset((void *)ctr_preload, 0, 16); - memset((void *)chain_buffer, 0, 16); - memset((void *)aes_out, 0, 16); - memset((void *)padded_buffer, 0, 16); - /* start to decrypt the payload */ num_blocks = (plen-8) / 16; /* plen including LLC, payload_length and mic) */ diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c index 73c70b016f00..0c6072d08661 100644 --- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c @@ -854,13 +854,8 @@ static void bwmode_update_check(struct adapter *padapter, struct ndis_80211_var_ pHT_info = (struct HT_info_element *)pIE->data; - if (pmlmeext->cur_channel > 14) { - if ((pregistrypriv->bw_mode & 0xf0) > 0) - cbw40_enable = 1; - } else { - if ((pregistrypriv->bw_mode & 0x0f) > 0) - cbw40_enable = 1; - } + if ((pregistrypriv->bw_mode & 0x0f) > 0) + cbw40_enable = 1; if ((pHT_info->infos[0] & BIT(2)) && cbw40_enable) { new_bwmode = CHANNEL_WIDTH_40; diff --git a/drivers/staging/rtl8723bs/core/rtw_xmit.c b/drivers/staging/rtl8723bs/core/rtw_xmit.c index 297c93d65315..8c6841f078b4 100644 --- a/drivers/staging/rtl8723bs/core/rtw_xmit.c +++ b/drivers/staging/rtl8723bs/core/rtw_xmit.c @@ -381,7 +381,7 @@ static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame * while (true) { /* IOT action */ if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && (pattrib->ampdu_en == true) && - (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) { + (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) { pattrib->vcs_mode = CTS_TO_SELF; break; } @@ -943,7 +943,7 @@ s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattr if (psta) { psta->sta_xmitpriv.txseq_tid[pattrib->priority]++; - psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; + psta->sta_xmitpriv.txseq_tid[pattrib->priority] %= 4096u; pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority]; SetSeqNum(hdr, pattrib->seqnum); @@ -963,11 +963,14 @@ s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattr if (SN_LESS(pattrib->seqnum, tx_seq)) { pattrib->ampdu_en = false;/* AGG BK */ } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) { - psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff; + psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = + (tx_seq + 1) % 4096u; pattrib->ampdu_en = true;/* AGG EN */ } else { - psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff; + psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = + (pattrib->seqnum + 1) % 4096u; + pattrib->ampdu_en = true;/* AGG EN */ } } @@ -1936,7 +1939,6 @@ static void do_queue_select(struct adapter *padapter, struct pkt_attrib *pattrib s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt) { static unsigned long start; - static u32 drop_cnt; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct xmit_frame *pxmitframe = NULL; @@ -1948,15 +1950,11 @@ s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt) pxmitframe = rtw_alloc_xmitframe(pxmitpriv); - if (jiffies_to_msecs(jiffies - start) > 2000) { + if (jiffies_to_msecs(jiffies - start) > 2000) start = jiffies; - drop_cnt = 0; - } - if (!pxmitframe) { - drop_cnt++; + if (!pxmitframe) return -1; - } res = update_attrib(padapter, *ppkt, &pxmitframe->attrib); diff --git a/drivers/staging/rtl8723bs/hal/HalBtc8723b2Ant.c b/drivers/staging/rtl8723bs/hal/HalBtc8723b2Ant.c index c1c7b5cc17a7..d32dbf94858f 100644 --- a/drivers/staging/rtl8723bs/hal/HalBtc8723b2Ant.c +++ b/drivers/staging/rtl8723bs/hal/HalBtc8723b2Ant.c @@ -1100,7 +1100,7 @@ static bool halbtc8723b2ant_IsCommonAction(struct btc_coexist *pBtCoexist) bCommon = true; } else { - if (BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) { + if (pCoexDm->btStatus == BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE) { bLowPwrDisable = false; pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, false, false, 0x8); @@ -1115,7 +1115,7 @@ static bool halbtc8723b2ant_IsCommonAction(struct btc_coexist *pBtCoexist) halbtc8723b2ant_SwMechanism2(pBtCoexist, false, false, false, 0x18); bCommon = true; - } else if (BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) { + } else if (pCoexDm->btStatus == BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE) { bLowPwrDisable = true; pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); @@ -1605,7 +1605,7 @@ static void halbtc8723b2ant_ActionSco(struct btc_coexist *pBtCoexist) pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - if (BTC_WIFI_BW_LEGACY == wifiBw) /* for SCO quality at 11b/g mode */ + if (wifiBw == BTC_WIFI_BW_LEGACY) /* for SCO quality at 11b/g mode */ halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); else /* for SCO quality & wifi performance balance at 11n mode */ halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); @@ -1613,7 +1613,7 @@ static void halbtc8723b2ant_ActionSco(struct btc_coexist *pBtCoexist) halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 0); /* for voice quality */ /* sw mechanism */ - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { if ( (wifiRssiState == BTC_RSSI_STATE_HIGH) || (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) @@ -1660,7 +1660,7 @@ static void halbtc8723b2ant_ActionHid(struct btc_coexist *pBtCoexist) pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - if (BTC_WIFI_BW_LEGACY == wifiBw) /* for HID at 11b/g mode */ + if (wifiBw == BTC_WIFI_BW_LEGACY) /* for HID at 11b/g mode */ halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); else /* for HID quality & wifi performance balance at 11n mode */ halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 9); @@ -1674,7 +1674,7 @@ static void halbtc8723b2ant_ActionHid(struct btc_coexist *pBtCoexist) halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 13); /* sw mechanism */ - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { if ( (wifiRssiState == BTC_RSSI_STATE_HIGH) || (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) @@ -1723,7 +1723,7 @@ static void halbtc8723b2ant_ActionA2dp(struct btc_coexist *pBtCoexist) /* sw mechanism */ pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { halbtc8723b2ant_SwMechanism1(pBtCoexist, true, false, false, false); halbtc8723b2ant_SwMechanism2(pBtCoexist, true, false, true, 0x18); } else { @@ -1755,7 +1755,7 @@ static void halbtc8723b2ant_ActionA2dp(struct btc_coexist *pBtCoexist) /* sw mechanism */ pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { if ( (wifiRssiState == BTC_RSSI_STATE_HIGH) || (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) @@ -1805,7 +1805,7 @@ static void halbtc8723b2ant_ActionA2dpPanHs(struct btc_coexist *pBtCoexist) /* sw mechanism */ pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { if ( (wifiRssiState == BTC_RSSI_STATE_HIGH) || (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) @@ -1861,7 +1861,7 @@ static void halbtc8723b2ant_ActionPanEdr(struct btc_coexist *pBtCoexist) /* sw mechanism */ pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { if ( (wifiRssiState == BTC_RSSI_STATE_HIGH) || (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) @@ -1912,7 +1912,7 @@ static void halbtc8723b2ant_ActionPanHs(struct btc_coexist *pBtCoexist) halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, false, 1); pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { if ( (wifiRssiState == BTC_RSSI_STATE_HIGH) || (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) @@ -1964,7 +1964,7 @@ static void halbtc8723b2ant_ActionPanEdrA2dp(struct btc_coexist *pBtCoexist) (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) { halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 12); - if (BTC_WIFI_BW_HT40 == wifiBw) + if (wifiBw == BTC_WIFI_BW_HT40) halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, false, true, 3); else halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, false, false, 3); @@ -1974,7 +1974,7 @@ static void halbtc8723b2ant_ActionPanEdrA2dp(struct btc_coexist *pBtCoexist) } /* sw mechanism */ - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { if ( (wifiRssiState == BTC_RSSI_STATE_HIGH) || (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) @@ -2019,7 +2019,7 @@ static void halbtc8723b2ant_ActionPanEdrHid(struct btc_coexist *pBtCoexist) (btRssiState == BTC_RSSI_STATE_HIGH) || (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) { - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 3); halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 11); pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); @@ -2037,7 +2037,7 @@ static void halbtc8723b2ant_ActionPanEdrHid(struct btc_coexist *pBtCoexist) } /* sw mechanism */ - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { if ( (wifiRssiState == BTC_RSSI_STATE_HIGH) || (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) @@ -2090,7 +2090,7 @@ static void halbtc8723b2ant_ActionHidA2dpPanEdr(struct btc_coexist *pBtCoexist) (btRssiState == BTC_RSSI_STATE_HIGH) || (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) { - if (BTC_WIFI_BW_HT40 == wifiBw) + if (wifiBw == BTC_WIFI_BW_HT40) halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, true, true, 2); else halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, true, false, 3); @@ -2098,7 +2098,7 @@ static void halbtc8723b2ant_ActionHidA2dpPanEdr(struct btc_coexist *pBtCoexist) halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, true, true, 3); /* sw mechanism */ - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { if ( (wifiRssiState == BTC_RSSI_STATE_HIGH) || (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) @@ -2140,7 +2140,7 @@ static void halbtc8723b2ant_ActionHidA2dp(struct btc_coexist *pBtCoexist) halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - if (BTC_WIFI_BW_LEGACY == wifiBw) { + if (wifiBw == BTC_WIFI_BW_LEGACY) { if (BTC_RSSI_HIGH(btRssiState)) halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); else if (BTC_RSSI_MEDIUM(btRssiState)) @@ -2173,7 +2173,7 @@ static void halbtc8723b2ant_ActionHidA2dp(struct btc_coexist *pBtCoexist) halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, true, true, 2); /* sw mechanism */ - if (BTC_WIFI_BW_HT40 == wifiBw) { + if (wifiBw == BTC_WIFI_BW_HT40) { if ( (wifiRssiState == BTC_RSSI_STATE_HIGH) || (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) @@ -2391,12 +2391,12 @@ void EXhalbtc8723b2ant_InitCoexDm(struct btc_coexist *pBtCoexist) void EXhalbtc8723b2ant_IpsNotify(struct btc_coexist *pBtCoexist, u8 type) { - if (BTC_IPS_ENTER == type) { + if (type == BTC_IPS_ENTER) { pCoexSta->bUnderIps = true; halbtc8723b2ant_WifiOffHwCfg(pBtCoexist); halbtc8723b2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, true); halbtc8723b2ant_CoexAllOff(pBtCoexist); - } else if (BTC_IPS_LEAVE == type) { + } else if (type == BTC_IPS_LEAVE) { pCoexSta->bUnderIps = false; halbtc8723b2ant_InitHwConfig(pBtCoexist, false); halbtc8723b2ant_InitCoexDm(pBtCoexist); @@ -2406,24 +2406,24 @@ void EXhalbtc8723b2ant_IpsNotify(struct btc_coexist *pBtCoexist, u8 type) void EXhalbtc8723b2ant_LpsNotify(struct btc_coexist *pBtCoexist, u8 type) { - if (BTC_LPS_ENABLE == type) { + if (type == BTC_LPS_ENABLE) { pCoexSta->bUnderLps = true; - } else if (BTC_LPS_DISABLE == type) { + } else if (type == BTC_LPS_DISABLE) { pCoexSta->bUnderLps = false; } } void EXhalbtc8723b2ant_ScanNotify(struct btc_coexist *pBtCoexist, u8 type) { - if (BTC_SCAN_START == type) { - } else if (BTC_SCAN_FINISH == type) { + if (type == BTC_SCAN_START) { + } else if (type == BTC_SCAN_FINISH) { } } void EXhalbtc8723b2ant_ConnectNotify(struct btc_coexist *pBtCoexist, u8 type) { - if (BTC_ASSOCIATE_START == type) { - } else if (BTC_ASSOCIATE_FINISH == type) { + if (type == BTC_ASSOCIATE_START) { + } else if (type == BTC_ASSOCIATE_FINISH) { } } @@ -2436,11 +2436,11 @@ void EXhalbtc8723b2ant_MediaStatusNotify(struct btc_coexist *pBtCoexist, u8 type /* only 2.4G we need to inform bt the chnl mask */ pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); - if ((BTC_MEDIA_CONNECT == type) && (wifiCentralChnl <= 14)) { + if ((type == BTC_MEDIA_CONNECT) && (wifiCentralChnl <= 14)) { H2C_Parameter[0] = 0x1; H2C_Parameter[1] = wifiCentralChnl; pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); - if (BTC_WIFI_BW_HT40 == wifiBw) + if (wifiBw == BTC_WIFI_BW_HT40) H2C_Parameter[2] = 0x30; else { pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &apNum); @@ -2573,9 +2573,9 @@ void EXhalbtc8723b2ant_BtInfoNotify( } if ( - (BT_8723B_2ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || - (BT_8723B_2ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || - (BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) + (pCoexDm->btStatus == BT_8723B_2ANT_BT_STATUS_ACL_BUSY) || + (pCoexDm->btStatus == BT_8723B_2ANT_BT_STATUS_SCO_BUSY) || + (pCoexDm->btStatus == BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY) ) { bBtBusy = true; bLimitedDig = true; @@ -2603,8 +2603,8 @@ void EXhalbtc8723b2ant_HaltNotify(struct btc_coexist *pBtCoexist) void EXhalbtc8723b2ant_PnpNotify(struct btc_coexist *pBtCoexist, u8 pnpState) { - if (BTC_WIFI_PNP_SLEEP == pnpState) { - } else if (BTC_WIFI_PNP_WAKE_UP == pnpState) { + if (pnpState == BTC_WIFI_PNP_SLEEP) { + } else if (pnpState == BTC_WIFI_PNP_WAKE_UP) { halbtc8723b2ant_InitHwConfig(pBtCoexist, false); halbtc8723b2ant_InitCoexDm(pBtCoexist); halbtc8723b2ant_QueryBtInfo(pBtCoexist); diff --git a/drivers/staging/rtl8723bs/hal/HalPhyRf.h b/drivers/staging/rtl8723bs/hal/HalPhyRf.h index fdbdd68edf2a..1e79ab9cb773 100644 --- a/drivers/staging/rtl8723bs/hal/HalPhyRf.h +++ b/drivers/staging/rtl8723bs/hal/HalPhyRf.h @@ -15,7 +15,6 @@ enum pwrtrack_method { }; typedef void (*FuncSetPwr)(struct dm_odm_t *, enum pwrtrack_method, u8, u8); -typedef void (*FuncIQK)(struct dm_odm_t *, u8, u8, u8); typedef void (*FuncLCK)(struct dm_odm_t *); typedef void (*FuncSwing)(struct dm_odm_t *, u8 **, u8 **, u8 **, u8 **); @@ -27,7 +26,6 @@ struct txpwrtrack_cfg { u8 RfPathCount; u32 ThermalRegAddr; FuncSetPwr ODM_TxPwrTrackSetPwr; - FuncIQK DoIQK; FuncLCK PHY_LCCalibrate; FuncSwing GetDeltaSwingTable; }; diff --git a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c index 81149ab81904..34692cca33f5 100644 --- a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c +++ b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c @@ -142,15 +142,6 @@ static void setCCKFilterCoefficient(struct dm_odm_t *pDM_Odm, u8 CCKSwingIndex) } } -void DoIQK_8723B( - struct dm_odm_t *pDM_Odm, - u8 DeltaThermalIndex, - u8 ThermalValue, - u8 Threshold -) -{ -} - /*----------------------------------------------------------------------------- * Function: odm_TxPwrTrackSetPwr88E() * @@ -353,7 +344,6 @@ void ConfigureTxpowerTrack_8723B(struct txpwrtrack_cfg *pConfig) pConfig->ThermalRegAddr = RF_T_METER_8723B; pConfig->ODM_TxPwrTrackSetPwr = ODM_TxPwrTrackSetPwr_8723B; - pConfig->DoIQK = DoIQK_8723B; pConfig->PHY_LCCalibrate = PHY_LCCalibrate_8723B; pConfig->GetDeltaSwingTable = GetDeltaSwingTable_8723B; } diff --git a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.h b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.h index 775095ad0921..c83442917f9d 100644 --- a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.h +++ b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.h @@ -18,13 +18,6 @@ void ConfigureTxpowerTrack_8723B(struct txpwrtrack_cfg *pConfig); -void DoIQK_8723B( - struct dm_odm_t *pDM_Odm, - u8 DeltaThermalIndex, - u8 ThermalValue, - u8 Threshold -); - void ODM_TxPwrTrackSetPwr_8723B( struct dm_odm_t *pDM_Odm, enum pwrtrack_method Method, diff --git a/drivers/staging/rtl8723bs/hal/hal_btcoex.c b/drivers/staging/rtl8723bs/hal/hal_btcoex.c index b72cf520d576..9105594d2dde 100644 --- a/drivers/staging/rtl8723bs/hal/hal_btcoex.c +++ b/drivers/staging/rtl8723bs/hal/hal_btcoex.c @@ -91,7 +91,7 @@ static void halbtcoutsrc_LeaveLowPower(struct btc_coexist *pBtCoexist) stime = jiffies; do { ready = rtw_register_task_alive(padapter, BTCOEX_ALIVE); - if (_SUCCESS == ready) + if (ready == _SUCCESS) break; utime = jiffies_to_msecs(jiffies - stime); @@ -668,7 +668,7 @@ static void halbtcoutsrc_WriteLocalReg1Byte(void *pBtcContext, u32 RegAddr, u8 D struct btc_coexist *pBtCoexist = (struct btc_coexist *)pBtcContext; struct adapter *Adapter = pBtCoexist->Adapter; - if (BTC_INTF_SDIO == pBtCoexist->chipInterface) + if (pBtCoexist->chipInterface == BTC_INTF_SDIO) rtw_write8(Adapter, SDIO_LOCAL_BASE | RegAddr, Data); else rtw_write8(Adapter, RegAddr, Data); @@ -894,7 +894,7 @@ void EXhalbtcoutsrc_IpsNotify(struct btc_coexist *pBtCoexist, u8 type) if (pBtCoexist->bManualControl) return; - if (IPS_NONE == type) + if (type == IPS_NONE) ipsType = BTC_IPS_LEAVE; else ipsType = BTC_IPS_ENTER; @@ -922,7 +922,7 @@ void EXhalbtcoutsrc_LpsNotify(struct btc_coexist *pBtCoexist, u8 type) if (pBtCoexist->bManualControl) return; - if (PS_MODE_ACTIVE == type) + if (type == PS_MODE_ACTIVE) lpsType = BTC_LPS_DISABLE; else lpsType = BTC_LPS_ENABLE; @@ -1000,7 +1000,7 @@ void EXhalbtcoutsrc_MediaStatusNotify(struct btc_coexist *pBtCoexist, enum if (pBtCoexist->bManualControl) return; - if (RT_MEDIA_CONNECT == mediaStatus) + if (mediaStatus == RT_MEDIA_CONNECT) mStatus = BTC_MEDIA_CONNECT; else mStatus = BTC_MEDIA_DISCONNECT; @@ -1026,11 +1026,11 @@ void EXhalbtcoutsrc_SpecialPacketNotify(struct btc_coexist *pBtCoexist, u8 pktTy if (pBtCoexist->bManualControl) return; - if (PACKET_DHCP == pktType) { + if (pktType == PACKET_DHCP) { packetType = BTC_PACKET_DHCP; - } else if (PACKET_EAPOL == pktType) { + } else if (pktType == PACKET_EAPOL) { packetType = BTC_PACKET_EAPOL; - } else if (PACKET_ARP == pktType) { + } else if (pktType == PACKET_ARP) { packetType = BTC_PACKET_ARP; } else { return; @@ -1114,13 +1114,13 @@ void EXhalbtcoutsrc_Periodical(struct btc_coexist *pBtCoexist) void EXhalbtcoutsrc_SetAntNum(u8 type, u8 antNum) { - if (BT_COEX_ANT_TYPE_PG == type) { + if (type == BT_COEX_ANT_TYPE_PG) { GLBtCoexist.boardInfo.pgAntNum = antNum; GLBtCoexist.boardInfo.btdmAntNum = antNum; - } else if (BT_COEX_ANT_TYPE_ANTDIV == type) { + } else if (type == BT_COEX_ANT_TYPE_ANTDIV) { GLBtCoexist.boardInfo.btdmAntNum = antNum; /* GLBtCoexist.boardInfo.btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT; */ - } else if (BT_COEX_ANT_TYPE_DETECTED == type) { + } else if (type == BT_COEX_ANT_TYPE_DETECTED) { GLBtCoexist.boardInfo.btdmAntNum = antNum; /* GLBtCoexist.boardInfo.btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT; */ } diff --git a/drivers/staging/rtl8723bs/hal/hal_com.c b/drivers/staging/rtl8723bs/hal/hal_com.c index 1213a91cffff..07e9d3423651 100644 --- a/drivers/staging/rtl8723bs/hal/hal_com.c +++ b/drivers/staging/rtl8723bs/hal/hal_com.c @@ -569,19 +569,12 @@ void rtw_hal_update_sta_rate_mask(struct adapter *padapter, struct sta_info *pst psta->init_rate = get_highest_rate_idx(tx_ra_bitmap)&0x3f; } -void hw_var_port_switch(struct adapter *adapter) -{ -} - void SetHwReg(struct adapter *adapter, u8 variable, u8 *val) { struct hal_com_data *hal_data = GET_HAL_DATA(adapter); struct dm_odm_t *odm = &(hal_data->odmpriv); switch (variable) { - case HW_VAR_PORT_SWITCH: - hw_var_port_switch(adapter); - break; case HW_VAR_INIT_RTS_RATE: rtw_warn_on(1); break; @@ -890,15 +883,14 @@ static u32 Array_kfreemap[] = { void rtw_bb_rf_gain_offset(struct adapter *padapter) { u8 value = padapter->eeprompriv.EEPROMRFGainOffset; - u32 res, i = 0; u32 *Array = Array_kfreemap; u32 v1 = 0, v2 = 0, target = 0; + u32 i = 0; if (value & BIT4) { if (padapter->eeprompriv.EEPROMRFGainVal != 0xff) { - res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff); - res &= 0xfff87fff; - /* res &= 0xfff87fff; */ + rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff); + for (i = 0; i < ARRAY_SIZE(Array_kfreemap); i += 2) { v1 = Array[i]; v2 = Array[i+1]; @@ -909,9 +901,7 @@ void rtw_bb_rf_gain_offset(struct adapter *padapter) } PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18|BIT17|BIT16|BIT15, target); - /* res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f)<< 15; */ - /* rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, RF_GAIN_OFFSET_MASK, res); */ - res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff); + rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff); } } } diff --git a/drivers/staging/rtl8723bs/hal/hal_intf.c b/drivers/staging/rtl8723bs/hal/hal_intf.c index 0db8f623b805..961b0563951d 100644 --- a/drivers/staging/rtl8723bs/hal/hal_intf.c +++ b/drivers/staging/rtl8723bs/hal/hal_intf.c @@ -38,10 +38,6 @@ void rtw_hal_dm_init(struct adapter *padapter) rtl8723b_init_dm_priv(padapter); } -void rtw_hal_dm_deinit(struct adapter *padapter) -{ -} - static void rtw_hal_init_opmode(struct adapter *padapter) { enum ndis_802_11_network_infrastructure networkType = Ndis802_11InfrastructureMax; @@ -77,8 +73,6 @@ uint rtw_hal_init(struct adapter *padapter) if (padapter->registrypriv.notch_filter == 1) rtw_hal_notch_filter(padapter, 1); - rtw_hal_reset_security_engine(padapter); - rtw_sec_restore_wep_key(dvobj->padapters); init_hw_mlme_ext(padapter); @@ -133,8 +127,7 @@ u8 rtw_hal_get_def_var(struct adapter *padapter, enum hal_def_variable eVariable void rtw_hal_set_odm_var(struct adapter *padapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet) { - if (padapter->HalFunc.SetHalODMVarHandler) - padapter->HalFunc.SetHalODMVarHandler(padapter, eVariable, pValue1, bSet); + SetHalODMVar(padapter, eVariable, pValue1, bSet); } void rtw_hal_enable_interrupt(struct adapter *padapter) @@ -290,21 +283,12 @@ void beacon_timing_control(struct adapter *padapter) s32 rtw_hal_xmit_thread_handler(struct adapter *padapter) { - if (padapter->HalFunc.xmit_thread_handler) - return padapter->HalFunc.xmit_thread_handler(padapter); - return _FAIL; + return rtl8723bs_xmit_buf_handler(padapter); } void rtw_hal_notch_filter(struct adapter *adapter, bool enable) { - if (adapter->HalFunc.hal_notch_filter) - adapter->HalFunc.hal_notch_filter(adapter, enable); -} - -void rtw_hal_reset_security_engine(struct adapter *adapter) -{ - if (adapter->HalFunc.hal_reset_security_engine) - adapter->HalFunc.hal_reset_security_engine(adapter); + hal_notch_filter_8723b(adapter, enable); } bool rtw_hal_c2h_valid(struct adapter *adapter, u8 *buf) @@ -314,16 +298,12 @@ bool rtw_hal_c2h_valid(struct adapter *adapter, u8 *buf) s32 rtw_hal_c2h_handler(struct adapter *adapter, u8 *c2h_evt) { - s32 ret = _FAIL; - - if (adapter->HalFunc.c2h_handler) - ret = adapter->HalFunc.c2h_handler(adapter, c2h_evt); - return ret; + return c2h_handler_8723b(adapter, c2h_evt); } c2h_id_filter rtw_hal_c2h_id_filter_ccx(struct adapter *adapter) { - return adapter->HalFunc.c2h_id_filter_ccx; + return c2h_id_filter_ccx_8723b; } s32 rtw_hal_macid_sleep(struct adapter *padapter, u32 macid) @@ -356,10 +336,5 @@ s32 rtw_hal_macid_wakeup(struct adapter *padapter, u32 macid) s32 rtw_hal_fill_h2c_cmd(struct adapter *padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) { - s32 ret = _FAIL; - - if (padapter->HalFunc.fill_h2c_cmd) - ret = padapter->HalFunc.fill_h2c_cmd(padapter, ElementID, CmdLen, pCmdBuffer); - - return ret; + return FillH2CCmd8723B(padapter, ElementID, CmdLen, pCmdBuffer); } diff --git a/drivers/staging/rtl8723bs/hal/odm.c b/drivers/staging/rtl8723bs/hal/odm.c index 8d6131f0ad47..ba85efb30db2 100644 --- a/drivers/staging/rtl8723bs/hal/odm.c +++ b/drivers/staging/rtl8723bs/hal/odm.c @@ -315,14 +315,6 @@ static void odm_CommonInfoSelfUpdate(struct dm_odm_t *pDM_Odm) pDM_Odm->bOneEntryOnly = false; } -static void odm_CmnInfoInit_Debug(struct dm_odm_t *pDM_Odm) -{ -} - -static void odm_BasicDbgMessage(struct dm_odm_t *pDM_Odm) -{ -} - /* 3 ============================================================ */ /* 3 RATR MASK */ /* 3 ============================================================ */ @@ -735,7 +727,6 @@ void ODM_DMInit(struct dm_odm_t *pDM_Odm) { odm_CommonInfoSelfInit(pDM_Odm); - odm_CmnInfoInit_Debug(pDM_Odm); odm_DIGInit(pDM_Odm); odm_NHMCounterStatisticsInit(pDM_Odm); odm_AdaptivityInit(pDM_Odm); @@ -761,7 +752,6 @@ void ODM_DMInit(struct dm_odm_t *pDM_Odm) void ODM_DMWatchdog(struct dm_odm_t *pDM_Odm) { odm_CommonInfoSelfUpdate(pDM_Odm); - odm_BasicDbgMessage(pDM_Odm); odm_FalseAlarmCounterStatistics(pDM_Odm); odm_NHMCounterStatistics(pDM_Odm); diff --git a/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c b/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c index 928c58be6c9b..666a9f44012d 100644 --- a/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c +++ b/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c @@ -155,9 +155,9 @@ void ODM_CfoTracking(void *pDM_VOID) /* 4 1.6 Big jump */ if (pCfoTrack->bAdjust) { if (CFO_ave > CFO_TH_XTAL_LOW) - Adjust_Xtal = Adjust_Xtal+((CFO_ave-CFO_TH_XTAL_LOW)>>2); + Adjust_Xtal = Adjust_Xtal + ((CFO_ave - CFO_TH_XTAL_LOW) >> 2); else if (CFO_ave < (-CFO_TH_XTAL_LOW)) - Adjust_Xtal = Adjust_Xtal+((CFO_TH_XTAL_LOW-CFO_ave)>>2); + Adjust_Xtal = Adjust_Xtal + ((CFO_TH_XTAL_LOW - CFO_ave) >> 2); } /* 4 1.7 Adjust Crystal Cap. */ diff --git a/drivers/staging/rtl8723bs/hal/odm_DIG.c b/drivers/staging/rtl8723bs/hal/odm_DIG.c index 97a51546463a..f10427abd849 100644 --- a/drivers/staging/rtl8723bs/hal/odm_DIG.c +++ b/drivers/staging/rtl8723bs/hal/odm_DIG.c @@ -56,7 +56,7 @@ void odm_NHMBBInit(void *pDM_VOID) { struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; - pDM_Odm->adaptivity_flag = 0; + pDM_Odm->adaptivity_flag = false; pDM_Odm->tolerance_cnt = 3; pDM_Odm->NHMLastTxOkcnt = 0; pDM_Odm->NHMLastRxOkcnt = 0; @@ -370,7 +370,6 @@ void odm_DIGInit(void *pDM_VOID) pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; - } diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c b/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c index 56526056dd1d..63c4ebe9df12 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c @@ -57,13 +57,11 @@ s32 FillH2CCmd8723B(struct adapter *padapter, u8 ElementID, u32 CmdLen, u8 *pCmd if (mutex_lock_interruptible(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex))) return ret; - if (!pCmdBuffer) { + if (!pCmdBuffer) goto exit; - } - if (CmdLen > RTL8723B_MAX_CMD_LEN) { + if (CmdLen > RTL8723B_MAX_CMD_LEN) goto exit; - } if (padapter->bSurpriseRemoved) goto exit; @@ -287,15 +285,6 @@ static void ConstructNullFunctionData( *pLength = pktlen; } -/* - * To check if reserved page content is destroyed by beacon because beacon - * is too large. - */ -/* 2010.06.23. Added by tynli. */ -void CheckFwRsvdPageContent(struct adapter *Adapter) -{ -} - static void rtl8723b_set_FwRsvdPage_cmd(struct adapter *padapter, struct rsvdpage_loc *rsvdpageloc) { u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0}; @@ -309,10 +298,6 @@ static void rtl8723b_set_FwRsvdPage_cmd(struct adapter *padapter, struct rsvdpag FillH2CCmd8723B(padapter, H2C_8723B_RSVD_PAGE, H2C_RSVDPAGE_LOC_LEN, u1H2CRsvdPageParm); } -static void rtl8723b_set_FwAoacRsvdPage_cmd(struct adapter *padapter, struct rsvdpage_loc *rsvdpageloc) -{ -} - void rtl8723b_set_FwMediaStatusRpt_cmd(struct adapter *padapter, u8 mstatus, u8 macid) { u8 u1H2CMediaStatusRptParm[H2C_MEDIA_STATUS_RPT_LEN] = {0}; @@ -614,12 +599,9 @@ static void rtl8723b_set_FwRsvdPagePkt( dump_mgntframe_and_wait(padapter, pcmdframe, 100); } - if (check_fwstate(pmlmepriv, _FW_LINKED)) { + if (check_fwstate(pmlmepriv, _FW_LINKED)) rtl8723b_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc); - rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc); - } else { - rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc); - } + return; error: @@ -885,7 +867,6 @@ static void SetFwRsvdPagePkt_BTCoex(struct adapter *padapter) dump_mgntframe_and_wait(padapter, pcmdframe, 100); rtl8723b_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc); - rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc); return; diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_dm.c b/drivers/staging/rtl8723bs/hal/rtl8723b_dm.c index d1c875cf8e6d..928226679ab4 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_dm.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_dm.c @@ -12,9 +12,6 @@ /* Global var */ -static void dm_CheckStatistics(struct adapter *Adapter) -{ -} /* */ /* functions */ /* */ @@ -144,10 +141,6 @@ void rtl8723b_HalDmWatchDog(struct adapter *Adapter) (hw_init_completed == true) && ((!fw_current_in_ps_mode) && bFwPSAwake) ) { - /* */ - /* Calculate Tx/Rx statistics. */ - /* */ - dm_CheckStatistics(Adapter); rtw_hal_check_rxfifo_full(Adapter); } diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c index e15ec6452fd0..1608bc71bd71 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c @@ -501,8 +501,7 @@ void Hal_GetEfuseDefinition( switch (type) { case TYPE_EFUSE_MAX_SECTION: { - u8 *pMax_section; - pMax_section = pOut; + u8 *pMax_section = pOut; if (efuseType == EFUSE_WIFI) *pMax_section = EFUSE_MAX_SECTION_8723B; @@ -513,8 +512,7 @@ void Hal_GetEfuseDefinition( case TYPE_EFUSE_REAL_CONTENT_LEN: { - u16 *pu2Tmp; - pu2Tmp = pOut; + u16 *pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B; @@ -525,8 +523,7 @@ void Hal_GetEfuseDefinition( case TYPE_AVAILABLE_EFUSE_BYTES_BANK: { - u16 *pu2Tmp; - pu2Tmp = pOut; + u16 *pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES); @@ -537,8 +534,7 @@ void Hal_GetEfuseDefinition( case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: { - u16 *pu2Tmp; - pu2Tmp = pOut; + u16 *pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES); @@ -549,8 +545,7 @@ void Hal_GetEfuseDefinition( case TYPE_EFUSE_MAP_LEN: { - u16 *pu2Tmp; - pu2Tmp = pOut; + u16 *pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = EFUSE_MAX_MAP_LEN; @@ -561,8 +556,7 @@ void Hal_GetEfuseDefinition( case TYPE_EFUSE_PROTECT_BYTES_BANK: { - u8 *pu1Tmp; - pu1Tmp = pOut; + u8 *pu1Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu1Tmp = EFUSE_OOB_PROTECT_BYTES; @@ -573,8 +567,7 @@ void Hal_GetEfuseDefinition( case TYPE_EFUSE_CONTENT_LEN_BANK: { - u16 *pu2Tmp; - pu2Tmp = pOut; + u16 *pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B; @@ -585,8 +578,7 @@ void Hal_GetEfuseDefinition( default: { - u8 *pu1Tmp; - pu1Tmp = pOut; + u8 *pu1Tmp = pOut; *pu1Tmp = 0; } break; @@ -835,9 +827,8 @@ static void hal_ReadEFuse_BT( } if (offset < EFUSE_BT_MAX_SECTION) { - u16 addr; + u16 addr = offset * PGPKT_DATA_SIZE; - addr = offset * PGPKT_DATA_SIZE; for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { /* Check word enable condition in the section */ if (!(wden & (0x01<<i))) { @@ -1086,71 +1077,6 @@ u16 Hal_EfuseGetCurrentSize( return ret; } -static u8 Hal_EfuseWordEnableDataWrite( - struct adapter *padapter, - u16 efuse_addr, - u8 word_en, - u8 *data, - bool bPseudoTest -) -{ - u16 tmpaddr = 0; - u16 start_addr = efuse_addr; - u8 badworden = 0x0F; - u8 tmpdata[PGPKT_DATA_SIZE]; - - memset(tmpdata, 0xFF, PGPKT_DATA_SIZE); - - if (!(word_en & BIT(0))) { - tmpaddr = start_addr; - efuse_OneByteWrite(padapter, start_addr++, data[0], bPseudoTest); - efuse_OneByteWrite(padapter, start_addr++, data[1], bPseudoTest); - - efuse_OneByteRead(padapter, tmpaddr, &tmpdata[0], bPseudoTest); - efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[1], bPseudoTest); - if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1])) { - badworden &= (~BIT(0)); - } - } - if (!(word_en & BIT(1))) { - tmpaddr = start_addr; - efuse_OneByteWrite(padapter, start_addr++, data[2], bPseudoTest); - efuse_OneByteWrite(padapter, start_addr++, data[3], bPseudoTest); - - efuse_OneByteRead(padapter, tmpaddr, &tmpdata[2], bPseudoTest); - efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[3], bPseudoTest); - if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3])) { - badworden &= (~BIT(1)); - } - } - - if (!(word_en & BIT(2))) { - tmpaddr = start_addr; - efuse_OneByteWrite(padapter, start_addr++, data[4], bPseudoTest); - efuse_OneByteWrite(padapter, start_addr++, data[5], bPseudoTest); - - efuse_OneByteRead(padapter, tmpaddr, &tmpdata[4], bPseudoTest); - efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[5], bPseudoTest); - if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5])) { - badworden &= (~BIT(2)); - } - } - - if (!(word_en & BIT(3))) { - tmpaddr = start_addr; - efuse_OneByteWrite(padapter, start_addr++, data[6], bPseudoTest); - efuse_OneByteWrite(padapter, start_addr++, data[7], bPseudoTest); - - efuse_OneByteRead(padapter, tmpaddr, &tmpdata[6], bPseudoTest); - efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[7], bPseudoTest); - if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7])) { - badworden &= (~BIT(3)); - } - } - - return badworden; -} - static struct hal_version ReadChipVersion8723B(struct adapter *padapter) { u32 value32; @@ -1196,10 +1122,9 @@ void rtl8723b_InitBeaconParameters(struct adapter *padapter) { struct hal_com_data *pHalData = GET_HAL_DATA(padapter); u16 val16; - u8 val8; + u8 val8 = DIS_TSF_UDT; - val8 = DIS_TSF_UDT; val16 = val8 | (val8 << 8); /* port0 and port1 */ /* Enable prot0 beacon function for PSTDMA */ @@ -1271,8 +1196,6 @@ static void StopTxBeacon(struct adapter *padapter) rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0x64); pHalData->RegReg542 &= ~BIT(0); rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542); - - CheckFwRsvdPageContent(padapter); /* 2010.06.23. Added by tynli. */ } static void _BeaconFunctionEnable(struct adapter *padapter, u8 Enable, u8 Linked) @@ -1342,17 +1265,7 @@ void rtl8723b_SetBeaconRelatedRegisters(struct adapter *padapter) rtw_write8(padapter, bcn_ctrl_reg, val8); } -static void rtl8723b_SetHalODMVar( - struct adapter *Adapter, - enum hal_odm_variable eVariable, - void *pValue1, - bool bSet -) -{ - SetHalODMVar(Adapter, eVariable, pValue1, bSet); -} - -static void hal_notch_filter_8723b(struct adapter *adapter, bool enable) +void hal_notch_filter_8723b(struct adapter *adapter, bool enable) { if (enable) rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1); @@ -1397,23 +1310,6 @@ void UpdateHalRAMask8723B(struct adapter *padapter, u32 mac_id, u8 rssi_level) pdmpriv->INIDATA_RATE[mac_id] = psta->init_rate; } - -void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc) -{ - /* Efuse related function */ - pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite; - - pHalFunc->SetHalODMVarHandler = &rtl8723b_SetHalODMVar; - - pHalFunc->xmit_thread_handler = &hal_xmit_handler; - pHalFunc->hal_notch_filter = &hal_notch_filter_8723b; - - pHalFunc->c2h_handler = c2h_handler_8723b; - pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8723b; - - pHalFunc->fill_h2c_cmd = &FillH2CCmd8723B; -} - void rtl8723b_InitAntenna_Selection(struct adapter *padapter) { u8 val; @@ -1496,10 +1392,7 @@ s32 rtl8723b_InitLLTTable(struct adapter *padapter) { unsigned long start, passing_time; u32 val32; - s32 ret; - - - ret = _FAIL; + s32 ret = _FAIL; val32 = rtw_read32(padapter, REG_AUTO_LLT); val32 |= BIT_AUTO_INIT_LLT; @@ -2273,9 +2166,8 @@ void rtl8723b_fill_fake_txdesc( /* Encrypt the data frame if under security mode excepct null data. Suggested by CCW. */ /* */ if (bDataFrame) { - u32 EncAlg; + u32 EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm; - EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm; switch (EncAlg) { case _NO_PRIVACY_: SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x0); @@ -2378,9 +2270,7 @@ static void hw_var_set_opmode(struct adapter *padapter, u8 variable, u8 *val) static void hw_var_set_macaddr(struct adapter *padapter, u8 variable, u8 *val) { u8 idx = 0; - u32 reg_macid; - - reg_macid = REG_MACID; + u32 reg_macid = REG_MACID; for (idx = 0 ; idx < 6; idx++) rtw_write8(GET_PRIMARY_ADAPTER(padapter), (reg_macid+idx), val[idx]); @@ -2389,9 +2279,7 @@ static void hw_var_set_macaddr(struct adapter *padapter, u8 variable, u8 *val) static void hw_var_set_bssid(struct adapter *padapter, u8 variable, u8 *val) { u8 idx = 0; - u32 reg_bssid; - - reg_bssid = REG_BSSID; + u32 reg_bssid = REG_BSSID; for (idx = 0 ; idx < 6; idx++) rtw_write8(padapter, (reg_bssid+idx), val[idx]); @@ -2399,9 +2287,7 @@ static void hw_var_set_bssid(struct adapter *padapter, u8 variable, u8 *val) static void hw_var_set_bcn_func(struct adapter *padapter, u8 variable, u8 *val) { - u32 bcn_ctrl_reg; - - bcn_ctrl_reg = REG_BCN_CTRL; + u32 bcn_ctrl_reg = REG_BCN_CTRL; if (*(u8 *)val) rtw_write8(padapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT)); @@ -2422,12 +2308,8 @@ static void hw_var_set_correct_tsf(struct adapter *padapter, u8 variable, u8 *va { u8 val8; u64 tsf; - struct mlme_ext_priv *pmlmeext; - struct mlme_ext_info *pmlmeinfo; - - - pmlmeext = &padapter->mlmeextpriv; - pmlmeinfo = &pmlmeext->mlmext_info; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; tsf = pmlmeext->TSFValue-do_div(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024))-1024; /* us */ @@ -2543,15 +2425,12 @@ static void hw_var_set_mlme_join(struct adapter *padapter, u8 variable, u8 *val) u8 val8; u16 val16; u32 val32; - u8 RetryLimit; - u8 type; - struct mlme_priv *pmlmepriv; + u8 RetryLimit = 0x30; + u8 type = *(u8 *)val; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct eeprom_priv *pEEPROM; - RetryLimit = 0x30; - type = *(u8 *)val; - pmlmepriv = &padapter->mlmepriv; pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); if (type == 0) { /* prepare to join */ @@ -2850,12 +2729,11 @@ void SetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val) case HW_VAR_ACK_PREAMBLE: { - u8 regTmp; + u8 regTmp = 0; u8 bShortPreamble = *val; /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */ /* regTmp = (pHalData->nCur40MhzPrimeSC)<<5; */ - regTmp = 0; if (bShortPreamble) regTmp |= 0x80; rtw_write8(padapter, REG_RRSR+2, regTmp); @@ -3213,7 +3091,7 @@ void GetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val) break; case HW_VAR_CHK_HI_QUEUE_EMPTY: val16 = rtw_read16(padapter, REG_TXPKT_EMPTY); - *val = (val16 & BIT(10)) ? true:false; + *val = (val16 & BIT(10)) ? true : false; break; default: GetHwReg(padapter, variable, val); @@ -3226,9 +3104,7 @@ void GetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val) */ u8 SetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable, void *pval) { - u8 bResult; - - bResult = _SUCCESS; + u8 bResult = _SUCCESS; switch (variable) { default: @@ -3244,9 +3120,7 @@ u8 SetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable, v */ u8 GetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable, void *pval) { - u8 bResult; - - bResult = _SUCCESS; + u8 bResult = _SUCCESS; switch (variable) { case HAL_DEF_MAX_RECVBUF_SZ: @@ -3281,9 +3155,8 @@ u8 GetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable, v case HW_DEF_RA_INFO_DUMP: { u8 mac_id = *(u8 *)pval; - u32 cmd; + u32 cmd = 0x40000100 | mac_id; - cmd = 0x40000100 | mac_id; rtw_write32(padapter, REG_HMEBOX_DBG_2_8723B, cmd); msleep(10); rtw_read32(padapter, 0x2F0); // info 1 diff --git a/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c b/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c index 5dc1c12fe03e..842e19b53421 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c @@ -120,13 +120,10 @@ free_xmitbuf: */ s32 rtl8723bs_xmit_buf_handler(struct adapter *padapter) { - struct xmit_priv *pxmitpriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; u8 queue_empty, queue_pending; s32 ret; - - pxmitpriv = &padapter->xmitpriv; - if (wait_for_completion_interruptible(&pxmitpriv->xmit_comp)) { netdev_emerg(padapter->pnetdev, "%s: down SdioXmitBufSema fail!\n", __func__); @@ -357,12 +354,9 @@ static s32 xmit_xmitframes(struct adapter *padapter, struct xmit_priv *pxmitpriv */ static s32 rtl8723bs_xmit_handler(struct adapter *padapter) { - struct xmit_priv *pxmitpriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; s32 ret; - - pxmitpriv = &padapter->xmitpriv; - if (wait_for_completion_interruptible(&pxmitpriv->SdioXmitStart)) { netdev_emerg(padapter->pnetdev, "%s: SdioXmitStart fail!\n", __func__); @@ -408,13 +402,9 @@ next: int rtl8723bs_xmit_thread(void *context) { - s32 ret; - struct adapter *padapter; - struct xmit_priv *pxmitpriv; - - ret = _SUCCESS; - padapter = context; - pxmitpriv = &padapter->xmitpriv; + s32 ret = _SUCCESS; + struct adapter *padapter = context; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; allow_signal(SIGTERM); @@ -435,16 +425,13 @@ s32 rtl8723bs_mgnt_xmit( ) { s32 ret = _SUCCESS; - struct pkt_attrib *pattrib; - struct xmit_buf *pxmitbuf; + struct pkt_attrib *pattrib = &pmgntframe->attrib; + struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); u8 *pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; u8 txdesc_size = TXDESC_SIZE; - pattrib = &pmgntframe->attrib; - pxmitbuf = pmgntframe->pxmitbuf; - rtl8723b_update_txdesc(pmgntframe, pmgntframe->buf_addr); pxmitbuf->len = txdesc_size + pattrib->last_txcmdsz; @@ -557,15 +544,13 @@ s32 rtl8723bs_init_xmit_priv(struct adapter *padapter) void rtl8723bs_free_xmit_priv(struct adapter *padapter) { - struct xmit_priv *pxmitpriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct xmit_buf *pxmitbuf; - struct __queue *pqueue; + struct __queue *pqueue = &pxmitpriv->pending_xmitbuf_queue; struct list_head *plist, *phead; struct list_head tmplist; - pxmitpriv = &padapter->xmitpriv; - pqueue = &pxmitpriv->pending_xmitbuf_queue; phead = get_list_head(pqueue); INIT_LIST_HEAD(&tmplist); diff --git a/drivers/staging/rtl8723bs/hal/sdio_halinit.c b/drivers/staging/rtl8723bs/hal/sdio_halinit.c index af9a2b068796..73561a63401e 100644 --- a/drivers/staging/rtl8723bs/hal/sdio_halinit.c +++ b/drivers/staging/rtl8723bs/hal/sdio_halinit.c @@ -1094,10 +1094,6 @@ static void _ReadPROMContent(struct adapter *padapter) _ReadEfuseInfo8723BS(padapter); } -static void _InitOtherVariable(struct adapter *Adapter) -{ -} - /* */ /* Description: */ /* Read HW adapter information by E-Fuse or EEPROM according CR9346 reported. */ @@ -1122,7 +1118,6 @@ static s32 _ReadAdapterInfo8723BS(struct adapter *padapter) _EfuseCellSel(padapter); _ReadRFType(padapter); _ReadPROMContent(padapter); - _InitOtherVariable(padapter); if (!padapter->hw_init_completed) { rtw_write8(padapter, 0x67, 0x00); /* for BT, Switch Ant control to BT */ @@ -1251,11 +1246,3 @@ u8 SetHalDefVar8723BSDIO(struct adapter *Adapter, enum hal_def_variable eVariabl { return SetHalDefVar8723B(Adapter, eVariable, pValue); } - -void rtl8723bs_set_hal_ops(struct adapter *padapter) -{ - struct hal_ops *pHalFunc = &padapter->HalFunc; - - rtl8723b_set_hal_ops(pHalFunc); - -} diff --git a/drivers/staging/rtl8723bs/include/basic_types.h b/drivers/staging/rtl8723bs/include/basic_types.h index 57bb717327ce..24626e65fc7f 100644 --- a/drivers/staging/rtl8723bs/include/basic_types.h +++ b/drivers/staging/rtl8723bs/include/basic_types.h @@ -163,7 +163,7 @@ ( \ LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \ ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \ - ); + ) #define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \ *((u8 *)(__pstart)) = EF1BYTE \ diff --git a/drivers/staging/rtl8723bs/include/drv_types.h b/drivers/staging/rtl8723bs/include/drv_types.h index 7b0e824e05a9..080c321665c0 100644 --- a/drivers/staging/rtl8723bs/include/drv_types.h +++ b/drivers/staging/rtl8723bs/include/drv_types.h @@ -350,7 +350,6 @@ struct adapter { void *HalData; u32 hal_data_sz; - struct hal_ops HalFunc; s32 bDriverStopped; s32 bSurpriseRemoved; diff --git a/drivers/staging/rtl8723bs/include/hal_com.h b/drivers/staging/rtl8723bs/include/hal_com.h index 258a74076dd9..7ea9ee2b3975 100644 --- a/drivers/staging/rtl8723bs/include/hal_com.h +++ b/drivers/staging/rtl8723bs/include/hal_com.h @@ -134,8 +134,6 @@ s32 c2h_evt_read_88xx(struct adapter *adapter, u8 *buf); u8 rtw_get_mgntframe_raid(struct adapter *adapter, unsigned char network_type); void rtw_hal_update_sta_rate_mask(struct adapter *padapter, struct sta_info *psta); -void hw_var_port_switch(struct adapter *adapter); - void SetHwReg(struct adapter *padapter, u8 variable, u8 *val); void GetHwReg(struct adapter *padapter, u8 variable, u8 *val); void rtw_hal_check_rxfifo_full(struct adapter *adapter); diff --git a/drivers/staging/rtl8723bs/include/hal_intf.h b/drivers/staging/rtl8723bs/include/hal_intf.h index 85de862823c2..67d51e55bd44 100644 --- a/drivers/staging/rtl8723bs/include/hal_intf.h +++ b/drivers/staging/rtl8723bs/include/hal_intf.h @@ -160,20 +160,6 @@ enum hal_intf_ps_func { typedef s32 (*c2h_id_filter)(u8 *c2h_evt); -struct hal_ops { - void (*SetHalODMVarHandler)(struct adapter *padapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet); - - u8 (*Efuse_WordEnableDataWrite)(struct adapter *padapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest); - - s32 (*xmit_thread_handler)(struct adapter *padapter); - void (*hal_notch_filter)(struct adapter *adapter, bool enable); - void (*hal_reset_security_engine)(struct adapter *adapter); - s32 (*c2h_handler)(struct adapter *padapter, u8 *c2h_evt); - c2h_id_filter c2h_id_filter_ccx; - - s32 (*fill_h2c_cmd)(struct adapter *, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); -}; - #define RF_CHANGE_BY_INIT 0 #define RF_CHANGE_BY_IPS BIT28 #define RF_CHANGE_BY_PS BIT29 @@ -200,7 +186,6 @@ void rtw_hal_def_value_init(struct adapter *padapter); void rtw_hal_free_data(struct adapter *padapter); void rtw_hal_dm_init(struct adapter *padapter); -void rtw_hal_dm_deinit(struct adapter *padapter); uint rtw_hal_init(struct adapter *padapter); uint rtw_hal_deinit(struct adapter *padapter); @@ -263,7 +248,6 @@ void rtw_hal_dm_watchdog_in_lps(struct adapter *padapter); s32 rtw_hal_xmit_thread_handler(struct adapter *padapter); void rtw_hal_notch_filter(struct adapter *adapter, bool enable); -void rtw_hal_reset_security_engine(struct adapter *adapter); bool rtw_hal_c2h_valid(struct adapter *adapter, u8 *buf); s32 rtw_hal_c2h_handler(struct adapter *adapter, u8 *c2h_evt); @@ -287,4 +271,5 @@ void Hal_ReadEFuse(struct adapter *padapter, u8 efuseType, u16 _offset, void Hal_GetEfuseDefinition(struct adapter *padapter, u8 efuseType, u8 type, void *pOut, bool bPseudoTest); u16 Hal_EfuseGetCurrentSize(struct adapter *padapter, u8 efuseType, bool bPseudoTest); +void hal_notch_filter_8723b(struct adapter *adapter, bool enable); #endif /* __HAL_INTF_H__ */ diff --git a/drivers/staging/rtl8723bs/include/hal_pwr_seq.h b/drivers/staging/rtl8723bs/include/hal_pwr_seq.h index b93d74a5b9a5..48bf7f66a06e 100644 --- a/drivers/staging/rtl8723bs/include/hal_pwr_seq.h +++ b/drivers/staging/rtl8723bs/include/hal_pwr_seq.h @@ -209,7 +209,7 @@ #define RTL8723B_TRANS_END \ /* format */ \ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ - {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, 0, PWR_CMD_END, 0, 0}, + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, 0, PWR_CMD_END, 0, 0}, extern struct wlan_pwr_cfg rtl8723B_power_on_flow[RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS+RTL8723B_TRANS_END_STEPS]; diff --git a/drivers/staging/rtl8723bs/include/ioctl_cfg80211.h b/drivers/staging/rtl8723bs/include/ioctl_cfg80211.h index 993a7b3c3d22..753009b07451 100644 --- a/drivers/staging/rtl8723bs/include/ioctl_cfg80211.h +++ b/drivers/staging/rtl8723bs/include/ioctl_cfg80211.h @@ -94,6 +94,7 @@ void rtw_cfg80211_init_wiphy(struct adapter *padapter); void rtw_cfg80211_unlink_bss(struct adapter *padapter, struct wlan_network *pnetwork); void rtw_cfg80211_surveydone_event_callback(struct adapter *padapter); +int rtw_ieee80211_channel_to_frequency(int chan); struct cfg80211_bss *rtw_cfg80211_inform_bss(struct adapter *padapter, struct wlan_network *pnetwork); int rtw_cfg80211_check_bss(struct adapter *padapter); void rtw_cfg80211_ibss_indicate_connect(struct adapter *padapter); diff --git a/drivers/staging/rtl8723bs/include/rtl8723b_cmd.h b/drivers/staging/rtl8723bs/include/rtl8723b_cmd.h index dbcf01bbf051..6b2d79e19088 100644 --- a/drivers/staging/rtl8723bs/include/rtl8723b_cmd.h +++ b/drivers/staging/rtl8723bs/include/rtl8723b_cmd.h @@ -175,11 +175,8 @@ void rtl8723b_set_FwMediaStatusRpt_cmd(struct adapter *padapter, u8 mstatus, u8 void rtl8723b_download_rsvd_page(struct adapter *padapter, u8 mstatus); void rtl8723b_download_BTCoex_AP_mode_rsvd_page(struct adapter *padapter); -void CheckFwRsvdPageContent(struct adapter *padapter); - void rtl8723b_set_FwPwrModeInIPS_cmd(struct adapter *padapter, u8 cmd_param); s32 FillH2CCmd8723B(struct adapter *padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); -#define FillH2CCmd FillH2CCmd8723B #endif diff --git a/drivers/staging/rtl8723bs/include/rtl8723b_hal.h b/drivers/staging/rtl8723bs/include/rtl8723b_hal.h index a4a14474c35d..40ff96d3cf74 100644 --- a/drivers/staging/rtl8723bs/include/rtl8723b_hal.h +++ b/drivers/staging/rtl8723bs/include/rtl8723b_hal.h @@ -223,7 +223,6 @@ void Hal_EfuseParseVoltage_8723B(struct adapter *padapter, u8 *hwinfo, void C2HPacketHandler_8723B(struct adapter *padapter, u8 *pbuffer, u16 length); -void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc); void SetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val); void GetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val); u8 SetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable, diff --git a/drivers/staging/rtl8723bs/include/rtl8723b_xmit.h b/drivers/staging/rtl8723bs/include/rtl8723b_xmit.h index ac4ca7e05b9b..ddf868c7899b 100644 --- a/drivers/staging/rtl8723bs/include/rtl8723b_xmit.h +++ b/drivers/staging/rtl8723bs/include/rtl8723b_xmit.h @@ -414,7 +414,6 @@ s32 rtl8723bs_mgnt_xmit(struct adapter *padapter, struct xmit_frame *pmgntframe) s32 rtl8723bs_hal_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8723bs_xmit_buf_handler(struct adapter *padapter); int rtl8723bs_xmit_thread(void *context); -#define hal_xmit_handler rtl8723bs_xmit_buf_handler u8 BWMapping_8723B(struct adapter *Adapter, struct pkt_attrib *pattrib); u8 SCMapping_8723B(struct adapter *Adapter, struct pkt_attrib *pattrib); diff --git a/drivers/staging/rtl8723bs/include/rtw_efuse.h b/drivers/staging/rtl8723bs/include/rtw_efuse.h index d6ea8a4a856f..669565fa1c69 100644 --- a/drivers/staging/rtl8723bs/include/rtw_efuse.h +++ b/drivers/staging/rtl8723bs/include/rtw_efuse.h @@ -96,7 +96,6 @@ u8 efuse_OneByteRead(struct adapter *padapter, u16 addr, u8 *data, bool bPseudo u8 efuse_OneByteWrite(struct adapter *padapter, u16 addr, u8 data, bool bPseudoTest); void Efuse_PowerSwitch(struct adapter *padapter, u8 bWrite, u8 PwrState); -u8 Efuse_WordEnableDataWrite(struct adapter *padapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest); u8 EFUSE_Read1Byte(struct adapter *padapter, u16 Address); void EFUSE_ShadowMapUpdate(struct adapter *padapter, u8 efuseType, bool bPseudoTest); diff --git a/drivers/staging/rtl8723bs/include/rtw_mlme.h b/drivers/staging/rtl8723bs/include/rtw_mlme.h index e665479babc2..3cf68b85eb32 100644 --- a/drivers/staging/rtl8723bs/include/rtw_mlme.h +++ b/drivers/staging/rtl8723bs/include/rtw_mlme.h @@ -341,8 +341,6 @@ extern void rtw_init_registrypriv_dev_network(struct adapter *adapter); extern void rtw_update_registrypriv_dev_network(struct adapter *adapter); -extern void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter *adapter); - extern void _rtw_join_timeout_handler(struct timer_list *t); extern void rtw_scan_timeout_handler(struct timer_list *t); diff --git a/drivers/staging/rtl8723bs/include/sdio_hal.h b/drivers/staging/rtl8723bs/include/sdio_hal.h index 024acf9b530d..6538253765f1 100644 --- a/drivers/staging/rtl8723bs/include/sdio_hal.h +++ b/drivers/staging/rtl8723bs/include/sdio_hal.h @@ -11,6 +11,4 @@ u8 sd_int_isr(struct adapter *padapter); void sd_int_dpc(struct adapter *padapter); void rtw_set_hal_ops(struct adapter *padapter); -void rtl8723bs_set_hal_ops(struct adapter *padapter); - #endif /* __SDIO_HAL_H__ */ diff --git a/drivers/staging/rtl8723bs/include/sta_info.h b/drivers/staging/rtl8723bs/include/sta_info.h index b3535fed3de7..63343998266a 100644 --- a/drivers/staging/rtl8723bs/include/sta_info.h +++ b/drivers/staging/rtl8723bs/include/sta_info.h @@ -86,7 +86,7 @@ struct sta_info { uint qos_option; u8 hwaddr[ETH_ALEN]; - uint ieee8021x_blocked; /* 0: allowed, 1:blocked */ + bool ieee8021x_blocked; uint dot118021XPrivacy; /* aes, tkip... */ union Keytype dot11tkiptxmickey; union Keytype dot11tkiprxmickey; diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index 7fcc46a0bb48..ac3d085808e9 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -192,14 +192,14 @@ rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { }, }; -static int rtw_ieee80211_channel_to_frequency(int chan, int band) +int rtw_ieee80211_channel_to_frequency(int chan) { - if (band == NL80211_BAND_2GHZ) { - if (chan == 14) - return 2484; - else if (chan < 14) - return 2407 + chan * 5; - } + /* NL80211_BAND_2GHZ */ + if (chan == 14) + return 2484; + + if (chan < 14) + return 2407 + chan * 5; return 0; /* not supported */ } @@ -266,7 +266,7 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(struct adapter *padapter, struct wl /* spin_unlock_bh(&pwdev_priv->scan_req_lock); */ channel = pnetwork->network.configuration.ds_config; - freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ); + freq = rtw_ieee80211_channel_to_frequency(channel); notify_channel = ieee80211_get_channel(wiphy, freq); @@ -340,7 +340,7 @@ int rtw_cfg80211_check_bss(struct adapter *padapter) if (!(pnetwork) || !(padapter->rtw_wdev)) return false; - freq = rtw_ieee80211_channel_to_frequency(pnetwork->configuration.ds_config, NL80211_BAND_2GHZ); + freq = rtw_ieee80211_channel_to_frequency(pnetwork->configuration.ds_config); notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq); bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel, @@ -440,7 +440,7 @@ check_bss: u16 channel = cur_network->network.configuration.ds_config; struct cfg80211_roam_info roam_info = {}; - freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ); + freq = rtw_ieee80211_channel_to_frequency(channel); notify_channel = ieee80211_get_channel(wiphy, freq); @@ -1298,7 +1298,8 @@ exit: return ret; } -static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed) +static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, int radio_idx, + u32 changed) { return 0; } @@ -1795,7 +1796,7 @@ static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev, } static int cfg80211_rtw_set_txpower(struct wiphy *wiphy, - struct wireless_dev *wdev, + struct wireless_dev *wdev, int radio_idx, enum nl80211_tx_power_setting type, int mbm) { return 0; @@ -1803,6 +1804,7 @@ static int cfg80211_rtw_set_txpower(struct wiphy *wiphy, static int cfg80211_rtw_get_txpower(struct wiphy *wiphy, struct wireless_dev *wdev, + int radio_idx, unsigned int link_id, int *dbm) { *dbm = (12); @@ -1976,7 +1978,7 @@ static int cfg80211_rtw_get_channel(struct wiphy *wiphy, struct wireless_dev *wd if (!channel) return -ENODATA; - freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ); + freq = rtw_ieee80211_channel_to_frequency(channel); chan = ieee80211_get_channel(adapter->rtw_wdev->wiphy, freq); @@ -2456,7 +2458,7 @@ void rtw_cfg80211_rx_action(struct adapter *adapter, u8 *frame, uint frame_len, rtw_action_frame_parse(frame, frame_len, &category, &action); - freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ); + freq = rtw_ieee80211_channel_to_frequency(channel); rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC); } diff --git a/drivers/staging/rtl8723bs/os_dep/mlme_linux.c b/drivers/staging/rtl8723bs/os_dep/mlme_linux.c index 1904e82a24b5..fd4ae870a617 100644 --- a/drivers/staging/rtl8723bs/os_dep/mlme_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/mlme_linux.c @@ -9,7 +9,7 @@ static void _dynamic_check_timer_handler(struct timer_list *t) { struct adapter *adapter = - from_timer(adapter, t, mlmepriv.dynamic_chk_timer); + timer_container_of(adapter, t, mlmepriv.dynamic_chk_timer); rtw_dynamic_check_timer_handler(adapter); @@ -19,7 +19,7 @@ static void _dynamic_check_timer_handler(struct timer_list *t) static void _rtw_set_scan_deny_timer_hdl(struct timer_list *t) { struct adapter *adapter = - from_timer(adapter, t, mlmepriv.set_scan_deny_timer); + timer_container_of(adapter, t, mlmepriv.set_scan_deny_timer); rtw_clear_scan_deny(adapter); } diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c index 0248dff8f2aa..6ca6dc548805 100644 --- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c @@ -99,8 +99,6 @@ MODULE_PARM_DESC(rtw_ant_num, "Antenna number setting"); static int rtw_antdiv_cfg = 1; /* 0:OFF , 1:ON, 2:decide by Efuse config */ static int rtw_antdiv_type; /* 0:decide by efuse 1: for 88EE, 1Tx and 1RxCG are diversity.(2 Ant with SPDT), 2: for 88EE, 1Tx and 2Rx are diversity.(2 Ant, Tx and RxCG are both on aux port, RxCS is on main port), 3: for 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */ - - static int rtw_hw_wps_pbc; int rtw_mc2u_disable; @@ -523,7 +521,6 @@ static void rtw_init_default_value(struct adapter *padapter) pmlmepriv->htpriv.ampdu_enable = false;/* set to disabled */ /* security_priv */ - /* rtw_get_encrypt_decrypt_from_registrypriv(padapter); */ psecuritypriv->binstallGrpkey = _FAIL; psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt; psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt; @@ -627,7 +624,6 @@ void rtw_reset_drv_sw(struct adapter *padapter) padapter->mlmeextpriv.sitesurvey_res.state = SCAN_DISABLE; rtw_set_signal_stat_timer(&padapter->recvpriv); - } @@ -709,9 +705,6 @@ void rtw_cancel_all_timer(struct adapter *padapter) rtw_clear_scan_deny(padapter); timer_delete_sync(&padapter->recvpriv.signal_stat_timer); - - /* cancel dm timer */ - rtw_hal_dm_deinit(padapter); } u8 rtw_free_drv_sw(struct adapter *padapter) @@ -922,7 +915,7 @@ static int pm_netdev_open(struct net_device *pnetdev, u8 bnormal) mutex_unlock(&(adapter_to_dvobj(padapter)->hw_init_mutex)); } } else { - status = (_SUCCESS == ips_netdrv_open(padapter)) ? (0) : (-1); + status = (ips_netdrv_open(padapter) == _SUCCESS) ? (0) : (-1); } return status; @@ -1112,7 +1105,7 @@ void rtw_suspend_common(struct adapter *padapter) if ((!padapter->bup) || (padapter->bDriverStopped) || (padapter->bSurpriseRemoved)) { pdbgpriv->dbg_suspend_error_cnt++; - goto exit; + return; } rtw_ps_deny(padapter, PS_DENY_SUSPEND); @@ -1134,10 +1127,6 @@ void rtw_suspend_common(struct adapter *padapter) netdev_dbg(padapter->pnetdev, "rtw suspend success in %d ms\n", jiffies_to_msecs(jiffies - start_time)); - -exit: - - return; } static int rtw_resume_process_normal(struct adapter *padapter) @@ -1211,9 +1200,9 @@ int rtw_resume_common(struct adapter *padapter) hal_btcoex_SuspendNotify(padapter, 0); - if (pwrpriv) { + if (pwrpriv) pwrpriv->bInSuspend = false; - } + netdev_dbg(padapter->pnetdev, "%s:%d in %d ms\n", __func__, ret, jiffies_to_msecs(jiffies - start_time)); diff --git a/drivers/staging/rtl8723bs/os_dep/recv_linux.c b/drivers/staging/rtl8723bs/os_dep/recv_linux.c index ca808ded61ac..98d3e4777210 100644 --- a/drivers/staging/rtl8723bs/os_dep/recv_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/recv_linux.c @@ -45,9 +45,8 @@ void rtw_os_recv_resource_free(struct recv_priv *precvpriv) /* free os related resource in struct recv_buf */ void rtw_os_recvbuf_resource_free(struct adapter *padapter, struct recv_buf *precvbuf) { - if (precvbuf->pskb) { + if (precvbuf->pskb) dev_kfree_skb_any(precvbuf->pskb); - } } struct sk_buff *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, u16 nSubframe_Length, u8 *pdata) @@ -160,21 +159,19 @@ void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup) } } - if (bgroup) { + if (bgroup) key_type |= NL80211_KEYTYPE_GROUP; - } else { + else key_type |= NL80211_KEYTYPE_PAIRWISE; - } cfg80211_michael_mic_failure(padapter->pnetdev, (u8 *)&pmlmepriv->assoc_bssid[0], key_type, -1, NULL, GFP_ATOMIC); memset(&ev, 0x00, sizeof(ev)); - if (bgroup) { + if (bgroup) ev.flags |= IW_MICFAILURE_GROUP; - } else { + else ev.flags |= IW_MICFAILURE_PAIRWISE; - } ev.src_addr.sa_family = ARPHRD_ETHER; memcpy(ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[0], ETH_ALEN); diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c index 5a7238e661ff..f3caaa857c86 100644 --- a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c @@ -216,8 +216,6 @@ void rtw_set_hal_ops(struct adapter *padapter) { /* alloc memory for HAL DATA */ rtw_hal_data_init(padapter); - - rtl8723bs_set_hal_ops(padapter); } static void sd_intf_start(struct adapter *padapter) @@ -289,7 +287,7 @@ static struct adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj, const struct rtw_hal_chip_configure(padapter); - hal_btcoex_Initialize((void *) padapter); + hal_btcoex_Initialize((void *)padapter); /* 3 6. read efuse/eeprom data */ rtw_hal_read_chip_info(padapter); diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c b/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c index 4a7c0c9cc7ef..5dc00e9117ae 100644 --- a/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c @@ -305,7 +305,6 @@ void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err) } } } - } } diff --git a/drivers/staging/rtl8723bs/os_dep/wifi_regd.c b/drivers/staging/rtl8723bs/os_dep/wifi_regd.c index dbd4bf531339..f9c4d487badf 100644 --- a/drivers/staging/rtl8723bs/os_dep/wifi_regd.c +++ b/drivers/staging/rtl8723bs/os_dep/wifi_regd.c @@ -41,17 +41,6 @@ static const struct ieee80211_regdomain rtw_regdom_rd = { } }; -static int rtw_ieee80211_channel_to_frequency(int chan, int band) -{ - /* NL80211_BAND_2GHZ */ - if (chan == 14) - return 2484; - else if (chan < 14) - return 2407 + chan * 5; - else - return 0; /* not supported */ -} - static void _rtw_reg_apply_flags(struct wiphy *wiphy) { struct adapter *padapter = wiphy_to_adapter(wiphy); @@ -82,10 +71,7 @@ static void _rtw_reg_apply_flags(struct wiphy *wiphy) /* channels apply by channel plans. */ for (i = 0; i < max_chan_nums; i++) { channel = channel_set[i].ChannelNum; - freq = - rtw_ieee80211_channel_to_frequency(channel, - NL80211_BAND_2GHZ); - + freq = rtw_ieee80211_channel_to_frequency(channel); ch = ieee80211_get_channel(wiphy, freq); if (ch) { if (channel_set[i].ScanType == SCAN_PASSIVE) diff --git a/drivers/staging/sm750fb/Makefile b/drivers/staging/sm750fb/Makefile index b89aa4c12e9d..f7e227df0e54 100644 --- a/drivers/staging/sm750fb/Makefile +++ b/drivers/staging/sm750fb/Makefile @@ -3,5 +3,4 @@ obj-$(CONFIG_FB_SM750) += sm750fb.o sm750fb-objs := sm750.o sm750_hw.o sm750_accel.o sm750_cursor.o \ ddk750_chip.o ddk750_power.o ddk750_mode.o \ - ddk750_display.o ddk750_swi2c.o ddk750_sii164.o \ - ddk750_dvi.o ddk750_hwi2c.o + ddk750_display.o ddk750_swi2c.o diff --git a/drivers/staging/sm750fb/TODO b/drivers/staging/sm750fb/TODO index 9dd57c566257..7ce632d040b3 100644 --- a/drivers/staging/sm750fb/TODO +++ b/drivers/staging/sm750fb/TODO @@ -3,9 +3,6 @@ TODO: - use kernel coding style - refine the code and remove unused code - Implement hardware acceleration for imageblit if image->depth > 1 -- check on hardware effects of removal of USE_HW_I2C and USE_DVICHIP (these two - are supposed to be sample code which is given here if someone wants to - use those functionalities) - must be ported to the atomic kms framework in the drm subsystem (which will give you a basic fbdev driver for free) diff --git a/drivers/staging/sm750fb/ddk750.h b/drivers/staging/sm750fb/ddk750.h index 64ef4d258a91..8a32f8cf3a98 100644 --- a/drivers/staging/sm750fb/ddk750.h +++ b/drivers/staging/sm750fb/ddk750.h @@ -14,8 +14,5 @@ #include "ddk750_chip.h" #include "ddk750_display.h" #include "ddk750_power.h" -#ifdef USE_HW_I2C -#include "ddk750_hwi2c.h" -#endif #include "ddk750_swi2c.h" #endif diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c index 172624ff98b0..4e390541a507 100644 --- a/drivers/staging/sm750fb/ddk750_display.c +++ b/drivers/staging/sm750fb/ddk750_display.c @@ -3,7 +3,6 @@ #include "ddk750_chip.h" #include "ddk750_display.h" #include "ddk750_power.h" -#include "ddk750_dvi.h" static void set_display_control(int ctrl, int disp_state) { diff --git a/drivers/staging/sm750fb/ddk750_dvi.c b/drivers/staging/sm750fb/ddk750_dvi.c deleted file mode 100644 index 8b81e8642f9e..000000000000 --- a/drivers/staging/sm750fb/ddk750_dvi.c +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#define USE_DVICHIP -#ifdef USE_DVICHIP -#include "ddk750_chip.h" -#include "ddk750_reg.h" -#include "ddk750_dvi.h" -#include "ddk750_sii164.h" - -/* - * This global variable contains all the supported driver and its corresponding - * function API. Please set the function pointer to NULL whenever the function - * is not supported. - */ -static struct dvi_ctrl_device dcft_supported_dvi_controller[] = { -#ifdef DVI_CTRL_SII164 - { - .init = sii164_init_chip, - .get_vendor_id = sii164_get_vendor_id, - .get_device_id = sii164GetDeviceID, -#ifdef SII164_FULL_FUNCTIONS - .reset_chip = sii164ResetChip, - .get_chip_string = sii164GetChipString, - .set_power = sii164SetPower, - .enable_hot_plug_detection = sii164EnableHotPlugDetection, - .is_connected = sii164IsConnected, - .check_interrupt = sii164CheckInterrupt, - .clear_interrupt = sii164ClearInterrupt, -#endif - }, -#endif -}; - -int dvi_init(unsigned char edge_select, - unsigned char bus_select, - unsigned char dual_edge_clk_select, - unsigned char hsync_enable, - unsigned char vsync_enable, - unsigned char deskew_enable, - unsigned char deskew_setting, - unsigned char continuous_sync_enable, - unsigned char pll_filter_enable, - unsigned char pll_filter_value) -{ - struct dvi_ctrl_device *current_dvi_ctrl; - - current_dvi_ctrl = dcft_supported_dvi_controller; - if (current_dvi_ctrl->init) { - return current_dvi_ctrl->init(edge_select, - bus_select, - dual_edge_clk_select, - hsync_enable, - vsync_enable, - deskew_enable, - deskew_setting, - continuous_sync_enable, - pll_filter_enable, - pll_filter_value); - } - return -1; /* error */ -} - -#endif diff --git a/drivers/staging/sm750fb/ddk750_dvi.h b/drivers/staging/sm750fb/ddk750_dvi.h deleted file mode 100644 index c2518b73bdbd..000000000000 --- a/drivers/staging/sm750fb/ddk750_dvi.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef DDK750_DVI_H__ -#define DDK750_DVI_H__ - -/* dvi chip stuffs structros */ - -typedef long (*PFN_DVICTRL_INIT)(unsigned char edge_select, - unsigned char bus_select, - unsigned char dual_edge_clk_select, - unsigned char hsync_enable, - unsigned char vsync_enable, - unsigned char deskew_enable, - unsigned char deskew_setting, - unsigned char continuous_sync_enable, - unsigned char pll_filter_enable, - unsigned char pll_filter_value); - -typedef void (*PFN_DVICTRL_RESETCHIP)(void); -typedef char* (*PFN_DVICTRL_GETCHIPSTRING)(void); -typedef unsigned short (*PFN_DVICTRL_GETVENDORID)(void); -typedef unsigned short (*PFN_DVICTRL_GETDEVICEID)(void); -typedef void (*PFN_DVICTRL_SETPOWER)(unsigned char power_up); -typedef void (*PFN_DVICTRL_HOTPLUGDETECTION)(unsigned char enable_hot_plug); -typedef unsigned char (*PFN_DVICTRL_ISCONNECTED)(void); -typedef unsigned char (*PFN_DVICTRL_CHECKINTERRUPT)(void); -typedef void (*PFN_DVICTRL_CLEARINTERRUPT)(void); - -/* Structure to hold all the function pointer to the DVI Controller. */ -struct dvi_ctrl_device { - PFN_DVICTRL_INIT init; - PFN_DVICTRL_RESETCHIP reset_chip; - PFN_DVICTRL_GETCHIPSTRING get_chip_string; - PFN_DVICTRL_GETVENDORID get_vendor_id; - PFN_DVICTRL_GETDEVICEID get_device_id; - PFN_DVICTRL_SETPOWER set_power; - PFN_DVICTRL_HOTPLUGDETECTION enable_hot_plug_detection; - PFN_DVICTRL_ISCONNECTED is_connected; - PFN_DVICTRL_CHECKINTERRUPT check_interrupt; - PFN_DVICTRL_CLEARINTERRUPT clear_interrupt; -}; - -#define DVI_CTRL_SII164 - -/* dvi functions prototype */ -int dvi_init(unsigned char edge_select, - unsigned char bus_select, - unsigned char dual_edge_clk_select, - unsigned char hsync_enable, - unsigned char vsync_enable, - unsigned char deskew_enable, - unsigned char deskew_setting, - unsigned char continuous_sync_enable, - unsigned char pll_filter_enable, - unsigned char pll_filter_value); - -#endif - diff --git a/drivers/staging/sm750fb/ddk750_hwi2c.c b/drivers/staging/sm750fb/ddk750_hwi2c.c deleted file mode 100644 index 8482689b665b..000000000000 --- a/drivers/staging/sm750fb/ddk750_hwi2c.c +++ /dev/null @@ -1,247 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#define USE_HW_I2C -#ifdef USE_HW_I2C -#include "ddk750_chip.h" -#include "ddk750_reg.h" -#include "ddk750_hwi2c.h" -#include "ddk750_power.h" - -#define MAX_HWI2C_FIFO 16 -#define HWI2C_WAIT_TIMEOUT 0xF0000 - -int sm750_hw_i2c_init(unsigned char bus_speed_mode) -{ - unsigned int value; - - /* Enable GPIO 30 & 31 as IIC clock & data */ - value = peek32(GPIO_MUX); - - value |= (GPIO_MUX_30 | GPIO_MUX_31); - poke32(GPIO_MUX, value); - - /* - * Enable Hardware I2C power. - * TODO: Check if we need to enable GPIO power? - */ - sm750_enable_i2c(1); - - /* Enable the I2C Controller and set the bus speed mode */ - value = peek32(I2C_CTRL) & ~(I2C_CTRL_MODE | I2C_CTRL_EN); - if (bus_speed_mode) - value |= I2C_CTRL_MODE; - value |= I2C_CTRL_EN; - poke32(I2C_CTRL, value); - - return 0; -} - -void sm750_hw_i2c_close(void) -{ - unsigned int value; - - /* Disable I2C controller */ - value = peek32(I2C_CTRL) & ~I2C_CTRL_EN; - poke32(I2C_CTRL, value); - - /* Disable I2C Power */ - sm750_enable_i2c(0); - - /* Set GPIO 30 & 31 back as GPIO pins */ - value = peek32(GPIO_MUX); - value &= ~GPIO_MUX_30; - value &= ~GPIO_MUX_31; - poke32(GPIO_MUX, value); -} - -static long hw_i2c_wait_tx_done(void) -{ - unsigned int timeout; - - /* Wait until the transfer is completed. */ - timeout = HWI2C_WAIT_TIMEOUT; - while (!(peek32(I2C_STATUS) & I2C_STATUS_TX) && (timeout != 0)) - timeout--; - - if (timeout == 0) - return -1; - - return 0; -} - -/* - * This function writes data to the i2c slave device registers. - * - * Parameters: - * addr - i2c Slave device address - * length - Total number of bytes to be written to the device - * buf - The buffer that contains the data to be written to the - * i2c device. - * - * Return Value: - * Total number of bytes those are actually written. - */ -static unsigned int hw_i2c_write_data(unsigned char addr, - unsigned int length, - unsigned char *buf) -{ - unsigned char count, i; - unsigned int total_bytes = 0; - - /* Set the Device Address */ - poke32(I2C_SLAVE_ADDRESS, addr & ~0x01); - - /* - * Write data. - * Note: - * Only 16 byte can be accessed per i2c start instruction. - */ - do { - /* - * Reset I2C by writing 0 to I2C_RESET register to - * clear the previous status. - */ - poke32(I2C_RESET, 0); - - /* Set the number of bytes to be written */ - if (length < MAX_HWI2C_FIFO) - count = length - 1; - else - count = MAX_HWI2C_FIFO - 1; - poke32(I2C_BYTE_COUNT, count); - - /* Move the data to the I2C data register */ - for (i = 0; i <= count; i++) - poke32(I2C_DATA0 + i, *buf++); - - /* Start the I2C */ - poke32(I2C_CTRL, peek32(I2C_CTRL) | I2C_CTRL_CTRL); - - /* Wait until the transfer is completed. */ - if (hw_i2c_wait_tx_done() != 0) - break; - - /* Subtract length */ - length -= (count + 1); - - /* Total byte written */ - total_bytes += (count + 1); - - } while (length > 0); - - return total_bytes; -} - -/* - * This function reads data from the slave device and stores them - * in the given buffer - * - * Parameters: - * addr - i2c Slave device address - * length - Total number of bytes to be read - * buf - Pointer to a buffer to be filled with the data read - * from the slave device. It has to be the same size as the - * length to make sure that it can keep all the data read. - * - * Return Value: - * Total number of actual bytes read from the slave device - */ -static unsigned int hw_i2c_read_data(unsigned char addr, - unsigned int length, - unsigned char *buf) -{ - unsigned char count, i; - unsigned int total_bytes = 0; - - /* Set the Device Address */ - poke32(I2C_SLAVE_ADDRESS, addr | 0x01); - - /* - * Read data and save them to the buffer. - * Note: - * Only 16 byte can be accessed per i2c start instruction. - */ - do { - /* - * Reset I2C by writing 0 to I2C_RESET register to - * clear all the status. - */ - poke32(I2C_RESET, 0); - - /* Set the number of bytes to be read */ - if (length <= MAX_HWI2C_FIFO) - count = length - 1; - else - count = MAX_HWI2C_FIFO - 1; - poke32(I2C_BYTE_COUNT, count); - - /* Start the I2C */ - poke32(I2C_CTRL, peek32(I2C_CTRL) | I2C_CTRL_CTRL); - - /* Wait until transaction done. */ - if (hw_i2c_wait_tx_done() != 0) - break; - - /* Save the data to the given buffer */ - for (i = 0; i <= count; i++) - *buf++ = peek32(I2C_DATA0 + i); - - /* Subtract length by 16 */ - length -= (count + 1); - - /* Number of bytes read. */ - total_bytes += (count + 1); - - } while (length > 0); - - return total_bytes; -} - -/* - * This function reads the slave device's register - * - * Parameters: - * deviceAddress - i2c Slave device address which register - * to be read from - * registerIndex - Slave device's register to be read - * - * Return Value: - * Register value - */ -unsigned char sm750_hw_i2c_read_reg(unsigned char addr, unsigned char reg) -{ - unsigned char value = 0xFF; - - if (hw_i2c_write_data(addr, 1, ®) == 1) - hw_i2c_read_data(addr, 1, &value); - - return value; -} - -/* - * This function writes a value to the slave device's register - * - * Parameters: - * deviceAddress - i2c Slave device address which register - * to be written - * registerIndex - Slave device's register to be written - * data - Data to be written to the register - * - * Result: - * 0 - Success - * -1 - Fail - */ -int sm750_hw_i2c_write_reg(unsigned char addr, - unsigned char reg, - unsigned char data) -{ - unsigned char value[2]; - - value[0] = reg; - value[1] = data; - if (hw_i2c_write_data(addr, 2, value) == 2) - return 0; - - return -1; -} - -#endif diff --git a/drivers/staging/sm750fb/ddk750_hwi2c.h b/drivers/staging/sm750fb/ddk750_hwi2c.h deleted file mode 100644 index 337c6493ca61..000000000000 --- a/drivers/staging/sm750fb/ddk750_hwi2c.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef DDK750_HWI2C_H__ -#define DDK750_HWI2C_H__ - -/* hwi2c functions */ -int sm750_hw_i2c_init(unsigned char bus_speed_mode); -void sm750_hw_i2c_close(void); - -unsigned char sm750_hw_i2c_read_reg(unsigned char addr, unsigned char reg); -int sm750_hw_i2c_write_reg(unsigned char addr, unsigned char reg, - unsigned char data); -#endif diff --git a/drivers/staging/sm750fb/ddk750_power.h b/drivers/staging/sm750fb/ddk750_power.h index 63c9e8b6ffb3..5cbb11986bb8 100644 --- a/drivers/staging/sm750fb/ddk750_power.h +++ b/drivers/staging/sm750fb/ddk750_power.h @@ -3,10 +3,10 @@ #define DDK750_POWER_H__ enum dpms { - crtDPMS_ON = 0x0, - crtDPMS_STANDBY = 0x1, - crtDPMS_SUSPEND = 0x2, - crtDPMS_OFF = 0x3, + CRT_DPMS_ON = 0x0, + CRT_DPMS_STANDBY = 0x1, + CRT_DPMS_SUSPEND = 0x2, + CRT_DPMS_OFF = 0x3, }; #define set_DAC(off) { \ diff --git a/drivers/staging/sm750fb/ddk750_sii164.c b/drivers/staging/sm750fb/ddk750_sii164.c deleted file mode 100644 index 2532b60245ac..000000000000 --- a/drivers/staging/sm750fb/ddk750_sii164.c +++ /dev/null @@ -1,408 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#define USE_DVICHIP -#ifdef USE_DVICHIP - -#include "ddk750_sii164.h" -#include "ddk750_hwi2c.h" - -/* I2C Address of each SII164 chip */ -#define SII164_I2C_ADDRESS 0x70 - -/* Define this definition to use hardware i2c. */ -#define USE_HW_I2C - -#ifdef USE_HW_I2C - #define i2cWriteReg sm750_hw_i2c_write_reg - #define i2cReadReg sm750_hw_i2c_read_reg -#else - #define i2cWriteReg sm750_sw_i2c_write_reg - #define i2cReadReg sm750_sw_i2c_read_reg -#endif - -/* SII164 Vendor and Device ID */ -#define SII164_VENDOR_ID 0x0001 -#define SII164_DEVICE_ID 0x0006 - -#ifdef SII164_FULL_FUNCTIONS -/* Name of the DVI Controller chip */ -static char *gDviCtrlChipName = "Silicon Image SiI 164"; -#endif - -/* - * sii164_get_vendor_id - * This function gets the vendor ID of the DVI controller chip. - * - * Output: - * Vendor ID - */ -unsigned short sii164_get_vendor_id(void) -{ - unsigned short vendorID; - - vendorID = ((unsigned short)i2cReadReg(SII164_I2C_ADDRESS, - SII164_VENDOR_ID_HIGH) << 8) | - (unsigned short)i2cReadReg(SII164_I2C_ADDRESS, - SII164_VENDOR_ID_LOW); - - return vendorID; -} - -/* - * sii164GetDeviceID - * This function gets the device ID of the DVI controller chip. - * - * Output: - * Device ID - */ -unsigned short sii164GetDeviceID(void) -{ - unsigned short deviceID; - - deviceID = ((unsigned short)i2cReadReg(SII164_I2C_ADDRESS, - SII164_DEVICE_ID_HIGH) << 8) | - (unsigned short)i2cReadReg(SII164_I2C_ADDRESS, - SII164_DEVICE_ID_LOW); - - return deviceID; -} - -/* - * DVI.C will handle all SiI164 chip stuffs and try its best to make code - * minimal and useful - */ - -/* - * sii164_init_chip - * This function initialize and detect the DVI controller chip. - * - * Input: - * edge_select - Edge Select: - * 0 = Input data is falling edge latched (falling - * edge latched first in dual edge mode) - * 1 = Input data is rising edge latched (rising - * edge latched first in dual edge mode) - * bus_select - Input Bus Select: - * 0 = Input data bus is 12-bits wide - * 1 = Input data bus is 24-bits wide - * dual_edge_clk_select - Dual Edge Clock Select - * 0 = Input data is single edge latched - * 1 = Input data is dual edge latched - * hsync_enable - Horizontal Sync Enable: - * 0 = HSYNC input is transmitted as fixed LOW - * 1 = HSYNC input is transmitted as is - * vsync_enable - Vertical Sync Enable: - * 0 = VSYNC input is transmitted as fixed LOW - * 1 = VSYNC input is transmitted as is - * deskew_enable - De-skewing Enable: - * 0 = De-skew disabled - * 1 = De-skew enabled - * deskew_setting - De-skewing Setting (increment of 260psec) - * 0 = 1 step --> minimum setup / maximum hold - * 1 = 2 step - * 2 = 3 step - * 3 = 4 step - * 4 = 5 step - * 5 = 6 step - * 6 = 7 step - * 7 = 8 step --> maximum setup / minimum hold - * continuous_sync_enable- SYNC Continuous: - * 0 = Disable - * 1 = Enable - * pll_filter_enable - PLL Filter Enable - * 0 = Disable PLL Filter - * 1 = Enable PLL Filter - * pll_filter_value - PLL Filter characteristics: - * 0~7 (recommended value is 4) - * - * Output: - * 0 - Success - * -1 - Fail. - */ -long sii164_init_chip(unsigned char edge_select, - unsigned char bus_select, - unsigned char dual_edge_clk_select, - unsigned char hsync_enable, - unsigned char vsync_enable, - unsigned char deskew_enable, - unsigned char deskew_setting, - unsigned char continuous_sync_enable, - unsigned char pll_filter_enable, - unsigned char pll_filter_value) -{ - unsigned char config; - - /* Initialize the i2c bus */ -#ifdef USE_HW_I2C - /* Use fast mode. */ - sm750_hw_i2c_init(1); -#else - sm750_sw_i2c_init(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA); -#endif - - /* Check if SII164 Chip exists */ - if ((sii164_get_vendor_id() == SII164_VENDOR_ID) && - (sii164GetDeviceID() == SII164_DEVICE_ID)) { - /* - * Initialize SII164 controller chip. - */ - - /* Select the edge */ - if (edge_select == 0) - config = SII164_CONFIGURATION_LATCH_FALLING; - else - config = SII164_CONFIGURATION_LATCH_RISING; - - /* Select bus wide */ - if (bus_select == 0) - config |= SII164_CONFIGURATION_BUS_12BITS; - else - config |= SII164_CONFIGURATION_BUS_24BITS; - - /* Select Dual/Single Edge Clock */ - if (dual_edge_clk_select == 0) - config |= SII164_CONFIGURATION_CLOCK_SINGLE; - else - config |= SII164_CONFIGURATION_CLOCK_DUAL; - - /* Select HSync Enable */ - if (hsync_enable == 0) - config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW; - else - config |= SII164_CONFIGURATION_HSYNC_AS_IS; - - /* Select VSync Enable */ - if (vsync_enable == 0) - config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW; - else - config |= SII164_CONFIGURATION_VSYNC_AS_IS; - - i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); - - /* - * De-skew enabled with default 111b value. - * This fixes some artifacts problem in some mode on board 2.2. - * Somehow this fix does not affect board 2.1. - */ - if (deskew_enable == 0) - config = SII164_DESKEW_DISABLE; - else - config = SII164_DESKEW_ENABLE; - - switch (deskew_setting) { - case 0: - config |= SII164_DESKEW_1_STEP; - break; - case 1: - config |= SII164_DESKEW_2_STEP; - break; - case 2: - config |= SII164_DESKEW_3_STEP; - break; - case 3: - config |= SII164_DESKEW_4_STEP; - break; - case 4: - config |= SII164_DESKEW_5_STEP; - break; - case 5: - config |= SII164_DESKEW_6_STEP; - break; - case 6: - config |= SII164_DESKEW_7_STEP; - break; - case 7: - config |= SII164_DESKEW_8_STEP; - break; - } - i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config); - - /* Enable/Disable Continuous Sync. */ - if (continuous_sync_enable == 0) - config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE; - else - config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE; - - /* Enable/Disable PLL Filter */ - if (pll_filter_enable == 0) - config |= SII164_PLL_FILTER_DISABLE; - else - config |= SII164_PLL_FILTER_ENABLE; - - /* Set the PLL Filter value */ - config |= ((pll_filter_value & 0x07) << 1); - - i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config); - - /* Recover from Power Down and enable output. */ - config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION); - config |= SII164_CONFIGURATION_POWER_NORMAL; - i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); - - return 0; - } - - /* Return -1 if initialization fails. */ - return -1; -} - -/* below sii164 function is not necessary */ - -#ifdef SII164_FULL_FUNCTIONS - -/* - * sii164ResetChip - * This function resets the DVI Controller Chip. - */ -void sii164ResetChip(void) -{ - /* Power down */ - sii164SetPower(0); - sii164SetPower(1); -} - -/* - * sii164GetChipString - * This function returns a char string name of the current DVI Controller - * chip. - * - * It's convenient for application need to display the chip name. - */ -char *sii164GetChipString(void) -{ - return gDviCtrlChipName; -} - -/* - * sii164SetPower - * This function sets the power configuration of the DVI Controller Chip. - * - * Input: - * powerUp - Flag to set the power down or up - */ -void sii164SetPower(unsigned char powerUp) -{ - unsigned char config; - - config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION); - if (powerUp == 1) { - /* Power up the chip */ - config &= ~SII164_CONFIGURATION_POWER_MASK; - config |= SII164_CONFIGURATION_POWER_NORMAL; - i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); - } else { - /* Power down the chip */ - config &= ~SII164_CONFIGURATION_POWER_MASK; - config |= SII164_CONFIGURATION_POWER_DOWN; - i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); - } -} - -/* - * sii164SelectHotPlugDetectionMode - * This function selects the mode of the hot plug detection. - */ -static -void sii164SelectHotPlugDetectionMode(enum sii164_hot_plug_mode hotPlugMode) -{ - unsigned char detectReg; - - detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & - ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG; - switch (hotPlugMode) { - case SII164_HOTPLUG_DISABLE: - detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH; - break; - case SII164_HOTPLUG_USE_MDI: - detectReg &= ~SII164_DETECT_INTERRUPT_MASK; - detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN; - detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI; - break; - case SII164_HOTPLUG_USE_RSEN: - detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN; - break; - case SII164_HOTPLUG_USE_HTPLG: - detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG; - break; - } - - i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg); -} - -/* - * sii164EnableHotPlugDetection - * This function enables the Hot Plug detection. - * - * enableHotPlug - Enable (=1) / disable (=0) Hot Plug detection - */ -void sii164EnableHotPlugDetection(unsigned char enableHotPlug) -{ - unsigned char detectReg; - - detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT); - - /* Depending on each DVI controller, need to enable the hot plug based - * on each individual chip design. - */ - if (enableHotPlug != 0) - sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI); - else - sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE); -} - -/* - * sii164IsConnected - * Check if the DVI Monitor is connected. - * - * Output: - * 0 - Not Connected - * 1 - Connected - */ -unsigned char sii164IsConnected(void) -{ - unsigned char hotPlugValue; - - hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & - SII164_DETECT_HOT_PLUG_STATUS_MASK; - if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON) - return 1; - else - return 0; -} - -/* - * sii164CheckInterrupt - * Checks if interrupt has occurred. - * - * Output: - * 0 - No interrupt - * 1 - Interrupt occurs - */ -unsigned char sii164CheckInterrupt(void) -{ - unsigned char detectReg; - - detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & - SII164_DETECT_MONITOR_STATE_MASK; - if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE) - return 1; - else - return 0; -} - -/* - * sii164ClearInterrupt - * Clear the hot plug interrupt. - */ -void sii164ClearInterrupt(void) -{ - unsigned char detectReg; - - /* Clear the MDI interrupt */ - detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT); - i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, - detectReg | SII164_DETECT_MONITOR_STATE_CLEAR); -} - -#endif - -#endif diff --git a/drivers/staging/sm750fb/ddk750_sii164.h b/drivers/staging/sm750fb/ddk750_sii164.h deleted file mode 100644 index 71a7c1cb42c4..000000000000 --- a/drivers/staging/sm750fb/ddk750_sii164.h +++ /dev/null @@ -1,174 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef DDK750_SII164_H__ -#define DDK750_SII164_H__ - -#define USE_DVICHIP - -/* Hot Plug detection mode structure */ -enum sii164_hot_plug_mode { - SII164_HOTPLUG_DISABLE = 0, /* Disable Hot Plug output bit - * (always high). - */ - - SII164_HOTPLUG_USE_MDI, /* Use Monitor Detect Interrupt bit. */ - SII164_HOTPLUG_USE_RSEN, /* Use Receiver Sense detect bit. */ - SII164_HOTPLUG_USE_HTPLG /* Use Hot Plug detect bit. */ -}; - -/* Silicon Image SiI164 chip prototype */ -long sii164_init_chip(unsigned char edgeSelect, - unsigned char busSelect, - unsigned char dualEdgeClkSelect, - unsigned char hsyncEnable, - unsigned char vsyncEnable, - unsigned char deskewEnable, - unsigned char deskewSetting, - unsigned char continuousSyncEnable, - unsigned char pllFilterEnable, - unsigned char pllFilterValue); - -unsigned short sii164_get_vendor_id(void); -unsigned short sii164GetDeviceID(void); - -#ifdef SII164_FULL_FUNCTIONS -void sii164ResetChip(void); -char *sii164GetChipString(void); -void sii164SetPower(unsigned char powerUp); -void sii164EnableHotPlugDetection(unsigned char enableHotPlug); -unsigned char sii164IsConnected(void); -unsigned char sii164CheckInterrupt(void); -void sii164ClearInterrupt(void); -#endif -/* - * below register definition is used for - * Silicon Image SiI164 DVI controller chip - */ -/* - * Vendor ID registers - */ -#define SII164_VENDOR_ID_LOW 0x00 -#define SII164_VENDOR_ID_HIGH 0x01 - -/* - * Device ID registers - */ -#define SII164_DEVICE_ID_LOW 0x02 -#define SII164_DEVICE_ID_HIGH 0x03 - -/* - * Device Revision - */ -#define SII164_DEVICE_REVISION 0x04 - -/* - * Frequency Limitation registers - */ -#define SII164_FREQUENCY_LIMIT_LOW 0x06 -#define SII164_FREQUENCY_LIMIT_HIGH 0x07 - -/* - * Power Down and Input Signal Configuration registers - */ -#define SII164_CONFIGURATION 0x08 - -/* Power down (PD) */ -#define SII164_CONFIGURATION_POWER_DOWN 0x00 -#define SII164_CONFIGURATION_POWER_NORMAL 0x01 -#define SII164_CONFIGURATION_POWER_MASK 0x01 - -/* Input Edge Latch Select (EDGE) */ -#define SII164_CONFIGURATION_LATCH_FALLING 0x00 -#define SII164_CONFIGURATION_LATCH_RISING 0x02 - -/* Bus Select (BSEL) */ -#define SII164_CONFIGURATION_BUS_12BITS 0x00 -#define SII164_CONFIGURATION_BUS_24BITS 0x04 - -/* Dual Edge Clock Select (DSEL) */ -#define SII164_CONFIGURATION_CLOCK_SINGLE 0x00 -#define SII164_CONFIGURATION_CLOCK_DUAL 0x08 - -/* Horizontal Sync Enable (HEN) */ -#define SII164_CONFIGURATION_HSYNC_FORCE_LOW 0x00 -#define SII164_CONFIGURATION_HSYNC_AS_IS 0x10 - -/* Vertical Sync Enable (VEN) */ -#define SII164_CONFIGURATION_VSYNC_FORCE_LOW 0x00 -#define SII164_CONFIGURATION_VSYNC_AS_IS 0x20 - -/* - * Detection registers - */ -#define SII164_DETECT 0x09 - -/* Monitor Detect Interrupt (MDI) */ -#define SII164_DETECT_MONITOR_STATE_CHANGE 0x00 -#define SII164_DETECT_MONITOR_STATE_NO_CHANGE 0x01 -#define SII164_DETECT_MONITOR_STATE_CLEAR 0x01 -#define SII164_DETECT_MONITOR_STATE_MASK 0x01 - -/* Hot Plug detect Input (HTPLG) */ -#define SII164_DETECT_HOT_PLUG_STATUS_OFF 0x00 -#define SII164_DETECT_HOT_PLUG_STATUS_ON 0x02 -#define SII164_DETECT_HOT_PLUG_STATUS_MASK 0x02 - -/* Receiver Sense (RSEN) */ -#define SII164_DETECT_RECEIVER_SENSE_NOT_DETECTED 0x00 -#define SII164_DETECT_RECEIVER_SENSE_DETECTED 0x04 - -/* Interrupt Generation Method (TSEL) */ -#define SII164_DETECT_INTERRUPT_BY_RSEN_PIN 0x00 -#define SII164_DETECT_INTERRUPT_BY_HTPLG_PIN 0x08 -#define SII164_DETECT_INTERRUPT_MASK 0x08 - -/* Monitor Sense Output (MSEN) */ -#define SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH 0x00 -#define SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI 0x10 -#define SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN 0x20 -#define SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG 0x30 -#define SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG 0x30 - -/* - * Skewing registers - */ -#define SII164_DESKEW 0x0A - -/* General Purpose Input (CTL[3:1]) */ -#define SII164_DESKEW_GENERAL_PURPOSE_INPUT_MASK 0x0E - -/* De-skewing Enable bit (DKEN) */ -#define SII164_DESKEW_DISABLE 0x00 -#define SII164_DESKEW_ENABLE 0x10 - -/* De-skewing Setting (DK[3:1])*/ -#define SII164_DESKEW_1_STEP 0x00 -#define SII164_DESKEW_2_STEP 0x20 -#define SII164_DESKEW_3_STEP 0x40 -#define SII164_DESKEW_4_STEP 0x60 -#define SII164_DESKEW_5_STEP 0x80 -#define SII164_DESKEW_6_STEP 0xA0 -#define SII164_DESKEW_7_STEP 0xC0 -#define SII164_DESKEW_8_STEP 0xE0 - -/* - * User Configuration Data registers (CFG 7:0) - */ -#define SII164_USER_CONFIGURATION 0x0B - -/* - * PLL registers - */ -#define SII164_PLL 0x0C - -/* PLL Filter Value (PLLF) */ -#define SII164_PLL_FILTER_VALUE_MASK 0x0E - -/* PLL Filter Enable (PFEN) */ -#define SII164_PLL_FILTER_DISABLE 0x00 -#define SII164_PLL_FILTER_ENABLE 0x01 - -/* Sync Continuous (SCNT) */ -#define SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE 0x00 -#define SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE 0x80 - -#endif diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 04c1b32a22c5..3659af7e519d 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -120,14 +120,14 @@ static int lynxfb_ops_cursor(struct fb_info *info, struct fb_cursor *fbcursor) sm750_hw_cursor_disable(cursor); if (fbcursor->set & FB_CUR_SETSIZE) - sm750_hw_cursor_setSize(cursor, + sm750_hw_cursor_set_size(cursor, fbcursor->image.width, fbcursor->image.height); if (fbcursor->set & FB_CUR_SETPOS) - sm750_hw_cursor_setPos(cursor, - fbcursor->image.dx - info->var.xoffset, - fbcursor->image.dy - info->var.yoffset); + sm750_hw_cursor_set_pos(cursor, + fbcursor->image.dx - info->var.xoffset, + fbcursor->image.dy - info->var.yoffset); if (fbcursor->set & FB_CUR_SETCMAP) { /* get the 16bit color of kernel means */ @@ -141,14 +141,12 @@ static int lynxfb_ops_cursor(struct fb_info *info, struct fb_cursor *fbcursor) ((info->cmap.green[fbcursor->image.bg_color] & 0xfc00) >> 5) | ((info->cmap.blue[fbcursor->image.bg_color] & 0xf800) >> 11); - sm750_hw_cursor_setColor(cursor, fg, bg); + sm750_hw_cursor_set_color(cursor, fg, bg); } if (fbcursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) { - sm750_hw_cursor_setData(cursor, - fbcursor->rop, - fbcursor->image.data, - fbcursor->mask); + sm750_hw_cursor_set_data(cursor, fbcursor->rop, fbcursor->image.data, + fbcursor->mask); } if (fbcursor->enable) @@ -162,7 +160,7 @@ static void lynxfb_ops_fillrect(struct fb_info *info, { struct lynxfb_par *par; struct sm750_dev *sm750_dev; - unsigned int base, pitch, Bpp, rop; + unsigned int base, pitch, bpp, rop; u32 color; if (info->state != FBINFO_STATE_RUNNING) @@ -177,9 +175,9 @@ static void lynxfb_ops_fillrect(struct fb_info *info, */ base = par->crtc.o_screen; pitch = info->fix.line_length; - Bpp = info->var.bits_per_pixel >> 3; + bpp = info->var.bits_per_pixel >> 3; - color = (Bpp == 1) ? region->color : + color = (bpp == 1) ? region->color : ((u32 *)info->pseudo_palette)[region->color]; rop = (region->rop != ROP_COPY) ? HW_ROP2_XOR : HW_ROP2_COPY; @@ -192,7 +190,7 @@ static void lynxfb_ops_fillrect(struct fb_info *info, spin_lock(&sm750_dev->slock); sm750_dev->accel.de_fillrect(&sm750_dev->accel, - base, pitch, Bpp, + base, pitch, bpp, region->dx, region->dy, region->width, region->height, color, rop); @@ -204,7 +202,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info, { struct lynxfb_par *par; struct sm750_dev *sm750_dev; - unsigned int base, pitch, Bpp; + unsigned int base, pitch, bpp; par = info->par; sm750_dev = par->dev; @@ -215,7 +213,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info, */ base = par->crtc.o_screen; pitch = info->fix.line_length; - Bpp = info->var.bits_per_pixel >> 3; + bpp = info->var.bits_per_pixel >> 3; /* * If not use spin_lock, system will die if user load driver @@ -227,7 +225,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info, sm750_dev->accel.de_copyarea(&sm750_dev->accel, base, pitch, region->sx, region->sy, - base, pitch, Bpp, region->dx, region->dy, + base, pitch, bpp, region->dx, region->dy, region->width, region->height, HW_ROP2_COPY); spin_unlock(&sm750_dev->slock); @@ -236,7 +234,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info, static void lynxfb_ops_imageblit(struct fb_info *info, const struct fb_image *image) { - unsigned int base, pitch, Bpp; + unsigned int base, pitch, bpp; unsigned int fgcol, bgcol; struct lynxfb_par *par; struct sm750_dev *sm750_dev; @@ -249,7 +247,7 @@ static void lynxfb_ops_imageblit(struct fb_info *info, */ base = par->crtc.o_screen; pitch = info->fix.line_length; - Bpp = info->var.bits_per_pixel >> 3; + bpp = info->var.bits_per_pixel >> 3; /* TODO: Implement hardware acceleration for image->depth > 1 */ if (image->depth != 1) { @@ -276,7 +274,7 @@ static void lynxfb_ops_imageblit(struct fb_info *info, sm750_dev->accel.de_imageblit(&sm750_dev->accel, image->data, image->width >> 3, 0, - base, pitch, Bpp, + base, pitch, bpp, image->dx, image->dy, image->width, image->height, fgcol, bgcol, HW_ROP2_COPY); @@ -394,9 +392,9 @@ static int lynxfb_ops_set_par(struct fb_info *info) pr_err("bpp %d not supported\n", var->bits_per_pixel); return ret; } - ret = hw_sm750_crtc_setMode(crtc, var, fix); + ret = hw_sm750_crtc_set_mode(crtc, var, fix); if (!ret) - ret = hw_sm750_output_setMode(output, var, fix); + ret = hw_sm750_output_set_mode(output, var, fix); return ret; } @@ -514,7 +512,7 @@ static int lynxfb_ops_check_var(struct fb_var_screeninfo *var, return -ENOMEM; } - return hw_sm750_crtc_checkMode(crtc, var); + return hw_sm750_crtc_check_mode(crtc, var); } static int lynxfb_ops_setcolreg(unsigned int regno, @@ -547,7 +545,7 @@ static int lynxfb_ops_setcolreg(unsigned int regno, red >>= 8; green >>= 8; blue >>= 8; - ret = hw_sm750_setColReg(crtc, regno, red, green, blue); + ret = hw_sm750_set_col_reg(crtc, regno, red, green, blue); goto exit; } @@ -573,13 +571,19 @@ exit: static int lynxfb_ops_blank(int blank, struct fb_info *info) { + struct sm750_dev *sm750_dev; struct lynxfb_par *par; struct lynxfb_output *output; pr_debug("blank = %d.\n", blank); par = info->par; output = &par->output; - return output->proc_setBLANK(output, blank); + sm750_dev = par->dev; + + if (sm750_dev->revid == SM750LE_REVISION_ID) + return hw_sm750le_set_blank(output, blank); + else + return hw_sm750_set_blank(output, blank); } static int sm750fb_set_drv(struct lynxfb_par *par) @@ -600,18 +604,16 @@ static int sm750fb_set_drv(struct lynxfb_par *par) crtc->vidmem_size >>= 1; /* setup crtc and output member */ - sm750_dev->hwCursor = g_hwcursor; + sm750_dev->hw_cursor = g_hwcursor; crtc->line_pad = 16; crtc->xpanstep = 8; crtc->ypanstep = 1; crtc->ywrapstep = 0; - output->proc_setBLANK = (sm750_dev->revid == SM750LE_REVISION_ID) ? - hw_sm750le_setBLANK : hw_sm750_setBLANK; /* chip specific phase */ sm750_dev->accel.de_wait = (sm750_dev->revid == SM750LE_REVISION_ID) ? - hw_sm750le_deWait : hw_sm750_deWait; + hw_sm750le_de_wait : hw_sm750_de_wait; switch (sm750_dev->dataflow) { case sm750_simul_pri: output->paths = sm750_pnc; diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h index aff69661c8e6..d7f40efe3a2c 100644 --- a/drivers/staging/sm750fb/sm750.h +++ b/drivers/staging/sm750fb/sm750.h @@ -113,7 +113,7 @@ struct sm750_dev { * 2: secondary crtc hw cursor enabled * 3: both ctrc hw cursor enabled */ - int hwCursor; + int hw_cursor; }; struct lynx_cursor { @@ -169,8 +169,6 @@ struct lynxfb_output { * output->channel ==> &crtc->channel */ void *priv; - - int (*proc_setBLANK)(struct lynxfb_output *output, int blank); }; struct lynxfb_par { @@ -193,26 +191,26 @@ static inline unsigned long ps_to_hz(unsigned int psvalue) int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev); int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev); -void hw_sm750_initAccel(struct sm750_dev *sm750_dev); -int hw_sm750_deWait(void); -int hw_sm750le_deWait(void); +void hw_sm750_init_accel(struct sm750_dev *sm750_dev); +int hw_sm750_de_wait(void); +int hw_sm750le_de_wait(void); -int hw_sm750_output_setMode(struct lynxfb_output *output, - struct fb_var_screeninfo *var, - struct fb_fix_screeninfo *fix); +int hw_sm750_output_set_mode(struct lynxfb_output *output, + struct fb_var_screeninfo *var, + struct fb_fix_screeninfo *fix); -int hw_sm750_crtc_checkMode(struct lynxfb_crtc *crtc, - struct fb_var_screeninfo *var); +int hw_sm750_crtc_check_mode(struct lynxfb_crtc *crtc, + struct fb_var_screeninfo *var); -int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc, - struct fb_var_screeninfo *var, - struct fb_fix_screeninfo *fix); +int hw_sm750_crtc_set_mode(struct lynxfb_crtc *crtc, + struct fb_var_screeninfo *var, + struct fb_fix_screeninfo *fix); -int hw_sm750_setColReg(struct lynxfb_crtc *crtc, ushort index, - ushort red, ushort green, ushort blue); +int hw_sm750_set_col_reg(struct lynxfb_crtc *crtc, ushort index, + ushort red, ushort green, ushort blue); -int hw_sm750_setBLANK(struct lynxfb_output *output, int blank); -int hw_sm750le_setBLANK(struct lynxfb_output *output, int blank); +int hw_sm750_set_blank(struct lynxfb_output *output, int blank); +int hw_sm750le_set_blank(struct lynxfb_output *output, int blank); int hw_sm750_pan_display(struct lynxfb_crtc *crtc, const struct fb_var_screeninfo *var, const struct fb_info *info); diff --git a/drivers/staging/sm750fb/sm750_cursor.c b/drivers/staging/sm750fb/sm750_cursor.c index eea4d1bd36ce..7ede144905c9 100644 --- a/drivers/staging/sm750fb/sm750_cursor.c +++ b/drivers/staging/sm750fb/sm750_cursor.c @@ -57,13 +57,13 @@ void sm750_hw_cursor_disable(struct lynx_cursor *cursor) poke32(HWC_ADDRESS, 0); } -void sm750_hw_cursor_setSize(struct lynx_cursor *cursor, int w, int h) +void sm750_hw_cursor_set_size(struct lynx_cursor *cursor, int w, int h) { cursor->w = w; cursor->h = h; } -void sm750_hw_cursor_setPos(struct lynx_cursor *cursor, int x, int y) +void sm750_hw_cursor_set_pos(struct lynx_cursor *cursor, int x, int y) { u32 reg; @@ -72,7 +72,7 @@ void sm750_hw_cursor_setPos(struct lynx_cursor *cursor, int x, int y) poke32(HWC_LOCATION, reg); } -void sm750_hw_cursor_setColor(struct lynx_cursor *cursor, u32 fg, u32 bg) +void sm750_hw_cursor_set_color(struct lynx_cursor *cursor, u32 fg, u32 bg) { u32 reg = (fg << HWC_COLOR_12_2_RGB565_SHIFT) & HWC_COLOR_12_2_RGB565_MASK; @@ -81,8 +81,8 @@ void sm750_hw_cursor_setColor(struct lynx_cursor *cursor, u32 fg, u32 bg) poke32(HWC_COLOR_3, 0xffe0); } -void sm750_hw_cursor_setData(struct lynx_cursor *cursor, u16 rop, - const u8 *pcol, const u8 *pmsk) +void sm750_hw_cursor_set_data(struct lynx_cursor *cursor, u16 rop, + const u8 *pcol, const u8 *pmsk) { int i, j, count, pitch, offset; u8 color, mask, opr; @@ -131,8 +131,8 @@ void sm750_hw_cursor_setData(struct lynx_cursor *cursor, u16 rop, } } -void sm750_hw_cursor_setData2(struct lynx_cursor *cursor, u16 rop, - const u8 *pcol, const u8 *pmsk) +void sm750_hw_cursor_set_data2(struct lynx_cursor *cursor, u16 rop, + const u8 *pcol, const u8 *pmsk) { int i, j, count, pitch, offset; u8 color, mask; diff --git a/drivers/staging/sm750fb/sm750_cursor.h b/drivers/staging/sm750fb/sm750_cursor.h index b59643dd61ed..88fa02f6377a 100644 --- a/drivers/staging/sm750fb/sm750_cursor.h +++ b/drivers/staging/sm750fb/sm750_cursor.h @@ -5,11 +5,11 @@ /* hw_cursor_xxx works for voyager,718 and 750 */ void sm750_hw_cursor_enable(struct lynx_cursor *cursor); void sm750_hw_cursor_disable(struct lynx_cursor *cursor); -void sm750_hw_cursor_setSize(struct lynx_cursor *cursor, int w, int h); -void sm750_hw_cursor_setPos(struct lynx_cursor *cursor, int x, int y); -void sm750_hw_cursor_setColor(struct lynx_cursor *cursor, u32 fg, u32 bg); -void sm750_hw_cursor_setData(struct lynx_cursor *cursor, u16 rop, - const u8 *data, const u8 *mask); -void sm750_hw_cursor_setData2(struct lynx_cursor *cursor, u16 rop, +void sm750_hw_cursor_set_size(struct lynx_cursor *cursor, int w, int h); +void sm750_hw_cursor_set_pos(struct lynx_cursor *cursor, int x, int y); +void sm750_hw_cursor_set_color(struct lynx_cursor *cursor, u32 fg, u32 bg); +void sm750_hw_cursor_set_data(struct lynx_cursor *cursor, u16 rop, const u8 *data, const u8 *mask); +void sm750_hw_cursor_set_data2(struct lynx_cursor *cursor, u16 rop, + const u8 *data, const u8 *mask); #endif diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c index 4bc89218c11c..7119b67efe11 100644 --- a/drivers/staging/sm750fb/sm750_hw.c +++ b/drivers/staging/sm750fb/sm750_hw.c @@ -55,9 +55,8 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev) pr_err("mmio failed\n"); ret = -EFAULT; goto exit; - } else { - pr_info("mmio virtual addr = %p\n", sm750_dev->pvReg); } + pr_info("mmio virtual addr = %p\n", sm750_dev->pvReg); sm750_dev->accel.dprBase = sm750_dev->pvReg + DE_BASE_ADDR_TYPE1; sm750_dev->accel.dpPortBase = sm750_dev->pvReg + DE_PORT_ADDR_TYPE1; @@ -84,9 +83,8 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev) pr_err("Map video memory failed\n"); ret = -EFAULT; goto exit; - } else { - pr_info("video memory vaddr = %p\n", sm750_dev->pvMem); } + pr_info("video memory vaddr = %p\n", sm750_dev->pvMem); exit: return ret; } @@ -175,14 +173,14 @@ int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev) /* init 2d engine */ if (!sm750_dev->accel_off) - hw_sm750_initAccel(sm750_dev); + hw_sm750_init_accel(sm750_dev); return 0; } -int hw_sm750_output_setMode(struct lynxfb_output *output, - struct fb_var_screeninfo *var, - struct fb_fix_screeninfo *fix) +int hw_sm750_output_set_mode(struct lynxfb_output *output, + struct fb_var_screeninfo *var, + struct fb_fix_screeninfo *fix) { int ret; enum disp_output disp_set; @@ -221,8 +219,8 @@ int hw_sm750_output_setMode(struct lynxfb_output *output, return ret; } -int hw_sm750_crtc_checkMode(struct lynxfb_crtc *crtc, - struct fb_var_screeninfo *var) +int hw_sm750_crtc_check_mode(struct lynxfb_crtc *crtc, + struct fb_var_screeninfo *var) { struct sm750_dev *sm750_dev; struct lynxfb_par *par = container_of(crtc, struct lynxfb_par, crtc); @@ -247,9 +245,9 @@ int hw_sm750_crtc_checkMode(struct lynxfb_crtc *crtc, } /* set the controller's mode for @crtc charged with @var and @fix parameters */ -int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc, - struct fb_var_screeninfo *var, - struct fb_fix_screeninfo *fix) +int hw_sm750_crtc_set_mode(struct lynxfb_crtc *crtc, + struct fb_var_screeninfo *var, + struct fb_fix_screeninfo *fix) { int ret, fmt; u32 reg; @@ -372,8 +370,8 @@ exit: return ret; } -int hw_sm750_setColReg(struct lynxfb_crtc *crtc, ushort index, ushort red, - ushort green, ushort blue) +int hw_sm750_set_col_reg(struct lynxfb_crtc *crtc, ushort index, ushort red, + ushort green, ushort blue) { static unsigned int add[] = { PANEL_PALETTE_RAM, CRT_PALETTE_RAM }; @@ -382,7 +380,7 @@ int hw_sm750_setColReg(struct lynxfb_crtc *crtc, ushort index, ushort red, return 0; } -int hw_sm750le_setBLANK(struct lynxfb_output *output, int blank) +int hw_sm750le_set_blank(struct lynxfb_output *output, int blank) { int dpms, crtdb; @@ -423,7 +421,7 @@ int hw_sm750le_setBLANK(struct lynxfb_output *output, int blank) return 0; } -int hw_sm750_setBLANK(struct lynxfb_output *output, int blank) +int hw_sm750_set_blank(struct lynxfb_output *output, int blank) { unsigned int dpms, pps, crtdb; @@ -476,7 +474,7 @@ int hw_sm750_setBLANK(struct lynxfb_output *output, int blank) return 0; } -void hw_sm750_initAccel(struct sm750_dev *sm750_dev) +void hw_sm750_init_accel(struct sm750_dev *sm750_dev) { u32 reg; @@ -506,7 +504,7 @@ void hw_sm750_initAccel(struct sm750_dev *sm750_dev) sm750_dev->accel.de_init(&sm750_dev->accel); } -int hw_sm750le_deWait(void) +int hw_sm750le_de_wait(void) { int i = 0x10000000; unsigned int mask = DE_STATE2_DE_STATUS_BUSY | DE_STATE2_DE_FIFO_EMPTY | @@ -523,7 +521,7 @@ int hw_sm750le_deWait(void) return -1; } -int hw_sm750_deWait(void) +int hw_sm750_de_wait(void) { int i = 0x10000000; unsigned int mask = SYSTEM_CTRL_DE_STATUS_BUSY | diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c index 1c1f040122d7..7d0ddd5c8cce 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c @@ -71,6 +71,7 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + struct snd_ctl_elem_info info; int val, *valp; int changed = 0; @@ -84,6 +85,11 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, return -EINVAL; val = ucontrol->value.integer.value[0]; + + snd_bcm2835_ctl_info(kcontrol, &info); + if (val < info.value.integer.min || val > info.value.integer.max) + return -EINVAL; + mutex_lock(&chip->audio_mutex); if (val != *valp) { *valp = val; diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c b/drivers/staging/vc04_services/bcm2835-camera/controls.c index 6bce45925bf1..e670226f1edf 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/controls.c +++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c @@ -533,17 +533,15 @@ static int ctrl_set_image_effect(struct bcm2835_mmal_dev *dev, control = &dev->component[COMP_CAMERA]->control; - ret = vchiq_mmal_port_parameter_set( - dev->instance, control, - MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, - &imagefx, sizeof(imagefx)); + ret = vchiq_mmal_port_parameter_set(dev->instance, control, + MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, + &imagefx, sizeof(imagefx)); if (ret) goto exit; - ret = vchiq_mmal_port_parameter_set( - dev->instance, control, - MMAL_PARAMETER_COLOUR_EFFECT, - &dev->colourfx, sizeof(dev->colourfx)); + ret = vchiq_mmal_port_parameter_set(dev->instance, control, + MMAL_PARAMETER_COLOUR_EFFECT, + &dev->colourfx, sizeof(dev->colourfx)); } exit: diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index 5dbf8d53db09..721b15b7e13b 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -97,6 +97,13 @@ struct vchiq_arm_state { * tracked separately with the state. */ int peer_use_count; + + /* + * Flag to indicate that the first vchiq connect has made it through. + * This means that both sides should be fully ready, and we should + * be able to suspend after this point. + */ + int first_connect; }; static int @@ -273,6 +280,29 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state return 0; } +int +vchiq_platform_init_state(struct vchiq_state *state) +{ + struct vchiq_arm_state *platform_state; + + platform_state = devm_kzalloc(state->dev, sizeof(*platform_state), GFP_KERNEL); + if (!platform_state) + return -ENOMEM; + + rwlock_init(&platform_state->susp_res_lock); + + init_completion(&platform_state->ka_evt); + atomic_set(&platform_state->ka_use_count, 0); + atomic_set(&platform_state->ka_use_ack_count, 0); + atomic_set(&platform_state->ka_release_count, 0); + + platform_state->state = state; + + state->platform_state = (struct opaque_platform_state *)platform_state; + + return 0; +} + static struct vchiq_arm_state *vchiq_platform_get_arm_state(struct vchiq_state *state) { return (struct vchiq_arm_state *)state->platform_state; @@ -363,8 +393,7 @@ int vchiq_shutdown(struct vchiq_instance *instance) struct vchiq_state *state = instance->state; int ret = 0; - if (mutex_lock_killable(&state->mutex)) - return -EAGAIN; + mutex_lock(&state->mutex); /* Remove all services */ vchiq_shutdown_internal(state, instance); @@ -982,39 +1011,6 @@ exit: } int -vchiq_platform_init_state(struct vchiq_state *state) -{ - struct vchiq_arm_state *platform_state; - char threadname[16]; - - platform_state = devm_kzalloc(state->dev, sizeof(*platform_state), GFP_KERNEL); - if (!platform_state) - return -ENOMEM; - - snprintf(threadname, sizeof(threadname), "vchiq-keep/%d", - state->id); - platform_state->ka_thread = kthread_create(&vchiq_keepalive_thread_func, - (void *)state, threadname); - if (IS_ERR(platform_state->ka_thread)) { - dev_err(state->dev, "couldn't create thread %s\n", threadname); - return PTR_ERR(platform_state->ka_thread); - } - - rwlock_init(&platform_state->susp_res_lock); - - init_completion(&platform_state->ka_evt); - atomic_set(&platform_state->ka_use_count, 0); - atomic_set(&platform_state->ka_use_ack_count, 0); - atomic_set(&platform_state->ka_release_count, 0); - - platform_state->state = state; - - state->platform_state = (struct opaque_platform_state *)platform_state; - - return 0; -} - -int vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service, enum USE_TYPE_E use_type) { @@ -1329,19 +1325,37 @@ out: return ret; } -void vchiq_platform_connected(struct vchiq_state *state) -{ - struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state); - - wake_up_process(arm_state->ka_thread); -} - void vchiq_platform_conn_state_changed(struct vchiq_state *state, enum vchiq_connstate oldstate, enum vchiq_connstate newstate) { + struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state); + char threadname[16]; + dev_dbg(state->dev, "suspend: %d: %s->%s\n", state->id, get_conn_state_name(oldstate), get_conn_state_name(newstate)); + if (state->conn_state != VCHIQ_CONNSTATE_CONNECTED) + return; + + write_lock_bh(&arm_state->susp_res_lock); + if (arm_state->first_connect) { + write_unlock_bh(&arm_state->susp_res_lock); + return; + } + + arm_state->first_connect = 1; + write_unlock_bh(&arm_state->susp_res_lock); + snprintf(threadname, sizeof(threadname), "vchiq-keep/%d", + state->id); + arm_state->ka_thread = kthread_create(&vchiq_keepalive_thread_func, + (void *)state, + threadname); + if (IS_ERR(arm_state->ka_thread)) { + dev_err(state->dev, "suspend: Couldn't create thread %s\n", + threadname); + } else { + wake_up_process(arm_state->ka_thread); + } } static const struct of_device_id vchiq_of_match[] = { diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c index e7b0c800a205..e2cac0898b8f 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c @@ -3343,7 +3343,6 @@ vchiq_connect_internal(struct vchiq_state *state, struct vchiq_instance *instanc return -EAGAIN; vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED); - vchiq_platform_connected(state); complete(&state->connect); } diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h index 3b5c0618e567..9b4e766990a4 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h @@ -575,8 +575,6 @@ int vchiq_send_remote_use(struct vchiq_state *state); int vchiq_send_remote_use_active(struct vchiq_state *state); -void vchiq_platform_connected(struct vchiq_state *state); - void vchiq_platform_conn_state_changed(struct vchiq_state *state, enum vchiq_connstate oldstate, enum vchiq_connstate newstate); diff --git a/drivers/staging/vme_user/vme.c b/drivers/staging/vme_user/vme.c index 42304c9f83a2..2095de72596a 100644 --- a/drivers/staging/vme_user/vme.c +++ b/drivers/staging/vme_user/vme.c @@ -809,7 +809,7 @@ EXPORT_SYMBOL(vme_master_free); * @vdev: Pointer to VME device struct vme_dev assigned to driver instance. * @route: Required src/destination combination. * - * Request a VME DMA controller with capability to perform transfers bewteen + * Request a VME DMA controller with capability to perform transfers between * requested source/destination combination. * * Return: Pointer to VME DMA resource on success, NULL on failure. @@ -1045,7 +1045,7 @@ void vme_dma_free_attribute(struct vme_dma_attr *attributes) EXPORT_SYMBOL(vme_dma_free_attribute); /** - * vme_dma_list_add - Add enty to a VME DMA list. + * vme_dma_list_add - Add entry to a VME DMA list. * @list: Pointer to VME list. * @src: Pointer to DMA list attribute to use as source. * @dest: Pointer to DMA list attribute to use as destination. @@ -1925,7 +1925,7 @@ EXPORT_SYMBOL(vme_unregister_driver); static int vme_bus_match(struct device *dev, const struct device_driver *drv) { - struct vme_driver *vme_drv; + const struct vme_driver *vme_drv; vme_drv = container_of(drv, struct vme_driver, driver); diff --git a/drivers/staging/vme_user/vme_fake.c b/drivers/staging/vme_user/vme_fake.c index 4a59c9069605..731fbba17dfd 100644 --- a/drivers/staging/vme_user/vme_fake.c +++ b/drivers/staging/vme_user/vme_fake.c @@ -1061,7 +1061,7 @@ static int __init fake_init(void) if (geoid >= VME_MAX_SLOTS) { pr_err("VME geographical address must be between 0 and %d (exclusive), but got %d\n", - VME_MAX_SLOTS, geoid); + VME_MAX_SLOTS, geoid); return -EINVAL; } diff --git a/drivers/staging/vme_user/vme_tsi148.h b/drivers/staging/vme_user/vme_tsi148.h index db246cbc54c3..f73ac92320bb 100644 --- a/drivers/staging/vme_user/vme_tsi148.h +++ b/drivers/staging/vme_user/vme_tsi148.h @@ -1347,7 +1347,7 @@ static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C, #define TSI148_GCSR_GCTRL_LRST BIT(15) /* Local Reset */ #define TSI148_GCSR_GCTRL_SFAILEN BIT(14) /* System Fail enable */ #define TSI148_GCSR_GCTRL_BDFAILS BIT(13) /* Board Fail Status */ -#define TSI148_GCSR_GCTRL_SCON BIT(12) /* System Copntroller */ +#define TSI148_GCSR_GCTRL_SCON BIT(12) /* System Controller */ #define TSI148_GCSR_GCTRL_MEN BIT(11) /* Module Enable (READY) */ #define TSI148_GCSR_GCTRL_LMI3S BIT(7) /* Loc Monitor 3 Int Status */ |