diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c index 46bc6c5b77580..ec1d96b58c8c6 100644 --- a/drivers/media/i2c/ov5693.c +++ b/drivers/media/i2c/ov5693.c @@ -172,6 +172,46 @@ struct ov5693_device { } ctrls; }; +static void ov5693_log_stream_state(struct ov5693_device *ov5693, const char *tag, int enable) +{ + dev_dbg(ov5693->dev, + "%s: stream=%d fmt=%ux%u crop=[l=%d t=%d w=%u h=%u] binning[x=%d y=%d] inc[x_odd=%u y_odd=%u] vts=%u ctrls[vblank=%d exp=%d again=%d dgain=%d hflip=%d vflip=%d test_pattern=%d\n", + tag, enable, + ov5693->mode.format.width, ov5693->mode.format.height, + ov5693->mode.crop.left, ov5693->mode.crop.top, + ov5693->mode.crop.width, ov5693->mode.crop.height, + ov5693->mode.binning_x, ov5693->mode.binning_y, + ov5693->mode.inc_x_odd, ov5693->mode.inc_y_odd, ov5693->mode.vts, + ov5693->ctrls.vblank ? ov5693->ctrls.vblank->val : -1, + ov5693->ctrls.exposure ? ov5693->ctrls.exposure->val : -1, + ov5693->ctrls.analogue_gain ? ov5693->ctrls.analogue_gain->val : -1, + ov5693->ctrls.digital_gain ? ov5693->ctrls.digital_gain->val : -1, + ov5693->ctrls.hflip ? ov5693->ctrls.hflip->val : -1, + ov5693->ctrls.vflip ? ov5693->ctrls.vflip->val : -1, + ov5693->ctrls.test_pattern ? ov5693->ctrls.test_pattern->val : -1); +} + +static void ov5693_log_hw_state(struct ov5693_device *ov5693, const char *tag) +{ + u64 stream_reg; + int ret; + + ret = cci_read(ov5693->regmap, OV5693_SW_STREAM_REG, &stream_reg, NULL); + if (ret) { + dev_dbg(ov5693->dev, "%s: failed to read stream reg: %d\n", tag, ret); + return; + } + + dev_dbg(ov5693->dev, + "%s: stream_reg=0x%02llx hts=%u vts=%u out=%ux%u crop=[x=%u..%u y=%u..%u]\n", + tag, stream_reg, OV5693_FIXED_PPL, ov5693->mode.vts, + ov5693->mode.format.width, ov5693->mode.format.height, + ov5693->mode.crop.left, + ov5693->mode.crop.left + ov5693->mode.crop.width, + ov5693->mode.crop.top, + ov5693->mode.crop.top + ov5693->mode.crop.height); +} + static const struct cci_reg_sequence ov5693_global_regs[] = { {CCI_REG8(0x3016), 0xf0}, {CCI_REG8(0x3017), 0xf0}, @@ -631,6 +671,7 @@ static int ov5693_sensor_init(struct ov5693_device *ov5693) { int ret; + dev_dbg(ov5693->dev, "sensor_init: start\n"); ret = ov5693_sw_reset(ov5693); if (ret) return dev_err_probe(ov5693->dev, ret, @@ -643,6 +684,8 @@ static int ov5693_sensor_init(struct ov5693_device *ov5693) "global settings error\n"); ret = ov5693_mode_configure(ov5693); + if (!ret) + ov5693_log_stream_state(ov5693, "sensor_init configured mode", 0); if (ret) return dev_err_probe(ov5693->dev, ret, "mode configure error\n"); @@ -650,24 +693,32 @@ static int ov5693_sensor_init(struct ov5693_device *ov5693) ret = ov5693_enable_streaming(ov5693, false); if (ret) dev_err(ov5693->dev, "stop streaming error\n"); + else + ov5693_log_hw_state(ov5693, "sensor_init stream-off"); return ret; } static void ov5693_sensor_powerdown(struct ov5693_device *ov5693) { + dev_dbg(ov5693->dev, "powerdown: reset-gpio=%d powerdown-gpio=%d\n", + ov5693->reset ? 1 : 0, ov5693->powerdown ? 1 : 0); gpiod_set_value_cansleep(ov5693->reset, 1); gpiod_set_value_cansleep(ov5693->powerdown, 1); regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies); clk_disable_unprepare(ov5693->xvclk); + dev_dbg(ov5693->dev, "powerdown: done\n"); } static int ov5693_sensor_powerup(struct ov5693_device *ov5693) { int ret; + unsigned long xvclk_rate = clk_get_rate(ov5693->xvclk); + dev_dbg(ov5693->dev, "powerup: xvclk=%lu reset-gpio=%d powerdown-gpio=%d\n", + xvclk_rate, ov5693->reset ? 1 : 0, ov5693->powerdown ? 1 : 0); gpiod_set_value_cansleep(ov5693->reset, 1); gpiod_set_value_cansleep(ov5693->powerdown, 1); @@ -683,11 +734,13 @@ static int ov5693_sensor_powerup(struct ov5693_device *ov5693) goto fail_power; } + dev_dbg(ov5693->dev, "powerup: regulators enabled (avdd,dovdd,dvdd)\n"); gpiod_set_value_cansleep(ov5693->powerdown, 0); gpiod_set_value_cansleep(ov5693->reset, 0); usleep_range(5000, 7500); + dev_dbg(ov5693->dev, "powerup: done\n"); return 0; fail_power: @@ -738,6 +791,9 @@ static int ov5693_detect(struct ov5693_device *ov5693) u64 id; ret = cci_read(ov5693->regmap, OV5693_REG_CHIP_ID, &id, NULL); + dev_dbg(ov5693->dev, + "detect: chip-id read ret=%d id=0x%04llx expected=0x%04x\n", + ret, id, OV5693_CHIP_ID); if (ret) return ret; @@ -970,33 +1026,54 @@ static int ov5693_s_stream(struct v4l2_subdev *sd, int enable) struct ov5693_device *ov5693 = to_ov5693_sensor(sd); int ret; + dev_dbg(ov5693->dev, "s_stream: request enable=%d\n", + enable); + ov5693_log_stream_state(ov5693, "s_stream pre", enable); + if (enable) { ret = pm_runtime_resume_and_get(ov5693->dev); - if (ret) + if (ret) { + dev_err(ov5693->dev, + "s_stream: pm_runtime_resume_and_get failed: %d\n", + ret); return ret; + } mutex_lock(&ov5693->lock); ret = __v4l2_ctrl_handler_setup(&ov5693->ctrls.handler); if (ret) { + dev_err(ov5693->dev, "s_stream: ctrl setup failed: %d\n", ret); mutex_unlock(&ov5693->lock); goto err_power_down; } ret = ov5693_enable_streaming(ov5693, true); + dev_dbg(ov5693->dev, "s_stream: stream-on register write ret=%d\n", + ret); + if (!ret) + ov5693_log_hw_state(ov5693, "s_stream stream-on"); mutex_unlock(&ov5693->lock); } else { mutex_lock(&ov5693->lock); ret = ov5693_enable_streaming(ov5693, false); + dev_dbg(ov5693->dev, "s_stream: stream-off register write ret=%d\n", + ret); + if (!ret) + ov5693_log_hw_state(ov5693, "s_stream stream-off"); mutex_unlock(&ov5693->lock); } if (ret) goto err_power_down; + ov5693_log_stream_state(ov5693, "s_stream post", enable); + if (!enable) pm_runtime_put(ov5693->dev); return 0; err_power_down: + dev_err(ov5693->dev, "s_stream: failed enable=%d ret=%d\n", + enable, ret); pm_runtime_put_noidle(ov5693->dev); return ret; } @@ -1236,6 +1313,11 @@ static int ov5693_check_hwcfg(struct ov5693_device *ov5693) if (ret) return ret; + dev_dbg(ov5693->dev, + "check_hwcfg: lanes=%u nr_of_link_frequencies=%u\n", + bus_cfg.bus.mipi_csi2.num_data_lanes, + bus_cfg.nr_of_link_frequencies); + if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) { dev_err(ov5693->dev, "only a 2-lane CSI2 config is supported"); ret = -EINVAL; @@ -1248,9 +1330,13 @@ static int ov5693_check_hwcfg(struct ov5693_device *ov5693) goto out_free_bus_cfg; } - for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) + for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { + dev_dbg(ov5693->dev, + "check_hwcfg: link_frequencies[%u]=%lld\n", + i, bus_cfg.link_frequencies[i]); if (bus_cfg.link_frequencies[i] == OV5693_LINK_FREQ_419_2MHZ) break; + } if (i == bus_cfg.nr_of_link_frequencies) { dev_err(ov5693->dev, "supported link freq %ull not found\n", @@ -1285,6 +1371,8 @@ static int ov5693_probe(struct i2c_client *client) if (ret) return ret; + dev_dbg(&client->dev, "probe: hwcfg validated\n"); + mutex_init(&ov5693->lock); v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops); @@ -1340,6 +1428,8 @@ static int ov5693_probe(struct i2c_client *client) if (ret) goto err_powerdown; + dev_dbg(&client->dev, "probe: sensor detected and runtime-pm setup starting\n"); + pm_runtime_set_active(&client->dev); pm_runtime_get_noresume(&client->dev); pm_runtime_enable(&client->dev); diff --git a/drivers/media/pci/intel/Kconfig b/drivers/media/pci/intel/Kconfig index d9fcddce028bf..84211d8f86b1e 100644 --- a/drivers/media/pci/intel/Kconfig +++ b/drivers/media/pci/intel/Kconfig @@ -19,3 +19,67 @@ config IPU_BRIDGE - Microsoft Surface models (except Surface Pro 3) - The Lenovo Miix line (for example the 510, 520, 710 and 720) - Dell 7285 + +config VIDEO_INTEL_IPU + tristate "Intel IPU driver" + depends on ACPI + select IOMMU_API + select IOMMU_IOVA + select X86_DEV_DMA_OPS if X86 + select VIDEOBUF2_DMA_CONTIG + select PHYS_ADDR_T_64BIT + select COMMON_CLK + help + Main driver for Intel Image Processing Unit. Say Y here. + +choice + prompt "Intel IPU generation type" + depends on VIDEO_INTEL_IPU + default VIDEO_INTEL_IPU4P + +config VIDEO_INTEL_IPU4 + bool "Compile for IPU4 driver" + help + Select IPU4 for Intel Apollo Lake (PCI ID 8086:5a88): + Celeron N3350, Pentium N4200 or Atom E3900 Series Imaging Unit. + +config VIDEO_INTEL_IPU4P + bool "Compile for IPU4P driver" + help + Select IPU4P for Intel Ice Lake (PCI ID 8086 8a19). + Supported systems include: + - Surface Pro 7 + - Surface Book 3 + - Surface Laptop 3 + - Dell XPS 13 7390 2-in-1 + +endchoice + +choice + prompt "Intel IPU hardware platform type" + depends on VIDEO_INTEL_IPU + default VIDEO_INTEL_IPU_SOC + +config VIDEO_INTEL_IPU_SOC + bool "Compile for SOC" + help + Select for SOC platform + +endchoice + +config VIDEO_INTEL_IPU_FW_LIB + bool "Compile firmware library" + depends on VIDEO_INTEL_IPU + default y + help + If selected, the firmware hostlib css will be compiled + +config VIDEO_INTEL_IPU_WERROR + bool "Force GCC to throw errors instead of warnings when compiling" + depends on VIDEO_INTEL_IPU + depends on EXPERT + depends on !COMPILE_TEST + default n + help + Adds -Werror to the build flags for the Intel IPU module. + Recommended for driver developers only. diff --git a/drivers/media/pci/intel/Makefile b/drivers/media/pci/intel/Makefile index 3a2cc65671597..90557e8d3556e 100644 --- a/drivers/media/pci/intel/Makefile +++ b/drivers/media/pci/intel/Makefile @@ -5,4 +5,17 @@ obj-$(CONFIG_IPU_BRIDGE) += ipu-bridge.o obj-y += ipu3/ obj-y += ivsc/ +# force check the compile warning to make sure zero warnings +# note we may have build issue when gcc upgraded. +ccflags-y := -Wno-error=uninitialized +subdir-ccflags-y += $(call cc-disable-warning, unused-parameter) +subdir-ccflags-y += $(call cc-disable-warning, implicit-fallthrough) +subdir-ccflags-y += $(call cc-disable-warning, missing-field-initializers) +subdir-ccflags-y += $(call cc-disable-warning, int-conversion) +subdir-ccflags-y += $(call cc-disable-warning, enum-conversion) +subdir-ccflags-y += $(call cc-disable-warning, uninitialized) +subdir-ccflags-$(CONFIG_VIDEO_INTEL_IPU_WERROR) += -Werror + obj-$(CONFIG_VIDEO_INTEL_IPU6) += ipu6/ +obj-$(CONFIG_VIDEO_INTEL_IPU4) += ipu4/ +obj-$(CONFIG_VIDEO_INTEL_IPU4P) += ipu4/ diff --git a/drivers/media/pci/intel/ipu-bus.c b/drivers/media/pci/intel/ipu-bus.c new file mode 100644 index 0000000000000..7d48bd3a7dd18 --- /dev/null +++ b/drivers/media/pci/intel/ipu-bus.c @@ -0,0 +1,417 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipu.h" +#include "ipu-platform.h" +#include "ipu-dma.h" +#include "ipu-mmu.h" + +#ifdef CONFIG_PM +static struct bus_type ipu_bus; + +static int bus_pm_suspend_child_dev(struct device *dev, void *p) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct device *parent = (struct device *)p; + + if (!ipu_bus_get_drvdata(adev)) + return 0; /* Device not attached to any driver yet */ + + if (dev->parent != parent || adev->ctrl) + return 0; + + return pm_generic_runtime_suspend(dev); +} + +static int bus_pm_runtime_suspend(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + int rval; + + if (!adev->ctrl) { + dev_dbg(dev, "has no buttress control info, bailing out\n"); + return 0; + } + + rval = bus_for_each_dev(&ipu_bus, NULL, dev, bus_pm_suspend_child_dev); + if (rval) { + dev_err(dev, "failed to suspend child device\n"); + return rval; + } + + rval = pm_generic_runtime_suspend(dev); + if (rval) + return rval; + + rval = ipu_buttress_power(dev, adev->ctrl, false); + dev_dbg(dev, "%s: buttress power down %d\n", __func__, rval); + if (!rval) + return 0; + + dev_err(dev, "power down failed!\n"); + + /* Powering down failed, attempt to resume device now */ + rval = pm_generic_runtime_resume(dev); + if (!rval) + return -EBUSY; + + return -EIO; +} + +static int bus_pm_resume_child_dev(struct device *dev, void *p) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct device *parent = (struct device *)p; + int r; + + if (!ipu_bus_get_drvdata(adev)) + return 0; /* Device not attached to any driver yet */ + + if (dev->parent != parent || adev->ctrl) + return 0; + + mutex_lock(&adev->resume_lock); + r = pm_generic_runtime_resume(dev); + mutex_unlock(&adev->resume_lock); + return r; +} + +static int bus_pm_runtime_resume(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + int rval; + + if (!adev->ctrl) { + dev_dbg(dev, "has no buttress control info, bailing out\n"); + return 0; + } + + rval = ipu_buttress_power(dev, adev->ctrl, true); + dev_dbg(dev, "%s: buttress power up %d\n", __func__, rval); + if (rval) + return rval; + + rval = pm_generic_runtime_resume(dev); + dev_dbg(dev, "%s: resume %d\n", __func__, rval); + if (rval) + goto out_err; + + /* + * It needs to be ensured that IPU child devices' resume/suspend are + * called only when the child devices' power is turned on/off by the + * parent device here. Therefore, children's suspend/resume are called + * from here, because that is the only way to guarantee it. + */ + rval = bus_for_each_dev(&ipu_bus, NULL, dev, bus_pm_resume_child_dev); + if (rval) { + dev_err(dev, "failed to resume child device - reset it\n"); + + rval = pm_generic_runtime_suspend(dev); + dev_dbg(dev, "%s: suspend %d\n", __func__, rval); + + rval = ipu_buttress_power(dev, adev->ctrl, false); + dev_dbg(dev, "%s: buttress power down %d\n", __func__, rval); + if (rval) + return rval; + + usleep_range(1000, 1100); + + rval = ipu_buttress_power(dev, adev->ctrl, true); + dev_dbg(dev, "%s: buttress power up %d\n", __func__, rval); + if (rval) + return rval; + + rval = pm_generic_runtime_resume(dev); + dev_dbg(dev, "%s: re-resume %d\n", __func__, rval); + if (rval) + goto out_err; + + rval = bus_for_each_dev(&ipu_bus, NULL, dev, + bus_pm_resume_child_dev); + + if (rval) { + dev_err(dev, "resume retry failed\n"); + goto out_err; + } + } + + return 0; + +out_err: + if (adev->ctrl) + ipu_buttress_power(dev, adev->ctrl, false); + + return -EBUSY; +} + +static const struct dev_pm_ops ipu_bus_pm_ops = { + .runtime_suspend = bus_pm_runtime_suspend, + .runtime_resume = bus_pm_runtime_resume, +}; + +#define IPU_BUS_PM_OPS (&ipu_bus_pm_ops) +#else +#define IPU_BUS_PM_OPS NULL +#endif + +static int ipu_bus_match(struct device *dev, const struct device_driver *drv) +{ + struct ipu_bus_driver *adrv = to_ipu_bus_driver(drv); + + dev_dbg(dev, "bus match: \"%s\" --- \"%s\"\n", dev_name(dev), + adrv->wanted); + + return !strncmp(dev_name(dev), adrv->wanted, strlen(adrv->wanted)); +} + +static struct ipu_dma_mapping *alloc_dma_mapping(struct device *dev) +{ + struct ipu_dma_mapping *dmap; + + dmap = kzalloc(sizeof(*dmap), GFP_KERNEL); + if (!dmap) + return NULL; + + dmap->mmu_info = ipu_mmu_alloc(); + if (!dmap->mmu_info) { + kfree(dmap); + return NULL; + } + + init_iova_domain(&dmap->iovad, SZ_4K, 1); + + dmap->mmu_info->dmap = dmap; + + kref_init(&dmap->ref); + + pr_debug("alloc mapping\n"); + + iova_cache_get(); + + return dmap; +} + +static void free_dma_mapping(struct ipu_mmu *mmu) +{ + struct ipu_dma_mapping *dmap = mmu->dmap; + + ipu_mmu_destroy(dmap->mmu_info); + mmu->set_mapping(mmu, NULL); + iova_cache_put(); + put_iova_domain(&dmap->iovad); + kfree(dmap); +} + +static int ipu_bus_probe(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_bus_driver *adrv = to_ipu_bus_driver(dev->driver); + struct ipu_mmu *mmu; + struct ipu_dma_mapping *dmap; + int rval; + + dev_dbg(dev, "bus probe dev %s\n", dev_name(dev)); + + if (adev->iommu) { + dev_dbg(dev, "alloc dma mapping\n"); + mmu = ipu_bus_get_drvdata(to_ipu_bus_device(adev->iommu)); + + dmap = alloc_dma_mapping(dev); + if (!dmap) { + dev_err(dev, "%s: can't alloc dma mapping\n", __func__); + rval = -ENOMEM; + goto out_err; + } + + /* + * Turn mmu on and off synchronously. Otherwise it may still + * be on at psys / isys probing phase and that may cause + * problems on development environments. + */ + pm_runtime_get_sync(dev); + mmu->set_mapping(mmu, dmap); + pm_runtime_put_sync(dev); + } + + adev->adrv = adrv; + if (adrv->probe) { + rval = adrv->probe(adev); + if (!rval) { + /* + * If the device power, after probe, is enabled + * (from the parent device), its resume needs to + * be called to initialize the device properly. + */ + if (!adev->ctrl && + !pm_runtime_status_suspended(dev->parent)) { + mutex_lock(&adev->resume_lock); + pm_generic_runtime_resume(dev); + mutex_unlock(&adev->resume_lock); + } + } + } else { + rval = -ENODEV; + } + + if (rval) + goto out_err; + + return 0; + +out_err: + ipu_bus_set_drvdata(adev, NULL); + adev->adrv = NULL; + return rval; +} + +static void ipu_bus_remove(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_bus_driver *adrv = to_ipu_bus_driver(dev->driver); + struct ipu_bus_device *adev_iommu = to_ipu_bus_device(adev->iommu); + struct ipu_mmu *mmu = ipu_bus_get_drvdata(adev_iommu); + + if (adrv->remove) + adrv->remove(adev); + + if (adev->iommu) + free_dma_mapping(mmu); +} + +static struct bus_type ipu_bus = { + .name = IPU_BUS_NAME, + .match = ipu_bus_match, + .probe = ipu_bus_probe, + .remove = ipu_bus_remove, + .pm = IPU_BUS_PM_OPS, +}; + +static struct mutex ipu_bus_mutex; + +static void ipu_bus_release(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + + kfree(adev); +} + +struct ipu_bus_device *ipu_bus_add_device(struct pci_dev *pdev, + struct device *parent, void *pdata, + struct device *iommu, + struct ipu_buttress_ctrl *ctrl, + char *name, unsigned int nr) +{ + struct ipu_bus_device *adev; + struct ipu_device *isp = pci_get_drvdata(pdev); + int rval; + + adev = kzalloc(sizeof(*adev), GFP_KERNEL); + if (!adev) + return ERR_PTR(-ENOMEM); + + adev->dev.parent = parent; + adev->dev.bus = &ipu_bus; + adev->dev.release = ipu_bus_release; + adev->dev.dma_ops = &ipu_dma_ops; + adev->dma_mask = DMA_BIT_MASK(isp->secure_mode ? + IPU_MMU_ADDRESS_BITS : + IPU_MMU_ADDRESS_BITS_NON_SECURE); + adev->dev.dma_mask = &adev->dma_mask; + adev->dev.coherent_dma_mask = adev->dma_mask; + adev->iommu = iommu; + adev->ctrl = ctrl; + adev->pdata = pdata; + adev->isp = isp; + mutex_init(&adev->resume_lock); + dev_set_name(&adev->dev, "%s%d", name, nr); + + rval = device_register(&adev->dev); + if (rval) { + put_device(&adev->dev); + return ERR_PTR(rval); + } + + mutex_lock(&ipu_bus_mutex); + list_add(&adev->list, &isp->devices); + mutex_unlock(&ipu_bus_mutex); + + return adev; +} + +void ipu_bus_del_devices(struct pci_dev *pdev) +{ + struct ipu_device *isp = pci_get_drvdata(pdev); + struct ipu_bus_device *adev, *save; + + mutex_lock(&ipu_bus_mutex); + + list_for_each_entry_safe(adev, save, &isp->devices, list) { + list_del(&adev->list); + device_unregister(&adev->dev); + } + + mutex_unlock(&ipu_bus_mutex); +} + +int ipu_bus_register_driver(struct ipu_bus_driver *adrv) +{ + adrv->drv.bus = &ipu_bus; + return driver_register(&adrv->drv); +} +EXPORT_SYMBOL(ipu_bus_register_driver); + +int ipu_bus_unregister_driver(struct ipu_bus_driver *adrv) +{ + driver_unregister(&adrv->drv); + return 0; +} +EXPORT_SYMBOL(ipu_bus_unregister_driver); + +int ipu_bus_register(void) +{ + mutex_init(&ipu_bus_mutex); + return bus_register(&ipu_bus); +} +EXPORT_SYMBOL(ipu_bus_register); + +void ipu_bus_unregister(void) +{ + mutex_destroy(&ipu_bus_mutex); + return bus_unregister(&ipu_bus); +} +EXPORT_SYMBOL(ipu_bus_unregister); + +static int flr_rpm_recovery(struct device *dev, void *p) +{ + dev_dbg(dev, "FLR recovery call\n"); + /* + * We are not necessarily going through device from child to + * parent. runtime PM refuses to change state for parent if the child + * is still active. At FLR (full reset for whole IPU) that doesn't + * matter. Everything has been power gated by HW during the FLR cycle + * and we are just cleaning up SW state. Thus, ignore child during + * set_suspended. + */ + pm_suspend_ignore_children(dev, true); + pm_runtime_set_suspended(dev); + pm_suspend_ignore_children(dev, false); + + return 0; +} + +int ipu_bus_flr_recovery(void) +{ + bus_for_each_dev(&ipu_bus, NULL, NULL, flr_rpm_recovery); + return 0; +} +EXPORT_SYMBOL(ipu_bus_flr_recovery); diff --git a/drivers/media/pci/intel/ipu-bus.h b/drivers/media/pci/intel/ipu-bus.h new file mode 100644 index 0000000000000..5d47d03b06c47 --- /dev/null +++ b/drivers/media/pci/intel/ipu-bus.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_BUS_H +#define IPU_BUS_H + +#include +#include +#include +#include +#include +#include + +#define IPU_BUS_NAME IPU_NAME "-bus" + +struct ipu_buttress_ctrl; +struct ipu_subsystem_trace_config; + +struct ipu_bus_device { + struct device dev; + struct list_head list; + void *pdata; + struct ipu_bus_driver *adrv; + struct device *iommu; + struct iommu_device iommu_dev; + struct ipu_device *isp; + struct ipu_subsystem_trace_config *trace_cfg; + struct ipu_buttress_ctrl *ctrl; + u64 dma_mask; + /* Protect runtime_resume calls on the dev */ + struct mutex resume_lock; +}; + +#define to_ipu_bus_device(_dev) container_of(_dev, struct ipu_bus_device, dev) + +struct ipu_bus_driver { + struct device_driver drv; + char wanted[20]; + int (*probe)(struct ipu_bus_device *adev); + void (*remove)(struct ipu_bus_device *adev); + irqreturn_t (*isr)(struct ipu_bus_device *adev); + irqreturn_t (*isr_threaded)(struct ipu_bus_device *adev); + bool wake_isr_thread; +}; + +#define to_ipu_bus_driver(_drv) container_of(_drv, struct ipu_bus_driver, drv) + +struct ipu_bus_device *ipu_bus_add_device(struct pci_dev *pdev, + struct device *parent, void *pdata, + struct device *iommu, + struct ipu_buttress_ctrl *ctrl, + char *name, unsigned int nr); +void ipu_bus_del_devices(struct pci_dev *pdev); + +int ipu_bus_register_driver(struct ipu_bus_driver *adrv); +int ipu_bus_unregister_driver(struct ipu_bus_driver *adrv); + +int ipu_bus_register(void); +void ipu_bus_unregister(void); + +#define module_ipu_bus_driver(drv) \ + module_driver(drv, ipu_bus_register_driver, \ + ipu_bus_unregister_driver) + +#define ipu_bus_set_drvdata(adev, data) dev_set_drvdata(&(adev)->dev, data) +#define ipu_bus_get_drvdata(adev) dev_get_drvdata(&(adev)->dev) + +int ipu_bus_flr_recovery(void); + +#endif diff --git a/drivers/media/pci/intel/ipu-buttress.c b/drivers/media/pci/intel/ipu-buttress.c new file mode 100644 index 0000000000000..c5d5247eb5622 --- /dev/null +++ b/drivers/media/pci/intel/ipu-buttress.c @@ -0,0 +1,1776 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ipu.h" +#include "ipu-bus.h" +#include "ipu-buttress.h" +#include "ipu-platform-buttress-regs.h" +#include "ipu-cpd.h" +#define CREATE_TRACE_POINTS +#define IPU_PERF_REG_TRACE +#include "ipu-trace-event.h" + +#define BOOTLOADER_STATUS_OFFSET 0x8000 +#define BOOTLOADER_MAGIC_KEY 0xb00710ad + +#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 10 + +#define BUTTRESS_CSE_BOOTLOAD_TIMEOUT 5000000 +#define BUTTRESS_CSE_AUTHENTICATE_TIMEOUT 10000000 +#define BUTTRESS_CSE_FWRESET_TIMEOUT 100000 + +#define BUTTRESS_IPC_TX_TIMEOUT 1000 +#define BUTTRESS_IPC_RESET_TIMEOUT 2000 +#define BUTTRESS_IPC_RX_TIMEOUT 1000 +#define BUTTRESS_IPC_VALIDITY_TIMEOUT 1000000 +#define BUTTRESS_TSC_SYNC_TIMEOUT 5000 + +#define IPU_BUTTRESS_TSC_LIMIT 500 /* 26 us @ 19.2 MHz */ +#define IPU_BUTTRESS_TSC_RETRY 10 + +#define BUTTRESS_CSE_IPC_RESET_RETRY 4 + +#define BUTTRESS_IPC_CMD_SEND_RETRY 1 + +static const struct ipu_buttress_sensor_clk_freq sensor_clk_freqs[] = { + {6750000, BUTTRESS_SENSOR_CLK_FREQ_6P75MHZ}, + {8000000, BUTTRESS_SENSOR_CLK_FREQ_8MHZ}, + {9600000, BUTTRESS_SENSOR_CLK_FREQ_9P6MHZ}, + {12000000, BUTTRESS_SENSOR_CLK_FREQ_12MHZ}, + {13600000, BUTTRESS_SENSOR_CLK_FREQ_13P6MHZ}, + {14400000, BUTTRESS_SENSOR_CLK_FREQ_14P4MHZ}, + {15800000, BUTTRESS_SENSOR_CLK_FREQ_15P8MHZ}, + {16200000, BUTTRESS_SENSOR_CLK_FREQ_16P2MHZ}, + {17300000, BUTTRESS_SENSOR_CLK_FREQ_17P3MHZ}, + {18600000, BUTTRESS_SENSOR_CLK_FREQ_18P6MHZ}, + {19200000, BUTTRESS_SENSOR_CLK_FREQ_19P2MHZ}, + {24000000, BUTTRESS_SENSOR_CLK_FREQ_24MHZ}, + {26000000, BUTTRESS_SENSOR_CLK_FREQ_26MHZ}, + {27000000, BUTTRESS_SENSOR_CLK_FREQ_27MHZ} +}; + +static const u32 ipu_adev_irq_mask[] = { + BUTTRESS_ISR_IS_IRQ, BUTTRESS_ISR_PS_IRQ +}; + +int ipu_buttress_ipc_reset(struct ipu_device *isp, struct ipu_buttress_ipc *ipc) +{ + struct ipu_buttress *b = &isp->buttress; + unsigned int retries = BUTTRESS_IPC_RESET_TIMEOUT; + u32 val = 0, csr_in_clr; + + if (!isp->secure_mode) { + dev_info(&isp->pdev->dev, "Skip ipc reset for non-secure mode"); + 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; + + while (retries--) { + usleep_range(400, 500); + val = readl(isp->base + ipc->csr_in); + switch (val) { + case (ENTRY | EXIT): + case (ENTRY | EXIT | QUERY): + dev_dbg(&isp->pdev->dev, + "%s:%s & %s\n", __func__, + "IPC_PEER_COMP_ACTIONS_RST_PHASE1", + "IPC_PEER_COMP_ACTIONS_RST_PHASE2"); + /* + * 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): + dev_dbg(&isp->pdev->dev, + "%s:IPC_PEER_COMP_ACTIONS_RST_PHASE1\n", + __func__); + /* + * 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): + dev_dbg(&isp->pdev->dev, + "%s: IPC_PEER_COMP_ACTIONS_RST_PHASE2\n", + __func__); + /* + * 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(&isp->pdev->dev, + "%s: RST_PHASE2 retry csr_in = %x\n", + __func__, val); + break; + } + mutex_unlock(&b->ipc_mutex); + return 0; + case QUERY: + dev_dbg(&isp->pdev->dev, + "%s: %s\n", __func__, + "IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE"); + /* + * 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(&isp->pdev->dev, + "%s: unexpected CSR 0x%x\n", + __func__, val); + break; + } + } + + mutex_unlock(&b->ipc_mutex); + dev_err(&isp->pdev->dev, "Timed out while waiting for CSE\n"); + + return -ETIMEDOUT; +} + +static void +ipu_buttress_ipc_validity_close(struct ipu_device *isp, + struct ipu_buttress_ipc *ipc) +{ + /* Set bit 5 in CSE CSR */ + writel(BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ, + isp->base + ipc->csr_out); +} + +static int +ipu_buttress_ipc_validity_open(struct ipu_device *isp, + struct ipu_buttress_ipc *ipc) +{ + unsigned int mask = BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID; + unsigned int tout = BUTTRESS_IPC_VALIDITY_TIMEOUT; + void __iomem *addr; + int ret; + u32 val; + + /* Set bit 3 in CSE CSR */ + 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, tout); + if (ret) { + val = readl(addr); + 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 ipu_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); +} + +int +ipu_buttress_ipc_send_bulk(struct ipu_device *isp, + enum ipu_buttress_ipc_domain ipc_domain, + struct ipu_ipc_buttress_bulk_msg *msgs, u32 size) +{ + struct ipu_buttress *b = &isp->buttress; + struct ipu_buttress_ipc *ipc; + unsigned long tx_timeout_jiffies, rx_timeout_jiffies; + u32 val; + int ret; + int tout; + unsigned int i, retry = BUTTRESS_IPC_CMD_SEND_RETRY; + + ipc = ipc_domain == IPU_BUTTRESS_IPC_CSE ? &b->cse : &b->ish; + + mutex_lock(&b->ipc_mutex); + + ret = ipu_buttress_ipc_validity_open(isp, ipc); + if (ret) { + dev_err(&isp->pdev->dev, "IPC validity open failed\n"); + goto out; + } + + tx_timeout_jiffies = msecs_to_jiffies(BUTTRESS_IPC_TX_TIMEOUT); + rx_timeout_jiffies = msecs_to_jiffies(BUTTRESS_IPC_RX_TIMEOUT); + + for (i = 0; i < size; i++) { + reinit_completion(&ipc->send_complete); + if (msgs[i].require_resp) + reinit_completion(&ipc->recv_complete); + + dev_dbg(&isp->pdev->dev, "bulk IPC command: 0x%x\n", + msgs[i].cmd); + writel(msgs[i].cmd, isp->base + ipc->data0_out); + + val = 1 << BUTTRESS_IU2CSEDB0_BUSY_SHIFT | msgs[i].cmd_size; + + writel(val, isp->base + ipc->db0_out); + + tout = wait_for_completion_timeout(&ipc->send_complete, + tx_timeout_jiffies); + if (!tout) { + dev_err(&isp->pdev->dev, "send IPC response timeout\n"); + if (!retry--) { + ret = -ETIMEDOUT; + goto out; + } + + /* + * WORKAROUND: Sometimes CSE is not + * responding on first try, try again. + */ + writel(0, isp->base + ipc->db0_out); + i--; + continue; + } + + retry = BUTTRESS_IPC_CMD_SEND_RETRY; + + if (!msgs[i].require_resp) + continue; + + tout = wait_for_completion_timeout(&ipc->recv_complete, + rx_timeout_jiffies); + if (!tout) { + dev_err(&isp->pdev->dev, "recv IPC response timeout\n"); + ret = -ETIMEDOUT; + goto out; + } + + if (ipc->nack_mask && + (ipc->recv_data & ipc->nack_mask) == ipc->nack) { + dev_err(&isp->pdev->dev, + "IPC NACK for cmd 0x%x\n", msgs[i].cmd); + ret = -ENODEV; + goto out; + } + + if (ipc->recv_data != msgs[i].expected_resp) { + dev_err(&isp->pdev->dev, + "expected resp: 0x%x, IPC response: 0x%x ", + msgs[i].expected_resp, ipc->recv_data); + ret = -EIO; + goto out; + } + } + + dev_dbg(&isp->pdev->dev, "bulk IPC commands completed\n"); + +out: + ipu_buttress_ipc_validity_close(isp, ipc); + mutex_unlock(&b->ipc_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(ipu_buttress_ipc_send_bulk); + +static int +ipu_buttress_ipc_send(struct ipu_device *isp, + enum ipu_buttress_ipc_domain ipc_domain, + u32 ipc_msg, u32 size, bool require_resp, + u32 expected_resp) +{ + struct ipu_ipc_buttress_bulk_msg msg = { + .cmd = ipc_msg, + .cmd_size = size, + .require_resp = require_resp, + .expected_resp = expected_resp, + }; + + return ipu_buttress_ipc_send_bulk(isp, ipc_domain, &msg, 1); +} + +static irqreturn_t ipu_buttress_call_isr(struct ipu_bus_device *adev) +{ + irqreturn_t ret = IRQ_WAKE_THREAD; + + if (!adev || !adev->adrv) + return IRQ_NONE; + + if (adev->adrv->isr) + ret = adev->adrv->isr(adev); + + if (ret == IRQ_WAKE_THREAD && !adev->adrv->isr_threaded) + ret = IRQ_NONE; + + adev->adrv->wake_isr_thread = (ret == IRQ_WAKE_THREAD); + + return ret; +} + +irqreturn_t ipu_buttress_isr(int irq, void *isp_ptr) +{ + struct ipu_device *isp = isp_ptr; + struct ipu_bus_device *adev[] = { isp->isys, isp->psys }; + struct ipu_buttress *b = &isp->buttress; + irqreturn_t ret = IRQ_NONE; + u32 disable_irqs = 0; + u32 irq_status; +#ifdef CONFIG_VIDEO_INTEL_IPU4 + u32 reg_irq_sts = BUTTRESS_REG_ISR_ENABLED_STATUS; +#else + u32 reg_irq_sts = BUTTRESS_REG_ISR_STATUS; +#endif + unsigned int i; + + dev_dbg(&isp->pdev->dev, "isr: Buttress interrupt handler\n"); + + pm_runtime_get(&isp->pdev->dev); + + if (!pm_runtime_active(&isp->pdev->dev)) { + irq_status = readl(isp->base + reg_irq_sts); + writel(irq_status, isp->base + BUTTRESS_REG_ISR_CLEAR); + pm_runtime_put(&isp->pdev->dev); + return IRQ_HANDLED; + } + + trace_ipu_perf_reg(BUTTRESS_REG_IS_FREQ_CTL, + readl(isp->base + BUTTRESS_REG_IS_FREQ_CTL)); + trace_ipu_perf_reg(BUTTRESS_REG_PS_FREQ_CTL, + readl(isp->base + BUTTRESS_REG_PS_FREQ_CTL)); + + irq_status = readl(isp->base + reg_irq_sts); + if (!irq_status) { + pm_runtime_put(&isp->pdev->dev); + return IRQ_NONE; + } + + do { + writel(irq_status, isp->base + BUTTRESS_REG_ISR_CLEAR); + + for (i = 0; i < ARRAY_SIZE(ipu_adev_irq_mask); i++) { + if (irq_status & ipu_adev_irq_mask[i]) { + irqreturn_t r = ipu_buttress_call_isr(adev[i]); + + if (r == IRQ_WAKE_THREAD) { + ret = IRQ_WAKE_THREAD; + disable_irqs |= ipu_adev_irq_mask[i]; + } else if (ret == IRQ_NONE && r == IRQ_HANDLED) { + ret = IRQ_HANDLED; + } + } + } + + if (irq_status & (BUTTRESS_ISR_IPC_FROM_CSE_IS_WAITING | + BUTTRESS_ISR_IPC_FROM_ISH_IS_WAITING | + BUTTRESS_ISR_IPC_EXEC_DONE_BY_CSE | + BUTTRESS_ISR_IPC_EXEC_DONE_BY_ISH | + BUTTRESS_ISR_SAI_VIOLATION) && + ret == IRQ_NONE) + ret = IRQ_HANDLED; + + if (irq_status & BUTTRESS_ISR_IPC_FROM_CSE_IS_WAITING) { + dev_dbg(&isp->pdev->dev, + "BUTTRESS_ISR_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_ISR_IPC_FROM_ISH_IS_WAITING) { + dev_dbg(&isp->pdev->dev, + "BUTTRESS_ISR_IPC_FROM_ISH_IS_WAITING\n"); + ipu_buttress_ipc_recv(isp, &b->ish, &b->ish.recv_data); + complete(&b->ish.recv_complete); + } + + if (irq_status & BUTTRESS_ISR_IPC_EXEC_DONE_BY_CSE) { + dev_dbg(&isp->pdev->dev, + "BUTTRESS_ISR_IPC_EXEC_DONE_BY_CSE\n"); + complete(&b->cse.send_complete); + } + + if (irq_status & BUTTRESS_ISR_IPC_EXEC_DONE_BY_ISH) { + dev_dbg(&isp->pdev->dev, + "BUTTRESS_ISR_IPC_EXEC_DONE_BY_CSE\n"); + complete(&b->ish.send_complete); + } + + if (irq_status & BUTTRESS_ISR_SAI_VIOLATION) { + dev_err(&isp->pdev->dev, + "BUTTRESS_ISR_SAI_VIOLATION\n"); + WARN_ON(1); + } + + irq_status = readl(isp->base + reg_irq_sts); + } while (irq_status && !isp->flr_done); + + if (disable_irqs) + writel(BUTTRESS_IRQS & ~disable_irqs, + isp->base + BUTTRESS_REG_ISR_ENABLE); + + pm_runtime_put(&isp->pdev->dev); + + return ret; +} + +irqreturn_t ipu_buttress_isr_threaded(int irq, void *isp_ptr) +{ + struct ipu_device *isp = isp_ptr; + struct ipu_bus_device *adev[] = { isp->isys, isp->psys }; + irqreturn_t ret = IRQ_NONE; + unsigned int i; + + dev_dbg(&isp->pdev->dev, "isr: Buttress threaded interrupt handler\n"); + + for (i = 0; i < ARRAY_SIZE(ipu_adev_irq_mask); i++) { + if (adev[i] && adev[i]->adrv && + adev[i]->adrv->wake_isr_thread && + adev[i]->adrv->isr_threaded(adev[i]) == IRQ_HANDLED) + ret = IRQ_HANDLED; + } + + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_ISR_ENABLE); + + return ret; +} + +int ipu_buttress_power(struct device *dev, + struct ipu_buttress_ctrl *ctrl, bool on) +{ + struct ipu_device *isp = to_ipu_bus_device(dev)->isp; + u32 pwr_sts, val; + int ret = 0; + + if (!ctrl) + return 0; + + /* Until FLR completion nothing is expected to work */ + if (isp->flr_done) + return 0; + + mutex_lock(&isp->buttress.power_mutex); + + if (!on) { + val = 0; + pwr_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift; + } else { + val = 1 << BUTTRESS_FREQ_CTL_START_SHIFT + | ctrl->divisor << ctrl->divisor_shift + | ctrl->qos_floor << BUTTRESS_FREQ_CTL_QOS_FLOOR_SHIFT; + + pwr_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift; + } + + writel(val, isp->base + ctrl->freq_ctl); + + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATE, + val, ((val & ctrl->pwr_sts_mask) == pwr_sts), + 100, BUTTRESS_POWER_TIMEOUT); + if (ret) + dev_err(&isp->pdev->dev, + "Change power status timeout with 0x%x\n", val); + + ctrl->started = !ret && on; + + trace_ipu_perf_reg(BUTTRESS_REG_IS_FREQ_CTL, + readl(isp->base + BUTTRESS_REG_IS_FREQ_CTL)); + trace_ipu_perf_reg(BUTTRESS_REG_PS_FREQ_CTL, + readl(isp->base + BUTTRESS_REG_PS_FREQ_CTL)); + + mutex_unlock(&isp->buttress.power_mutex); + + return ret; +} + +static bool secure_mode_enable = 1; +module_param(secure_mode_enable, bool, 0660); +MODULE_PARM_DESC(secure_mode, "IPU secure mode enable"); + +void ipu_buttress_set_secure_mode(struct ipu_device *isp) +{ + u8 retry = 100; + u32 val, read; + + /* + * HACK to disable possible secure mode. This can be + * reverted when CSE is disabling the secure mode + */ + read = readl(isp->base + BUTTRESS_REG_SECURITY_CTL); + + if (secure_mode_enable) + val = read |= 1 << BUTTRESS_SECURITY_CTL_FW_SECURE_MODE_SHIFT; + else + val = read & ~(1 << BUTTRESS_SECURITY_CTL_FW_SECURE_MODE_SHIFT); + + if (val == read) + return; + + writel(val, isp->base + BUTTRESS_REG_SECURITY_CTL); + + /* In B0, for some registers in buttress, because of a hw bug, write + * might not succeed at first attempt. Write twice until the + * write is successful + */ + writel(val, isp->base + BUTTRESS_REG_SECURITY_CTL); + + while (retry--) { + read = readl(isp->base + BUTTRESS_REG_SECURITY_CTL); + if (read == val) + break; + + writel(val, isp->base + BUTTRESS_REG_SECURITY_CTL); + + if (retry == 0) + dev_err(&isp->pdev->dev, + "update security control register failed\n"); + } +} +EXPORT_SYMBOL_GPL(ipu_buttress_set_secure_mode); + +bool ipu_buttress_get_secure_mode(struct ipu_device *isp) +{ + u32 val; + + val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL); + + return val & (1 << BUTTRESS_SECURITY_CTL_FW_SECURE_MODE_SHIFT); +} + +bool ipu4_buttress_auth_done(struct ipu_device *isp) +{ + u32 val; + + if (!isp->secure_mode) + return 1; + + val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL); + + return (val & BUTTRESS_SECURITY_CTL_FW_SETUP_MASK) == + BUTTRESS_SECURITY_CTL_AUTH_DONE; +} +EXPORT_SYMBOL(ipu4_buttress_auth_done); + +static void ipu_buttress_set_psys_ratio(struct ipu_device *isp, + unsigned int psys_divisor, + unsigned int psys_qos_floor) +{ + struct ipu_buttress_ctrl *ctrl = isp->psys_iommu->ctrl; + + mutex_lock(&isp->buttress.power_mutex); + + if (ctrl->divisor == psys_divisor && ctrl->qos_floor == psys_qos_floor) + goto out_mutex_unlock; + + ctrl->divisor = psys_divisor; + ctrl->qos_floor = psys_qos_floor; + + if (ctrl->started) { + /* + * According to documentation driver initiates DVFS + * transition by writing wanted ratio, floor ratio and start + * bit. No need to stop PS first + */ + writel(1 << BUTTRESS_FREQ_CTL_START_SHIFT | + ctrl-> + qos_floor << BUTTRESS_FREQ_CTL_QOS_FLOOR_SHIFT | + psys_divisor, isp->base + BUTTRESS_REG_PS_FREQ_CTL); + } + +out_mutex_unlock: + mutex_unlock(&isp->buttress.power_mutex); +} + +static void ipu_buttress_set_psys_freq(struct ipu_device *isp, + unsigned int freq) +{ + unsigned int psys_ratio = freq / BUTTRESS_PS_FREQ_STEP; + + if (isp->buttress.psys_force_ratio) + return; + + ipu_buttress_set_psys_ratio(isp, psys_ratio, psys_ratio); +} + +void +ipu_buttress_add_psys_constraint(struct ipu_device *isp, + struct ipu_buttress_constraint *constraint) +{ + struct ipu_buttress *b = &isp->buttress; + + mutex_lock(&b->cons_mutex); + list_add(&constraint->list, &b->constraints); + + if (constraint->min_freq > b->psys_min_freq) { + isp->buttress.psys_min_freq = min(constraint->min_freq, + b->psys_fused_freqs.max_freq); + ipu_buttress_set_psys_freq(isp, b->psys_min_freq); + } + mutex_unlock(&isp->buttress.cons_mutex); +} +EXPORT_SYMBOL_GPL(ipu_buttress_add_psys_constraint); + +void +ipu_buttress_remove_psys_constraint(struct ipu_device *isp, + struct ipu_buttress_constraint *constraint) +{ + struct ipu_buttress *b = &isp->buttress; + struct ipu_buttress_constraint *c; + unsigned int min_freq = 0; + + mutex_lock(&b->cons_mutex); + list_del(&constraint->list); + + if (constraint->min_freq >= b->psys_min_freq) { + list_for_each_entry(c, &b->constraints, list) + if (c->min_freq > min_freq) + min_freq = c->min_freq; + + b->psys_min_freq = clamp(min_freq, + b->psys_fused_freqs.efficient_freq, + b->psys_fused_freqs.max_freq); + ipu_buttress_set_psys_freq(isp, b->psys_min_freq); + } + mutex_unlock(&b->cons_mutex); +} +EXPORT_SYMBOL_GPL(ipu_buttress_remove_psys_constraint); + +int ipu_buttress_reset_authentication(struct ipu_device *isp) +{ + int ret; + u32 val; + + if (!isp->secure_mode) { + dev_dbg(&isp->pdev->dev, + "Non-secure mode -> skip authentication\n"); + return 0; + } + + writel(1 << BUTTRESS_FW_RESET_CTL_START_SHIFT, isp->base + + BUTTRESS_REG_FW_RESET_CTL); + + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_FW_RESET_CTL, val, + val & 1 << BUTTRESS_FW_RESET_CTL_DONE_SHIFT, 500, + BUTTRESS_CSE_FWRESET_TIMEOUT); + if (ret) { + dev_err(&isp->pdev->dev, + "Time out while resetting authentication state\n"); + } else { + dev_info(&isp->pdev->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 ret; +} + +int ipu_buttress_map_fw_image(struct ipu_bus_device *sys, + const struct firmware *fw, struct sg_table *sgt) +{ + struct page **pages; + const void *addr; + unsigned long n_pages; + int rval, i; + + n_pages = PAGE_ALIGN(fw->size) >> PAGE_SHIFT; + + pages = kmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL); + if (!pages) + return -ENOMEM; + + addr = fw->data; + for (i = 0; i < n_pages; i++) { + struct page *p = vmalloc_to_page(addr); + + if (!p) { + rval = -ENODEV; + goto out; + } + pages[i] = p; + addr += PAGE_SIZE; + } + + rval = sg_alloc_table_from_pages(sgt, pages, n_pages, 0, fw->size, + GFP_KERNEL); + if (rval) { + rval = -ENOMEM; + goto out; + } + + rval = dma_map_sgtable(&sys->dev, sgt, DMA_TO_DEVICE, 0); + if (rval < 0) { + rval = -ENOMEM; + sg_free_table(sgt); + goto out; + } + + dma_sync_sgtable_for_device(&sys->dev, sgt, DMA_TO_DEVICE); + +out: + kfree(pages); + + return rval; +} +EXPORT_SYMBOL_GPL(ipu_buttress_map_fw_image); + +int ipu_buttress_unmap_fw_image(struct ipu_bus_device *sys, + struct sg_table *sgt) +{ + dma_unmap_sg(&sys->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE); + sg_free_table(sgt); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_buttress_unmap_fw_image); + +int ipu_buttress_authenticate(struct ipu_device *isp) +{ + struct ipu_psys_pdata *psys_pdata; + struct ipu_buttress *b = &isp->buttress; + u32 data, mask, done, fail; + int rval; + + if (!isp->secure_mode) { + dev_dbg(&isp->pdev->dev, + "Non-secure mode -> skip authentication\n"); + return 0; + } + + psys_pdata = isp->psys->pdata; + + mutex_lock(&b->auth_mutex); + + rval = pm_runtime_get_sync(&isp->psys_iommu->dev); + if (rval < 0) { + dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n", rval); + goto iunit_power_off; + } + + if (ipu4_buttress_auth_done(isp)) { + rval = 0; + goto iunit_power_off; + } + + /* + * Write address of FIT table to FW_SOURCE register + * Let's use fw address. I.e. not using FIT table yet + */ + data = lower_32_bits(isp->pkg_dir_dma_addr); + writel(data, isp->base + BUTTRESS_REG_FW_SOURCE_BASE_LO); + + data = upper_32_bits(isp->pkg_dir_dma_addr); + writel(data, isp->base + BUTTRESS_REG_FW_SOURCE_BASE_HI); + + /* + * Write boot_load into IU2CSEDATA0 + * Write sizeof(boot_load) | 0x2 << CLIENT_ID to + * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as + */ + dev_info(&isp->pdev->dev, "Sending BOOT_LOAD to CSE\n"); + rval = ipu_buttress_ipc_send(isp, IPU_BUTTRESS_IPC_CSE, + BUTTRESS_IU2CSEDATA0_IPC_BOOT_LOAD, + 1, 1, + BUTTRESS_CSE2IUDATA0_IPC_BOOT_LOAD_DONE); + if (rval) { + dev_err(&isp->pdev->dev, "CSE boot_load failed\n"); + goto iunit_power_off; + } + + mask = BUTTRESS_SECURITY_CTL_FW_SETUP_MASK; + done = BUTTRESS_SECURITY_CTL_FW_SETUP_DONE; + fail = BUTTRESS_SECURITY_CTL_AUTH_FAILED; + rval = readl_poll_timeout(isp->base + BUTTRESS_REG_SECURITY_CTL, data, + ((data & mask) == done || + (data & mask) == fail), 500, + BUTTRESS_CSE_BOOTLOAD_TIMEOUT); + if (rval) { + dev_err(&isp->pdev->dev, "CSE boot_load timeout\n"); + goto iunit_power_off; + } + + data = readl(isp->base + BUTTRESS_REG_SECURITY_CTL) & mask; + if (data == fail) { + dev_err(&isp->pdev->dev, "CSE auth failed\n"); + rval = -EINVAL; + goto iunit_power_off; + } + + rval = readl_poll_timeout(psys_pdata->base + BOOTLOADER_STATUS_OFFSET, + data, data == BOOTLOADER_MAGIC_KEY, 500, + BUTTRESS_CSE_BOOTLOAD_TIMEOUT); + if (rval) { + dev_err(&isp->pdev->dev, "Expect magic number timeout 0x%x\n", + data); + goto iunit_power_off; + } + + /* + * Write authenticate_run into IU2CSEDATA0 + * Write sizeof(boot_load) | 0x2 << CLIENT_ID to + * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as + */ + dev_info(&isp->pdev->dev, "Sending AUTHENTICATE_RUN to CSE\n"); + rval = ipu_buttress_ipc_send(isp, IPU_BUTTRESS_IPC_CSE, + BUTTRESS_IU2CSEDATA0_IPC_AUTH_RUN, + 1, 1, + BUTTRESS_CSE2IUDATA0_IPC_AUTH_RUN_DONE); + if (rval) { + dev_err(&isp->pdev->dev, "CSE authenticate_run failed\n"); + goto iunit_power_off; + } + + done = BUTTRESS_SECURITY_CTL_AUTH_DONE; + rval = readl_poll_timeout(isp->base + BUTTRESS_REG_SECURITY_CTL, data, + ((data & mask) == done || + (data & mask) == fail), 500, + BUTTRESS_CSE_AUTHENTICATE_TIMEOUT); + if (rval) { + dev_err(&isp->pdev->dev, "CSE authenticate timeout\n"); + goto iunit_power_off; + } + + data = readl(isp->base + BUTTRESS_REG_SECURITY_CTL) & mask; + if (data == fail) { + dev_err(&isp->pdev->dev, "CSE boot_load failed\n"); + rval = -EINVAL; + goto iunit_power_off; + } + + dev_info(&isp->pdev->dev, "CSE authenticate_run done\n"); + +iunit_power_off: + mutex_unlock(&b->auth_mutex); + + return rval; +} +EXPORT_SYMBOL(ipu_buttress_authenticate); + +static int ipu_buttress_send_tsc_request(struct ipu_device *isp) +{ + u32 val, mask, shift, done; + int ret; + + mask = BUTTRESS_PWR_STATE_HH_STATUS_MASK; + shift = BUTTRESS_PWR_STATE_HH_STATUS_SHIFT; + + writel(BUTTRESS_FABRIC_CMD_START_TSC_SYNC, + isp->base + BUTTRESS_REG_FABRIC_CMD); + + val = readl(isp->base + BUTTRESS_REG_PWR_STATE); + val = (val & mask) >> shift; + if (val == BUTTRESS_PWR_STATE_HH_STATE_ERR) { + dev_err(&isp->pdev->dev, "Start tsc sync failed\n"); + return -EINVAL; + } + + done = BUTTRESS_PWR_STATE_HH_STATE_DONE; + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATE, val, + ((val & mask) >> shift == done), 500, + BUTTRESS_TSC_SYNC_TIMEOUT); + if (ret) + dev_err(&isp->pdev->dev, "Start tsc sync timeout\n"); + + return ret; +} + +int ipu4_buttress_start_tsc_sync(struct ipu_device *isp) +{ + unsigned int i; + + for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) { + int ret; + + ret = ipu_buttress_send_tsc_request(isp); + if (ret == -ETIMEDOUT) { + u32 val; + /* set tsw soft reset */ + val = readl(isp->base + BUTTRESS_REG_TSW_CTL); + val = val | BUTTRESS_TSW_CTL_SOFT_RESET; + writel(val, isp->base + BUTTRESS_REG_TSW_CTL); + /* clear tsw soft reset */ + val = val & (~BUTTRESS_TSW_CTL_SOFT_RESET); + writel(val, isp->base + BUTTRESS_REG_TSW_CTL); + + continue; + } + return ret; + } + + dev_err(&isp->pdev->dev, "TSC sync failed(timeout).\n"); + + return -ETIMEDOUT; +} +EXPORT_SYMBOL(ipu4_buttress_start_tsc_sync); + +struct clk_ipu_sensor { + struct ipu_device *isp; + struct clk_hw hw; + unsigned int id; + unsigned long rate; +}; + +#define to_clk_ipu_sensor(_hw) container_of(_hw, struct clk_ipu_sensor, hw) + +static int ipu_buttress_clk_pll_prepare(struct clk_hw *hw) +{ + struct clk_ipu_sensor *ck = to_clk_ipu_sensor(hw); + int ret; + + /* Workaround needed to get sensor clock running in some cases */ + ret = pm_runtime_get_sync(&ck->isp->isys->dev); + return ret >= 0 ? 0 : ret; +} + +static void ipu_buttress_clk_pll_unprepare(struct clk_hw *hw) +{ + struct clk_ipu_sensor *ck = to_clk_ipu_sensor(hw); + + /* Workaround needed to get sensor clock stopped in some cases */ + pm_runtime_put(&ck->isp->isys->dev); +} + +static int ipu_buttress_clk_pll_enable(struct clk_hw *hw) +{ + struct clk_ipu_sensor *ck = to_clk_ipu_sensor(hw); + u32 val; + unsigned int i; + + /* + * Start bit behaves like master clock request towards ICLK. + * It is needed regardless of the 24 MHz or per clock out pll + * setting. + */ + val = readl(ck->isp->base + BUTTRESS_REG_SENSOR_FREQ_CTL); + val |= 1 << BUTTRESS_FREQ_CTL_START_SHIFT; + val &= ~BUTTRESS_SENSOR_FREQ_CTL_OSC_OUT_FREQ_MASK(ck->id); + for (i = 0; i < ARRAY_SIZE(sensor_clk_freqs); i++) + if (sensor_clk_freqs[i].rate == ck->rate) + break; + + if (i < ARRAY_SIZE(sensor_clk_freqs)) + val |= sensor_clk_freqs[i].val << + BUTTRESS_SENSOR_FREQ_CTL_OSC_OUT_FREQ_SHIFT(ck->id); + else + val |= BUTTRESS_SENSOR_FREQ_CTL_OSC_OUT_FREQ_DEFAULT(ck->id); + + writel(val, ck->isp->base + BUTTRESS_REG_SENSOR_FREQ_CTL); + + return 0; +} + +static void ipu_buttress_clk_pll_disable(struct clk_hw *hw) +{ + struct clk_ipu_sensor *ck = to_clk_ipu_sensor(hw); + u32 val; + int i; + + val = readl(ck->isp->base + BUTTRESS_REG_SENSOR_CLK_CTL); + for (i = 0; i < IPU_BUTTRESS_NUM_OF_SENS_CKS; i++) { + if (val & + (1 << BUTTRESS_SENSOR_CLK_CTL_OSC_CLK_OUT_EN_SHIFT(i))) + return; + } + + /* See enable control above */ + val = readl(ck->isp->base + BUTTRESS_REG_SENSOR_FREQ_CTL); + val &= ~(1 << BUTTRESS_FREQ_CTL_START_SHIFT); + writel(val, ck->isp->base + BUTTRESS_REG_SENSOR_FREQ_CTL); +} + +static int ipu_buttress_clk_enable(struct clk_hw *hw) +{ + struct clk_ipu_sensor *ck = to_clk_ipu_sensor(hw); + u32 val; + + val = readl(ck->isp->base + BUTTRESS_REG_SENSOR_CLK_CTL); + val |= 1 << BUTTRESS_SENSOR_CLK_CTL_OSC_CLK_OUT_EN_SHIFT(ck->id); + + /* Enable dynamic sensor clock */ + val |= 1 << BUTTRESS_SENSOR_CLK_CTL_OSC_CLK_OUT_SEL_SHIFT(ck->id); + writel(val, ck->isp->base + BUTTRESS_REG_SENSOR_CLK_CTL); + + return 0; +} + +static void ipu_buttress_clk_disable(struct clk_hw *hw) +{ + struct clk_ipu_sensor *ck = to_clk_ipu_sensor(hw); + u32 val; + + val = readl(ck->isp->base + BUTTRESS_REG_SENSOR_CLK_CTL); + val &= ~(1 << BUTTRESS_SENSOR_CLK_CTL_OSC_CLK_OUT_EN_SHIFT(ck->id)); + writel(val, ck->isp->base + BUTTRESS_REG_SENSOR_CLK_CTL); +} + +static long ipu_buttress_clk_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *parent_rate) +{ + unsigned long best = ULONG_MAX; + unsigned long round_rate = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(sensor_clk_freqs); i++) { + long diff = sensor_clk_freqs[i].rate - rate; + + if (diff == 0) + return rate; + + diff = abs(diff); + if (diff < best) { + best = diff; + round_rate = sensor_clk_freqs[i].rate; + } + } + + return round_rate; +} + +static unsigned long +ipu_buttress_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_ipu_sensor *ck = to_clk_ipu_sensor(hw); + + return ck->rate; +} + +static int ipu_buttress_clk_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct clk_ipu_sensor *ck = to_clk_ipu_sensor(hw); + + /* + * R N P PVD PLLout + * 1 45 128 2 6.75 + * 1 40 96 2 8 + * 1 40 80 2 9.6 + * 1 15 20 4 14.4 + * 1 40 32 2 24 + * 1 65 48 1 26 + * + */ + ck->rate = rate; + + return 0; +} + +static const struct clk_ops ipu_buttress_clk_sensor_ops = { + .enable = ipu_buttress_clk_enable, + .disable = ipu_buttress_clk_disable, +}; + +static const struct clk_ops ipu_buttress_clk_sensor_ops_parent = { + .enable = ipu_buttress_clk_pll_enable, + .disable = ipu_buttress_clk_pll_disable, + .prepare = ipu_buttress_clk_pll_prepare, + .unprepare = ipu_buttress_clk_pll_unprepare, + .round_rate = ipu_buttress_clk_round_rate, + .recalc_rate = ipu_buttress_clk_recalc_rate, + .set_rate = ipu_buttress_clk_set_rate, +}; + +static struct clk_init_data ipu_buttress_sensor_clk_data[] = { + { + .name = "OSC_CLK_OUT0", + .ops = &ipu_buttress_clk_sensor_ops, + .parent_names = (const char *[]){"ipu_sensor_pll0"}, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, + { + .name = "OSC_CLK_OUT1", + .ops = &ipu_buttress_clk_sensor_ops, + .parent_names = (const char *[]){"ipu_sensor_pll1"}, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, + { + .name = "OSC_CLK_OUT2", + .ops = &ipu_buttress_clk_sensor_ops, + .parent_names = (const char *[]){"ipu_sensor_pll2"}, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_init_data ipu_buttress_sensor_pll_data[] = { + { + .name = "ipu_sensor_pll0", + .ops = &ipu_buttress_clk_sensor_ops_parent, + }, + { + .name = "ipu_sensor_pll1", + .ops = &ipu_buttress_clk_sensor_ops_parent, + }, + { + .name = "ipu_sensor_pll2", + .ops = &ipu_buttress_clk_sensor_ops_parent, + }, +}; + +static void ipu_buttress_read_psys_fused_freqs(struct ipu_device *isp) +{ + struct ipu_buttress_fused_freqs *fused_freq = + &isp->buttress.psys_fused_freqs; + u32 reg_val, max_ratio, min_ratio, efficient_ratio; + + reg_val = readl(isp->base + BUTTRESS_REG_PS_FREQ_CAPABILITIES); + + min_ratio = (reg_val & + BUTTRESS_PS_FREQ_CAPABILITIES_MIN_RATIO_MASK) >> + BUTTRESS_PS_FREQ_CAPABILITIES_MIN_RATIO_SHIFT; + max_ratio = (reg_val & + BUTTRESS_PS_FREQ_CAPABILITIES_MAX_RATIO_MASK) >> + BUTTRESS_PS_FREQ_CAPABILITIES_MAX_RATIO_SHIFT; + efficient_ratio = + (reg_val & + BUTTRESS_PS_FREQ_CAPABILITIES_EFFICIENT_RATIO_MASK) >> + BUTTRESS_PS_FREQ_CAPABILITIES_EFFICIENT_RATIO_SHIFT; + + fused_freq->min_freq = min_ratio * BUTTRESS_PS_FREQ_STEP; + fused_freq->max_freq = max_ratio * BUTTRESS_PS_FREQ_STEP; + fused_freq->efficient_freq = efficient_ratio * BUTTRESS_PS_FREQ_STEP; +} + +#ifdef I2C_WA +/* + * The dev_id was hard code in platform data, as i2c bus number + * may change dynamiclly, we need to update this bus id + * accordingly. + * + * @adapter_id: hardware i2c adapter id, this was fixed in platform data + * return: i2c bus id registered in system + */ +int ipu_get_i2c_bus_id(int adapter_id) +{ + struct i2c_adapter *adapter; + char name[32]; + int i = 0; + + snprintf(name, sizeof(name), "i2c_designware.%d", adapter_id); + while ((adapter = i2c_get_adapter(i)) != NULL) { + struct device *parent = adapter->dev.parent; + + if (parent && !strncmp(name, dev_name(parent), sizeof(name))) + return i; + i++; + } + + /* Not found, should never happen! */ + WARN_ON_ONCE(1); + return -1; +} +EXPORT_SYMBOL_GPL(ipu_get_i2c_bus_id); +#endif + +static int ipu_buttress_clk_init(struct ipu_device *isp) +{ + struct ipu_buttress *b = &isp->buttress; + struct ipu_isys_subdev_pdata *pdata = isp->pdev->dev.platform_data; + struct ipu_isys_clk_mapping *clkmap = pdata ? pdata->clk_map : NULL; + struct clk_init_data *clk_data_parent; + struct clk_init_data *clk_data; + int i, rval; + unsigned int num_plls; + + ipu_buttress_read_psys_fused_freqs(isp); + isp->buttress.psys_min_freq = b->psys_fused_freqs.efficient_freq; + + clk_data_parent = ipu_buttress_sensor_pll_data; + + num_plls = ARRAY_SIZE(ipu_buttress_sensor_pll_data); + + for (i = 0; i < num_plls; i++) { + struct clk_ipu_sensor *parent_clk = + devm_kzalloc(&isp->pdev->dev, + sizeof(*parent_clk), GFP_KERNEL); + + if (!parent_clk) { + rval = -ENOMEM; + goto err; + } + + parent_clk->hw.init = &clk_data_parent[i]; + parent_clk->isp = isp; + parent_clk->id = i; + + b->pll_sensor[i] = clk_register(NULL, &parent_clk->hw); + if (IS_ERR(b->pll_sensor[i])) { + rval = PTR_ERR(b->pll_sensor[i]); + goto err; + } + } + + clk_data = ipu_buttress_sensor_clk_data; + + for (i = 0; i < IPU_BUTTRESS_NUM_OF_SENS_CKS; i++) { + char buffer[16]; /* max for clk_register_clkdev */ + unsigned int parent_index = 0; + struct clk_ipu_sensor *my_clk = + devm_kzalloc(&isp->pdev->dev, sizeof(*my_clk), + GFP_KERNEL); + + if (!my_clk) { + rval = -ENOMEM; + goto err; + } + + if (i < num_plls) + parent_index = i; + + my_clk->hw.init = &clk_data[i]; + + my_clk->id = i; + my_clk->isp = isp; + + b->clk_sensor[i] = clk_register(NULL, &my_clk->hw); + if (IS_ERR(b->clk_sensor[i])) { + rval = PTR_ERR(b->clk_sensor[i]); + goto err; + } + rval = clk_set_parent(b->clk_sensor[i], + b->pll_sensor[parent_index]); + if (rval) + goto err; + + /* Register generic clocks for sensor driver */ + snprintf(buffer, sizeof(buffer), "ipu_cam_clk%d", i); + rval = clk_register_clkdev(b->clk_sensor[i], buffer, NULL); + if (rval) + goto err; + } + + /* Now map sensor clocks */ + if (!clkmap) + return 0; + + while (clkmap->clkdev_data.dev_id) { +#ifdef I2C_WA + char *dev_id = kstrdup(clkmap->clkdev_data.dev_id, GFP_KERNEL); + int adapter_id = clkmap->clkdev_data.dev_id[0] - '0'; + char *addr = strpbrk(clkmap->clkdev_data.dev_id, "-"); + int bus_id = ipu_get_i2c_bus_id(adapter_id); + + snprintf(dev_id, PAGE_SIZE, "%d-%s", bus_id, addr + 1); +#endif + + /* + * Lookup table must be NULL terminated + * CLKDEV_INIT(NULL, NULL, NULL) + */ + for (i = 0; i < IPU_BUTTRESS_NUM_OF_SENS_CKS; i++) { + if (!strcmp(clkmap->platform_clock_name, + clk_data[i].name)) { + clkmap->clkdev_data.clk = b->clk_sensor[i]; +#ifdef I2C_WA + clkmap->clkdev_data.dev_id = dev_id; +#endif + clkdev_add(&clkmap->clkdev_data); + break; + } + } + clkmap++; + } + + return 0; + +err: + /* It is safe to call clk_unregister with null pointer */ + for (i = IPU_BUTTRESS_NUM_OF_SENS_CKS - 1; i >= 0; i--) + clk_unregister(b->clk_sensor[i]); + + for (i = num_plls - 1; i >= 0; i--) + clk_unregister(b->pll_sensor[i]); + + return rval; +} + +static void ipu_buttress_clk_exit(struct ipu_device *isp) +{ + struct ipu_buttress *b = &isp->buttress; + int i; + + /* It is safe to call clk_unregister with null pointer */ + for (i = 0; i < IPU_BUTTRESS_NUM_OF_SENS_CKS; i++) + clk_unregister(b->clk_sensor[i]); + + for (i = 0; i < ARRAY_SIZE(ipu_buttress_sensor_pll_data); i++) + clk_unregister(b->pll_sensor[i]); +} + +int ipu4_buttress_tsc_read(struct ipu_device *isp, u64 *val) +{ + struct ipu_buttress *b = &isp->buttress; + u32 tsc_hi, tsc_lo_1, tsc_lo_2, tsc_lo_3, tsc_chk = 0; + unsigned long flags; + short retry = IPU_BUTTRESS_TSC_RETRY; + + do { + spin_lock_irqsave(&b->tsc_lock, flags); + tsc_hi = readl(isp->base + BUTTRESS_REG_TSC_HI); + + /* + * We are occasionally getting broken values from + * HH. Reading 3 times and doing sanity check as a WA + */ + tsc_lo_1 = readl(isp->base + BUTTRESS_REG_TSC_LO); + tsc_lo_2 = readl(isp->base + BUTTRESS_REG_TSC_LO); + tsc_lo_3 = readl(isp->base + BUTTRESS_REG_TSC_LO); + tsc_chk = readl(isp->base + BUTTRESS_REG_TSC_HI); + spin_unlock_irqrestore(&b->tsc_lock, flags); + if (tsc_chk == tsc_hi && tsc_lo_2 && + tsc_lo_2 - tsc_lo_1 <= IPU_BUTTRESS_TSC_LIMIT && + tsc_lo_3 - tsc_lo_2 <= IPU_BUTTRESS_TSC_LIMIT) { + *val = (u64)tsc_hi << 32 | tsc_lo_2; + return 0; + } + + /* + * Trace error only if limit checkings fails at least + * by two consecutive readings. + */ + if (retry < IPU_BUTTRESS_TSC_RETRY - 1 && tsc_lo_2) + dev_err(&isp->pdev->dev, + "%s = %u, %s = %u, %s = %u, %s = %u, %s = %u", + "failure: tsc_hi", tsc_hi, + "tsc_chk", tsc_chk, + "tsc_lo_1", tsc_lo_1, + "tsc_lo_2", tsc_lo_2, "tsc_lo_3", tsc_lo_3); + } while (retry--); + + if (!tsc_chk && !tsc_lo_2) + return -EIO; + + WARN_ON_ONCE(1); + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(ipu4_buttress_tsc_read); + +#ifdef CONFIG_DEBUG_FS + +static int ipu_buttress_reg_open(struct inode *inode, struct file *file) +{ + if (!inode->i_private) + return -EACCES; + + file->private_data = inode->i_private; + return 0; +} + +static ssize_t ipu_buttress_reg_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct debugfs_reg32 *reg = file->private_data; + u8 tmp[11]; + u32 val = readl((void __iomem *)reg->offset); + int len = scnprintf(tmp, sizeof(tmp), "0x%08x", val); + + return simple_read_from_buffer(buf, len, ppos, &tmp, len); +} + +static ssize_t ipu_buttress_reg_write(struct file *file, + const char __user *buf, + size_t count, loff_t *ppos) +{ + struct debugfs_reg32 *reg = file->private_data; + u32 val; + int rval; + + rval = kstrtou32_from_user(buf, count, 0, &val); + if (rval) + return rval; + + writel(val, (void __iomem *)reg->offset); + + return count; +} + +static struct debugfs_reg32 buttress_regs[] = { + {"IU2CSEDB0", BUTTRESS_REG_IU2CSEDB0}, + {"IU2CSEDATA0", BUTTRESS_REG_IU2CSEDATA0}, + {"CSE2IUDB0", BUTTRESS_REG_CSE2IUDB0}, + {"CSE2IUDATA0", BUTTRESS_REG_CSE2IUDATA0}, + {"CSE2IUCSR", BUTTRESS_REG_CSE2IUCSR}, + {"IU2CSECSR", BUTTRESS_REG_IU2CSECSR}, +}; + +static const struct file_operations ipu_buttress_reg_fops = { + .owner = THIS_MODULE, + .open = ipu_buttress_reg_open, + .read = ipu_buttress_reg_read, + .write = ipu_buttress_reg_write, +}; + +static int ipu4_buttress_start_tsc_sync_set(void *data, u64 val) +{ + struct ipu_device *isp = data; + + return ipu4_buttress_start_tsc_sync(isp); +} + +DEFINE_SIMPLE_ATTRIBUTE(ipu4_buttress_start_tsc_sync_fops, NULL, + ipu4_buttress_start_tsc_sync_set, "%llu\n"); + +static int ipu_buttress_tsc_get(void *data, u64 *val) +{ + return ipu4_buttress_tsc_read(data, val); +} +DEFINE_SIMPLE_ATTRIBUTE(ipu_buttress_tsc_fops, ipu_buttress_tsc_get, + NULL, "%llu\n"); + +static int ipu_buttress_psys_force_freq_get(void *data, u64 *val) +{ + struct ipu_device *isp = data; + + *val = isp->buttress.psys_force_ratio * BUTTRESS_PS_FREQ_STEP; + + return 0; +} + +static int ipu_buttress_psys_force_freq_set(void *data, u64 val) +{ + struct ipu_device *isp = data; + + if (val && (val < BUTTRESS_MIN_FORCE_PS_FREQ || + val > BUTTRESS_MAX_FORCE_PS_FREQ)) + return -EINVAL; + + do_div(val, BUTTRESS_PS_FREQ_STEP); + isp->buttress.psys_force_ratio = val; + + if (isp->buttress.psys_force_ratio) + ipu_buttress_set_psys_ratio(isp, + isp->buttress.psys_force_ratio, + isp->buttress.psys_force_ratio); + else + ipu_buttress_set_psys_freq(isp, isp->buttress.psys_min_freq); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(ipu_buttress_psys_force_freq_fops, + ipu_buttress_psys_force_freq_get, + ipu_buttress_psys_force_freq_set, "%llu\n"); + +DEFINE_SIMPLE_ATTRIBUTE(ipu_buttress_psys_freq_fops, + ipu_buttress_psys_freq_get, NULL, "%llu\n"); + +DEFINE_SIMPLE_ATTRIBUTE(ipu_buttress_isys_freq_fops, + ipu_buttress_isys_freq_get, NULL, "%llu\n"); + +int ipu_buttress_debugfs_init(struct ipu_device *isp) +{ + struct debugfs_reg32 *reg = + devm_kcalloc(&isp->pdev->dev, ARRAY_SIZE(buttress_regs), + sizeof(*reg), GFP_KERNEL); + struct dentry *dir, *file; + int i; + + if (!reg) + return -ENOMEM; + + dir = debugfs_create_dir("buttress", isp->ipu_dir); + if (!dir) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(buttress_regs); i++, reg++) { + reg->offset = (unsigned long)isp->base + + buttress_regs[i].offset; + reg->name = buttress_regs[i].name; + file = debugfs_create_file(reg->name, 0700, + dir, reg, &ipu_buttress_reg_fops); + if (!file) + goto err; + } + + file = debugfs_create_file("start_tsc_sync", 0200, dir, isp, + &ipu4_buttress_start_tsc_sync_fops); + if (!file) + goto err; + file = debugfs_create_file("tsc", 0400, dir, isp, + &ipu_buttress_tsc_fops); + if (!file) + goto err; + file = debugfs_create_file("psys_force_freq", 0700, dir, isp, + &ipu_buttress_psys_force_freq_fops); + if (!file) + goto err; + + file = debugfs_create_file("psys_freq", 0400, dir, isp, + &ipu_buttress_psys_freq_fops); + if (!file) + goto err; + + file = debugfs_create_file("isys_freq", 0400, dir, isp, + &ipu_buttress_isys_freq_fops); + if (!file) + goto err; + + return 0; +err: + debugfs_remove_recursive(dir); + return -ENOMEM; +} + +#endif /* CONFIG_DEBUG_FS */ + +u64 ipu4_buttress_tsc_ticks_to_ns(u64 ticks) +{ + u64 ns = ticks * 10000; + /* + * TSC clock frequency is 19.2MHz, + * converting TSC tick count to ns is calculated by: + * ns = ticks * 1000 000 000 / 19.2Mhz + * = ticks * 1000 000 000 / 19200000Hz + * = ticks * 10000 / 192 ns + */ + do_div(ns, 192); + + return ns; +} +EXPORT_SYMBOL_GPL(ipu4_buttress_tsc_ticks_to_ns); + +static ssize_t +ipu_buttress_psys_fused_min_freq_get(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ipu_device *isp = pci_get_drvdata(to_pci_dev(dev)); + + return snprintf(buf, PAGE_SIZE, "%u\n", + isp->buttress.psys_fused_freqs.min_freq); +} + +static DEVICE_ATTR(psys_fused_min_freq, 0444, + ipu_buttress_psys_fused_min_freq_get, NULL); + +static ssize_t +ipu_buttress_psys_fused_max_freq_get(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ipu_device *isp = pci_get_drvdata(to_pci_dev(dev)); + + return snprintf(buf, PAGE_SIZE, "%u\n", + isp->buttress.psys_fused_freqs.max_freq); +} + +static DEVICE_ATTR(psys_fused_max_freq, 0444, + ipu_buttress_psys_fused_max_freq_get, NULL); + +static ssize_t +ipu_buttress_psys_fused_efficient_freq_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ipu_device *isp = pci_get_drvdata(to_pci_dev(dev)); + + return snprintf(buf, PAGE_SIZE, "%u\n", + isp->buttress.psys_fused_freqs.efficient_freq); +} + +static DEVICE_ATTR(psys_fused_efficient_freq, 0444, + ipu_buttress_psys_fused_efficient_freq_get, NULL); + +int ipu_buttress_restore(struct ipu_device *isp) +{ + struct ipu_buttress *b = &isp->buttress; + + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_ISR_CLEAR); + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_ISR_ENABLE); + writel(b->wdt_cached_value, isp->base + BUTTRESS_REG_WDT); + + return 0; +} +EXPORT_SYMBOL(ipu_buttress_restore); + +int ipu_buttress_init(struct ipu_device *isp) +{ + struct ipu_buttress *b = &isp->buttress; + int rval, ipc_reset_retry = BUTTRESS_CSE_IPC_RESET_RETRY; + + mutex_init(&b->power_mutex); + mutex_init(&b->auth_mutex); + mutex_init(&b->cons_mutex); + mutex_init(&b->ipc_mutex); + spin_lock_init(&b->tsc_lock); + init_completion(&b->ish.send_complete); + init_completion(&b->cse.send_complete); + init_completion(&b->ish.recv_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; + + b->ish.csr_in = BUTTRESS_REG_ISH2IUCSR; + b->ish.csr_out = BUTTRESS_REG_IU2ISHCSR; + b->ish.db0_in = BUTTRESS_REG_ISH2IUDB0; + b->ish.db0_out = BUTTRESS_REG_IU2ISHDB0; + b->ish.data0_in = BUTTRESS_REG_ISH2IUDATA0; + b->ish.data0_out = BUTTRESS_REG_IU2ISHDATA0; + INIT_LIST_HEAD(&b->constraints); + + rval = ipu_buttress_clk_init(isp); + if (rval) { + dev_err(&isp->pdev->dev, "Clock init failed\n"); + goto err_mutex_destroy; + } + + ipu_buttress_set_secure_mode(isp); + isp->secure_mode = ipu_buttress_get_secure_mode(isp); + if (isp->secure_mode != secure_mode_enable) + dev_warn(&isp->pdev->dev, "Unable to set secure mode!\n"); + + dev_info(&isp->pdev->dev, "IPU in %s mode\n", + isp->secure_mode ? "secure" : "non-secure"); + + b->wdt_cached_value = readl(isp->base + BUTTRESS_REG_WDT); + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_ISR_CLEAR); + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_ISR_ENABLE); + + rval = device_create_file(&isp->pdev->dev, + &dev_attr_psys_fused_min_freq); + if (rval) { + dev_err(&isp->pdev->dev, "Create min freq file failed\n"); + goto err_clk_unregister; + } + + rval = device_create_file(&isp->pdev->dev, + &dev_attr_psys_fused_max_freq); + if (rval) { + dev_err(&isp->pdev->dev, "Create max freq file failed\n"); + goto err_remove_min_freq_file; + } + + rval = device_create_file(&isp->pdev->dev, + &dev_attr_psys_fused_efficient_freq); + if (rval) { + dev_err(&isp->pdev->dev, "Create efficient freq file failed\n"); + goto err_remove_max_freq_file; + } + + /* + * We want to retry couple of time in case CSE initialization + * is delayed for reason or another. + */ + do { + rval = ipu_buttress_ipc_reset(isp, &b->cse); + if (rval) { + dev_err(&isp->pdev->dev, + "IPC reset protocol failed, retry!\n"); + } else { + dev_dbg(&isp->pdev->dev, "IPC reset completed!\n"); + return 0; + } + } while (ipc_reset_retry--); + + dev_err(&isp->pdev->dev, "IPC reset protocol failed\n"); + +err_remove_max_freq_file: + device_remove_file(&isp->pdev->dev, &dev_attr_psys_fused_max_freq); +err_remove_min_freq_file: + device_remove_file(&isp->pdev->dev, &dev_attr_psys_fused_min_freq); +err_clk_unregister: + ipu_buttress_clk_exit(isp); +err_mutex_destroy: + mutex_destroy(&b->power_mutex); + mutex_destroy(&b->auth_mutex); + mutex_destroy(&b->cons_mutex); + mutex_destroy(&b->ipc_mutex); + + return rval; +} + +void ipu_buttress_exit(struct ipu_device *isp) +{ + struct ipu_buttress *b = &isp->buttress; + + writel(0, isp->base + BUTTRESS_REG_ISR_ENABLE); + + device_remove_file(&isp->pdev->dev, + &dev_attr_psys_fused_efficient_freq); + device_remove_file(&isp->pdev->dev, &dev_attr_psys_fused_max_freq); + device_remove_file(&isp->pdev->dev, &dev_attr_psys_fused_min_freq); + + ipu_buttress_clk_exit(isp); + + mutex_destroy(&b->power_mutex); + mutex_destroy(&b->auth_mutex); + mutex_destroy(&b->cons_mutex); + mutex_destroy(&b->ipc_mutex); +} diff --git a/drivers/media/pci/intel/ipu-buttress.h b/drivers/media/pci/intel/ipu-buttress.h new file mode 100644 index 0000000000000..e751703eb859e --- /dev/null +++ b/drivers/media/pci/intel/ipu-buttress.h @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_BUTTRESS_H +#define IPU_BUTTRESS_H + +#include +#include +#include "ipu.h" + +#define IPU_BUTTRESS_NUM_OF_SENS_CKS 3 +#define IPU_BUTTRESS_NUM_OF_PLL_CKS 3 +#define IPU_BUTTRESS_TSC_CLK 19200000 + +#define BUTTRESS_POWER_TIMEOUT 200 + +#define BUTTRESS_PS_FREQ_STEP 25U +#define BUTTRESS_MIN_FORCE_PS_FREQ (BUTTRESS_PS_FREQ_STEP * 8) +#define BUTTRESS_MAX_FORCE_PS_FREQ (BUTTRESS_PS_FREQ_STEP * 32) + +struct ipu_buttress_ctrl { + u32 freq_ctl, pwr_sts_shift, pwr_sts_mask, pwr_sts_on, pwr_sts_off; + union { + unsigned int divisor; + unsigned int ratio; + }; + union { + unsigned int divisor_shift; + unsigned int ratio_shift; + }; + unsigned int ovrd; + u32 ovrd_shift; + unsigned int qos_floor; + bool started; +}; + +struct ipu_buttress_fused_freqs { + unsigned int min_freq; + unsigned int max_freq; + unsigned int efficient_freq; +}; + +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; + spinlock_t tsc_lock; /* tsc lock */ + struct clk *clk_sensor[IPU_BUTTRESS_NUM_OF_SENS_CKS]; + struct clk *pll_sensor[IPU_BUTTRESS_NUM_OF_PLL_CKS]; + struct ipu_buttress_ipc cse; + struct ipu_buttress_ipc ish; + struct list_head constraints; + struct ipu_buttress_fused_freqs psys_fused_freqs; + unsigned int psys_min_freq; + u32 wdt_cached_value; + u8 psys_force_ratio; + bool force_suspend; + bool ps_started; +}; + +struct ipu_buttress_sensor_clk_freq { + unsigned int rate; + unsigned int val; +}; + +struct firmware; + +enum ipu_buttress_ipc_domain { + IPU_BUTTRESS_IPC_CSE, + IPU_BUTTRESS_IPC_ISH, +}; + +struct ipu_buttress_constraint { + struct list_head list; + unsigned int min_freq; +}; + +struct ipu_ipc_buttress_bulk_msg { + u32 cmd; + u32 expected_resp; + bool require_resp; + u8 cmd_size; +}; + +int ipu_buttress_ipc_reset(struct ipu_device *isp, + struct ipu_buttress_ipc *ipc); +int ipu_buttress_map_fw_image(struct ipu_bus_device *sys, + const struct firmware *fw, struct sg_table *sgt); +int ipu_buttress_unmap_fw_image(struct ipu_bus_device *sys, + struct sg_table *sgt); +int ipu_buttress_power(struct device *dev, + struct ipu_buttress_ctrl *ctrl, bool on); +void +ipu_buttress_add_psys_constraint(struct ipu_device *isp, + struct ipu_buttress_constraint *constraint); +void +ipu_buttress_remove_psys_constraint(struct ipu_device *isp, + struct ipu_buttress_constraint *constraint); +void ipu_buttress_set_secure_mode(struct ipu_device *isp); +bool ipu_buttress_get_secure_mode(struct ipu_device *isp); +int ipu_buttress_authenticate(struct ipu_device *isp); +int ipu_buttress_reset_authentication(struct ipu_device *isp); +bool ipu4_buttress_auth_done(struct ipu_device *isp); +int ipu4_buttress_start_tsc_sync(struct ipu_device *isp); +int ipu4_buttress_tsc_read(struct ipu_device *isp, u64 *val); +u64 ipu4_buttress_tsc_ticks_to_ns(u64 ticks); + +irqreturn_t ipu_buttress_isr(int irq, void *isp_ptr); +irqreturn_t ipu_buttress_isr_threaded(int irq, void *isp_ptr); +int ipu_buttress_debugfs_init(struct ipu_device *isp); +int ipu_buttress_init(struct ipu_device *isp); +void ipu_buttress_exit(struct ipu_device *isp); +void ipu_buttress_csi_port_config(struct ipu_device *isp, + u32 legacy, u32 combo); +int ipu_buttress_restore(struct ipu_device *isp); + +int +ipu_buttress_ipc_send_bulk(struct ipu_device *isp, + enum ipu_buttress_ipc_domain ipc_domain, + struct ipu_ipc_buttress_bulk_msg *msgs, u32 size); +int ipu_buttress_psys_freq_get(void *data, u64 *val); +int ipu_buttress_isys_freq_get(void *data, u64 *val); +#ifdef I2C_WA +int ipu_get_i2c_bus_id(int adapter_id); +#endif /* I2C_WA */ +#endif /* IPU_BUTTRESS_H */ diff --git a/drivers/media/pci/intel/ipu-cpd.c b/drivers/media/pci/intel/ipu-cpd.c new file mode 100644 index 0000000000000..4c0e048290c2a --- /dev/null +++ b/drivers/media/pci/intel/ipu-cpd.c @@ -0,0 +1,462 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2015 - 2018 Intel Corporation + +#include +#include + +#include "ipu.h" +#include "ipu-cpd.h" + +#include "ipu4-css/ia_css_fw_pkg_release.h" + +/* 15 entries + header*/ +#define MAX_PKG_DIR_ENT_CNT 16 +/* 2 qword per entry/header */ +#define PKG_DIR_ENT_LEN 2 +/* PKG_DIR size in bytes */ +#define PKG_DIR_SIZE ((MAX_PKG_DIR_ENT_CNT) * \ + (PKG_DIR_ENT_LEN) * sizeof(u64)) +#define PKG_DIR_ID_SHIFT 48 +#define PKG_DIR_ID_MASK 0x7f +#define PKG_DIR_VERSION_SHIFT 32 +#define PKG_DIR_SIZE_MASK 0xfffff +/* _IUPKDR_ */ +#define PKG_DIR_HDR_MARK 0x5f4955504b44525f + +/* $CPD */ +#define CPD_HDR_MARK 0x44504324 + +/* Maximum size is 2K DWORDs */ +#define MAX_MANIFEST_SIZE (2 * 1024 * sizeof(u32)) + +/* Maximum size is 64k */ +#define MAX_METADATA_SIZE (64 * 1024) + +#define MAX_COMPONENT_ID 127 +#define MAX_COMPONENT_VERSION 0xffff + +#define CPD_MANIFEST_IDX 0 +#define CPD_METADATA_IDX 1 +#define CPD_MODULEDATA_IDX 2 + +#define ipu_cpd_get_entries(cpd) ((struct ipu_cpd_ent *) \ + ((struct ipu_cpd_hdr *)cpd + 1)) +#define ipu_cpd_get_entry(cpd, idx) (&ipu_cpd_get_entries(cpd)[idx]) +#define ipu_cpd_get_manifest(cpd) ipu_cpd_get_entry(cpd, CPD_MANIFEST_IDX) +#define ipu_cpd_get_metadata(cpd) ipu_cpd_get_entry(cpd, CPD_METADATA_IDX) +#define ipu_cpd_get_moduledata(cpd) ipu_cpd_get_entry(cpd, CPD_MODULEDATA_IDX) + +static bool fw_version_check = true; +module_param(fw_version_check, bool, 0444); +MODULE_PARM_DESC(fw_version_check, "enable/disable checking firmware version"); + +static const struct ipu_cpd_metadata_cmpnt * +ipu_cpd_metadata_get_cmpnt(struct ipu_device *isp, + const void *metadata, + unsigned int metadata_size, + u8 idx) +{ + const struct ipu_cpd_metadata_extn *extn; + const struct ipu_cpd_metadata_cmpnt *cmpnts; + int cmpnt_count; + + extn = metadata; + cmpnts = metadata + sizeof(*extn); + cmpnt_count = (metadata_size - sizeof(*extn)) / sizeof(*cmpnts); + + if (idx > MAX_COMPONENT_ID || idx >= cmpnt_count) { + dev_err(&isp->pdev->dev, "Component index out of range (%d)\n", + idx); + return ERR_PTR(-EINVAL); + } + + return &cmpnts[idx]; +} + +static u32 ipu_cpd_metadata_cmpnt_version(struct ipu_device *isp, + const void *metadata, + unsigned int metadata_size, u8 idx) +{ + const struct ipu_cpd_metadata_cmpnt *cmpnt = + ipu_cpd_metadata_get_cmpnt(isp, metadata, + metadata_size, idx); + + if (IS_ERR(cmpnt)) + return PTR_ERR(cmpnt); + + return cmpnt->ver; +} + +static int ipu_cpd_metadata_get_cmpnt_id(struct ipu_device *isp, + const void *metadata, + unsigned int metadata_size, u8 idx) +{ + const struct ipu_cpd_metadata_cmpnt *cmpnt = + ipu_cpd_metadata_get_cmpnt(isp, metadata, + metadata_size, idx); + + if (IS_ERR(cmpnt)) + return PTR_ERR(cmpnt); + + return cmpnt->id; +} + +static u32 +ipu_cpd_metadata_get_cmpnt_icache_base_offs(struct ipu_device *isp, + const void *metadata, + unsigned int metadata_size, u8 idx) +{ + const struct ipu_cpd_metadata_cmpnt *cmpnt = + ipu_cpd_metadata_get_cmpnt(isp, metadata, + metadata_size, idx); + + if (IS_ERR(cmpnt)) + return PTR_ERR(cmpnt); + + return cmpnt->icache_base_offs; +} + +static u32 +ipu_cpd_metadata_get_cmpnt_entry_point(struct ipu_device *isp, + const void *metadata, + unsigned int metadata_size, u8 idx) +{ + const struct ipu_cpd_metadata_cmpnt *cmpnt = + ipu_cpd_metadata_get_cmpnt(isp, metadata, + metadata_size, idx); + + if (IS_ERR(cmpnt)) + return PTR_ERR(cmpnt); + + return cmpnt->entry_point; +} + +static int ipu_cpd_parse_module_data(struct ipu_device *isp, + const void *module_data, + unsigned int module_data_size, + dma_addr_t dma_addr_module_data, + u64 *pkg_dir, + const void *metadata, + unsigned int metadata_size) +{ + const struct ipu_cpd_module_data_hdr *module_data_hdr; + const struct ipu_cpd_hdr *dir_hdr; + const struct ipu_cpd_ent *dir_ent; + int i; + + if (!module_data) + return -EINVAL; + + module_data_hdr = module_data; + dir_hdr = module_data + module_data_hdr->hdr_len; + dir_ent = (struct ipu_cpd_ent *)(dir_hdr + 1); + + pkg_dir[0] = PKG_DIR_HDR_MARK; + /* pkg_dir entry count = component count + pkg_dir header */ + pkg_dir[1] = dir_hdr->ent_cnt + 1; + + for (i = 0; i < dir_hdr->ent_cnt; i++, dir_ent++) { + u64 *p = &pkg_dir[PKG_DIR_ENT_LEN + i * PKG_DIR_ENT_LEN]; + int ver, id; + + *p++ = dma_addr_module_data + dir_ent->offset; + + id = ipu_cpd_metadata_get_cmpnt_id(isp, metadata, + metadata_size, i); + if (id < 0 || id > MAX_COMPONENT_ID) { + dev_err(&isp->pdev->dev, + "Failed to parse component id\n"); + return -EINVAL; + } + ver = ipu_cpd_metadata_cmpnt_version(isp, metadata, + metadata_size, i); + if (ver < 0 || ver > MAX_COMPONENT_VERSION) { + dev_err(&isp->pdev->dev, + "Failed to parse component version\n"); + return -EINVAL; + } + + /* + * PKG_DIR Entry (type == id) + * 63:56 55 54:48 47:32 31:24 23:0 + * Rsvd Rsvd Type Version Rsvd Size + */ + *p = dir_ent->len | (u64) id << PKG_DIR_ID_SHIFT | + (u64)ver << PKG_DIR_VERSION_SHIFT; + } + + return 0; +} + +void *ipu_cpd_create_pkg_dir(struct ipu_bus_device *adev, + const void *src, + dma_addr_t dma_addr_src, + dma_addr_t *dma_addr, unsigned int *pkg_dir_size) +{ + struct ipu_device *isp = adev->isp; + const struct ipu_cpd_ent *ent, *man_ent, *met_ent; + u64 *pkg_dir; + unsigned int man_sz, met_sz; + void *pkg_dir_pos; + int ret; + + man_ent = ipu_cpd_get_manifest(src); + man_sz = man_ent->len; + + met_ent = ipu_cpd_get_metadata(src); + met_sz = met_ent->len; + + *pkg_dir_size = PKG_DIR_SIZE + man_sz + met_sz; + pkg_dir = dma_alloc_coherent(&adev->dev, *pkg_dir_size, dma_addr, + GFP_KERNEL); + if (!pkg_dir) + return pkg_dir; + + /* + * pkg_dir entry/header: + * qword | 63:56 | 55 | 54:48 | 47:32 | 31:24 | 23:0 + * N Address/Offset/"_IUPKDR_" + * N + 1 | rsvd | rsvd | type | ver | rsvd | size + * + * We can ignore other fields that size in N + 1 qword as they + * are 0 anyway. Just setting size for now. + */ + + ent = ipu_cpd_get_moduledata(src); + + ret = ipu_cpd_parse_module_data(isp, src + ent->offset, + ent->len, + dma_addr_src + ent->offset, + pkg_dir, + src + met_ent->offset, met_ent->len); + if (ret) { + dev_err(&isp->pdev->dev, + "Unable to parse module data section!\n"); + dma_free_coherent(&isp->psys->dev, *pkg_dir_size, pkg_dir, + *dma_addr); + return NULL; + } + + /* Copy manifest after pkg_dir */ + pkg_dir_pos = pkg_dir + PKG_DIR_ENT_LEN * MAX_PKG_DIR_ENT_CNT; + memcpy(pkg_dir_pos, src + man_ent->offset, man_sz); + + /* Copy metadata after manifest */ + pkg_dir_pos += man_sz; + memcpy(pkg_dir_pos, src + met_ent->offset, met_sz); + + dma_sync_single_range_for_device(&adev->dev, *dma_addr, + 0, *pkg_dir_size, DMA_TO_DEVICE); + + return pkg_dir; +} +EXPORT_SYMBOL_GPL(ipu_cpd_create_pkg_dir); + +void ipu_cpd_free_pkg_dir(struct ipu_bus_device *adev, + u64 *pkg_dir, + dma_addr_t dma_addr, unsigned int pkg_dir_size) +{ + dma_free_coherent(&adev->dev, pkg_dir_size, pkg_dir, dma_addr); +} +EXPORT_SYMBOL_GPL(ipu_cpd_free_pkg_dir); + +u32 ipu_cpd_get_pg_icache_base(struct ipu_device *isp, + u8 idx, + const void *cpd_file, unsigned int cpd_file_size) +{ + const struct ipu_cpd_ent *metadata = ipu_cpd_get_metadata(cpd_file); + const void *metadata_addr = cpd_file + metadata->offset; + + return ipu_cpd_metadata_get_cmpnt_icache_base_offs(isp, + metadata_addr, + metadata->len, idx); +} +EXPORT_SYMBOL_GPL(ipu_cpd_get_pg_icache_base); + +u32 ipu_cpd_get_pg_entry_point(struct ipu_device *isp, + u8 idx, + const void *cpd_file, unsigned int cpd_file_size) +{ + const struct ipu_cpd_ent *metadata = ipu_cpd_get_metadata(cpd_file); + const void *metadata_addr = cpd_file + metadata->offset; + + return ipu_cpd_metadata_get_cmpnt_entry_point(isp, + metadata_addr, + metadata->len, idx); +} +EXPORT_SYMBOL_GPL(ipu_cpd_get_pg_entry_point); + +static int ipu_cpd_validate_cpd(struct ipu_device *isp, + const void *cpd, + unsigned long cpd_size, unsigned long data_size) +{ + const struct ipu_cpd_hdr *cpd_hdr = cpd; + struct ipu_cpd_ent *ent; + unsigned int i; + + /* Ensure cpd hdr is within moduledata */ + if (cpd_size < sizeof(*cpd_hdr)) { + dev_err(&isp->pdev->dev, "Invalid CPD moduledata size\n"); + return -EINVAL; + } + + /* Sanity check for CPD header */ + if ((cpd_size - sizeof(*cpd_hdr)) / sizeof(*ent) < cpd_hdr->ent_cnt) { + dev_err(&isp->pdev->dev, "Invalid CPD header\n"); + return -EINVAL; + } + + /* Ensure that all entries are within moduledata */ + ent = (struct ipu_cpd_ent *)(cpd_hdr + 1); + for (i = 0; i < cpd_hdr->ent_cnt; i++, ent++) { + if (data_size < ent->offset || + data_size - ent->offset < ent->len) { + dev_err(&isp->pdev->dev, "Invalid CPD entry (%d)\n", i); + return -EINVAL; + } + } + + return 0; +} + +static int ipu_cpd_validate_moduledata(struct ipu_device *isp, + const void *moduledata, + u32 moduledata_size) +{ + const struct ipu_cpd_module_data_hdr *mod_hdr = moduledata; + int rval; + + /* Ensure moduledata hdr is within moduledata */ + if (moduledata_size < sizeof(*mod_hdr) || + moduledata_size < mod_hdr->hdr_len) { + dev_err(&isp->pdev->dev, "Invalid moduledata size\n"); + return -EINVAL; + } + + if (fw_version_check && mod_hdr->fw_pkg_date != IA_CSS_FW_PKG_RELEASE) { + dev_err(&isp->pdev->dev, + "Moduledata and library version mismatch (%x != %x)\n", + mod_hdr->fw_pkg_date, IA_CSS_FW_PKG_RELEASE); + return -EINVAL; + } + + dev_warn(&isp->pdev->dev, + "Moduledata version: %x, library version: %x\n", + mod_hdr->fw_pkg_date, IA_CSS_FW_PKG_RELEASE); + + dev_info(&isp->pdev->dev, "CSS release: %x\n", IA_CSS_FW_PKG_RELEASE); + rval = ipu_cpd_validate_cpd(isp, moduledata + + mod_hdr->hdr_len, + moduledata_size - + mod_hdr->hdr_len, moduledata_size); + if (rval) { + dev_err(&isp->pdev->dev, "Invalid CPD in moduledata\n"); + return -EINVAL; + } + + return 0; +} + +static int ipu_cpd_validate_metadata(struct ipu_device *isp, + const void *metadata, u32 meta_size) +{ + const struct ipu_cpd_metadata_extn *extn = metadata; + + /* Sanity check for metadata size */ + if (meta_size < sizeof(*extn) || meta_size > MAX_METADATA_SIZE) { + dev_err(&isp->pdev->dev, "%s: Invalid metadata\n", __func__); + return -EINVAL; + } + + /* Validate extension and image types */ + if (extn->extn_type != IPU_CPD_METADATA_EXTN_TYPE_IUNIT || + extn->img_type != IPU_CPD_METADATA_IMAGE_TYPE_MAIN_FIRMWARE) { + dev_err(&isp->pdev->dev, + "Invalid metadata descriptor img_type (%d)\n", + extn->img_type); + return -EINVAL; + } + + /* Validate metadata size multiple of metadata components */ + if ((meta_size - sizeof(*extn)) % + sizeof(struct ipu_cpd_metadata_cmpnt)) { + dev_err(&isp->pdev->dev, "%s: Invalid metadata size\n", + __func__); + return -EINVAL; + } + + return 0; +} + +int ipu_cpd_validate_cpd_file(struct ipu_device *isp, + const void *cpd_file, unsigned long cpd_file_size) +{ + const struct ipu_cpd_hdr *hdr = cpd_file; + struct ipu_cpd_ent *ent; + int rval; + + rval = ipu_cpd_validate_cpd(isp, cpd_file, + cpd_file_size, cpd_file_size); + if (rval) { + dev_err(&isp->pdev->dev, "Invalid CPD in file\n"); + return -EINVAL; + } + + /* Check for CPD file marker */ + if (hdr->hdr_mark != CPD_HDR_MARK) { + dev_err(&isp->pdev->dev, "Invalid CPD header\n"); + return -EINVAL; + } + + /* Sanity check for manifest size */ + ent = ipu_cpd_get_manifest(cpd_file); + if (ent->len > MAX_MANIFEST_SIZE) { + dev_err(&isp->pdev->dev, "Invalid manifest size\n"); + return -EINVAL; + } + + /* Validate metadata */ + ent = ipu_cpd_get_metadata(cpd_file); + rval = ipu_cpd_validate_metadata(isp, cpd_file + ent->offset, ent->len); + if (rval) { + dev_err(&isp->pdev->dev, "Invalid metadata\n"); + return rval; + } + + /* Validate moduledata */ + ent = ipu_cpd_get_moduledata(cpd_file); + rval = ipu_cpd_validate_moduledata(isp, cpd_file + ent->offset, + ent->len); + if (rval) { + dev_err(&isp->pdev->dev, "Invalid moduledata\n"); + return rval; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_cpd_validate_cpd_file); + +unsigned int ipu_cpd_pkg_dir_get_address(const u64 *pkg_dir, int pkg_dir_idx) +{ + return pkg_dir[++pkg_dir_idx * PKG_DIR_ENT_LEN]; +} +EXPORT_SYMBOL_GPL(ipu_cpd_pkg_dir_get_address); + +unsigned int ipu_cpd_pkg_dir_get_num_entries(const u64 *pkg_dir) +{ + return pkg_dir[1]; +} +EXPORT_SYMBOL_GPL(ipu_cpd_pkg_dir_get_num_entries); + +unsigned int ipu_cpd_pkg_dir_get_size(const u64 *pkg_dir, int pkg_dir_idx) +{ + return pkg_dir[++pkg_dir_idx * PKG_DIR_ENT_LEN + 1] & PKG_DIR_SIZE_MASK; +} +EXPORT_SYMBOL_GPL(ipu_cpd_pkg_dir_get_size); + +unsigned int ipu_cpd_pkg_dir_get_type(const u64 *pkg_dir, int pkg_dir_idx) +{ + return pkg_dir[++pkg_dir_idx * PKG_DIR_ENT_LEN + 1] >> + PKG_DIR_ID_SHIFT & PKG_DIR_ID_MASK; +} +EXPORT_SYMBOL_GPL(ipu_cpd_pkg_dir_get_type); diff --git a/drivers/media/pci/intel/ipu-cpd.h b/drivers/media/pci/intel/ipu-cpd.h new file mode 100644 index 0000000000000..7033e90e135f5 --- /dev/null +++ b/drivers/media/pci/intel/ipu-cpd.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2015 - 2018 Intel Corporation */ + +#ifndef IPU_CPD_H +#define IPU_CPD_H + +#define IPU_CPD_SIZE_OF_FW_ARCH_VERSION 7 +#define IPU_CPD_SIZE_OF_SYSTEM_VERSION 11 +#define IPU_CPD_SIZE_OF_COMPONENT_NAME 12 + +#define IPU_CPD_METADATA_EXTN_TYPE_IUNIT 0x10 + +#define IPU_CPD_METADATA_IMAGE_TYPE_RESERVED 0 +#define IPU_CPD_METADATA_IMAGE_TYPE_BOOTLOADER 1 +#define IPU_CPD_METADATA_IMAGE_TYPE_MAIN_FIRMWARE 2 + +#define IPU_CPD_PKG_DIR_PSYS_SERVER_IDX 0 +#define IPU_CPD_PKG_DIR_ISYS_SERVER_IDX 1 + +#define IPU_CPD_PKG_DIR_CLIENT_PG_TYPE 3 + +struct __packed ipu_cpd_module_data_hdr { + u32 hdr_len; + u32 endian; + u32 fw_pkg_date; + u32 hive_sdk_date; + u32 compiler_date; + u32 target_platform_type; + u8 sys_ver[IPU_CPD_SIZE_OF_SYSTEM_VERSION]; + u8 fw_arch_ver[IPU_CPD_SIZE_OF_FW_ARCH_VERSION]; + u8 rsvd[2]; +}; + +struct __packed ipu_cpd_hdr { + u32 hdr_mark; + u32 ent_cnt; + u8 hdr_ver; + u8 ent_ver; + u8 hdr_len; +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + u8 chksm; + u32 name; +#else + u8 rsvd; + u32 sub_partition_name; + u32 chksm; +#endif +}; + +struct __packed ipu_cpd_ent { + u8 name[IPU_CPD_SIZE_OF_COMPONENT_NAME]; + u32 offset; + u32 len; + u8 rsvd[4]; +}; + +struct __packed ipu_cpd_metadata_cmpnt { + u32 id; + u32 size; + u32 ver; + u8 sha2_hash[32]; + u32 entry_point; + u32 icache_base_offs; + u8 attrs[16]; +}; + +struct __packed ipu_cpd_metadata_extn { + u32 extn_type; + u32 len; + u32 img_type; + u8 rsvd[16]; +}; + +struct __packed ipu_cpd_client_pkg_hdr { + u32 prog_list_offs; + u32 prog_list_size; + u32 prog_desc_offs; + u32 prog_desc_size; + u32 pg_manifest_offs; + u32 pg_manifest_size; + u32 prog_bin_offs; + u32 prog_bin_size; +}; + +void *ipu_cpd_create_pkg_dir(struct ipu_bus_device *adev, + const void *src, + dma_addr_t dma_addr_src, + dma_addr_t *dma_addr, unsigned int *pkg_dir_size); +void ipu_cpd_free_pkg_dir(struct ipu_bus_device *adev, + u64 *pkg_dir, + dma_addr_t dma_addr, unsigned int pkg_dir_size); +u32 ipu_cpd_get_pg_icache_base(struct ipu_device *isp, + u8 idx, + const void *cpd_file, + unsigned int cpd_file_size); +u32 ipu_cpd_get_pg_entry_point(struct ipu_device *isp, + u8 idx, + const void *cpd_file, + unsigned int cpd_file_size); +int ipu_cpd_validate_cpd_file(struct ipu_device *isp, + const void *cpd_file, + unsigned long cpd_file_size); +unsigned int ipu_cpd_pkg_dir_get_address(const u64 *pkg_dir, int pkg_dir_idx); +unsigned int ipu_cpd_pkg_dir_get_num_entries(const u64 *pkg_dir); +unsigned int ipu_cpd_pkg_dir_get_size(const u64 *pkg_dir, int pkg_dir_idx); +unsigned int ipu_cpd_pkg_dir_get_type(const u64 *pkg_dir, int pkg_dir_idx); + +#endif /* IPU_CPD_H */ diff --git a/drivers/media/pci/intel/ipu-dma.c b/drivers/media/pci/intel/ipu-dma.c new file mode 100644 index 0000000000000..fc667ccf0bf31 --- /dev/null +++ b/drivers/media/pci/intel/ipu-dma.c @@ -0,0 +1,490 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipu-dma.h" +#include "ipu-bus.h" +#include "ipu-mmu.h" + +struct ipu_dma_vma { + struct list_head list; + dma_addr_t iova; + size_t size; + void *vaddr; + struct page **pages; +}; + + +static struct ipu_dma_vma *ipu_dma_find_vma_by_iova(struct ipu_mmu *mmu, + dma_addr_t iova) +{ + struct ipu_dma_vma *info; + + list_for_each_entry(info, &mmu->vma_list, list) { + if (iova >= info->iova && iova < info->iova + info->size) + return info; + } + + return NULL; +} + +static struct ipu_dma_vma *ipu_dma_find_vma_by_vaddr(struct ipu_mmu *mmu, + void *vaddr) +{ + struct ipu_dma_vma *info; + + list_for_each_entry(info, &mmu->vma_list, list) { + if (info->vaddr == vaddr) + return info; + } + + return NULL; +} + +/* Begin of things adapted from arch/arm/mm/dma-mapping.c */ +static void __dma_clear_buffer(struct page *page, size_t size, + unsigned long attrs + ) +{ + /* + * Ensure that the allocated pages are zeroed, and that any data + * lurking in the kernel direct-mapped region is invalidated. + */ + if (PageHighMem(page)) { + while (size > 0) { + void *ptr = kmap_atomic(page); + + memset(ptr, 0, PAGE_SIZE); + if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) + clflush_cache_range(ptr, PAGE_SIZE); + kunmap_atomic(ptr); + page++; + size -= PAGE_SIZE; + } + } else { + void *ptr = page_address(page); + + memset(ptr, 0, size); + if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) + clflush_cache_range(ptr, size); + } +} + +static struct page **__dma_alloc_buffer(struct device *dev, size_t size, + gfp_t gfp, + unsigned long attrs + ) +{ + struct page **pages; + int count = size >> PAGE_SHIFT; + int array_size = count * sizeof(struct page *); + int i = 0; + + if (array_size <= PAGE_SIZE) + pages = kzalloc(array_size, GFP_KERNEL); + else + pages = vzalloc(array_size); + 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 = 1 << order; + while (--j) + pages[i + j] = pages[i] + j; + } + + __dma_clear_buffer(pages[i], PAGE_SIZE << order, attrs); + i += 1 << order; + count -= 1 << order; + } + + return pages; +error: + while (i--) + if (pages[i]) + __free_pages(pages[i], 0); + if (array_size <= PAGE_SIZE) + kfree(pages); + else + vfree(pages); + return NULL; +} + +static int __dma_free_buffer(struct device *dev, struct page **pages, + size_t size, + unsigned long attrs + ) +{ + int count = size >> PAGE_SHIFT; + int array_size = count * sizeof(struct page *); + int i; + + for (i = 0; i < count; i++) { + if (pages[i]) { + __dma_clear_buffer(pages[i], PAGE_SIZE, attrs); + __free_pages(pages[i], 0); + } + } + + if (array_size <= PAGE_SIZE) + kfree(pages); + else + vfree(pages); + return 0; +} + +/* End of things adapted from arch/arm/mm/dma-mapping.c */ + +static void ipu_dma_sync_single_for_cpu(struct device *dev, + dma_addr_t dma_handle, + size_t size, + enum dma_data_direction dir) +{ + struct device *aiommu = to_ipu_bus_device(dev)->iommu; + struct ipu_mmu *mmu = dev_get_drvdata(aiommu); + unsigned long pa = ipu_mmu_iova_to_phys(mmu->dmap->mmu_info, + dma_handle); + + clflush_cache_range(phys_to_virt(pa), size); +} + +static void ipu_dma_sync_sg_for_cpu(struct device *dev, + struct scatterlist *sglist, + int nents, enum dma_data_direction dir) +{ + struct scatterlist *sg; + int i; + + for_each_sg(sglist, sg, nents, i) + clflush_cache_range(page_to_virt(sg_page(sg)), sg->length); +} + +static void *ipu_dma_alloc(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + unsigned long attrs + ) +{ + struct device *aiommu = to_ipu_bus_device(dev)->iommu; + struct ipu_mmu *mmu = dev_get_drvdata(aiommu); + struct page **pages; + struct ipu_dma_vma *info; + struct iova *iova; + int i; + int rval; + unsigned int count; + void *addr; + + size = PAGE_ALIGN(size); + + iova = alloc_iova(&mmu->dmap->iovad, size >> PAGE_SHIFT, + dma_get_mask(dev) >> PAGE_SHIFT, 0); + if (!iova) + return NULL; + + pages = __dma_alloc_buffer(dev, size, gfp, attrs); + if (!pages) + goto out_free_iova; + + for (i = 0; iova->pfn_lo + i <= iova->pfn_hi; i++) { + rval = ipu_mmu_map(mmu->dmap->mmu_info, + (iova->pfn_lo + i) << PAGE_SHIFT, + page_to_phys(pages[i]), PAGE_SIZE); + if (rval) + goto out_unmap; + } + + count = iova->pfn_hi - iova->pfn_lo + 1; + + addr = vmap(pages, count, VM_MAP_PUT_PAGES, PAGE_KERNEL); + if (!addr) + goto out_unmap; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + goto out_vunmap; + + + *dma_handle = iova->pfn_lo << PAGE_SHIFT; + info->iova = *dma_handle; + info->size = size; + info->vaddr = addr; + info->pages = pages; + + mutex_lock(&mmu->vma_lock); + list_add(&info->list, &mmu->vma_list); + mutex_unlock(&mmu->vma_lock); + + mmu->tlb_invalidate(mmu); + + return addr; + +out_vunmap: + vunmap(addr); + +out_unmap: + for (i--; i >= 0; i--) { + ipu_mmu_unmap(mmu->dmap->mmu_info, + (iova->pfn_lo + i) << PAGE_SHIFT, + PAGE_SIZE); + } + __dma_free_buffer(dev, pages, size, attrs); + +out_free_iova: + __free_iova(&mmu->dmap->iovad, iova); + + return NULL; +} + +static void ipu_dma_free(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle, + unsigned long attrs + ) +{ + struct device *aiommu = to_ipu_bus_device(dev)->iommu; + struct ipu_mmu *mmu = dev_get_drvdata(aiommu); + struct ipu_dma_vma *info; + struct page **pages; + struct iova *iova = find_iova(&mmu->dmap->iovad, + dma_handle >> PAGE_SHIFT); + + /* dma_map_ops provides vaddr, but we use iova-keyed tracking. */ + (void)vaddr; + + if (WARN_ON(!iova)) + return; + + mutex_lock(&mmu->vma_lock); + info = ipu_dma_find_vma_by_iova(mmu, dma_handle); + if (WARN_ON(!info)) { + mutex_unlock(&mmu->vma_lock); + return; + } + + if (WARN_ON(!info->pages)) { + mutex_unlock(&mmu->vma_lock); + return; + } + + list_del(&info->list); + mutex_unlock(&mmu->vma_lock); + + size = PAGE_ALIGN(size); + if (WARN_ON(size > info->size)) + size = info->size; + + pages = info->pages; + + vunmap(info->vaddr); + + ipu_mmu_unmap(mmu->dmap->mmu_info, iova->pfn_lo << PAGE_SHIFT, + (iova->pfn_hi - iova->pfn_lo + 1) << PAGE_SHIFT); + + __dma_free_buffer(dev, pages, size, attrs); + + __free_iova(&mmu->dmap->iovad, iova); + + kfree(info); + + mmu->tlb_invalidate(mmu); +} + +static int ipu_dma_mmap(struct device *dev, struct vm_area_struct *vma, + void *addr, dma_addr_t iova, size_t size, + unsigned long attrs + ) +{ + struct device *aiommu = to_ipu_bus_device(dev)->iommu; + struct ipu_mmu *mmu = dev_get_drvdata(aiommu); + struct ipu_dma_vma *info; + size_t count = PAGE_ALIGN(size) >> PAGE_SHIFT; + size_t i; + + mutex_lock(&mmu->vma_lock); + info = ipu_dma_find_vma_by_iova(mmu, iova); + if (!info || !info->pages) { + mutex_unlock(&mmu->vma_lock); + return -EFAULT; + } + + if (vma->vm_start & ~PAGE_MASK) + goto out_unlock_einval; + + if (size > info->size) + goto out_unlock_efault; + + for (i = 0; i < count; i++) + vm_insert_page(vma, vma->vm_start + (i << PAGE_SHIFT), + info->pages[i]); + + mutex_unlock(&mmu->vma_lock); + + return 0; + +out_unlock_einval: + mutex_unlock(&mmu->vma_lock); + return -EINVAL; +out_unlock_efault: + mutex_unlock(&mmu->vma_lock); + return -EFAULT; +} + +static void ipu_dma_unmap_sg(struct device *dev, + struct scatterlist *sglist, + int nents, enum dma_data_direction dir, + unsigned long attrs + ) +{ + struct device *aiommu = to_ipu_bus_device(dev)->iommu; + struct ipu_mmu *mmu = dev_get_drvdata(aiommu); + struct iova *iova = find_iova(&mmu->dmap->iovad, + sg_dma_address(sglist) >> PAGE_SHIFT); + + if (!nents) + return; + + if (WARN_ON(!iova)) + return; + + if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) + ipu_dma_sync_sg_for_cpu(dev, sglist, nents, DMA_BIDIRECTIONAL); + + ipu_mmu_unmap(mmu->dmap->mmu_info, iova->pfn_lo << PAGE_SHIFT, + (iova->pfn_hi - iova->pfn_lo + 1) << PAGE_SHIFT); + + mmu->tlb_invalidate(mmu); + + __free_iova(&mmu->dmap->iovad, iova); +} + +static int ipu_dma_map_sg(struct device *dev, struct scatterlist *sglist, + int nents, enum dma_data_direction dir, + unsigned long attrs + ) +{ + struct device *aiommu = to_ipu_bus_device(dev)->iommu; + struct ipu_mmu *mmu = dev_get_drvdata(aiommu); + struct scatterlist *sg; + struct iova *iova; + size_t size = 0; + u32 iova_addr; + int i; + + for_each_sg(sglist, sg, nents, i) + size += PAGE_ALIGN(sg->length) >> PAGE_SHIFT; + + dev_dbg(dev, "dmamap: mapping sg %d entries, %zu pages\n", nents, size); + + iova = alloc_iova(&mmu->dmap->iovad, size, + dma_get_mask(dev) >> PAGE_SHIFT, 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) { + int rval; + + dev_dbg(dev, "mapping entry %d: iova 0x%8.8x,phy 0x%16.16llx\n", + i, iova_addr << PAGE_SHIFT, + (unsigned long long)page_to_phys(sg_page(sg))); + rval = ipu_mmu_map(mmu->dmap->mmu_info, iova_addr << PAGE_SHIFT, + page_to_phys(sg_page(sg)), + PAGE_ALIGN(sg->length)); + if (rval) + goto out_fail; + sg_dma_address(sg) = iova_addr << PAGE_SHIFT; +#ifdef CONFIG_NEED_SG_DMA_LENGTH + sg_dma_len(sg) = sg->length; +#endif /* CONFIG_NEED_SG_DMA_LENGTH */ + + iova_addr += PAGE_ALIGN(sg->length) >> PAGE_SHIFT; + } + + if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) + ipu_dma_sync_sg_for_cpu(dev, sglist, nents, DMA_BIDIRECTIONAL); + + mmu->tlb_invalidate(mmu); + + return nents; + +out_fail: + ipu_dma_unmap_sg(dev, sglist, i, dir, attrs); + + return 0; +} + +/* + * Create scatter-list for the already allocated DMA buffer + */ +static int ipu_dma_get_sgtable(struct device *dev, struct sg_table *sgt, + void *cpu_addr, dma_addr_t handle, size_t size, + unsigned long attrs + ) +{ + struct device *aiommu = to_ipu_bus_device(dev)->iommu; + struct ipu_mmu *mmu = dev_get_drvdata(aiommu); + struct ipu_dma_vma *info; + int n_pages; + int ret = 0; + + mutex_lock(&mmu->vma_lock); + info = ipu_dma_find_vma_by_iova(mmu, handle); + if (!info) + info = ipu_dma_find_vma_by_vaddr(mmu, cpu_addr); + + if (WARN_ON(!info || !info->pages)) { + mutex_unlock(&mmu->vma_lock); + return -ENOMEM; + } + + n_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; + + ret = sg_alloc_table_from_pages(sgt, info->pages, n_pages, 0, size, + GFP_KERNEL); + mutex_unlock(&mmu->vma_lock); + if (ret) + dev_dbg(dev, "IPU get sgt table fail\n"); + + return ret; +} + +const struct dma_map_ops ipu_dma_ops = { + .alloc = ipu_dma_alloc, + .free = ipu_dma_free, + .mmap = ipu_dma_mmap, + .map_sg = ipu_dma_map_sg, + .unmap_sg = ipu_dma_unmap_sg, + .sync_single_for_cpu = ipu_dma_sync_single_for_cpu, + .sync_single_for_device = ipu_dma_sync_single_for_cpu, + .sync_sg_for_cpu = ipu_dma_sync_sg_for_cpu, + .sync_sg_for_device = ipu_dma_sync_sg_for_cpu, + .get_sgtable = ipu_dma_get_sgtable, +}; +EXPORT_SYMBOL_GPL(ipu_dma_ops); diff --git a/drivers/media/pci/intel/ipu-dma.h b/drivers/media/pci/intel/ipu-dma.h new file mode 100644 index 0000000000000..f5af2c6fe90b6 --- /dev/null +++ b/drivers/media/pci/intel/ipu-dma.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_DMA_H +#define IPU_DMA_H + +#include + +struct ipu_mmu_info; + +struct ipu_dma_mapping { + struct ipu_mmu_info *mmu_info; + struct iova_domain iovad; + struct kref ref; +}; + +extern const struct dma_map_ops ipu_dma_ops; + +#endif /* IPU_DMA_H */ diff --git a/drivers/media/pci/intel/ipu-fw-com.c b/drivers/media/pci/intel/ipu-fw-com.c new file mode 100644 index 0000000000000..a4f5a9daf30ee --- /dev/null +++ b/drivers/media/pci/intel/ipu-fw-com.c @@ -0,0 +1,472 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include + +#include +#include +#include +#include +#include + +#include "ipu.h" +#include "ipu-fw-com.h" +#include "ipu-bus.h" + +/* + * FWCOM layer is a shared resource between FW and driver. It consist + * of token queues to both send and receive directions. Queue is simply + * an array of structures with read and write indexes to the queue. + * There are 1...n queues to both directions. Queues locates in + * system ram and are mapped to ISP MMU so that both CPU and ISP can + * see the same buffer. Indexes are located in ISP DMEM so that FW code + * can poll those with very low latency and cost. CPU access to indexes is + * more costly but that happens only at message sending time and + * interrupt trigged message handling. CPU doesn't need to poll indexes. + * wr_reg / rd_reg are offsets to those dmem location. They are not + * the indexes itself. + */ + +/* Shared structure between driver and FW - do not modify */ +struct ipu_fw_sys_queue { + u64 host_address; + u32 vied_address; + u32 size; + u32 token_size; + u32 wr_reg; /* reg no in subsystem's regmem */ + u32 rd_reg; + u32 _align; +}; + +struct ipu_fw_sys_queue_res { + u64 host_address; + u32 vied_address; + u32 reg; +}; + +enum syscom_state { + /* Program load or explicit host setting should init to this */ + SYSCOM_STATE_UNINIT = 0x57A7E000, + /* SP Syscom sets this when it is ready for use */ + SYSCOM_STATE_READY = 0x57A7E001, + /* SP Syscom sets this when no more syscom accesses will happen */ + SYSCOM_STATE_INACTIVE = 0x57A7E002 +}; + +enum syscom_cmd { + /* Program load or explicit host setting should init to this */ + SYSCOM_COMMAND_UNINIT = 0x57A7F000, + /* Host Syscom requests syscom to become inactive */ + SYSCOM_COMMAND_INACTIVE = 0x57A7F001 +}; + +/* firmware config: data that sent from the host to SP via DDR */ +/* Cell copies data into a context */ + +struct ipu_fw_syscom_config { + u32 firmware_address; + + u32 num_input_queues; + u32 num_output_queues; + + /* ISP pointers to an array of ipu_fw_sys_queue structures */ + u32 input_queue; + u32 output_queue; + + /* ISYS / PSYS private data */ + u32 specific_addr; + u32 specific_size; +}; + +/* End of shared structures / data */ + +struct ipu_fw_com_context { + struct ipu_bus_device *adev; + void __iomem *dmem_addr; + int (*cell_ready)(struct ipu_bus_device *adev); + void (*cell_start)(struct ipu_bus_device *adev); + + void *dma_buffer; + dma_addr_t dma_addr; + unsigned int dma_size; + unsigned long attrs; + + unsigned int num_input_queues; + unsigned int num_output_queues; + + struct ipu_fw_sys_queue *input_queue; /* array of host to SP queues */ + struct ipu_fw_sys_queue *output_queue; /* array of SP to host */ + + void *config_host_addr; + void *specific_host_addr; + u64 ibuf_host_addr; + u64 obuf_host_addr; + + u32 config_vied_addr; + u32 input_queue_vied_addr; + u32 output_queue_vied_addr; + u32 specific_vied_addr; + u32 ibuf_vied_addr; + u32 obuf_vied_addr; +}; + +#define FW_COM_WR_REG 0 +#define FW_COM_RD_REG 4 + +#define REGMEM_OFFSET 0 + +enum regmem_id { + /* pass pkg_dir address to SPC in non-secure mode */ + PKG_DIR_ADDR_REG = 0, + /* pass syscom configuration to SPC */ + SYSCOM_CONFIG_REG = 1, + /* syscom state - modified by SP */ + SYSCOM_STATE_REG = 2, + /* syscom commands - modified by the host */ + SYSCOM_COMMAND_REG = 3, + /* Store interrupt status - updated by SP */ + SYSCOM_IRQ_REG = 4, + /* Store VTL0_ADDR_MASK in trusted secure regision - provided by host.*/ + SYSCOM_VTL0_ADDR_MASK = 5, + /* first syscom queue pointer register */ + SYSCOM_QPR_BASE_REG = 6 +}; + +enum message_direction { + DIR_RECV = 0, + DIR_SEND +}; + +static unsigned int num_messages(unsigned int wr, unsigned int rd, + unsigned int size) +{ + if (wr < rd) + wr += size; + return wr - rd; +} + +static unsigned int num_free(unsigned int wr, unsigned int rd, + unsigned int size) +{ + return size - num_messages(wr, rd, size); +} + +static unsigned int curr_index(void __iomem *q_dmem, + enum message_direction dir) +{ + return readl(q_dmem + + (dir == DIR_RECV ? FW_COM_RD_REG : FW_COM_WR_REG)); +} + +static unsigned int inc_index(void __iomem *q_dmem, struct ipu_fw_sys_queue *q, + enum message_direction dir) +{ + unsigned int index; + + index = curr_index(q_dmem, dir) + 1; + return index >= q->size ? 0 : index; +} + +static unsigned int ipu_sys_queue_buf_size(unsigned int size, + unsigned int token_size) +{ + return (size + 1) * token_size; +} + +static void ipu_sys_queue_init(struct ipu_fw_sys_queue *q, unsigned int size, + unsigned int token_size, struct ipu_fw_sys_queue_res *res) +{ + unsigned int buf_size; + + q->size = size + 1; + q->token_size = token_size; + buf_size = ipu_sys_queue_buf_size(size, token_size); + + /* acquire the shared buffer space */ + q->host_address = res->host_address; + res->host_address += buf_size; + q->vied_address = res->vied_address; + res->vied_address += buf_size; + + /* acquire the shared read and writer pointers */ + q->wr_reg = res->reg; + res->reg++; + q->rd_reg = res->reg; + res->reg++; +} + +void *ipu_fw_com_prepare(struct ipu_fw_com_cfg *cfg, + struct ipu_bus_device *adev, void __iomem *base) +{ + struct ipu_fw_com_context *ctx; + struct ipu_fw_syscom_config *fw_cfg; + unsigned int i; + unsigned int sizeall, offset; + unsigned int sizeinput = 0, sizeoutput = 0; + unsigned long attrs = 0; + struct ipu_fw_sys_queue_res res; + + /* error handling */ + if (!cfg || !cfg->cell_start || !cfg->cell_ready) + return NULL; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return NULL; + ctx->dmem_addr = base + cfg->dmem_addr + REGMEM_OFFSET; + ctx->adev = adev; + ctx->cell_start = cfg->cell_start; + ctx->cell_ready = cfg->cell_ready; + + ctx->num_input_queues = cfg->num_input_queues; + ctx->num_output_queues = cfg->num_output_queues; + + /* + * Allocate DMA mapped memory. Allocate one big chunk. + */ + sizeall = + /* Base cfg for FW */ + roundup(sizeof(struct ipu_fw_syscom_config), 8) + + /* Descriptions of the queues */ + cfg->num_input_queues * sizeof(struct ipu_fw_sys_queue) + + cfg->num_output_queues * sizeof(struct ipu_fw_sys_queue) + + /* FW specific information structure */ + roundup(cfg->specific_size, 8); + + for (i = 0; i < cfg->num_input_queues; i++) + sizeinput += ipu_sys_queue_buf_size(cfg->input[i].queue_size, + cfg->input[i].token_size); + + for (i = 0; i < cfg->num_output_queues; i++) + sizeoutput += ipu_sys_queue_buf_size(cfg->output[i].queue_size, + cfg->output[i].token_size); + + sizeall += sizeinput + sizeoutput; + + ctx->dma_buffer = dma_alloc_attrs(&ctx->adev->dev, sizeall, + &ctx->dma_addr, GFP_KERNEL, + attrs); + ctx->attrs = attrs; + if (!ctx->dma_buffer) { + dev_err(&ctx->adev->dev, "failed to allocate dma memory\n"); + return NULL; + } + + ctx->dma_size = sizeall; + + /* This is the address where FW starts to parse allocations */ + ctx->config_host_addr = ctx->dma_buffer; + ctx->config_vied_addr = ctx->dma_addr; + fw_cfg = (struct ipu_fw_syscom_config *)ctx->config_host_addr; + offset = roundup(sizeof(struct ipu_fw_syscom_config), 8); + + ctx->input_queue = ctx->dma_buffer + offset; + ctx->input_queue_vied_addr = ctx->dma_addr + offset; + offset += cfg->num_input_queues * sizeof(struct ipu_fw_sys_queue); + + ctx->output_queue = ctx->dma_buffer + offset; + ctx->output_queue_vied_addr = ctx->dma_addr + offset; + offset += cfg->num_output_queues * sizeof(struct ipu_fw_sys_queue); + + ctx->specific_host_addr = ctx->dma_buffer + offset; + ctx->specific_vied_addr = ctx->dma_addr + offset; + offset += roundup(cfg->specific_size, 8); + + ctx->ibuf_host_addr = (uintptr_t)(ctx->dma_buffer + offset); + ctx->ibuf_vied_addr = ctx->dma_addr + offset; + offset += sizeinput; + + ctx->obuf_host_addr = (uintptr_t)(ctx->dma_buffer + offset); + ctx->obuf_vied_addr = ctx->dma_addr + offset; + offset += sizeoutput; + + /* initialize input queues */ + res.reg = SYSCOM_QPR_BASE_REG; + res.host_address = ctx->ibuf_host_addr; + res.vied_address = ctx->ibuf_vied_addr; + for (i = 0; i < cfg->num_input_queues; i++) { + ipu_sys_queue_init(ctx->input_queue + i, + cfg->input[i].queue_size, + cfg->input[i].token_size, &res); + } + + /* initialize output queues */ + res.host_address = ctx->obuf_host_addr; + res.vied_address = ctx->obuf_vied_addr; + for (i = 0; i < cfg->num_output_queues; i++) { + ipu_sys_queue_init(ctx->output_queue + i, + cfg->output[i].queue_size, + cfg->output[i].token_size, &res); + } + + /* copy firmware specific data */ + if (cfg->specific_addr && cfg->specific_size) { + memcpy((void *)ctx->specific_host_addr, + cfg->specific_addr, cfg->specific_size); + } + + fw_cfg->num_input_queues = cfg->num_input_queues; + fw_cfg->num_output_queues = cfg->num_output_queues; + fw_cfg->input_queue = ctx->input_queue_vied_addr; + fw_cfg->output_queue = ctx->output_queue_vied_addr; + fw_cfg->specific_addr = ctx->specific_vied_addr; + fw_cfg->specific_size = cfg->specific_size; + + clflush_cache_range(ctx->dma_buffer, sizeall); + + return ctx; +} +EXPORT_SYMBOL_GPL(ipu_fw_com_prepare); + +int ipu_fw_com_open(struct ipu_fw_com_context *ctx) +{ + /* Check if SP is in valid state */ + if (!ctx->cell_ready(ctx->adev)) + return -EIO; + + /* store syscom uninitialized state */ + writel(SYSCOM_STATE_UNINIT, ctx->dmem_addr + SYSCOM_STATE_REG * 4); + /* store syscom uninitialized command */ + writel(SYSCOM_COMMAND_UNINIT, + ctx->dmem_addr + SYSCOM_COMMAND_REG * 4); + /* store firmware configuration address */ + writel(ctx->config_vied_addr, + ctx->dmem_addr + SYSCOM_CONFIG_REG * 4); + + ctx->cell_start(ctx->adev); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fw_com_open); + +int ipu_fw_com_close(struct ipu_fw_com_context *ctx) +{ + int state; + + state = readl(ctx->dmem_addr + 4 * SYSCOM_STATE_REG); + if (state != SYSCOM_STATE_READY) + return -EBUSY; + + /* set close request flag */ + writel(SYSCOM_COMMAND_INACTIVE, ctx->dmem_addr + + SYSCOM_COMMAND_REG * 4); + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fw_com_close); + +int ipu_fw_com_release(struct ipu_fw_com_context *ctx, unsigned int force) +{ + /* check if release is forced, an verify cell state if it is not */ + if (!force && !ctx->cell_ready(ctx->adev)) + return -EBUSY; + + dma_free_attrs(&ctx->adev->dev, ctx->dma_size, + ctx->dma_buffer, ctx->dma_addr, + ctx->attrs); + kfree(ctx); + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fw_com_release); + +int ipu_fw_com_ready(struct ipu_fw_com_context *ctx) +{ + int state; + + /* check if SP syscom is ready to open the queue */ + state = readl(ctx->dmem_addr + SYSCOM_STATE_REG * 4); + if (state != SYSCOM_STATE_READY) + return -EBUSY; /* SPC is not ready to handle messages yet */ + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fw_com_ready); + +static bool is_index_valid(struct ipu_fw_sys_queue *q, unsigned int index) +{ + if (index >= q->size) + return false; + return true; +} + +void *ipu_send_get_token(struct ipu_fw_com_context *ctx, int q_nbr) +{ + struct ipu_fw_sys_queue *q = &ctx->input_queue[q_nbr]; + void __iomem *q_dmem = ctx->dmem_addr + q->wr_reg * 4; + unsigned int wr, rd; + unsigned int packets; + unsigned int index; + + wr = readl(q_dmem + FW_COM_WR_REG); + rd = readl(q_dmem + FW_COM_RD_REG); + + /* Catch indexes in dmem */ + if (!is_index_valid(q, wr) || !is_index_valid(q, rd)) + return NULL; + + packets = num_free(wr + 1, rd, q->size); + if (packets <= 0) + return NULL; + + index = curr_index(q_dmem, DIR_SEND); + + return (void *)(unsigned long)q->host_address + (index * q->token_size); +} +EXPORT_SYMBOL_GPL(ipu_send_get_token); + +void ipu_send_put_token(struct ipu_fw_com_context *ctx, int q_nbr) +{ + struct ipu_fw_sys_queue *q = &ctx->input_queue[q_nbr]; + void __iomem *q_dmem = ctx->dmem_addr + q->wr_reg * 4; + int index = curr_index(q_dmem, DIR_SEND); + void *addr = (void *)(unsigned long)q->host_address + + (index * q->token_size); + + clflush_cache_range(addr, q->token_size); + + /* Increment index */ + index = inc_index(q_dmem, q, DIR_SEND); + + writel(index, q_dmem + FW_COM_WR_REG); +} +EXPORT_SYMBOL_GPL(ipu_send_put_token); + +void *ipu_recv_get_token(struct ipu_fw_com_context *ctx, int q_nbr) +{ + struct ipu_fw_sys_queue *q = &ctx->output_queue[q_nbr]; + void __iomem *q_dmem = ctx->dmem_addr + q->wr_reg * 4; + unsigned int wr, rd; + unsigned int packets; + void *addr; + + wr = readl(q_dmem + FW_COM_WR_REG); + rd = readl(q_dmem + FW_COM_RD_REG); + + /* Catch indexes in dmem? */ + if (!is_index_valid(q, wr) || !is_index_valid(q, rd)) + return NULL; + + packets = num_messages(wr, rd, q->size); + if (packets <= 0) + return NULL; + + addr = (void *)(unsigned long)q->host_address + (rd * q->token_size); + clflush_cache_range(addr, q->token_size); + + return addr; +} +EXPORT_SYMBOL_GPL(ipu_recv_get_token); + +void ipu_recv_put_token(struct ipu_fw_com_context *ctx, int q_nbr) +{ + struct ipu_fw_sys_queue *q = &ctx->output_queue[q_nbr]; + void __iomem *q_dmem = ctx->dmem_addr + q->wr_reg * 4; + unsigned int rd = inc_index(q_dmem, q, DIR_RECV); + + /* Release index */ + writel(rd, q_dmem + FW_COM_RD_REG); +} +EXPORT_SYMBOL_GPL(ipu_recv_put_token); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu fw comm library"); diff --git a/drivers/media/pci/intel/ipu-fw-com.h b/drivers/media/pci/intel/ipu-fw-com.h new file mode 100644 index 0000000000000..de47455ea9a49 --- /dev/null +++ b/drivers/media/pci/intel/ipu-fw-com.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_FW_COM_H +#define IPU_FW_COM_H + +struct ipu_fw_com_context; +struct ipu_bus_device; + +struct ipu_fw_syscom_queue_config { + unsigned int queue_size; /* tokens per queue */ + unsigned int token_size; /* bytes per token */ +}; + +struct ipu_fw_com_cfg { + unsigned int num_input_queues; + unsigned int num_output_queues; + struct ipu_fw_syscom_queue_config *input; + struct ipu_fw_syscom_queue_config *output; + + unsigned int dmem_addr; + + /* firmware-specific configuration data */ + void *specific_addr; + unsigned int specific_size; + int (*cell_ready)(struct ipu_bus_device *adev); + void (*cell_start)(struct ipu_bus_device *adev); +}; + +void *ipu_fw_com_prepare(struct ipu_fw_com_cfg *cfg, + struct ipu_bus_device *adev, void __iomem *base); + +int ipu_fw_com_open(struct ipu_fw_com_context *ctx); +int ipu_fw_com_ready(struct ipu_fw_com_context *ctx); +int ipu_fw_com_close(struct ipu_fw_com_context *ctx); +int ipu_fw_com_release(struct ipu_fw_com_context *ctx, unsigned int force); + +void *ipu_recv_get_token(struct ipu_fw_com_context *ctx, int q_nbr); +void ipu_recv_put_token(struct ipu_fw_com_context *ctx, int q_nbr); +void *ipu_send_get_token(struct ipu_fw_com_context *ctx, int q_nbr); +void ipu_send_put_token(struct ipu_fw_com_context *ctx, int q_nbr); + +#endif diff --git a/drivers/media/pci/intel/ipu-fw-isys.c b/drivers/media/pci/intel/ipu-fw-isys.c new file mode 100644 index 0000000000000..130d2ca4a438f --- /dev/null +++ b/drivers/media/pci/intel/ipu-fw-isys.c @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include + +#include +#include +#include "ipu-platform-regs.h" +#include "ipu-fw-isys.h" +#include "ipu-fw-com.h" +#include "ipu-isys.h" + +#define IPU_FW_UNSUPPORTED_DATA_TYPE 0 +static const uint32_t +extracted_bits_per_pixel_per_mipi_data_type[N_IPU_FW_ISYS_MIPI_DATA_TYPE] = { + + 64, /* [0x00] IPU_FW_ISYS_MIPI_DATA_TYPE_FRAME_START_CODE */ + 64, /* [0x01] IPU_FW_ISYS_MIPI_DATA_TYPE_FRAME_END_CODE */ + 64, /* [0x02] IPU_FW_ISYS_MIPI_DATA_TYPE_LINE_START_CODE */ + 64, /* [0x03] IPU_FW_ISYS_MIPI_DATA_TYPE_LINE_END_CODE */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x04] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x05] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x06] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x07] */ + 64, /* [0x08] IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT1 */ + 64, /* [0x09] IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT2 */ + 64, /* [0x0A] IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT3 */ + 64, /* [0x0B] IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT4 */ + 64, /* [0x0C] IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT5 */ + 64, /* [0x0D] IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT6 */ + 64, /* [0x0E] IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT7 */ + 64, /* [0x0F] IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT8 */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x10] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x11] */ + 8, /* [0x12] IPU_FW_ISYS_MIPI_DATA_TYPE_EMBEDDED */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x13] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x14] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x15] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x16] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x17] */ + 12, /* [0x18] IPU_FW_ISYS_MIPI_DATA_TYPE_YUV420_8 */ + 15, /* [0x19] IPU_FW_ISYS_MIPI_DATA_TYPE_YUV420_10 */ + 12, /* [0x1A] IPU_FW_ISYS_MIPI_DATA_TYPE_YUV420_8_LEGACY */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x1B] */ + 12, /* [0x1C] IPU_FW_ISYS_MIPI_DATA_TYPE_YUV420_8_SHIFT */ + 15, /* [0x1D] IPU_FW_ISYS_MIPI_DATA_TYPE_YUV420_10_SHIFT */ + 16, /* [0x1E] IPU_FW_ISYS_MIPI_DATA_TYPE_YUV422_8 */ + 20, /* [0x1F] IPU_FW_ISYS_MIPI_DATA_TYPE_YUV422_10 */ + 16, /* [0x20] IPU_FW_ISYS_MIPI_DATA_TYPE_RGB_444 */ + 16, /* [0x21] IPU_FW_ISYS_MIPI_DATA_TYPE_RGB_555 */ + 16, /* [0x22] IPU_FW_ISYS_MIPI_DATA_TYPE_RGB_565 */ + 18, /* [0x23] IPU_FW_ISYS_MIPI_DATA_TYPE_RGB_666 */ + 24, /* [0x24] IPU_FW_ISYS_MIPI_DATA_TYPE_RGB_888 */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x25] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x26] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x27] */ + 6, /* [0x28] IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_6 */ + 7, /* [0x29] IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_7 */ + 8, /* [0x2A] IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_8 */ + 10, /* [0x2B] IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_10 */ + 12, /* [0x2C] IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_12 */ + 14, /* [0x2D] IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_14 */ + 16, /* [0x2E] IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_16 */ + 8, /* [0x2F] IPU_FW_ISYS_MIPI_DATA_TYPE_BINARY_8 */ + 8, /* [0x30] IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF1 */ + 8, /* [0x31] IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF2 */ + 8, /* [0x32] IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF3 */ + 8, /* [0x33] IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF4 */ + 8, /* [0x34] IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF5 */ + 8, /* [0x35] IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF6 */ + 8, /* [0x36] IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF7 */ + 8, /* [0x37] IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF8 */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x38] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x39] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x3A] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x3B] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x3C] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x3D] */ + IPU_FW_UNSUPPORTED_DATA_TYPE, /* [0x3E] */ + IPU_FW_UNSUPPORTED_DATA_TYPE /* [0x3F] */ +}; + + +void ipu_fw_isys_set_params(struct ipu_fw_isys_stream_cfg_data_abi *stream_cfg) +{ + unsigned int i; + unsigned int idx; + + for (i = 0; i < stream_cfg->nof_input_pins; i++) { + idx = stream_cfg->input_pins[i].dt; + stream_cfg->input_pins[i].bits_per_pix = + extracted_bits_per_pixel_per_mipi_data_type[idx]; + stream_cfg->input_pins[i].mapped_dt = + N_IPU_FW_ISYS_MIPI_DATA_TYPE; + } +} + +void +ipu_fw_isys_dump_stream_cfg(struct device *dev, + struct ipu_fw_isys_stream_cfg_data_abi *stream_cfg) +{ + unsigned int i; + + dev_dbg(dev, "---------------------------\n"); + dev_dbg(dev, "IPU_FW_ISYS_STREAM_CFG_DATA\n"); + dev_dbg(dev, "---------------------------\n"); + + dev_dbg(dev, "Source %d\n", stream_cfg->src); + dev_dbg(dev, "VC %d\n", stream_cfg->vc); + dev_dbg(dev, "Nof input pins %d\n", stream_cfg->nof_input_pins); + dev_dbg(dev, "Nof output pins %d\n", stream_cfg->nof_output_pins); + + for (i = 0; i < stream_cfg->nof_input_pins; i++) { + dev_dbg(dev, "Input pin %d\n", i); + dev_dbg(dev, "Mipi data type 0x%0x\n", + stream_cfg->input_pins[i].dt); + dev_dbg(dev, "Mipi store mode %d\n", + stream_cfg->input_pins[i].mipi_store_mode); + dev_dbg(dev, "Bits per pixel %d\n", + stream_cfg->input_pins[i].bits_per_pix); + dev_dbg(dev, "Mapped data type 0x%0x\n", + stream_cfg->input_pins[i].mapped_dt); + dev_dbg(dev, "Input res width %d\n", + stream_cfg->input_pins[i].input_res.width); + dev_dbg(dev, "Input res height %d\n", + stream_cfg->input_pins[i].input_res.height); + } + + for (i = 0; i < N_IPU_FW_ISYS_CROPPING_LOCATION; i++) { + dev_dbg(dev, "Crop info %d\n", i); + dev_dbg(dev, "Crop.top_offset %d\n", + stream_cfg->crop[i].top_offset); + dev_dbg(dev, "Crop.left_offset %d\n", + stream_cfg->crop[i].left_offset); + dev_dbg(dev, "Crop.bottom_offset %d\n", + stream_cfg->crop[i].bottom_offset); + dev_dbg(dev, "Crop.right_offset %d\n", + stream_cfg->crop[i].right_offset); + dev_dbg(dev, "----------------\n"); + } + + for (i = 0; i < stream_cfg->nof_output_pins; i++) { + dev_dbg(dev, "Output pin %d\n", i); + dev_dbg(dev, "Output input pin id %d\n", + stream_cfg->output_pins[i].input_pin_id); + dev_dbg(dev, "Output res width %d\n", + stream_cfg->output_pins[i].output_res.width); + dev_dbg(dev, "Output res height %d\n", + stream_cfg->output_pins[i].output_res.height); + dev_dbg(dev, "Stride %d\n", stream_cfg->output_pins[i].stride); + dev_dbg(dev, "Pin type %d\n", stream_cfg->output_pins[i].pt); + dev_dbg(dev, "Ft %d\n", stream_cfg->output_pins[i].ft); + dev_dbg(dev, "Watermar in lines %d\n", + stream_cfg->output_pins[i].watermark_in_lines); + dev_dbg(dev, "Send irq %d\n", + stream_cfg->output_pins[i].send_irq); + dev_dbg(dev, "Reserve compression %d\n", + stream_cfg->output_pins[i].reserve_compression); + dev_dbg(dev, "snoopable %d\n", + stream_cfg->output_pins[i].snoopable); + dev_dbg(dev, "sensor type %d\n", + stream_cfg->output_pins[i].sensor_type); + dev_dbg(dev, "----------------\n"); + } + + dev_dbg(dev, "Isl_use %d\n", stream_cfg->isl_use); + switch (stream_cfg->isl_use) { + case IPU_FW_ISYS_USE_SINGLE_ISA: + dev_dbg(dev, "ISA cfg:\n"); + dev_dbg(dev, "blc_enabled %d\n", stream_cfg->isa_cfg.cfg.blc); + dev_dbg(dev, "lsc_enabled %d\n", stream_cfg->isa_cfg.cfg.lsc); + dev_dbg(dev, "dpc_enabled %d\n", stream_cfg->isa_cfg.cfg.dpc); + dev_dbg(dev, "downscaler_enabled %d\n", + stream_cfg->isa_cfg.cfg.downscaler); + dev_dbg(dev, "awb_enabled %d\n", stream_cfg->isa_cfg.cfg.awb); + dev_dbg(dev, "af_enabled %d\n", stream_cfg->isa_cfg.cfg.af); + dev_dbg(dev, "ae_enabled %d\n", stream_cfg->isa_cfg.cfg.ae); + break; + case IPU_FW_ISYS_USE_SINGLE_DUAL_ISL: + case IPU_FW_ISYS_USE_NO_ISL_NO_ISA: + default: + break; + } +} + +void ipu_fw_isys_dump_frame_buff_set(struct device *dev, + struct ipu_fw_isys_frame_buff_set_abi *buf, + unsigned int outputs) +{ + unsigned int i; + + dev_dbg(dev, "--------------------------\n"); + dev_dbg(dev, "IPU_FW_ISYS_FRAME_BUFF_SET\n"); + dev_dbg(dev, "--------------------------\n"); + + for (i = 0; i < outputs; i++) { + dev_dbg(dev, "Output pin %d\n", i); + dev_dbg(dev, "out_buf_id %llu\n", + buf->output_pins[i].out_buf_id); + dev_dbg(dev, "addr 0x%x\n", buf->output_pins[i].addr); + dev_dbg(dev, "compress %u\n", buf->output_pins[i].compress); + + dev_dbg(dev, "----------------\n"); + } + + dev_dbg(dev, "process_group_light.addr 0x%x\n", + buf->process_group_light.addr); + dev_dbg(dev, "process_group_light.param_buf_id %llu\n", + buf->process_group_light.param_buf_id); + dev_dbg(dev, "send_irq_sof 0x%x\n", buf->send_irq_sof); + dev_dbg(dev, "send_irq_eof 0x%x\n", buf->send_irq_eof); + dev_dbg(dev, "send_resp_sof 0x%x\n", buf->send_resp_sof); + dev_dbg(dev, "send_resp_eof 0x%x\n", buf->send_resp_eof); +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + dev_dbg(dev, "send_irq_capture_ack 0x%x\n", buf->send_irq_capture_ack); + dev_dbg(dev, "send_irq_capture_done 0x%x\n", buf->send_irq_capture_done); +#endif +} diff --git a/drivers/media/pci/intel/ipu-fw-isys.h b/drivers/media/pci/intel/ipu-fw-isys.h new file mode 100644 index 0000000000000..2853e1e1c9d96 --- /dev/null +++ b/drivers/media/pci/intel/ipu-fw-isys.h @@ -0,0 +1,885 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_FW_ISYS_H +#define IPU_FW_ISYS_H + +#include "ipu-fw-com.h" + +/* Max number of Input/Output Pins */ +#define IPU_MAX_IPINS 4 + +/* worst case is ISA use where a single input pin produces: + * Mipi output, NS Pixel Output, and Scaled Pixel Output. + * This is how the 2 is calculated + */ +#define IPU_MAX_OPINS ((IPU_MAX_IPINS) + 2) + +/* Max number of supported virtual streams */ +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) +#define IPU_STREAM_ID_MAX 8 +#else +#define IPU_STREAM_ID_MAX 16 +#endif + +/* Aligned with the approach of having one dedicated per stream */ +#define IPU_N_MAX_MSG_SEND_QUEUES (IPU_STREAM_ID_MAX) +/* Single return queue for all streams/commands type */ +#define IPU_N_MAX_MSG_RECV_QUEUES 1 +/* Single device queue for high priority commands (bypass in-order queue) */ +#define IPU_N_MAX_DEV_SEND_QUEUES 1 +/* Single dedicated send queue for proxy interface */ +#define IPU_N_MAX_PROXY_SEND_QUEUES 1 +/* Single dedicated recv queue for proxy interface */ +#define IPU_N_MAX_PROXY_RECV_QUEUES 1 +/* Send queues layout */ +#define IPU_BASE_PROXY_SEND_QUEUES 0 +#define IPU_BASE_DEV_SEND_QUEUES \ + (IPU_BASE_PROXY_SEND_QUEUES + IPU_N_MAX_PROXY_SEND_QUEUES) +#define IPU_BASE_MSG_SEND_QUEUES \ + (IPU_BASE_DEV_SEND_QUEUES + IPU_N_MAX_DEV_SEND_QUEUES) +#define IPU_N_MAX_SEND_QUEUES \ + (IPU_BASE_MSG_SEND_QUEUES + IPU_N_MAX_MSG_SEND_QUEUES) +/* Recv queues layout */ +#define IPU_BASE_PROXY_RECV_QUEUES 0 +#define IPU_BASE_MSG_RECV_QUEUES \ + (IPU_BASE_PROXY_RECV_QUEUES + IPU_N_MAX_PROXY_RECV_QUEUES) +#define IPU_N_MAX_RECV_QUEUES \ + (IPU_BASE_MSG_RECV_QUEUES + IPU_N_MAX_MSG_RECV_QUEUES) + +/* Consider 1 slot per stream since driver is not expected to pipeline + * device commands for the same stream + */ +#define IPU_DEV_SEND_QUEUE_SIZE (IPU_STREAM_ID_MAX) + +/* Max number of supported SRAM buffer partitions. + * It refers to the size of stream partitions. + * These partitions are further subpartitioned internally + * by the FW, but by declaring statically the stream + * partitions we solve the buffer fragmentation issue + */ +#define IPU_NOF_SRAM_BLOCKS_MAX (IPU_STREAM_ID_MAX) + +/* Max number of supported input pins routed in ISL */ +#define IPU_MAX_IPINS_IN_ISL 2 + +/* Max number of planes for frame formats supported by the FW */ +#define IPU_PIN_PLANES_MAX 4 + +/** + * enum ipu_fw_isys_resp_type + */ +enum ipu_fw_isys_resp_type { + IPU_FW_ISYS_RESP_TYPE_STREAM_OPEN_DONE = 0, + IPU_FW_ISYS_RESP_TYPE_STREAM_START_ACK, + IPU_FW_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK, + IPU_FW_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK, + IPU_FW_ISYS_RESP_TYPE_STREAM_STOP_ACK, + IPU_FW_ISYS_RESP_TYPE_STREAM_FLUSH_ACK, + IPU_FW_ISYS_RESP_TYPE_STREAM_CLOSE_ACK, + IPU_FW_ISYS_RESP_TYPE_PIN_DATA_READY, + IPU_FW_ISYS_RESP_TYPE_PIN_DATA_WATERMARK, + IPU_FW_ISYS_RESP_TYPE_FRAME_SOF, + IPU_FW_ISYS_RESP_TYPE_FRAME_EOF, + IPU_FW_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE, + IPU_FW_ISYS_RESP_TYPE_STREAM_CAPTURE_DONE, + IPU_FW_ISYS_RESP_TYPE_PIN_DATA_SKIPPED, + IPU_FW_ISYS_RESP_TYPE_STREAM_CAPTURE_SKIPPED, + IPU_FW_ISYS_RESP_TYPE_FRAME_SOF_DISCARDED, + IPU_FW_ISYS_RESP_TYPE_FRAME_EOF_DISCARDED, + IPU_FW_ISYS_RESP_TYPE_STATS_DATA_READY, + N_IPU_FW_ISYS_RESP_TYPE +}; + +/** + * enum ipu_fw_isys_send_type + */ +enum ipu_fw_isys_send_type { + IPU_FW_ISYS_SEND_TYPE_STREAM_OPEN = 0, + IPU_FW_ISYS_SEND_TYPE_STREAM_START, + IPU_FW_ISYS_SEND_TYPE_STREAM_START_AND_CAPTURE, + IPU_FW_ISYS_SEND_TYPE_STREAM_CAPTURE, + IPU_FW_ISYS_SEND_TYPE_STREAM_STOP, + IPU_FW_ISYS_SEND_TYPE_STREAM_FLUSH, + IPU_FW_ISYS_SEND_TYPE_STREAM_CLOSE, + N_IPU_FW_ISYS_SEND_TYPE +}; + +/** + * enum ipu_fw_isys_queue_type + */ +enum ipu_fw_isys_queue_type { + IPU_FW_ISYS_QUEUE_TYPE_PROXY = 0, + IPU_FW_ISYS_QUEUE_TYPE_DEV, + IPU_FW_ISYS_QUEUE_TYPE_MSG, + N_IPU_FW_ISYS_QUEUE_TYPE +}; + +/** + * enum ipu_fw_isys_stream_source: Specifies a source for a stream + */ +enum ipu_fw_isys_stream_source { + IPU_FW_ISYS_STREAM_SRC_PORT_0 = 0, + IPU_FW_ISYS_STREAM_SRC_PORT_1, + IPU_FW_ISYS_STREAM_SRC_PORT_2, + IPU_FW_ISYS_STREAM_SRC_PORT_3, + IPU_FW_ISYS_STREAM_SRC_PORT_4, + IPU_FW_ISYS_STREAM_SRC_PORT_5, + IPU_FW_ISYS_STREAM_SRC_PORT_6, + IPU_FW_ISYS_STREAM_SRC_PORT_7, + IPU_FW_ISYS_STREAM_SRC_PORT_8, + IPU_FW_ISYS_STREAM_SRC_PORT_9, + IPU_FW_ISYS_STREAM_SRC_PORT_10, + IPU_FW_ISYS_STREAM_SRC_PORT_11, + IPU_FW_ISYS_STREAM_SRC_PORT_12, + IPU_FW_ISYS_STREAM_SRC_PORT_13, + IPU_FW_ISYS_STREAM_SRC_PORT_14, + IPU_FW_ISYS_STREAM_SRC_PORT_15, + IPU_FW_ISYS_STREAM_SRC_MIPIGEN_0, + IPU_FW_ISYS_STREAM_SRC_MIPIGEN_1, + IPU_FW_ISYS_STREAM_SRC_MIPIGEN_2, + IPU_FW_ISYS_STREAM_SRC_MIPIGEN_3, + IPU_FW_ISYS_STREAM_SRC_MIPIGEN_4, + IPU_FW_ISYS_STREAM_SRC_MIPIGEN_5, + IPU_FW_ISYS_STREAM_SRC_MIPIGEN_6, + IPU_FW_ISYS_STREAM_SRC_MIPIGEN_7, + IPU_FW_ISYS_STREAM_SRC_MIPIGEN_8, + IPU_FW_ISYS_STREAM_SRC_MIPIGEN_9, + N_IPU_FW_ISYS_STREAM_SRC +}; + +#if !defined(CONFIG_VIDEO_INTEL_IPU4) && !defined(CONFIG_VIDEO_INTEL_IPU4P) +enum ipu_fw_isys_sensor_type { + /* non-snoopable to PSYS */ + IPU_FW_ISYS_VC1_SENSOR_DATA = 0, + /* non-snoopable for PDAF */ + IPU_FW_ISYS_VC1_SENSOR_PDAF, + /* snoopable to CPU */ + IPU_FW_ISYS_VC0_SENSOR_METADATA, + /* snoopable to CPU */ + IPU_FW_ISYS_VC0_SENSOR_DATA, + N_IPU_FW_ISYS_SENSOR_TYPE +}; + +enum ipu_fw_isys_sensor_info { + /* VC1 */ + IPU_FW_ISYS_SENSOR_DATA_1 = 1, + IPU_FW_ISYS_SENSOR_DATA_2 = 2, + IPU_FW_ISYS_SENSOR_DATA_3 = 3, + IPU_FW_ISYS_SENSOR_DATA_4 = 4, + IPU_FW_ISYS_SENSOR_DATA_5 = 5, + IPU_FW_ISYS_SENSOR_DATA_6 = 6, + IPU_FW_ISYS_SENSOR_DATA_7 = 7, + IPU_FW_ISYS_SENSOR_DATA_8 = 8, + IPU_FW_ISYS_SENSOR_DATA_9 = 9, + IPU_FW_ISYS_SENSOR_DATA_10 = 10, + IPU_FW_ISYS_SENSOR_PDAF_1 = 11, + IPU_FW_ISYS_SENSOR_PDAF_2 = 12, + /* VC0 */ + IPU_FW_ISYS_SENSOR_METADATA = 13, + IPU_FW_ISYS_SENSOR_DATA_11 = 14, + IPU_FW_ISYS_SENSOR_DATA_12 = 15, + IPU_FW_ISYS_SENSOR_DATA_13 = 16, + IPU_FW_ISYS_SENSOR_DATA_14 = 17, + IPU_FW_ISYS_SENSOR_DATA_15 = 18, + IPU_FW_ISYS_SENSOR_DATA_16 = 19, + N_IPU_FW_ISYS_SENSOR_INFO, + IPU_FW_ISYS_VC1_SENSOR_DATA_START = IPU_FW_ISYS_SENSOR_DATA_1, + IPU_FW_ISYS_VC1_SENSOR_DATA_END = IPU_FW_ISYS_SENSOR_DATA_10, + IPU_FW_ISYS_VC0_SENSOR_DATA_START = IPU_FW_ISYS_SENSOR_DATA_11, + IPU_FW_ISYS_VC0_SENSOR_DATA_END = IPU_FW_ISYS_SENSOR_DATA_16, + IPU_FW_ISYS_VC1_SENSOR_PDAF_START = IPU_FW_ISYS_SENSOR_PDAF_1, + IPU_FW_ISYS_VC1_SENSOR_PDAF_END = IPU_FW_ISYS_SENSOR_PDAF_2, +}; +#endif + +#define IPU_FW_ISYS_STREAM_SRC_CSI2_PORT0 IPU_FW_ISYS_STREAM_SRC_PORT_0 +#define IPU_FW_ISYS_STREAM_SRC_CSI2_PORT1 IPU_FW_ISYS_STREAM_SRC_PORT_1 +#define IPU_FW_ISYS_STREAM_SRC_CSI2_PORT2 IPU_FW_ISYS_STREAM_SRC_PORT_2 +#define IPU_FW_ISYS_STREAM_SRC_CSI2_PORT3 IPU_FW_ISYS_STREAM_SRC_PORT_3 + +#define IPU_FW_ISYS_STREAM_SRC_CSI2_3PH_PORTA IPU_FW_ISYS_STREAM_SRC_PORT_4 +#define IPU_FW_ISYS_STREAM_SRC_CSI2_3PH_PORTB IPU_FW_ISYS_STREAM_SRC_PORT_5 +#define IPU_FW_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT0 IPU_FW_ISYS_STREAM_SRC_PORT_6 +#define IPU_FW_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT1 IPU_FW_ISYS_STREAM_SRC_PORT_7 +#define IPU_FW_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT2 IPU_FW_ISYS_STREAM_SRC_PORT_8 +#define IPU_FW_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT3 IPU_FW_ISYS_STREAM_SRC_PORT_9 + +#define IPU_FW_ISYS_STREAM_SRC_MIPIGEN_PORT0 IPU_FW_ISYS_STREAM_SRC_MIPIGEN_0 +#define IPU_FW_ISYS_STREAM_SRC_MIPIGEN_PORT1 IPU_FW_ISYS_STREAM_SRC_MIPIGEN_1 + +/** + * enum ipu_fw_isys_mipi_vc: MIPI csi2 spec + * supports up to 4 virtual per physical channel + */ +enum ipu_fw_isys_mipi_vc { + IPU_FW_ISYS_MIPI_VC_0 = 0, + IPU_FW_ISYS_MIPI_VC_1, + IPU_FW_ISYS_MIPI_VC_2, + IPU_FW_ISYS_MIPI_VC_3, + N_IPU_FW_ISYS_MIPI_VC +}; + +/** + * Supported Pixel Frame formats. Expandable if needed + */ +enum ipu_fw_isys_frame_format_type { + IPU_FW_ISYS_FRAME_FORMAT_NV11 = 0, /* 12 bit YUV 411, Y, UV plane */ + IPU_FW_ISYS_FRAME_FORMAT_NV12, /* 12 bit YUV 420, Y, UV plane */ + IPU_FW_ISYS_FRAME_FORMAT_NV12_16, /* 16 bit YUV 420, Y, UV plane */ + IPU_FW_ISYS_FRAME_FORMAT_NV12_TILEY, /* 12 bit YUV 420, + * Intel proprietary tiled format, + * TileY + */ + IPU_FW_ISYS_FRAME_FORMAT_NV16, /* 16 bit YUV 422, Y, UV plane */ + IPU_FW_ISYS_FRAME_FORMAT_NV21, /* 12 bit YUV 420, Y, VU plane */ + IPU_FW_ISYS_FRAME_FORMAT_NV61, /* 16 bit YUV 422, Y, VU plane */ + IPU_FW_ISYS_FRAME_FORMAT_YV12, /* 12 bit YUV 420, Y, V, U plane */ + IPU_FW_ISYS_FRAME_FORMAT_YV16, /* 16 bit YUV 422, Y, V, U plane */ + IPU_FW_ISYS_FRAME_FORMAT_YUV420, /* 12 bit YUV 420, Y, U, V plane */ + IPU_FW_ISYS_FRAME_FORMAT_YUV420_10, /* yuv420, 10 bits per subpixel */ + IPU_FW_ISYS_FRAME_FORMAT_YUV420_12, /* yuv420, 12 bits per subpixel */ + IPU_FW_ISYS_FRAME_FORMAT_YUV420_14, /* yuv420, 14 bits per subpixel */ + IPU_FW_ISYS_FRAME_FORMAT_YUV420_16, /* yuv420, 16 bits per subpixel */ + IPU_FW_ISYS_FRAME_FORMAT_YUV422, /* 16 bit YUV 422, Y, U, V plane */ + IPU_FW_ISYS_FRAME_FORMAT_YUV422_16, /* yuv422, 16 bits per subpixel */ + IPU_FW_ISYS_FRAME_FORMAT_UYVY, /* 16 bit YUV 422, UYVY interleaved */ + IPU_FW_ISYS_FRAME_FORMAT_YUYV, /* 16 bit YUV 422, YUYV interleaved */ + IPU_FW_ISYS_FRAME_FORMAT_YUV444, /* 24 bit YUV 444, Y, U, V plane */ + IPU_FW_ISYS_FRAME_FORMAT_YUV_LINE, /* Internal format, 2 y lines + * followed by a uvinterleaved line + */ + IPU_FW_ISYS_FRAME_FORMAT_RAW8, /* RAW8, 1 plane */ + IPU_FW_ISYS_FRAME_FORMAT_RAW10, /* RAW10, 1 plane */ + IPU_FW_ISYS_FRAME_FORMAT_RAW12, /* RAW12, 1 plane */ + IPU_FW_ISYS_FRAME_FORMAT_RAW14, /* RAW14, 1 plane */ + IPU_FW_ISYS_FRAME_FORMAT_RAW16, /* RAW16, 1 plane */ + IPU_FW_ISYS_FRAME_FORMAT_RGB565, /* 16 bit RGB, 1 plane. Each 3 sub + * pixels are packed into one 16 bit + * value, 5 bits for R, 6 bits + * for G and 5 bits for B. + */ + + IPU_FW_ISYS_FRAME_FORMAT_PLANAR_RGB888, /* 24 bit RGB, 3 planes */ + IPU_FW_ISYS_FRAME_FORMAT_RGBA888, /* 32 bit RGBA, 1 plane, + * A=Alpha (alpha is unused) + */ + IPU_FW_ISYS_FRAME_FORMAT_QPLANE6, /* Internal, for advanced ISP */ + IPU_FW_ISYS_FRAME_FORMAT_BINARY_8, /* byte stream, used for jpeg. */ + N_IPU_FW_ISYS_FRAME_FORMAT +}; + +/* Temporary for driver compatibility */ +#define IPU_FW_ISYS_FRAME_FORMAT_RAW (IPU_FW_ISYS_FRAME_FORMAT_RAW16) + +/** + * Supported MIPI data type. Keep in sync array in ipu_fw_isys_private.c + */ +enum ipu_fw_isys_mipi_data_type { + /** SYNCHRONIZATION SHORT PACKET DATA TYPES */ + IPU_FW_ISYS_MIPI_DATA_TYPE_FRAME_START_CODE = 0x00, + IPU_FW_ISYS_MIPI_DATA_TYPE_FRAME_END_CODE = 0x01, + IPU_FW_ISYS_MIPI_DATA_TYPE_LINE_START_CODE = 0x02, /* Optional */ + IPU_FW_ISYS_MIPI_DATA_TYPE_LINE_END_CODE = 0x03, /* Optional */ + /** Reserved 0x04-0x07 */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x04 = 0x04, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x05 = 0x05, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x06 = 0x06, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x07 = 0x07, + /** GENERIC SHORT PACKET DATA TYPES */ + /** They are used to keep the timing information for + * the opening/closing of shutters, + * triggering of flashes and etc. + */ + /* Generic Short Packet Codes 1 - 8 */ + IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT1 = 0x08, + IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT2 = 0x09, + IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT3 = 0x0A, + IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT4 = 0x0B, + IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT5 = 0x0C, + IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT6 = 0x0D, + IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT7 = 0x0E, + IPU_FW_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT8 = 0x0F, + /** GENERIC LONG PACKET DATA TYPES */ + IPU_FW_ISYS_MIPI_DATA_TYPE_NULL = 0x10, + IPU_FW_ISYS_MIPI_DATA_TYPE_BLANKING_DATA = 0x11, + /* Embedded 8-bit non Image Data */ + IPU_FW_ISYS_MIPI_DATA_TYPE_EMBEDDED = 0x12, + /** Reserved 0x13-0x17 */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x13 = 0x13, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x14 = 0x14, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x15 = 0x15, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x16 = 0x16, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x17 = 0x17, + /** YUV DATA TYPES */ + /* 8 bits per subpixel */ + IPU_FW_ISYS_MIPI_DATA_TYPE_YUV420_8 = 0x18, + /* 10 bits per subpixel */ + IPU_FW_ISYS_MIPI_DATA_TYPE_YUV420_10 = 0x19, + /* 8 bits per subpixel */ + IPU_FW_ISYS_MIPI_DATA_TYPE_YUV420_8_LEGACY = 0x1A, + /** Reserved 0x1B */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x1B = 0x1B, + /* YUV420 8-bit Chroma Shifted Pixel Sampling) */ + IPU_FW_ISYS_MIPI_DATA_TYPE_YUV420_8_SHIFT = 0x1C, + /* YUV420 8-bit (Chroma Shifted Pixel Sampling) */ + IPU_FW_ISYS_MIPI_DATA_TYPE_YUV420_10_SHIFT = 0x1D, + /* UYVY..UVYV, 8 bits per subpixel */ + IPU_FW_ISYS_MIPI_DATA_TYPE_YUV422_8 = 0x1E, + /* UYVY..UVYV, 10 bits per subpixel */ + IPU_FW_ISYS_MIPI_DATA_TYPE_YUV422_10 = 0x1F, + /** RGB DATA TYPES */ + /* BGR..BGR, 4 bits per subpixel */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RGB_444 = 0x20, + /* BGR..BGR, 5 bits per subpixel */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RGB_555 = 0x21, + /* BGR..BGR, 5 bits B and R, 6 bits G */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RGB_565 = 0x22, + /* BGR..BGR, 6 bits per subpixel */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RGB_666 = 0x23, + /* BGR..BGR, 8 bits per subpixel */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RGB_888 = 0x24, + /** Reserved 0x25-0x27 */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x25 = 0x25, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x26 = 0x26, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x27 = 0x27, + /** RAW DATA TYPES */ + /* RAW data, 6 - 14 bits per pixel */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_6 = 0x28, + IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_7 = 0x29, + IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_8 = 0x2A, + IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_10 = 0x2B, + IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_12 = 0x2C, + IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_14 = 0x2D, + /** Reserved 0x2E-2F are used with assigned meaning */ + /* RAW data, 16 bits per pixel, not specified in CSI-MIPI standard */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RAW_16 = 0x2E, + /* Binary byte stream, which is target at JPEG, + * not specified in CSI-MIPI standard + */ + IPU_FW_ISYS_MIPI_DATA_TYPE_BINARY_8 = 0x2F, + + /** USER DEFINED 8-BIT DATA TYPES */ + /** For example, the data transmitter (e.g. the SoC sensor) + * can keep the JPEG data as + * the User Defined Data Type 4 and the MPEG data as the + * User Defined Data Type 7. + */ + IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF1 = 0x30, + IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF2 = 0x31, + IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF3 = 0x32, + IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF4 = 0x33, + IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF5 = 0x34, + IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF6 = 0x35, + IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF7 = 0x36, + IPU_FW_ISYS_MIPI_DATA_TYPE_USER_DEF8 = 0x37, + /** Reserved 0x38-0x3F */ + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x38 = 0x38, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x39 = 0x39, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x3A = 0x3A, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x3B = 0x3B, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x3C = 0x3C, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x3D = 0x3D, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x3E = 0x3E, + IPU_FW_ISYS_MIPI_DATA_TYPE_RESERVED_0x3F = 0x3F, + + /* Keep always last and max value */ + N_IPU_FW_ISYS_MIPI_DATA_TYPE = 0x40 +}; + +/** enum ipu_fw_isys_pin_type: output pin buffer types. + * Buffers can be queued and de-queued to hand them over between IA and ISYS + */ +enum ipu_fw_isys_pin_type { + /* Captured as MIPI packets */ + IPU_FW_ISYS_PIN_TYPE_MIPI = 0, + /* Captured through the ISApf (with/without ISA) + * and the non-scaled output path + */ + IPU_FW_ISYS_PIN_TYPE_RAW_NS, + /* Captured through the ISApf + ISA and the scaled output path */ + IPU_FW_ISYS_PIN_TYPE_RAW_S, + /* Captured through the SoC path */ + IPU_FW_ISYS_PIN_TYPE_RAW_SOC, + /* Reserved for future use, maybe short packets */ + IPU_FW_ISYS_PIN_TYPE_METADATA_0, + /* Reserved for future use */ + IPU_FW_ISYS_PIN_TYPE_METADATA_1, + /* Legacy (non-PIV2), used for the AWB stats */ + IPU_FW_ISYS_PIN_TYPE_AWB_STATS, + /* Legacy (non-PIV2), used for the AF stats */ + IPU_FW_ISYS_PIN_TYPE_AF_STATS, + /* Legacy (non-PIV2), used for the AE stats */ + IPU_FW_ISYS_PIN_TYPE_HIST_STATS, + /* Used for the PAF FF */ + IPU_FW_ISYS_PIN_TYPE_PAF_FF, +#if !defined(CONFIG_VIDEO_INTEL_IPU4) && !defined(CONFIG_VIDEO_INTEL_IPU4P) + /* Captured through the SoC path + * (2D mode where odd and even lines are handled separately) + */ + IPU_FW_ISYS_PIN_TYPE_RAW_DUAL_SOC, +#endif + /* Keep always last and max value */ + N_IPU_FW_ISYS_PIN_TYPE +}; + +/** + * enum ipu_fw_isys_isl_use + * Describes the ISL/ISA use + */ +enum ipu_fw_isys_isl_use { + IPU_FW_ISYS_USE_NO_ISL_NO_ISA = 0, + IPU_FW_ISYS_USE_SINGLE_DUAL_ISL, + IPU_FW_ISYS_USE_SINGLE_ISA, + N_IPU_FW_ISYS_USE +}; + +/** + * enum ipu_fw_isys_mipi_store_mode. Describes if long MIPI packets reach + * MIPI SRAM with the long packet header or + * if not, then only option is to capture it with pin type MIPI. + */ +enum ipu_fw_isys_mipi_store_mode { + IPU_FW_ISYS_MIPI_STORE_MODE_NORMAL = 0, + IPU_FW_ISYS_MIPI_STORE_MODE_DISCARD_LONG_HEADER, + N_IPU_FW_ISYS_MIPI_STORE_MODE +}; + +/** + * enum ipu_fw_isys_type_paf. Describes the Type of PAF enabled + */ +enum ipu_fw_isys_type_paf { + /* PAF data not present */ + IPU_FW_ISYS_TYPE_NO_PAF = 0, + /* Type 2 sensor types, PAF coming separately from Image Frame */ + /* PAF data in interleaved format(RLRL or LRLR) */ + IPU_FW_ISYS_TYPE_INTERLEAVED_PAF, + /* PAF data in non-interleaved format(LL/RR or RR/LL) */ + IPU_FW_ISYS_TYPE_NON_INTERLEAVED_PAF, + /* Type 3 sensor types , PAF data embedded in Image Frame */ + /* Frame Embedded PAF in interleaved format(RLRL or LRLR) */ + IPU_FW_ISYS_TYPE_FRAME_EMB_INTERLEAVED_PAF, + /* Frame Embedded PAF non-interleaved format(LL/RR or RR/LL) */ + IPU_FW_ISYS_TYPE_FRAME_EMB_NON_INTERLEAVED_PAF, + N_IPU_FW_ISYS_TYPE_PAF +}; + +/** + * enum ipu_fw_isys_cropping_location. Enumerates the cropping locations in ISYS + */ +enum ipu_fw_isys_cropping_location { + /* Cropping executed in ISAPF (mainly), + * ISAPF preproc (odd column) and MIPI STR2MMIO (odd row) + */ + IPU_FW_ISYS_CROPPING_LOCATION_PRE_ISA = 0, + /* Reserved for legacy mode which will never be implemented */ + IPU_FW_ISYS_CROPPING_LOCATION_RESERVED_1, + /* Cropping executed in StreamPifConv in the ISA output for + * RAW_NS pin + */ + IPU_FW_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED, + /* Cropping executed in StreamScaledPifConv + * in the ISA output for RAW_S pin + */ + IPU_FW_ISYS_CROPPING_LOCATION_POST_ISA_SCALED, + N_IPU_FW_ISYS_CROPPING_LOCATION +}; + +/** + * enum ipu_fw_isys_resolution_info. Describes the resolution, + * required to setup the various ISA GP registers. + */ +enum ipu_fw_isys_resolution_info { + /* Scaled ISA output resolution before + * the StreamScaledPifConv cropping + */ + IPU_FW_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED = 0, + /* Non-Scaled ISA output resolution before the StreamPifConv cropping */ + IPU_FW_ISYS_RESOLUTION_INFO_POST_ISA_SCALED, + N_IPU_FW_ISYS_RESOLUTION_INFO +}; + +/** + * enum ipu_fw_isys_error. Describes the error type detected by the FW + */ +enum ipu_fw_isys_error { + IPU_FW_ISYS_ERROR_NONE = 0, /* No details */ + IPU_FW_ISYS_ERROR_FW_INTERNAL_CONSISTENCY, /* enum */ + IPU_FW_ISYS_ERROR_HW_CONSISTENCY, /* enum */ + IPU_FW_ISYS_ERROR_DRIVER_INVALID_COMMAND_SEQUENCE, /* enum */ + IPU_FW_ISYS_ERROR_DRIVER_INVALID_DEVICE_CONFIGURATION, /* enum */ + IPU_FW_ISYS_ERROR_DRIVER_INVALID_STREAM_CONFIGURATION, /* enum */ + IPU_FW_ISYS_ERROR_DRIVER_INVALID_FRAME_CONFIGURATION, /* enum */ + IPU_FW_ISYS_ERROR_INSUFFICIENT_RESOURCES, /* enum */ + IPU_FW_ISYS_ERROR_HW_REPORTED_STR2MMIO, /* HW code */ + IPU_FW_ISYS_ERROR_HW_REPORTED_SIG2CIO, /* HW code */ + IPU_FW_ISYS_ERROR_SENSOR_FW_SYNC, /* enum */ + IPU_FW_ISYS_ERROR_STREAM_IN_SUSPENSION, /* FW code */ + IPU_FW_ISYS_ERROR_RESPONSE_QUEUE_FULL, /* FW code */ + N_IPU_FW_ISYS_ERROR +}; + +/** + * enum ipu_fw_proxy_error. Describes the error type for + * the proxy detected by the FW + */ +enum ipu_fw_proxy_error { + IPU_FW_PROXY_ERROR_NONE = 0, + IPU_FW_PROXY_ERROR_INVALID_WRITE_REGION, + IPU_FW_PROXY_ERROR_INVALID_WRITE_OFFSET, + N_IPU_FW_PROXY_ERROR +}; + +struct ipu_isys; + +/** + * struct ipu_fw_isys_buffer_partition_abi - buffer partition information + * @num_gda_pages: Number of virtual gda pages available for each virtual stream + */ +struct ipu_fw_isys_buffer_partition_abi { + u32 num_gda_pages[IPU_STREAM_ID_MAX]; +}; + +/** + * struct ipu_fw_isys_fw_config - contains the parts from + * ia_css_isys_device_cfg_data we need to transfer to the cell + */ +struct ipu_fw_isys_fw_config { + struct ipu_fw_isys_buffer_partition_abi buffer_partition; + u32 num_send_queues[N_IPU_FW_ISYS_QUEUE_TYPE]; + u32 num_recv_queues[N_IPU_FW_ISYS_QUEUE_TYPE]; +}; + +/** + * struct ipu_fw_isys_resolution_abi: Generic resolution structure. + * @Width + * @Height + */ +struct ipu_fw_isys_resolution_abi { + u32 width; + u32 height; +}; + +/** + * struct ipu_fw_isys_output_pin_payload_abi + * @out_buf_id: Points to output pin buffer - buffer identifier + * @addr: Points to output pin buffer - CSS Virtual Address + * @compress: Request frame compression (1), or not (0) + */ +struct ipu_fw_isys_output_pin_payload_abi { + u64 out_buf_id; + u32 addr; + u32 compress; +}; + +/** + * struct ipu_fw_isys_output_pin_info_abi + * @output_res: output pin resolution + * @stride: output stride in Bytes (not valid for statistics) + * @watermark_in_lines: pin watermark level in lines + * @payload_buf_size: minimum size in Bytes of all buffers that will be + * supplied for capture on this pin + * @send_irq: assert if pin event should trigger irq + * @pt: pin type -real format "enum ipu_fw_isys_pin_type" + * @ft: frame format type -real format "enum ipu_fw_isys_frame_format_type" + * @input_pin_id: related input pin id + * @reserve_compression: reserve compression resources for pin + */ +struct ipu_fw_isys_output_pin_info_abi { + struct ipu_fw_isys_resolution_abi output_res; + u32 stride; + u32 watermark_in_lines; + u32 payload_buf_size; + u8 send_irq; + u8 input_pin_id; + u8 pt; + u8 ft; + u8 reserved; + u8 reserve_compression; + u8 snoopable; + u32 sensor_type; +}; + +/** + * struct ipu_fw_isys_param_pin_abi + * @param_buf_id: Points to param port buffer - buffer identifier + * @addr: Points to param pin buffer - CSS Virtual Address + */ +struct ipu_fw_isys_param_pin_abi { + u64 param_buf_id; + u32 addr; +}; + +/** + * struct ipu_fw_isys_input_pin_info_abi + * @input_res: input resolution + * @dt: mipi data type ((enum ipu_fw_isys_mipi_data_type) + * @mipi_store_mode: defines if legacy long packet header will be stored or + * discarded if discarded, output pin pin type for this + * input pin can only be MIPI + * (enum ipu_fw_isys_mipi_store_mode) + * @bits_per_pix: native bits per pixel + * @mapped_dt: actual data type from sensor +#if !defined(CONFIG_VIDEO_INTEL_IPU4) && !defined(CONFIG_VIDEO_INTEL_IPU4P) + * @crop_first_and_last_lines Control whether to crop the + * first and last line of the + * input image. Crop done by HW + * device. +#endif + */ +struct ipu_fw_isys_input_pin_info_abi { + struct ipu_fw_isys_resolution_abi input_res; + u8 dt; + u8 mipi_store_mode; + u8 bits_per_pix; + u8 mapped_dt; +#if !defined(CONFIG_VIDEO_INTEL_IPU4) && !defined(CONFIG_VIDEO_INTEL_IPU4P) + u8 crop_first_and_last_lines; +#endif +}; + +/** + * struct ipu_fw_isys_isa_cfg_abi. Describes the ISA cfg + */ +struct ipu_fw_isys_isa_cfg_abi { + struct ipu_fw_isys_resolution_abi + isa_res[N_IPU_FW_ISYS_RESOLUTION_INFO]; + struct { + unsigned int blc:1; + unsigned int lsc:1; + unsigned int dpc:1; + unsigned int downscaler:1; + unsigned int awb:1; + unsigned int af:1; + unsigned int ae:1; + unsigned int paf:8; + unsigned int send_irq_stats_ready:1; + unsigned int send_resp_stats_ready:1; + } cfg; +}; + +/** + * struct ipu_fw_isys_cropping_abi - cropping coordinates + */ +struct ipu_fw_isys_cropping_abi { + s32 top_offset; + s32 left_offset; + s32 bottom_offset; + s32 right_offset; +}; + +/** + * struct ipu_fw_isys_stream_cfg_data_abi + * ISYS stream configuration data structure + * @isa_cfg: details about what ACCs are active if ISA is used + * @crop: defines cropping resolution for the + * maximum number of input pins which can be cropped, + * it is directly mapped to the HW devices + * @input_pins: input pin descriptors + * @output_pins: output pin descriptors + * @compfmt: de-compression setting for User Defined Data + * @nof_input_pins: number of input pins + * @nof_output_pins: number of output pins + * @send_irq_sof_discarded: send irq on discarded frame sof response + * - if '1' it will override the send_resp_sof_discarded + * and send the response + * - if '0' the send_resp_sof_discarded will determine + * whether to send the response + * @send_irq_eof_discarded: send irq on discarded frame eof response + * - if '1' it will override the send_resp_eof_discarded + * and send the response + * - if '0' the send_resp_eof_discarded will determine + * whether to send the response + * @send_resp_sof_discarded: send response for discarded frame sof detected, + * used only when send_irq_sof_discarded is '0' + * @send_resp_eof_discarded: send response for discarded frame eof detected, + * used only when send_irq_eof_discarded is '0' + * @src: Stream source index e.g. MIPI_generator_0, CSI2-rx_1 + * @vc: MIPI Virtual Channel (up to 4 virtual per physical channel) + * @isl_use: indicates whether stream requires ISL and how + */ +struct ipu_fw_isys_stream_cfg_data_abi { + struct ipu_fw_isys_isa_cfg_abi isa_cfg; + struct ipu_fw_isys_cropping_abi crop[N_IPU_FW_ISYS_CROPPING_LOCATION]; + struct ipu_fw_isys_input_pin_info_abi input_pins[IPU_MAX_IPINS]; + struct ipu_fw_isys_output_pin_info_abi output_pins[IPU_MAX_OPINS]; + u32 compfmt; + u8 nof_input_pins; + u8 nof_output_pins; + u8 send_irq_sof_discarded; + u8 send_irq_eof_discarded; + u8 send_resp_sof_discarded; + u8 send_resp_eof_discarded; + u8 src; + u8 vc; + u8 isl_use; +}; + +/** + * struct ipu_fw_isys_frame_buff_set - frame buffer set + * @output_pins: output pin addresses + * @process_group_light: process_group_light buffer address + * @send_irq_sof: send irq on frame sof response + * - if '1' it will override the send_resp_sof and + * send the response + * - if '0' the send_resp_sof will determine whether to + * send the response + * @send_irq_eof: send irq on frame eof response + * - if '1' it will override the send_resp_eof and + * send the response + * - if '0' the send_resp_eof will determine whether to + * send the response + * @send_resp_sof: send response for frame sof detected, + * used only when send_irq_sof is '0' + * @send_resp_eof: send response for frame eof detected, + * used only when send_irq_eof is '0' + */ +struct ipu_fw_isys_frame_buff_set_abi { + struct ipu_fw_isys_output_pin_payload_abi output_pins[IPU_MAX_OPINS]; + struct ipu_fw_isys_param_pin_abi process_group_light; + u8 send_irq_sof; + u8 send_irq_eof; +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + u8 send_irq_capture_ack; + u8 send_irq_capture_done; +#endif + u8 send_resp_sof; + u8 send_resp_eof; + u8 reserved; +}; + +/** + * struct ipu_fw_isys_error_info_abi + * @error: error code if something went wrong + * @error_details: depending on error code, it may contain additional error info + */ +struct ipu_fw_isys_error_info_abi { + enum ipu_fw_isys_error error; + u32 error_details; +}; + +/** + * struct ipu_fw_isys_resp_info_comm + * @pin: this var is only valid for pin event related responses, + * contains pin addresses + * @process_group_light: this var is valid for stats ready related responses, + * contains process group addresses + * @error_info: error information from the FW + * @timestamp: Time information for event if available + * @stream_handle: stream id the response corresponds to + * @type: response type (enum ipu_fw_isys_resp_type) + * @pin_id: pin id that the pin payload corresponds to + * @acc_id: this var is valid for stats ready related responses, + * contains accelerator id that finished producing + * all related statistics + */ +struct ipu_fw_isys_resp_info_abi { + u64 buf_id; + struct ipu_fw_isys_output_pin_payload_abi pin; + struct ipu_fw_isys_param_pin_abi process_group_light; + struct ipu_fw_isys_error_info_abi error_info; + u32 timestamp[2]; + u8 stream_handle; + u8 type; + u8 pin_id; + u8 acc_id; + u16 reserved; +}; + +/** + * struct ipu_fw_isys_proxy_error_info_comm + * @proxy_error: error code if something went wrong + * @proxy_error_details: depending on error code, it may contain additional + * error info + */ +struct ipu_fw_isys_proxy_error_info_abi { + enum ipu_fw_proxy_error error; + u32 error_details; +}; + +struct ipu_fw_isys_proxy_resp_info_abi { + u32 request_id; + struct ipu_fw_isys_proxy_error_info_abi error_info; +}; + +/** + * struct ipu_fw_proxy_write_queue_token + * @request_id: update id for the specific proxy write request + * @region_index: Region id for the proxy write request + * @offset: Offset of the write request according to the base address + * of the region + * @value: Value that is requested to be written with the proxy write request + */ +struct ipu_fw_proxy_write_queue_token { + u32 request_id; + u32 region_index; + u32 offset; + u32 value; +}; + +/* From here on type defines not coming from the ISYSAPI interface */ + +/** + * struct ipu_fw_resp_queue_token + */ +struct ipu_fw_resp_queue_token { + struct ipu_fw_isys_resp_info_abi resp_info; +}; + +/** + * struct ipu_fw_send_queue_token + */ +struct ipu_fw_send_queue_token { + u64 buf_handle; + u32 payload; + u16 send_type; + u16 stream_id; +}; + +/** + * struct ipu_fw_proxy_resp_queue_token + */ +struct ipu_fw_proxy_resp_queue_token { + struct ipu_fw_isys_proxy_resp_info_abi proxy_resp_info; +}; + +/** + * struct ipu_fw_proxy_send_queue_token + */ +struct ipu_fw_proxy_send_queue_token { + u32 request_id; + u32 region_index; + u32 offset; + u32 value; +}; + +void ipu_fw_isys_set_params(struct ipu_fw_isys_stream_cfg_data_abi *stream_cfg); + +void ipu_fw_isys_dump_stream_cfg(struct device *dev, + struct ipu_fw_isys_stream_cfg_data_abi + *stream_cfg); +void ipu_fw_isys_dump_frame_buff_set(struct device *dev, + struct ipu_fw_isys_frame_buff_set_abi *buf, + unsigned int outputs); +int ipu_fw_isys_init(struct ipu_isys *isys, unsigned int num_streams); +int ipu_fw_isys_close(struct ipu_isys *isys); +int ipu_fw_isys_simple_cmd(struct ipu_isys *isys, + const unsigned int stream_handle, + enum ipu_fw_isys_send_type send_type); +int ipu_fw_isys_complex_cmd(struct ipu_isys *isys, + const unsigned int stream_handle, + void *cpu_mapped_buf, + dma_addr_t dma_mapped_buf, + size_t size, enum ipu_fw_isys_send_type send_type); +int ipu_fw_isys_send_proxy_token(struct ipu_isys *isys, + unsigned int req_id, + unsigned int index, + unsigned int offset, u32 value); +void ipu_fw_isys_cleanup(struct ipu_isys *isys); +struct ipu_fw_isys_resp_info_abi *ipu_fw_isys_get_resp(void *context, + unsigned int queue, + struct + ipu_fw_isys_resp_info_abi + *response); +void ipu_fw_isys_put_resp(void *context, unsigned int queue); +#endif diff --git a/drivers/media/pci/intel/ipu-fw-psys.c b/drivers/media/pci/intel/ipu-fw-psys.c new file mode 100644 index 0000000000000..9ffe8cae1d884 --- /dev/null +++ b/drivers/media/pci/intel/ipu-fw-psys.c @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2016 - 2018 Intel Corporation + +#include + +#include + +#include "ipu-fw-com.h" +#include "ipu-fw-psys.h" +#include "ipu-psys.h" + +int ipu_fw_psys_pg_start(struct ipu_psys_kcmd *kcmd) +{ + kcmd->kpg->pg->state = IPU_FW_PSYS_PROCESS_GROUP_STARTED; + return 0; +} + +int ipu_fw_psys_pg_load_cycles(struct ipu_psys_kcmd *kcmd) +{ + return 0; +} + +int ipu_fw_psys_pg_init_cycles(struct ipu_psys_kcmd *kcmd) +{ + return 0; +} + +int ipu_fw_psys_pg_processing_cycles(struct ipu_psys_kcmd *kcmd) +{ + return 0; +} + + + +int ipu_fw_psys_pg_disown(struct ipu_psys_kcmd *kcmd) +{ + struct ipu_fw_psys_cmd *psys_cmd; + int ret = 0; + + psys_cmd = ipu_send_get_token(kcmd->fh->psys->fwcom, 0); + if (!psys_cmd) { + dev_err(&kcmd->fh->psys->adev->dev, "failed to get token!\n"); + kcmd->pg_user = NULL; + ret = -ENODATA; + goto out; + } + psys_cmd->command = IPU_FW_PSYS_PROCESS_GROUP_CMD_START; + psys_cmd->msg = 0; + psys_cmd->context_handle = kcmd->kpg->pg->ipu_virtual_address; + ipu_send_put_token(kcmd->fh->psys->fwcom, 0); + +out: + return ret; +} + + +int ipu_fw_psys_pg_abort(struct ipu_psys_kcmd *kcmd) +{ + struct ipu_fw_psys_cmd *psys_cmd; + int ret = 0; + + psys_cmd = ipu_send_get_token(kcmd->fh->psys->fwcom, 0); + if (!psys_cmd) { + dev_err(&kcmd->fh->psys->adev->dev, "failed to get token!\n"); + kcmd->pg_user = NULL; + ret = -ENODATA; + goto out; + } + psys_cmd->command = IPU_FW_PSYS_PROCESS_GROUP_CMD_STOP; + psys_cmd->msg = 0; + psys_cmd->context_handle = kcmd->kpg->pg->ipu_virtual_address; + ipu_send_put_token(kcmd->fh->psys->fwcom, 0); + +out: + return ret; +} + +int ipu_fw_psys_pg_submit(struct ipu_psys_kcmd *kcmd) +{ + kcmd->kpg->pg->state = IPU_FW_PSYS_PROCESS_GROUP_BLOCKED; + return 0; +} + +int ipu_fw_psys_rcv_event(struct ipu_psys *psys, + struct ipu_fw_psys_event *event) +{ + void *rcv; + + rcv = ipu_recv_get_token(psys->fwcom, 0); + if (!rcv) + return 0; + + memcpy(event, rcv, sizeof(*event)); + ipu_recv_put_token(psys->fwcom, 0); + return 1; +} + +int ipu_fw_psys_terminal_set(struct ipu_fw_psys_terminal *terminal, + int terminal_idx, + struct ipu_psys_kcmd *kcmd, + u32 buffer, unsigned int size) +{ + u32 type; + u32 buffer_state; + + type = terminal->terminal_type; + + switch (type) { + case IPU_FW_PSYS_TERMINAL_TYPE_PARAM_CACHED_IN: + case IPU_FW_PSYS_TERMINAL_TYPE_PARAM_CACHED_OUT: + case IPU_FW_PSYS_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IPU_FW_PSYS_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + case IPU_FW_PSYS_TERMINAL_TYPE_PARAM_SLICED_IN: + case IPU_FW_PSYS_TERMINAL_TYPE_PARAM_SLICED_OUT: + case IPU_FW_PSYS_TERMINAL_TYPE_PROGRAM: + buffer_state = IPU_FW_PSYS_BUFFER_UNDEFINED; + break; + case IPU_FW_PSYS_TERMINAL_TYPE_PARAM_STREAM: + case IPU_FW_PSYS_TERMINAL_TYPE_DATA_IN: + case IPU_FW_PSYS_TERMINAL_TYPE_STATE_IN: + buffer_state = IPU_FW_PSYS_BUFFER_FULL; + break; + case IPU_FW_PSYS_TERMINAL_TYPE_DATA_OUT: + case IPU_FW_PSYS_TERMINAL_TYPE_STATE_OUT: + buffer_state = IPU_FW_PSYS_BUFFER_EMPTY; + break; + default: + dev_err(&kcmd->fh->psys->adev->dev, + "unknown terminal type: 0x%x\n", type); + return -EAGAIN; + } + + if (type == IPU_FW_PSYS_TERMINAL_TYPE_DATA_IN || + type == IPU_FW_PSYS_TERMINAL_TYPE_DATA_OUT) { + struct ipu_fw_psys_data_terminal *dterminal = + (struct ipu_fw_psys_data_terminal *)terminal; + dterminal->connection_type = IPU_FW_PSYS_CONNECTION_MEMORY; + dterminal->frame.data_bytes = size; + if (!ipu_fw_psys_pg_get_protocol(kcmd)) + dterminal->frame.data = buffer; + else + dterminal->frame.data_index = terminal_idx; + dterminal->frame.buffer_state = buffer_state; + } else { + struct ipu_fw_psys_param_terminal *pterminal = + (struct ipu_fw_psys_param_terminal *)terminal; + if (!ipu_fw_psys_pg_get_protocol(kcmd)) + pterminal->param_payload.buffer = buffer; + else + pterminal->param_payload.terminal_index = terminal_idx; + } + return 0; +} + +static int process_get_cell(struct ipu_fw_psys_process *process, int index) +{ + int cell; + +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + cell = process->cell_id; +#else + cell = process->cells[index]; +#endif + return cell; +} + +static u32 process_get_cells_bitmap(struct ipu_fw_psys_process *process) +{ + unsigned int i; + int cell_id; + u32 bitmap = 0; + + for (i = 0; i < IPU_FW_PSYS_PROCESS_MAX_CELLS; i++) { + cell_id = process_get_cell(process, i); + if (cell_id != IPU_FW_PSYS_N_CELL_ID) + bitmap |= (1 << cell_id); + } + return bitmap; +} + +void ipu_fw_psys_pg_dump(struct ipu_psys *psys, + struct ipu_psys_kcmd *kcmd, const char *note) +{ + struct ipu_fw_psys_process_group *pg = kcmd->kpg->pg; + u32 pgid = pg->ID; + u8 processes = pg->process_count; + u16 *process_offset_table = (u16 *)((char *)pg + pg->processes_offset); + unsigned int p, chn, mem, mem_id; + int cell; + + dev_dbg(&psys->adev->dev, "%s %s pgid %i has %i processes:\n", + __func__, note, pgid, processes); + + for (p = 0; p < processes; p++) { + struct ipu_fw_psys_process *process = + (struct ipu_fw_psys_process *) + ((char *)pg + process_offset_table[p]); + cell = process_get_cell(process, 0); + dev_dbg(&psys->adev->dev, "\t process %i size=%u", + p, process->size); + dev_dbg(&psys->adev->dev, + "\t cell %i cell_bitmap=0x%x kernel_bitmap 0x%llx", + cell, process_get_cells_bitmap(process), + (u64) process->kernel_bitmap[1] << 32 | + (u64) process->kernel_bitmap[0]); + for (mem = 0; mem < IPU_FW_PSYS_N_DATA_MEM_TYPE_ID; mem++) { + mem_id = process->ext_mem_id[mem]; + if (mem_id != IPU_FW_PSYS_N_MEM_ID) + dev_dbg(&psys->adev->dev, + "\t mem type %u id %d offset=0x%x", + mem, mem_id, + process->ext_mem_offset[mem]); + } + for (chn = 0; chn < IPU_FW_PSYS_N_DEV_CHN_ID; chn++) { + if (process->dev_chn_offset[chn] != (u16)(-1)) + dev_dbg(&psys->adev->dev, + "\t dev_chn[%u]=0x%x\n", + chn, process->dev_chn_offset[chn]); + } + } +} + +int ipu_fw_psys_pg_get_id(struct ipu_psys_kcmd *kcmd) +{ + return kcmd->kpg->pg->ID; +} + +int ipu_fw_psys_pg_get_terminal_count(struct ipu_psys_kcmd *kcmd) +{ + return kcmd->kpg->pg->terminal_count; +} + +int ipu_fw_psys_pg_get_size(struct ipu_psys_kcmd *kcmd) +{ + return kcmd->kpg->pg->size; +} + +int ipu_fw_psys_pg_set_ipu_vaddress(struct ipu_psys_kcmd *kcmd, + dma_addr_t vaddress) +{ + kcmd->kpg->pg->ipu_virtual_address = vaddress; + return 0; +} + +struct ipu_fw_psys_terminal *ipu_fw_psys_pg_get_terminal(struct ipu_psys_kcmd + *kcmd, int index) +{ + struct ipu_fw_psys_terminal *terminal; + u16 *terminal_offset_table; + + terminal_offset_table = + (uint16_t *)((char *)kcmd->kpg->pg + + kcmd->kpg->pg->terminals_offset); + terminal = (struct ipu_fw_psys_terminal *) + ((char *)kcmd->kpg->pg + terminal_offset_table[index]); + return terminal; +} + +void ipu_fw_psys_pg_set_token(struct ipu_psys_kcmd *kcmd, u64 token) +{ + kcmd->kpg->pg->token = (u64)token; +} + +u64 ipu_fw_psys_pg_get_token(struct ipu_psys_kcmd *kcmd) +{ + return kcmd->kpg->pg->token; +} + +int ipu_fw_psys_pg_get_protocol(struct ipu_psys_kcmd *kcmd) +{ + return kcmd->kpg->pg->protocol_version; +} + + +int ipu_fw_psys_open(struct ipu_psys *psys) +{ + int retry = IPU_PSYS_OPEN_RETRY, retval; + + retval = ipu_fw_com_open(psys->fwcom); + if (retval) { + dev_err(&psys->adev->dev, "fw com open failed.\n"); + return retval; + } + + do { + usleep_range(IPU_PSYS_OPEN_TIMEOUT_US, + IPU_PSYS_OPEN_TIMEOUT_US + 10); + retval = ipu_fw_com_ready(psys->fwcom); + if (!retval) { + dev_dbg(&psys->adev->dev, "psys port open ready!\n"); + break; + } + } while (retry-- > 0); + + if (!retry && retval) { + dev_err(&psys->adev->dev, "psys port open ready failed %d\n", + retval); + ipu_fw_com_close(psys->fwcom); + return retval; + } + return 0; +} + +int ipu_fw_psys_close(struct ipu_psys *psys) +{ + int retval; + + retval = ipu_fw_com_close(psys->fwcom); + if (retval) { + dev_err(&psys->adev->dev, "fw com close failed.\n"); + return retval; + } + return retval; +} diff --git a/drivers/media/pci/intel/ipu-fw-psys.h b/drivers/media/pci/intel/ipu-fw-psys.h new file mode 100644 index 0000000000000..1738f6cec768a --- /dev/null +++ b/drivers/media/pci/intel/ipu-fw-psys.h @@ -0,0 +1,350 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2016 - 2018 Intel Corporation */ + +#ifndef IPU_FW_PSYS_H +#define IPU_FW_PSYS_H + +#include "ipu-platform-resources.h" + +/* ia_css_psys_device.c */ +#define IPU_FW_PSYS_CMD_QUEUE_SIZE 0x20 +#define IPU_FW_PSYS_EVENT_QUEUE_SIZE 0x40 + +/* ia_css_psys_transport.h */ +#define IPU_FW_PSYS_CMD_BITS 64 +#define IPU_FW_PSYS_EVENT_BITS 128 + +/* ia_css_psys_transport.h */ +enum { + IPU_FW_PSYS_EVENT_TYPE_SUCCESS = 0, + IPU_FW_PSYS_EVENT_TYPE_UNKNOWN_ERROR = 1, + IPU_FW_PSYS_EVENT_TYPE_RET_REM_OBJ_NOT_FOUND = 2, + IPU_FW_PSYS_EVENT_TYPE_RET_REM_OBJ_TOO_BIG = 3, + IPU_FW_PSYS_EVENT_TYPE_RET_REM_OBJ_DDR_TRANS_ERR = 4, + IPU_FW_PSYS_EVENT_TYPE_RET_REM_OBJ_NULL_PKG_DIR_ADDR = 5, + IPU_FW_PSYS_EVENT_TYPE_PROC_GRP_LOAD_FRAME_ERR = 6, + IPU_FW_PSYS_EVENT_TYPE_PROC_GRP_LOAD_FRAGMENT_ERR = 7, + IPU_FW_PSYS_EVENT_TYPE_PROC_GRP_PROCESS_COUNT_ZERO = 8, + IPU_FW_PSYS_EVENT_TYPE_PROC_GRP_PROCESS_INIT_ERR = 9, + IPU_FW_PSYS_EVENT_TYPE_PROC_GRP_ABORT = 10, + IPU_FW_PSYS_EVENT_TYPE_PROC_GRP_NULL = 11, + IPU_FW_PSYS_EVENT_TYPE_PROC_GRP_VALIDATION_ERR = 12 +}; + +enum { + IPU_FW_PSYS_EVENT_QUEUE_MAIN_ID, + IPU_FW_PSYS_N_PSYS_EVENT_QUEUE_ID +}; + +enum { + IPU_FW_PSYS_PROCESS_GROUP_ERROR = 0, + IPU_FW_PSYS_PROCESS_GROUP_CREATED, + IPU_FW_PSYS_PROCESS_GROUP_READY, + IPU_FW_PSYS_PROCESS_GROUP_BLOCKED, + IPU_FW_PSYS_PROCESS_GROUP_STARTED, + IPU_FW_PSYS_PROCESS_GROUP_RUNNING, + IPU_FW_PSYS_PROCESS_GROUP_STALLED, + IPU_FW_PSYS_PROCESS_GROUP_STOPPED, + IPU_FW_PSYS_N_PROCESS_GROUP_STATES +}; + +enum { + IPU_FW_PSYS_CONNECTION_MEMORY = 0, + IPU_FW_PSYS_CONNECTION_MEMORY_STREAM, + IPU_FW_PSYS_CONNECTION_STREAM, + IPU_FW_PSYS_N_CONNECTION_TYPES +}; + +enum { + IPU_FW_PSYS_BUFFER_NULL = 0, + IPU_FW_PSYS_BUFFER_UNDEFINED, + IPU_FW_PSYS_BUFFER_EMPTY, + IPU_FW_PSYS_BUFFER_NONEMPTY, + IPU_FW_PSYS_BUFFER_FULL, + IPU_FW_PSYS_N_BUFFER_STATES +}; + +enum { + IPU_FW_PSYS_TERMINAL_TYPE_DATA_IN = 0, + IPU_FW_PSYS_TERMINAL_TYPE_DATA_OUT, + IPU_FW_PSYS_TERMINAL_TYPE_PARAM_STREAM, + IPU_FW_PSYS_TERMINAL_TYPE_PARAM_CACHED_IN, + IPU_FW_PSYS_TERMINAL_TYPE_PARAM_CACHED_OUT, + IPU_FW_PSYS_TERMINAL_TYPE_PARAM_SPATIAL_IN, + IPU_FW_PSYS_TERMINAL_TYPE_PARAM_SPATIAL_OUT, + IPU_FW_PSYS_TERMINAL_TYPE_PARAM_SLICED_IN, + IPU_FW_PSYS_TERMINAL_TYPE_PARAM_SLICED_OUT, + IPU_FW_PSYS_TERMINAL_TYPE_STATE_IN, + IPU_FW_PSYS_TERMINAL_TYPE_STATE_OUT, + IPU_FW_PSYS_TERMINAL_TYPE_PROGRAM, + IPU_FW_PSYS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT, + IPU_FW_PSYS_N_TERMINAL_TYPES +}; + +enum { + IPU_FW_PSYS_COL_DIMENSION = 0, + IPU_FW_PSYS_ROW_DIMENSION = 1, + IPU_FW_PSYS_N_DATA_DIMENSION = 2 +}; + +enum { + IPU_FW_PSYS_PROCESS_GROUP_CMD_NOP = 0, + IPU_FW_PSYS_PROCESS_GROUP_CMD_SUBMIT, + IPU_FW_PSYS_PROCESS_GROUP_CMD_ATTACH, + IPU_FW_PSYS_PROCESS_GROUP_CMD_DETACH, + IPU_FW_PSYS_PROCESS_GROUP_CMD_START, + IPU_FW_PSYS_PROCESS_GROUP_CMD_DISOWN, + IPU_FW_PSYS_PROCESS_GROUP_CMD_RUN, + IPU_FW_PSYS_PROCESS_GROUP_CMD_STOP, + IPU_FW_PSYS_PROCESS_GROUP_CMD_SUSPEND, + IPU_FW_PSYS_PROCESS_GROUP_CMD_RESUME, + IPU_FW_PSYS_PROCESS_GROUP_CMD_ABORT, + IPU_FW_PSYS_PROCESS_GROUP_CMD_RESET, + IPU_FW_PSYS_N_PROCESS_GROUP_CMDS +}; + +enum { + IPU_FW_PSYS_PROCESS_GROUP_PROTOCOL_LEGACY = 0, + IPU_FW_PSYS_PROCESS_GROUP_N_PROTOCOLS +}; + +/* ia_css_psys_process_group_cmd_impl.h */ +struct __packed ipu_fw_psys_process_group { + u64 token; + u64 private_token; + u32 routing_bitmap[IPU_FW_PSYS_RBM_NOF_ELEMS]; + u32 size; + u32 pg_load_start_ts; + u32 pg_load_cycles; + u32 pg_init_cycles; + u32 pg_processing_cycles; + u32 ID; + u32 state; + u32 ipu_virtual_address; + u32 resource_bitmap; + u16 fragment_count; + u16 fragment_state; + u16 fragment_limit; + u16 processes_offset; + u16 terminals_offset; + u8 process_count; + u8 terminal_count; + u8 subgraph_count; + u8 protocol_version; + u8 base_queue_id; + u8 num_queues; + u8 padding[IPU_FW_PSYS_N_PADDING_UINT8_IN_PROCESS_GROUP_STRUCT]; +}; + +/* ia_css_psys_init.h */ +struct ipu_fw_psys_srv_init { + void *host_ddr_pkg_dir; + u32 ddr_pkg_dir_address; + u32 pkg_dir_size; + + u32 icache_prefetch_sp; + u32 icache_prefetch_isp; +}; + +/* ia_css_psys_transport.h */ +struct __packed ipu_fw_psys_cmd { + u16 command; + u16 msg; + u32 context_handle; +}; + +struct __packed ipu_fw_psys_event { + u16 status; + u16 command; + u32 context_handle; + u64 token; +}; + +/* ia_css_terminal_base_types.h */ +struct ipu_fw_psys_terminal { + u32 terminal_type; + s16 parent_offset; + u16 size; + u16 tm_index; + u8 ID; + u8 padding[IPU_FW_PSYS_N_PADDING_UINT8_IN_TERMINAL_STRUCT]; +}; + +/* ia_css_terminal_types.h */ +struct ipu_fw_psys_param_payload { + u64 host_buffer; + u32 buffer; + u32 terminal_index; +}; + +/* ia_css_program_group_param_types.h */ +struct ipu_fw_psys_param_terminal { + struct ipu_fw_psys_terminal base; + struct ipu_fw_psys_param_payload param_payload; + u16 param_section_desc_offset; + u8 padding[IPU_FW_PSYS_N_PADDING_UINT8_IN_PARAM_TERMINAL_STRUCT]; +}; + +struct ipu_fw_psys_frame { + u32 buffer_state; + u32 access_type; + u32 pointer_state; + u32 access_scope; + u32 data; + u32 data_index; + u32 data_bytes; + u8 padding[IPU_FW_PSYS_N_PADDING_UINT8_IN_FRAME_STRUCT]; +}; + +/* ia_css_program_group_data.h */ +struct ipu_fw_psys_frame_descriptor { + u32 frame_format_type; + u32 plane_count; + u32 plane_offsets[IPU_FW_PSYS_N_FRAME_PLANES]; + u32 stride[1]; + u16 dimension[2]; + u16 size; + u8 bpp; + u8 bpe; + u8 is_compressed; + u8 padding[IPU_FW_PSYS_N_PADDING_UINT8_IN_FRAME_DESC_STRUCT]; +}; + +struct ipu_fw_psys_stream { + u64 dummy; +}; + +/* ia_css_psys_terminal_private_types.h */ +struct ipu_fw_psys_data_terminal { + struct ipu_fw_psys_terminal base; + struct ipu_fw_psys_frame_descriptor frame_descriptor; + struct ipu_fw_psys_frame frame; + struct ipu_fw_psys_stream stream; + u32 reserved; + u32 connection_type; + u16 fragment_descriptor_offset; + u8 kernel_id; + u8 subgraph_id; + u8 padding[IPU_FW_PSYS_N_PADDING_UINT8_IN_DATA_TERMINAL_STRUCT]; +}; + +/* ia_css_psys_buffer_set.h */ +struct ipu_fw_psys_buffer_set { + u64 token; + u32 kernel_enable_bitmap[IPU_FW_PSYS_KERNEL_BITMAP_NOF_ELEMS]; + u32 ipu_virtual_address; + u32 process_group_handle; + u16 terminal_count; + u8 frame_counter; + u8 padding[IPU_FW_PSYS_N_PADDING_UINT8_IN_BUFFER_SET_STRUCT]; +}; + +struct ipu_fw_psys_program_group_manifest { + u32 kernel_bitmap[IPU_FW_PSYS_KERNEL_BITMAP_NOF_ELEMS]; + u32 ID; + u16 program_manifest_offset; + u16 terminal_manifest_offset; + u16 private_data_offset; + u16 rbm_manifest_offset; + u16 size; + u8 alignment; + u8 kernel_count; + u8 program_count; + u8 terminal_count; + u8 subgraph_count; + u8 reserved[5]; +}; + +struct ipu_fw_generic_program_manifest { + u16 *dev_chn_size; + u16 *dev_chn_offset; + u16 *ext_mem_size; + u16 *ext_mem_offset; + u8 cell_id; + u8 cells[IPU_FW_PSYS_PROCESS_MAX_CELLS]; + u8 cell_type_id; + u8 *is_dfm_relocatable; + u32 *dfm_port_bitmap; + u32 *dfm_active_port_bitmap; +}; + +struct ipu_fw_generic_process { + u16 ext_mem_id; + u16 ext_mem_offset; + u16 dev_chn_offset; + u16 cell_id; + u16 dfm_port_bitmap; + u16 dfm_active_port_bitmap; +}; + +struct ipu_fw_resource_definitions { + u32 num_cells; + u32 num_cells_type; +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + const u32 *cells; +#else + const u8 *cells; +#endif + u32 num_dev_channels; + const u16 *dev_channels; + + u32 num_ext_mem_types; + u32 num_ext_mem_ids; + const u16 *ext_mem_ids; + + u32 num_dfm_ids; + const u16 *dfms; + + u32 cell_mem_row; +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + const enum ipu_mem_id *cell_mem; +#else + const u8 *cell_mem; +#endif + struct ipu_fw_generic_process process; +}; + +struct ipu_psys_kcmd; +struct ipu_psys; +int ipu_fw_psys_pg_start(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_pg_disown(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_pg_abort(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_pg_submit(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_pg_load_cycles(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_pg_init_cycles(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_pg_processing_cycles(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_rcv_event(struct ipu_psys *psys, + struct ipu_fw_psys_event *event); +int ipu_fw_psys_terminal_set(struct ipu_fw_psys_terminal *terminal, + int terminal_idx, + struct ipu_psys_kcmd *kcmd, + u32 buffer, unsigned int size); +void ipu_fw_psys_pg_dump(struct ipu_psys *psys, + struct ipu_psys_kcmd *kcmd, const char *note); +int ipu_fw_psys_pg_get_id(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_pg_get_terminal_count(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_pg_get_size(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_pg_set_ipu_vaddress(struct ipu_psys_kcmd *kcmd, + dma_addr_t vaddress); +struct ipu_fw_psys_terminal *ipu_fw_psys_pg_get_terminal(struct ipu_psys_kcmd + *kcmd, int index); +void ipu_fw_psys_pg_set_token(struct ipu_psys_kcmd *kcmd, u64 token); +u64 ipu_fw_psys_pg_get_token(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_pg_get_protocol(struct ipu_psys_kcmd *kcmd); +int ipu_fw_psys_open(struct ipu_psys *psys); +int ipu_fw_psys_close(struct ipu_psys *psys); + +/* common resource interface for both abi and api mode */ +int ipu_fw_psys_set_process_cell_id(struct ipu_fw_psys_process *ptr, u8 index, + u8 value); +u8 ipu_fw_psys_get_process_cell_id(struct ipu_fw_psys_process *ptr, u8 index); +int ipu_fw_psys_clear_process_cell(struct ipu_fw_psys_process *ptr); +int ipu_fw_psys_set_process_dev_chn_offset(struct ipu_fw_psys_process *ptr, + u16 offset, u16 value); +int ipu_fw_psys_set_process_ext_mem(struct ipu_fw_psys_process *ptr, + u16 type_id, u16 mem_id, u16 offset); +int ipu_fw_psys_get_program_manifest_by_process( + struct ipu_fw_generic_program_manifest *gen_pm, + const struct ipu_fw_psys_program_group_manifest *pg_manifest, + struct ipu_fw_psys_process *process); +#endif /* IPU_FW_PSYS_H */ diff --git a/drivers/media/pci/intel/ipu-isys-csi2-be-soc.c b/drivers/media/pci/intel/ipu-isys-csi2-be-soc.c new file mode 100644 index 0000000000000..4d788b653b5bf --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-csi2-be-soc.c @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2014 - 2018 Intel Corporation + +#include +#include + +#include +#include +#include + +#include "ipu.h" +#include "ipu-bus.h" +#include "ipu-isys.h" +#include "ipu-isys-csi2-be.h" +#include "ipu-isys-subdev.h" +#include "ipu-isys-video.h" + +/* + * Raw bayer format pixel order MUST BE MAINTAINED in groups of four codes. + * Otherwise pixel order calculation below WILL BREAK! + */ +static const u32 csi2_be_soc_supported_codes_pad[] = { + MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_RGB565_1X16, + MEDIA_BUS_FMT_RGB888_1X24, + /* YUV420 plannar */ + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_SBGGR14_1X14, + MEDIA_BUS_FMT_SGBRG14_1X14, + MEDIA_BUS_FMT_SGRBG14_1X14, + MEDIA_BUS_FMT_SRGGB14_1X14, + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + 0, +}; + +/* + * Raw bayer format pixel order MUST BE MAINTAINED in groups of four codes. + * Otherwise pixel order calculation below WILL BREAK! + */ +static const u32 csi2_be_soc_supported_raw_bayer_codes_pad[] = { + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_Y8_1X8, + 0, +}; + +static int get_supported_code_index(u32 code) +{ + int i; + + for (i = 0; csi2_be_soc_supported_raw_bayer_codes_pad[i]; i++) { + if (csi2_be_soc_supported_raw_bayer_codes_pad[i] == code) + return i; + } + return -EINVAL; +} + +static const u32 *csi2_be_soc_supported_codes[NR_OF_CSI2_BE_SOC_PADS]; + +static struct v4l2_subdev_internal_ops csi2_be_soc_sd_internal_ops = { + .open = ipu_isys_subdev_open, + .close = ipu_isys_subdev_close, +}; + +static const struct v4l2_subdev_core_ops csi2_be_soc_sd_core_ops = { +}; + +static int set_stream(struct v4l2_subdev *sd, int enable) +{ + return 0; +} + +static const struct v4l2_subdev_video_ops csi2_be_soc_sd_video_ops = { + .s_stream = set_stream, +}; + +static int +__subdev_link_validate(struct v4l2_subdev *sd, struct media_link *link, + struct v4l2_subdev_format *source_fmt, + struct v4l2_subdev_format *sink_fmt) +{ + struct ipu_isys_pipeline *ip = container_of(media_entity_pipeline(&sd->entity), + struct ipu_isys_pipeline, + pipe); + + ip->csi2_be_soc = to_ipu_isys_csi2_be_soc(sd); + return ipu_isys_subdev_link_validate(sd, link, source_fmt, sink_fmt); +} + +static int +ipu_isys_csi2_be_soc_set_sel(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + struct media_pad *pad = &asd->sd.entity.pads[sel->pad]; + + if (sel->target == V4L2_SEL_TGT_CROP && + pad->flags & MEDIA_PAD_FL_SOURCE && + asd->valid_tgts[sel->pad].crop) { + struct v4l2_rect *r; + unsigned int sink_pad = 0; + int i; + + for (i = 0; i < asd->nstreams; i++) { + if (!(asd->route[i].flags & + V4L2_SUBDEV_ROUTE_FL_ACTIVE)) + continue; + if (asd->route[i].source == sel->pad) { + sink_pad = asd->route[i].sink; + break; + } + } + + if (i == asd->nstreams) { + dev_dbg(&asd->isys->adev->dev, "No sink pad routed.\n"); + return -EINVAL; + } + r = __ipu_isys_get_selection(sd, state, sel->target, + sink_pad, sel->which); + + /* Cropping is not supported by SoC BE. + * Only horizontal padding is allowed. + */ + sel->r.top = r->top; + sel->r.left = r->left; + sel->r.width = clamp(sel->r.width, r->width, + IPU_ISYS_MAX_WIDTH); + sel->r.height = r->height; + + *__ipu_isys_get_selection(sd, state, sel->target, sel->pad, + sel->which) = sel->r; + ipu_isys_subdev_fmt_propagate(sd, state, NULL, &sel->r, + IPU_ISYS_SUBDEV_PROP_TGT_SOURCE_CROP, + sel->pad, sel->which); + return 0; + } + return -EINVAL; +} + +static const struct v4l2_subdev_pad_ops csi2_be_soc_sd_pad_ops = { + .link_validate = __subdev_link_validate, + .get_fmt = ipu_isys_subdev_get_ffmt, + .set_fmt = ipu_isys_subdev_set_ffmt, + .get_selection = ipu_isys_subdev_get_sel, + .set_selection = ipu_isys_csi2_be_soc_set_sel, + .enum_mbus_code = ipu_isys_subdev_enum_mbus_code, + .set_routing = ipu_isys_subdev_set_routing, + .get_routing = ipu_isys_subdev_get_routing, +}; + +static struct v4l2_subdev_ops csi2_be_soc_sd_ops = { + .core = &csi2_be_soc_sd_core_ops, + .video = &csi2_be_soc_sd_video_ops, + .pad = &csi2_be_soc_sd_pad_ops, +}; + +static struct media_entity_operations csi2_be_soc_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +static void csi2_be_soc_set_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *fmt) +{ + struct v4l2_mbus_framefmt *ffmt = + __ipu_isys_get_ffmt(sd, state, fmt->pad, + fmt->stream, + fmt->which); + + if (sd->entity.pads[fmt->pad].flags & MEDIA_PAD_FL_SINK) { + if (fmt->format.field != V4L2_FIELD_ALTERNATE) + fmt->format.field = V4L2_FIELD_NONE; + *ffmt = fmt->format; + + ipu_isys_subdev_fmt_propagate(sd, state, &fmt->format, + NULL, + IPU_ISYS_SUBDEV_PROP_TGT_SINK_FMT, + fmt->pad, fmt->which); + } else if (sd->entity.pads[fmt->pad].flags & MEDIA_PAD_FL_SOURCE) { + struct v4l2_mbus_framefmt *sink_ffmt; + struct v4l2_rect *r = __ipu_isys_get_selection(sd, state, + V4L2_SEL_TGT_CROP, fmt->pad, fmt->which); + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + u32 code; + int idx; + + sink_ffmt = __ipu_isys_get_ffmt(sd, state, 0, 0, fmt->which); + code = sink_ffmt->code; + idx = get_supported_code_index(code); + + if (asd->valid_tgts[fmt->pad].crop && idx >= 0) { + int crop_info = 0; + + /* Only croping odd line at top side. */ + if (r->top & 1) + crop_info |= CSI2_BE_CROP_VER; + + code = csi2_be_soc_supported_raw_bayer_codes_pad + [((idx & CSI2_BE_CROP_MASK) ^ crop_info) + + (idx & ~CSI2_BE_CROP_MASK)]; + + } + ffmt->code = code; + ffmt->width = r->width; + ffmt->height = r->height; + ffmt->field = sink_ffmt->field; + + } +} + +void ipu_isys_csi2_be_soc_cleanup(struct ipu_isys_csi2_be_soc *csi2_be_soc) +{ + int i; + + if (!csi2_be_soc->asd.sd.v4l2_dev) + return; + + v4l2_device_unregister_subdev(&csi2_be_soc->asd.sd); + ipu_isys_subdev_cleanup(&csi2_be_soc->asd); + for (i = 0; i < NR_OF_CSI2_BE_SOC_STREAMS; i++) + ipu_isys_video_cleanup(&csi2_be_soc->av[i]); +} + +int ipu_isys_csi2_be_soc_init(struct ipu_isys_csi2_be_soc *csi2_be_soc, + struct ipu_isys *isys) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = CSI2_BE_SOC_PAD_SINK(0), + .format = { + .width = 4096, + .height = 3072, + }, + }; + int rval, i; + + csi2_be_soc->asd.sd.entity.ops = &csi2_be_soc_entity_ops; + csi2_be_soc->asd.isys = isys; + + rval = ipu_isys_subdev_init(&csi2_be_soc->asd, + &csi2_be_soc_sd_ops, 0, + NR_OF_CSI2_BE_SOC_PADS, + NR_OF_CSI2_BE_SOC_STREAMS, + NR_OF_CSI2_BE_SOC_SOURCE_PADS, + NR_OF_CSI2_BE_SOC_SINK_PADS, 0); + if (rval) + goto fail; + + for (i = CSI2_BE_SOC_PAD_SINK(0); i < NR_OF_CSI2_BE_SOC_SINK_PADS; i++) + csi2_be_soc->asd.pad[i].flags = MEDIA_PAD_FL_SINK; + + for (i = CSI2_BE_SOC_PAD_SOURCE(0); + i < NR_OF_CSI2_BE_SOC_SOURCE_PADS + CSI2_BE_SOC_PAD_SOURCE(0); + i++) { + csi2_be_soc->asd.pad[i].flags = MEDIA_PAD_FL_SOURCE; + csi2_be_soc->asd.valid_tgts[i].crop = true; + } + + for (i = 0; i < NR_OF_CSI2_BE_SOC_PADS; i++) + csi2_be_soc_supported_codes[i] = + csi2_be_soc_supported_codes_pad; + csi2_be_soc->asd.supported_codes = csi2_be_soc_supported_codes; + csi2_be_soc->asd.be_mode = IPU_BE_SOC; + csi2_be_soc->asd.isl_mode = IPU_ISL_OFF; + csi2_be_soc->asd.set_ffmt = csi2_be_soc_set_ffmt; + + for (i = CSI2_BE_SOC_PAD_SINK(0); i < NR_OF_CSI2_BE_SOC_SINK_PADS; + i++) { + fmt.pad = CSI2_BE_SOC_PAD_SINK(i); + ipu_isys_subdev_set_ffmt(&csi2_be_soc->asd.sd, NULL, &fmt); + } + + ipu_isys_subdev_set_ffmt(&csi2_be_soc->asd.sd, NULL, &fmt); + csi2_be_soc->asd.sd.internal_ops = &csi2_be_soc_sd_internal_ops; + + snprintf(csi2_be_soc->asd.sd.name, sizeof(csi2_be_soc->asd.sd.name), + IPU_ISYS_ENTITY_PREFIX " CSI2 BE SOC"); + + v4l2_set_subdevdata(&csi2_be_soc->asd.sd, &csi2_be_soc->asd); + + mutex_lock(&csi2_be_soc->asd.mutex); + rval = v4l2_device_register_subdev(&isys->v4l2_dev, + &csi2_be_soc->asd.sd); + if (rval) { + dev_info(&isys->adev->dev, "can't register v4l2 subdev\n"); + goto fail; + } + + /* create default route information */ + for (i = 0; i < NR_OF_CSI2_BE_SOC_STREAMS; i++) { + csi2_be_soc->asd.route[i].sink = CSI2_BE_SOC_PAD_SINK(i); + csi2_be_soc->asd.route[i].source = CSI2_BE_SOC_PAD_SOURCE(i); + csi2_be_soc->asd.route[i].flags = 0; + } + + for (i = 0; i < NR_OF_CSI2_BE_SOC_SOURCE_PADS; i++) { + csi2_be_soc->asd.stream[CSI2_BE_SOC_PAD_SINK(i)].stream_id[0] + = 0; + csi2_be_soc->asd.stream[CSI2_BE_SOC_PAD_SOURCE(i)].stream_id[0] + = 0; + } + for (i = 0; i < NR_OF_CSI2_BE_SOC_STREAMS; i++) { + csi2_be_soc->asd.route[i].flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE; + bitmap_set(csi2_be_soc->asd.stream[CSI2_BE_SOC_PAD_SINK(i)]. + streams_stat, 0, 1); + bitmap_set(csi2_be_soc->asd.stream[CSI2_BE_SOC_PAD_SOURCE(i)]. + streams_stat, 0, 1); + } + csi2_be_soc->asd.route[0].flags |= V4L2_SUBDEV_ROUTE_FL_IMMUTABLE; + mutex_unlock(&csi2_be_soc->asd.mutex); + for (i = 0; i < NR_OF_CSI2_BE_SOC_SOURCE_PADS; i++) { + snprintf(csi2_be_soc->av[i].vdev.name, + sizeof(csi2_be_soc->av[i].vdev.name), + IPU_ISYS_ENTITY_PREFIX " BE SOC capture %d", i); + /* + * Pin type could be overwritten for YUV422 to I420 case, at + * set_format phase + */ + csi2_be_soc->av[i].aq.css_pin_type = + IPU_FW_ISYS_PIN_TYPE_RAW_SOC; + csi2_be_soc->av[i].isys = isys; + csi2_be_soc->av[i].pfmts = ipu_isys_pfmts_be_soc; + + csi2_be_soc->av[i].try_fmt_vid_mplane = + ipu_isys_video_try_fmt_vid_mplane_default; + csi2_be_soc->av[i].prepare_firmware_stream_cfg = + ipu_isys_prepare_firmware_stream_cfg_default; + csi2_be_soc->av[i].aq.buf_prepare = ipu_isys_buf_prepare; + csi2_be_soc->av[i].aq.fill_frame_buff_set_pin = + ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set_pin; + csi2_be_soc->av[i].aq.link_fmt_validate = + ipu_isys_link_fmt_validate; + csi2_be_soc->av[i].aq.vbq.buf_struct_size = + sizeof(struct ipu_isys_video_buffer); + + rval = ipu_isys_video_init(&csi2_be_soc->av[i], + &csi2_be_soc->asd.sd.entity, + CSI2_BE_SOC_PAD_SOURCE(i), + MEDIA_PAD_FL_SINK, + MEDIA_LNK_FL_DYNAMIC); + if (rval) { + dev_info(&isys->adev->dev, "can't init video node\n"); + goto fail; + } + } + + return 0; + +fail: + ipu_isys_csi2_be_soc_cleanup(csi2_be_soc); + + return rval; +} diff --git a/drivers/media/pci/intel/ipu-isys-csi2-be.c b/drivers/media/pci/intel/ipu-isys-csi2-be.c new file mode 100644 index 0000000000000..2c1fc7123ad5e --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-csi2-be.c @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2014 - 2018 Intel Corporation + +#include +#include + +#include +#include +#include + +#include "ipu.h" +#include "ipu-bus.h" +#include "ipu-isys.h" +#include "ipu-isys-csi2-be.h" +#include "ipu-isys-subdev.h" +#include "ipu-isys-video.h" + +/* + * Raw bayer format pixel order MUST BE MAINTAINED in groups of four codes. + * Otherwise pixel order calculation below WILL BREAK! + */ +static const u32 csi2_be_supported_codes_pad[] = { + MEDIA_BUS_FMT_SBGGR14_1X14, + MEDIA_BUS_FMT_SGBRG14_1X14, + MEDIA_BUS_FMT_SGRBG14_1X14, + MEDIA_BUS_FMT_SRGGB14_1X14, + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + 0, +}; + +static const u32 *csi2_be_supported_codes[] = { + csi2_be_supported_codes_pad, + csi2_be_supported_codes_pad, +}; + +static struct v4l2_subdev_internal_ops csi2_be_sd_internal_ops = { + .open = ipu_isys_subdev_open, + .close = ipu_isys_subdev_close, +}; + +static const struct v4l2_subdev_core_ops csi2_be_sd_core_ops = { +}; + +static int set_stream(struct v4l2_subdev *sd, int enable) +{ + return 0; +} + +static const struct v4l2_subdev_video_ops csi2_be_sd_video_ops = { + .s_stream = set_stream, +}; + +static int __subdev_link_validate(struct v4l2_subdev *sd, + struct media_link *link, + struct v4l2_subdev_format *source_fmt, + struct v4l2_subdev_format *sink_fmt) +{ + struct ipu_isys_pipeline *ip = container_of(media_entity_pipeline(&sd->entity), + struct ipu_isys_pipeline, + pipe); + + ip->csi2_be = to_ipu_isys_csi2_be(sd); + return ipu_isys_subdev_link_validate(sd, link, source_fmt, sink_fmt); +} + +static int get_supported_code_index(u32 code) +{ + int i; + + for (i = 0; csi2_be_supported_codes_pad[i]; i++) { + if (csi2_be_supported_codes_pad[i] == code) + return i; + } + return -EINVAL; +} + +static int ipu_isys_csi2_be_set_sel(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + struct media_pad *pad = &asd->sd.entity.pads[sel->pad]; + + if (sel->target == V4L2_SEL_TGT_CROP && + pad->flags & MEDIA_PAD_FL_SOURCE && + asd->valid_tgts[CSI2_BE_PAD_SOURCE].crop) { + struct v4l2_mbus_framefmt *ffmt = + __ipu_isys_get_ffmt(sd, state, sel->pad, 0, sel->which); + struct v4l2_rect *r = __ipu_isys_get_selection + (sd, state, sel->target, CSI2_BE_PAD_SINK, sel->which); + + if (get_supported_code_index(ffmt->code) < 0) { + /* Non-bayer formats can't be single line cropped */ + sel->r.left &= ~1; + sel->r.top &= ~1; + + /* Non-bayer formats can't pe padded at all */ + sel->r.width = clamp(sel->r.width, + IPU_ISYS_MIN_WIDTH, r->width); + } else { + sel->r.width = clamp(sel->r.width, + IPU_ISYS_MIN_WIDTH, + IPU_ISYS_MAX_WIDTH); + } + + /* + * ISAPF can pad only horizontally, height is + * restricted by sink pad resolution. + */ + sel->r.height = clamp(sel->r.height, IPU_ISYS_MIN_HEIGHT, + r->height); + *__ipu_isys_get_selection(sd, state, sel->target, sel->pad, + sel->which) = sel->r; + ipu_isys_subdev_fmt_propagate + (sd, state, NULL, &sel->r, + IPU_ISYS_SUBDEV_PROP_TGT_SOURCE_CROP, + sel->pad, sel->which); + return 0; + } + return ipu_isys_subdev_set_sel(sd, state, sel); +} + +static const struct v4l2_subdev_pad_ops csi2_be_sd_pad_ops = { + .link_validate = __subdev_link_validate, + .get_fmt = ipu_isys_subdev_get_ffmt, + .set_fmt = ipu_isys_subdev_set_ffmt, + .get_selection = ipu_isys_subdev_get_sel, + .set_selection = ipu_isys_csi2_be_set_sel, + .enum_mbus_code = ipu_isys_subdev_enum_mbus_code, +}; + +static struct v4l2_subdev_ops csi2_be_sd_ops = { + .core = &csi2_be_sd_core_ops, + .video = &csi2_be_sd_video_ops, + .pad = &csi2_be_sd_pad_ops, +}; + +static struct media_entity_operations csi2_be_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +static void csi2_be_set_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *fmt) +{ + struct ipu_isys_csi2 *csi2 = to_ipu_isys_csi2(sd); + struct v4l2_mbus_framefmt *ffmt = + __ipu_isys_get_ffmt(sd, state, fmt->pad, fmt->stream, + fmt->which); + + switch (fmt->pad) { + case CSI2_BE_PAD_SINK: + if (fmt->format.field != V4L2_FIELD_ALTERNATE) + fmt->format.field = V4L2_FIELD_NONE; + *ffmt = fmt->format; + + ipu_isys_subdev_fmt_propagate + (sd, state, &fmt->format, NULL, + IPU_ISYS_SUBDEV_PROP_TGT_SINK_FMT, fmt->pad, fmt->which); + return; + case CSI2_BE_PAD_SOURCE: { + struct v4l2_mbus_framefmt *sink_ffmt = + __ipu_isys_get_ffmt(sd, state, CSI2_BE_PAD_SINK, + fmt->stream, fmt->which); + struct v4l2_rect *r = + __ipu_isys_get_selection(sd, state, V4L2_SEL_TGT_CROP, + CSI2_BE_PAD_SOURCE, + fmt->which); + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + u32 code = sink_ffmt->code; + int idx = get_supported_code_index(code); + + if (asd->valid_tgts[CSI2_BE_PAD_SOURCE].crop && idx >= 0) { + int crop_info = 0; + + if (r->top & 1) + crop_info |= CSI2_BE_CROP_VER; + if (r->left & 1) + crop_info |= CSI2_BE_CROP_HOR; + code = csi2_be_supported_codes_pad + [((idx & CSI2_BE_CROP_MASK) ^ crop_info) + + (idx & ~CSI2_BE_CROP_MASK)]; + } + ffmt->width = r->width; + ffmt->height = r->height; + ffmt->code = code; + ffmt->field = sink_ffmt->field; + return; + } + default: + dev_err(&csi2->isys->adev->dev, "Unknown pad type\n"); + WARN_ON(1); + } +} + +void ipu_isys_csi2_be_cleanup(struct ipu_isys_csi2_be *csi2_be) +{ + if (!csi2_be->asd.sd.v4l2_dev) + return; + + v4l2_device_unregister_subdev(&csi2_be->asd.sd); + ipu_isys_subdev_cleanup(&csi2_be->asd); + ipu_isys_video_cleanup(&csi2_be->av); +} + +int ipu_isys_csi2_be_init(struct ipu_isys_csi2_be *csi2_be, + struct ipu_isys *isys) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = CSI2_BE_PAD_SINK, + .format = { + .width = 4096, + .height = 3072, + }, + }; + struct v4l2_subdev_selection sel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = CSI2_BE_PAD_SOURCE, + .target = V4L2_SEL_TGT_CROP, + .r = { + .width = fmt.format.width, + .height = fmt.format.height, + }, + }; + int rval; + + csi2_be->asd.sd.entity.ops = &csi2_be_entity_ops; + csi2_be->asd.isys = isys; + + rval = ipu_isys_subdev_init(&csi2_be->asd, &csi2_be_sd_ops, 0, + NR_OF_CSI2_BE_PADS, + NR_OF_CSI2_BE_STREAMS, + NR_OF_CSI2_BE_SOURCE_PADS, + NR_OF_CSI2_BE_SINK_PADS, 0); + if (rval) + goto fail; + + csi2_be->asd.pad[CSI2_BE_PAD_SINK].flags = MEDIA_PAD_FL_SINK + | MEDIA_PAD_FL_MUST_CONNECT; + csi2_be->asd.pad[CSI2_BE_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + csi2_be->asd.valid_tgts[CSI2_BE_PAD_SOURCE].crop = true; + csi2_be->asd.set_ffmt = csi2_be_set_ffmt; + + BUILD_BUG_ON(ARRAY_SIZE(csi2_be_supported_codes) != NR_OF_CSI2_BE_PADS); + csi2_be->asd.supported_codes = csi2_be_supported_codes; + csi2_be->asd.be_mode = IPU_BE_RAW; + csi2_be->asd.isl_mode = IPU_ISL_CSI2_BE; + + ipu_isys_subdev_set_ffmt(&csi2_be->asd.sd, NULL, &fmt); + ipu_isys_csi2_be_set_sel(&csi2_be->asd.sd, NULL, &sel); + + csi2_be->asd.sd.internal_ops = &csi2_be_sd_internal_ops; + snprintf(csi2_be->asd.sd.name, sizeof(csi2_be->asd.sd.name), + IPU_ISYS_ENTITY_PREFIX " CSI2 BE"); + snprintf(csi2_be->av.vdev.name, sizeof(csi2_be->av.vdev.name), + IPU_ISYS_ENTITY_PREFIX " CSI2 BE capture"); + csi2_be->av.aq.css_pin_type = IPU_FW_ISYS_PIN_TYPE_RAW_NS; + v4l2_set_subdevdata(&csi2_be->asd.sd, &csi2_be->asd); + rval = v4l2_device_register_subdev(&isys->v4l2_dev, &csi2_be->asd.sd); + if (rval) { + dev_info(&isys->adev->dev, "can't register v4l2 subdev\n"); + goto fail; + } + + csi2_be->av.isys = isys; + csi2_be->av.pfmts = ipu_isys_pfmts; + csi2_be->av.try_fmt_vid_mplane = + ipu_isys_video_try_fmt_vid_mplane_default; + csi2_be->av.prepare_firmware_stream_cfg = + ipu_isys_prepare_firmware_stream_cfg_default; + csi2_be->av.aq.buf_prepare = ipu_isys_buf_prepare; + csi2_be->av.aq.fill_frame_buff_set_pin = + ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set_pin; + csi2_be->av.aq.link_fmt_validate = ipu_isys_link_fmt_validate; + csi2_be->av.aq.vbq.buf_struct_size = + sizeof(struct ipu_isys_video_buffer); + + rval = ipu_isys_video_init(&csi2_be->av, &csi2_be->asd.sd.entity, + CSI2_BE_PAD_SOURCE, MEDIA_PAD_FL_SINK, 0); + if (rval) { + dev_info(&isys->adev->dev, "can't init video node\n"); + goto fail; + } + + return 0; + +fail: + ipu_isys_csi2_be_cleanup(csi2_be); + + return rval; +} diff --git a/drivers/media/pci/intel/ipu-isys-csi2-be.h b/drivers/media/pci/intel/ipu-isys-csi2-be.h new file mode 100644 index 0000000000000..28c2895d9a333 --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-csi2-be.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2014 - 2018 Intel Corporation */ + +#ifndef IPU_ISYS_CSI2_BE_H +#define IPU_ISYS_CSI2_BE_H + +#include +#include + +#include "ipu-isys-queue.h" +#include "ipu-isys-subdev.h" +#include "ipu-isys-video.h" +#include "ipu-platform-isys.h" + +struct ipu_isys_csi2_be_pdata; +struct ipu_isys; + +#define CSI2_BE_PAD_SINK 0 +#define CSI2_BE_PAD_SOURCE 1 + +#define NR_OF_CSI2_BE_PADS 2 +#define NR_OF_CSI2_BE_SOURCE_PADS 1 +#define NR_OF_CSI2_BE_SINK_PADS 1 + +#define INVALID_VC_ID -1 + +#define NR_OF_CSI2_BE_STREAMS 1 +#define NR_OF_CSI2_BE_SOC_SOURCE_PADS NR_OF_CSI2_BE_SOC_STREAMS +#define NR_OF_CSI2_BE_SOC_SINK_PADS NR_OF_CSI2_BE_SOC_STREAMS +#define CSI2_BE_SOC_PAD_SINK(n) \ + ({ typeof(n) __n = (n); \ + (__n) >= NR_OF_CSI2_BE_SOC_SINK_PADS ? \ + (NR_OF_CSI2_BE_SOC_SINK_PADS) : (__n); }) +#define CSI2_BE_SOC_PAD_SOURCE(n) \ + ({ typeof(n) __n = (n); \ + (__n) >= NR_OF_CSI2_BE_SOC_SOURCE_PADS ? \ + (NR_OF_CSI2_BE_SOC_PADS - 1) : \ + ((__n) + NR_OF_CSI2_BE_SOC_SINK_PADS); }) +#define NR_OF_CSI2_BE_SOC_PADS \ + (NR_OF_CSI2_BE_SOC_SOURCE_PADS + NR_OF_CSI2_BE_SOC_SINK_PADS) + +#define CSI2_BE_CROP_HOR BIT(0) +#define CSI2_BE_CROP_VER BIT(1) +#define CSI2_BE_CROP_MASK (CSI2_BE_CROP_VER | CSI2_BE_CROP_HOR) + +/* + * struct ipu_isys_csi2_be + */ +struct ipu_isys_csi2_be { + struct ipu_isys_csi2_be_pdata *pdata; + struct ipu_isys_subdev asd; + struct ipu_isys_video av; +}; + +struct ipu_isys_csi2_be_soc { + struct ipu_isys_csi2_be_pdata *pdata; + struct ipu_isys_subdev asd; + struct ipu_isys_video av[NR_OF_CSI2_BE_SOC_SOURCE_PADS]; +}; + +#define to_ipu_isys_csi2_be(sd) \ + container_of(to_ipu_isys_subdev(sd), \ + struct ipu_isys_csi2_be, asd) + +#define to_ipu_isys_csi2_be_soc(sd) \ + container_of(to_ipu_isys_subdev(sd), \ + struct ipu_isys_csi2_be_soc, asd) + +int ipu_isys_csi2_be_init(struct ipu_isys_csi2_be *csi2_be, + struct ipu_isys *isys); +int ipu_isys_csi2_be_soc_init( + struct ipu_isys_csi2_be_soc *csi2_be_soc, struct ipu_isys *isys); +void ipu_isys_csi2_be_cleanup(struct ipu_isys_csi2_be *csi2_be); +void ipu_isys_csi2_be_soc_cleanup(struct ipu_isys_csi2_be_soc *csi2_be); + +#endif /* IPU_ISYS_CSI2_BE_H */ diff --git a/drivers/media/pci/intel/ipu-isys-csi2.c b/drivers/media/pci/intel/ipu-isys-csi2.c new file mode 100644 index 0000000000000..e188ebbf7d477 --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-csi2.c @@ -0,0 +1,948 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include + +#include +#include +#include +#include + +#include "ipu.h" +#include "ipu-bus.h" +#include "ipu-buttress.h" +#include "ipu-isys.h" +#include "ipu-isys-subdev.h" +#include "ipu-isys-video.h" +#include "ipu-platform-regs.h" + +#define CREATE_TRACE_POINTS +#define IPU_SOF_SEQID_TRACE +#define IPU_EOF_SEQID_TRACE +#include "ipu-trace-event.h" + +static const u32 csi2_supported_codes_pad_sink[] = { + 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_SBGGR10_DPCM8_1X8, + MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, + MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_SBGGR14_1X14, + MEDIA_BUS_FMT_SGBRG14_1X14, + MEDIA_BUS_FMT_SGRBG14_1X14, + MEDIA_BUS_FMT_SRGGB14_1X14, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + 0, +}; + +static const u32 csi2_supported_codes_pad_source[] = { + 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_SBGGR14_1X14, + MEDIA_BUS_FMT_SGBRG14_1X14, + MEDIA_BUS_FMT_SGRBG14_1X14, + MEDIA_BUS_FMT_SRGGB14_1X14, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + 0, +}; + +static const u32 csi2_supported_codes_pad_meta[] = { + MEDIA_BUS_FMT_FIXED, + 0, +}; + +static const u32 *csi2_supported_codes[NR_OF_CSI2_PADS]; + +static struct v4l2_subdev_internal_ops csi2_sd_internal_ops = { + .open = ipu_isys_subdev_open, + .close = ipu_isys_subdev_close, +}; + +int ipu_isys_csi2_get_link_freq(struct ipu_isys_csi2 *csi2, s64 *link_freq) +{ + struct media_pipeline *mp = media_entity_pipeline(&csi2->asd.sd.entity); + struct ipu_isys_pipeline *pipe = container_of(mp, + struct ipu_isys_pipeline, + pipe); + struct v4l2_subdev *ext_sd = + media_entity_to_v4l2_subdev(pipe->external->entity); + struct device *dev = &csi2->isys->adev->dev; + struct media_pad *src_pad; + unsigned int bpp, lanes; + s64 ret; + + if (!ext_sd) { + WARN_ON(1); + return -ENODEV; + } + + src_pad = media_entity_remote_source_pad_unique(&csi2->asd.sd.entity); + if (IS_ERR(src_pad)) { + dev_err(&csi2->isys->adev->dev, + "can't get source pad of %s (%pe)\n", + csi2->asd.sd.name, src_pad); + return PTR_ERR(src_pad); + } + + bpp = ipu_isys_mbus_code_to_bpp((*csi2->asd.ffmt)->code); + lanes = csi2->nlanes; + + ret = v4l2_get_link_freq(src_pad, bpp, lanes * 2); + if (ret < 0) { + dev_err(dev, "can't get link frequency (%lld)\n", ret); + return ret; + } + + dev_dbg(dev, "link freq of %s is %lld\n", ext_sd->name, ret); + *link_freq = ret; + + return 0; +} + +static int ipu_get_frame_desc_entry_by_dt(struct v4l2_subdev *sd, + struct v4l2_mbus_frame_desc_entry + *entry, u8 data_type) +{ + struct v4l2_mbus_frame_desc desc = { + .num_entries = V4L2_FRAME_DESC_ENTRY_MAX, + }; + int rval, i; + + rval = v4l2_subdev_call(sd, pad, get_frame_desc, 0, &desc); + if (rval) + return rval; + + for (i = 0; i < desc.num_entries; i++) { + if (desc.entry[i].bus.csi2.dt != data_type) + continue; + *entry = desc.entry[i]; + return 0; + } + + return -EINVAL; +} + +static void csi2_meta_prepare_firmware_stream_cfg_default( + struct ipu_isys_video *av, + struct ipu_fw_isys_stream_cfg_data_abi *cfg) +{ + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + struct ipu_isys_queue *aq = &av->aq; + struct ipu_fw_isys_output_pin_info_abi *pin_info; + struct v4l2_mbus_frame_desc_entry entry; + int pin = cfg->nof_output_pins++; + int inpin = cfg->nof_input_pins++; + int rval; + + aq->fw_output = pin; + ip->output_pins[pin].pin_ready = ipu_isys_queue_buf_ready; + ip->output_pins[pin].aq = aq; + + pin_info = &cfg->output_pins[pin]; + pin_info->input_pin_id = inpin; + pin_info->output_res.width = av->mpix.width; + pin_info->output_res.height = av->mpix.height; + pin_info->stride = av->mpix.plane_fmt[0].bytesperline; + pin_info->pt = aq->css_pin_type; + pin_info->ft = av->pfmt->css_pixelformat; + pin_info->send_irq = 1; + + rval = + ipu_get_frame_desc_entry_by_dt(media_entity_to_v4l2_subdev + (ip->external->entity), &entry, + IPU_ISYS_MIPI_CSI2_TYPE_EMBEDDED8); + if (!rval) { + cfg->input_pins[inpin].dt = IPU_ISYS_MIPI_CSI2_TYPE_EMBEDDED8; + cfg->input_pins[inpin].input_res.width = + entry.two_dim.width * entry.bpp / BITS_PER_BYTE; + cfg->input_pins[inpin].input_res.height = + entry.two_dim.height; + } +} + +static int subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, + struct v4l2_event_subscription *sub) +{ + struct ipu_isys_csi2 *csi2 = to_ipu_isys_csi2(sd); + + dev_dbg(&csi2->isys->adev->dev, "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 = subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, +}; + +static struct ipu_isys_pixelformat csi2_meta_pfmts[] = { + {V4L2_FMT_IPU_ISYS_META, 8, 8, 0, MEDIA_BUS_FMT_FIXED, 0}, + {}, +}; + +/* + * The input system CSI2+ receiver has several + * parameters affecting the receiver timings. These depend + * on the MIPI bus frequency F in Hz (sensor transmitter rate) + * as follows: + * register value = (A/1e9 + B * UI) / COUNT_ACC + * where + * UI = 1 / (2 * F) in seconds + * COUNT_ACC = counter accuracy in seconds + * For IPU4, COUNT_ACC = 0.125 ns + * + * A and B are coefficients from the table below, + * depending whether the register minimum or maximum value is + * calculated. + * Minimum Maximum + * Clock lane A B A B + * reg_rx_csi_dly_cnt_termen_clane 0 0 38 0 + * reg_rx_csi_dly_cnt_settle_clane 95 -8 300 -16 + * Data lanes + * reg_rx_csi_dly_cnt_termen_dlane0 0 0 35 4 + * reg_rx_csi_dly_cnt_settle_dlane0 85 -2 145 -6 + * reg_rx_csi_dly_cnt_termen_dlane1 0 0 35 4 + * reg_rx_csi_dly_cnt_settle_dlane1 85 -2 145 -6 + * reg_rx_csi_dly_cnt_termen_dlane2 0 0 35 4 + * reg_rx_csi_dly_cnt_settle_dlane2 85 -2 145 -6 + * reg_rx_csi_dly_cnt_termen_dlane3 0 0 35 4 + * reg_rx_csi_dly_cnt_settle_dlane3 85 -2 145 -6 + * + * We use the minimum values of both A and B. + */ + +#define DIV_SHIFT 8 + +static uint32_t calc_timing(s32 a, int32_t b, int64_t link_freq, int32_t accinv) +{ + return accinv * a + (accinv * b * (500000000 >> DIV_SHIFT) + / (int32_t)(link_freq >> DIV_SHIFT)); +} + +static int +ipu_isys_csi2_calc_timing(struct ipu_isys_csi2 *csi2, + struct ipu_isys_csi2_timing *timing, uint32_t accinv) +{ + __s64 link_freq; + int rval; + + rval = ipu_isys_csi2_get_link_freq(csi2, &link_freq); + if (rval) + return rval; + + timing->ctermen = calc_timing(CSI2_CSI_RX_DLY_CNT_TERMEN_CLANE_A, + CSI2_CSI_RX_DLY_CNT_TERMEN_CLANE_B, + link_freq, accinv); + timing->csettle = calc_timing(CSI2_CSI_RX_DLY_CNT_SETTLE_CLANE_A, + CSI2_CSI_RX_DLY_CNT_SETTLE_CLANE_B, + link_freq, accinv); + dev_dbg(&csi2->isys->adev->dev, "ctermen %u\n", timing->ctermen); + dev_dbg(&csi2->isys->adev->dev, "csettle %u\n", timing->csettle); + + timing->dtermen = calc_timing(CSI2_CSI_RX_DLY_CNT_TERMEN_DLANE_A, + CSI2_CSI_RX_DLY_CNT_TERMEN_DLANE_B, + link_freq, accinv); + timing->dsettle = calc_timing(CSI2_CSI_RX_DLY_CNT_SETTLE_DLANE_A, + CSI2_CSI_RX_DLY_CNT_SETTLE_DLANE_B, + link_freq, accinv); + dev_dbg(&csi2->isys->adev->dev, "dtermen %u\n", timing->dtermen); + dev_dbg(&csi2->isys->adev->dev, "dsettle %u\n", timing->dsettle); + + return 0; +} + +#define CSI2_ACCINV 8 + +static int set_stream(struct v4l2_subdev *sd, int enable) +{ + struct ipu_isys_csi2 *csi2 = to_ipu_isys_csi2(sd); + struct ipu_isys_pipeline *ip = container_of(media_entity_pipeline(&sd->entity), + struct ipu_isys_pipeline, + pipe); + struct ipu_isys_csi2_config *cfg; + struct v4l2_subdev *ext_sd; + struct v4l2_control c = {.id = V4L2_CID_MIPI_LANES, }; + struct ipu_isys_csi2_timing timing; + unsigned int nlanes; + int rval; + + dev_dbg(&csi2->isys->adev->dev, "csi2 s_stream %d\n", enable); + + if (!ip->external->entity) { + WARN_ON(1); + return -ENODEV; + } + ext_sd = media_entity_to_v4l2_subdev(ip->external->entity); + cfg = v4l2_get_subdev_hostdata(ext_sd); + + dev_dbg(&csi2->isys->adev->dev, + "csi2 set_stream(%d): stream_count=%u remote_streams=%u src=%u ext=%s\n", + enable, csi2->stream_count, csi2->remote_streams, + csi2->asd.source, ext_sd ? ext_sd->name : ""); + + if (!enable) { + csi2->stream_count--; + if (csi2->stream_count) + return 0; + + ipu_isys_csi2_set_stream(sd, timing, 0, enable); + return 0; + } + + ip->has_sof = true; + + if (csi2->stream_count) { + csi2->stream_count++; + dev_dbg(&csi2->isys->adev->dev, + "csi2 set_stream(%d): receiver already enabled, bump stream_count to %u\n", + enable, csi2->stream_count); + return 0; + } + + rval = v4l2_g_ctrl(ext_sd->ctrl_handler, &c); + if (cfg) + dev_dbg(&csi2->isys->adev->dev, + "csi2 lane cfg: hostdata nlanes=%u ctrl nlanes=%d ctrl_rval=%d\n", + cfg->nlanes, c.value, rval); + if (!rval && c.value > 0 && cfg->nlanes > c.value) { + nlanes = c.value; + dev_dbg(&csi2->isys->adev->dev, "lane nr %d.\n", nlanes); + } else { + nlanes = cfg->nlanes; + } + + rval = ipu_isys_csi2_calc_timing(csi2, &timing, CSI2_ACCINV); + if (rval) + return rval; + + ipu_isys_csi2_set_stream(sd, timing, nlanes, enable); + csi2->stream_count++; + + dev_dbg(&csi2->isys->adev->dev, + "csi2 set_stream(%d): receiver enabled, nlanes=%u stream_count=%u remote_streams=%u\n", + enable, nlanes, csi2->stream_count, csi2->remote_streams); + + return 0; +} + +static void csi2_capture_done(struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_resp_info_abi *info) +{ + if (ip->interlaced && ip->isys->short_packet_source == + IPU_ISYS_SHORT_PACKET_FROM_RECEIVER) { + struct ipu_isys_buffer *ib; + unsigned long flags; + + spin_lock_irqsave(&ip->short_packet_queue_lock, flags); + if (!list_empty(&ip->short_packet_active)) { + ib = list_last_entry(&ip->short_packet_active, + struct ipu_isys_buffer, head); + list_move(&ib->head, &ip->short_packet_incoming); + } + spin_unlock_irqrestore(&ip->short_packet_queue_lock, flags); + } + if (ip->csi2) { + ipu_isys_csi2_error(ip->csi2); + } +} + +static int csi2_link_validate(struct media_link *link) +{ + struct media_pipeline *media_pipe; + struct ipu_isys_csi2 *csi2; + struct ipu_isys_pipeline *ip; + struct v4l2_subdev_route r[IPU_ISYS_MAX_STREAMS]; + struct v4l2_subdev_routing routing = { + .routes = r, + .num_routes = IPU_ISYS_MAX_STREAMS, + }; + unsigned int active = 0; + int i; + int rval; + + media_pipe = media_entity_pipeline(link->sink->entity); + if (!media_pipe) + return -EINVAL; + csi2 = + to_ipu_isys_csi2(media_entity_to_v4l2_subdev(link->sink->entity)); + ip = to_ipu_isys_pipeline(media_pipe); + csi2->receiver_errors = 0; + ip->csi2 = csi2; + ipu_isys_video_add_capture_done(ip, csi2_capture_done); + + rval = v4l2_subdev_link_validate(link); + if (rval) + return rval; + + if (!v4l2_ctrl_g_ctrl(csi2->store_csi2_header)) { + for (i = 0; i < NR_OF_CSI2_SOURCE_PADS; i++) { + struct media_pad *remote_pad = + media_pad_remote_pad_first(&csi2->asd. + pad[CSI2_PAD_SOURCE(i)]); + + if (remote_pad && + is_media_entity_v4l2_subdev(remote_pad->entity)) { + dev_err(&csi2->isys->adev->dev, + "CSI2 BE requires CSI2 headers.\n"); + return -EINVAL; + } + } + } + + rval = + v4l2_subdev_call(media_entity_to_v4l2_subdev(link->source->entity), + pad, get_routing, &routing); + + if (rval) { + csi2->remote_streams = 1; + dev_dbg(&csi2->isys->adev->dev, + "link_validate: get_routing unavailable, default remote_streams=%u\n", + csi2->remote_streams); + return 0; + } + + for (i = 0; i < routing.num_routes; i++) { + struct v4l2_subdev_route *route = &r[i]; + if (route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) + active++; + } + + if (active != + bitmap_weight(csi2->asd.stream[link->sink->index].streams_stat, 32)) + return -EINVAL; + + csi2->remote_streams = active; + dev_dbg(&csi2->isys->adev->dev, + "link_validate: active routes=%u sink_stream_mask_weight=%u remote_streams=%u\n", + active, + bitmap_weight(csi2->asd.stream[link->sink->index].streams_stat, 32), + csi2->remote_streams); + + return 0; +} + +static const struct v4l2_subdev_video_ops csi2_sd_video_ops = { + .s_stream = set_stream, +}; + +static int get_metadata_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *fmt) +{ + struct media_pad *pad = + media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]); + struct v4l2_mbus_frame_desc_entry entry; + int rval; + + if (!pad) + return -EINVAL; + + rval = + ipu_get_frame_desc_entry_by_dt(media_entity_to_v4l2_subdev + (pad->entity), &entry, + IPU_ISYS_MIPI_CSI2_TYPE_EMBEDDED8); + + if (!rval) { + fmt->format.width = + entry.two_dim.width * entry.bpp / BITS_PER_BYTE; + fmt->format.height = entry.two_dim.height; + fmt->format.code = entry.pixelcode; + fmt->format.field = V4L2_FIELD_NONE; + } + return rval; +} + +static int ipu_isys_csi2_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *fmt) +{ + if (fmt->pad == CSI2_PAD_META) + return get_metadata_fmt(sd, state, fmt); + return ipu_isys_subdev_get_ffmt(sd, state, fmt); +} + +static int ipu_isys_csi2_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *fmt) +{ + if (fmt->pad == CSI2_PAD_META) + return get_metadata_fmt(sd, state, fmt); + return ipu_isys_subdev_set_ffmt(sd, state, fmt); +} + +static int __subdev_link_validate(struct v4l2_subdev *sd, + struct media_link *link, + struct v4l2_subdev_format *source_fmt, + struct v4l2_subdev_format *sink_fmt) +{ + struct ipu_isys_pipeline *ip = container_of(media_entity_pipeline(&sd->entity), + struct ipu_isys_pipeline, + pipe); + + if (source_fmt->format.field == V4L2_FIELD_ALTERNATE) + ip->interlaced = true; + + return ipu_isys_subdev_link_validate(sd, link, source_fmt, sink_fmt); +} + +static const struct v4l2_subdev_pad_ops csi2_sd_pad_ops = { + .link_validate = __subdev_link_validate, + .get_fmt = ipu_isys_csi2_get_fmt, + .set_fmt = ipu_isys_csi2_set_fmt, + .enum_mbus_code = ipu_isys_subdev_enum_mbus_code, + .set_routing = ipu_isys_subdev_set_routing, + .get_routing = ipu_isys_subdev_get_routing, +}; + +static struct v4l2_subdev_ops csi2_sd_ops = { + .core = &csi2_sd_core_ops, + .video = &csi2_sd_video_ops, + .pad = &csi2_sd_pad_ops, +}; + +static struct media_entity_operations csi2_entity_ops = { + .link_validate = csi2_link_validate, +}; + +static void csi2_set_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *fmt) +{ + struct v4l2_mbus_framefmt *ffmt = + __ipu_isys_get_ffmt(sd, state, fmt->pad, + fmt->stream, + fmt->which); + + if (fmt->format.field != V4L2_FIELD_ALTERNATE) + fmt->format.field = V4L2_FIELD_NONE; + + if (fmt->pad == CSI2_PAD_SINK) { + *ffmt = fmt->format; + if (fmt->stream) + return; + ipu_isys_subdev_fmt_propagate( + sd, state, &fmt->format, NULL, + IPU_ISYS_SUBDEV_PROP_TGT_SINK_FMT, + fmt->pad, fmt->which); + return; + } + + if (fmt->pad == CSI2_PAD_META) { + struct v4l2_mbus_framefmt *ffmt = + __ipu_isys_get_ffmt(sd, state, fmt->pad, + fmt->stream, + fmt->which); + struct media_pad *pad = media_pad_remote_pad_first( + &sd->entity.pads[CSI2_PAD_SINK]); + struct v4l2_mbus_frame_desc_entry entry; + int rval; + + if (!pad) { + ffmt->width = 0; + ffmt->height = 0; + ffmt->code = 0; + return; + } + + rval = ipu_get_frame_desc_entry_by_dt( + media_entity_to_v4l2_subdev(pad->entity), + &entry, + IPU_ISYS_MIPI_CSI2_TYPE_EMBEDDED8); + + if (!rval) { + ffmt->width = entry.two_dim.width * entry.bpp + / BITS_PER_BYTE; + ffmt->height = entry.two_dim.height; + ffmt->code = entry.pixelcode; + ffmt->field = V4L2_FIELD_NONE; + } + + return; + } + if (sd->entity.pads[fmt->pad].flags & MEDIA_PAD_FL_SOURCE) { + ffmt->width = fmt->format.width; + ffmt->height = fmt->format.height; + ffmt->field = fmt->format.field; + ffmt->code = + ipu_isys_subdev_code_to_uncompressed(fmt->format.code); + return; + } + + WARN_ON(1); +} + +static const struct ipu_isys_pixelformat * +csi2_try_fmt(struct ipu_isys_video *av, + struct v4l2_pix_format_mplane *mpix) +{ + struct media_link *link = list_first_entry(&av->vdev.entity.links, + struct media_link, list); + struct v4l2_subdev *sd = + media_entity_to_v4l2_subdev(link->source->entity); + struct ipu_isys_csi2 *csi2; + + if (!sd) + return NULL; + + csi2 = to_ipu_isys_csi2(sd); + + return ipu_isys_video_try_fmt_vid_mplane(av, mpix, + v4l2_ctrl_g_ctrl(csi2->store_csi2_header)); +} + +void ipu_isys_csi2_cleanup(struct ipu_isys_csi2 *csi2) +{ + int i; + + if (!csi2->isys) + return; + + v4l2_device_unregister_subdev(&csi2->asd.sd); + ipu_isys_subdev_cleanup(&csi2->asd); + for (i = 0; i < NR_OF_CSI2_SOURCE_PADS; i++) + ipu_isys_video_cleanup(&csi2->av[i]); + ipu_isys_video_cleanup(&csi2->av_meta); + csi2->isys = NULL; +} + +static void csi_ctrl_init(struct v4l2_subdev *sd) +{ + struct ipu_isys_csi2 *csi2 = to_ipu_isys_csi2(sd); + + static const struct v4l2_ctrl_config cfg = { + .id = V4L2_CID_IPU_STORE_CSI2_HEADER, + .name = "Store CSI-2 Headers", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = 0, + .max = 1, + .step = 1, + .def = 1, + }; + + csi2->store_csi2_header = v4l2_ctrl_new_custom(&csi2->asd.ctrl_handler, + &cfg, NULL); +} + +int ipu_isys_csi2_init(struct ipu_isys_csi2 *csi2, + struct ipu_isys *isys, + void __iomem *base, unsigned int index) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = CSI2_PAD_SINK, + .format = { + .width = 4096, + .height = 3072, + }, + }; + struct v4l2_subdev_format fmt_meta = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = CSI2_PAD_META, + }; + int i, rval, src; + + csi2->isys = isys; + csi2->base = base; + csi2->index = index; + + csi2->asd.sd.entity.ops = &csi2_entity_ops; + csi2->asd.ctrl_init = csi_ctrl_init; + csi2->asd.isys = isys; + init_completion(&csi2->eof_completion); + csi2->remote_streams = 1; + csi2->stream_count = 0; + + rval = ipu_isys_subdev_init(&csi2->asd, &csi2_sd_ops, 0, + NR_OF_CSI2_PADS, + NR_OF_CSI2_STREAMS, + NR_OF_CSI2_SOURCE_PADS, + NR_OF_CSI2_SINK_PADS, + 0); + if (rval) + goto fail; + + csi2->asd.pad[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK + | MEDIA_PAD_FL_MUST_CONNECT | MEDIA_PAD_FL_MULTIPLEX; + for (i = CSI2_PAD_SOURCE(0); + i < (NR_OF_CSI2_SOURCE_PADS + CSI2_PAD_SOURCE(0)); i++) + csi2->asd.pad[i].flags = MEDIA_PAD_FL_SOURCE; + + csi2->asd.pad[CSI2_PAD_META].flags = MEDIA_PAD_FL_SOURCE; + src = index; +#ifdef CONFIG_VIDEO_INTEL_IPU4P + src = index ? (index + 5) : (index + 3); +#endif + csi2->asd.source = IPU_FW_ISYS_STREAM_SRC_CSI2_PORT0 + src; + csi2_supported_codes[CSI2_PAD_SINK] = csi2_supported_codes_pad_sink; + + for (i = 0; i < NR_OF_CSI2_SOURCE_PADS; i++) + csi2_supported_codes[i + 1] = csi2_supported_codes_pad_source; + csi2_supported_codes[CSI2_PAD_META] = csi2_supported_codes_pad_meta; + csi2->asd.supported_codes = csi2_supported_codes; + csi2->asd.set_ffmt = csi2_set_ffmt; + + csi2->asd.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS; + csi2->asd.sd.internal_ops = &csi2_sd_internal_ops; + snprintf(csi2->asd.sd.name, sizeof(csi2->asd.sd.name), + IPU_ISYS_ENTITY_PREFIX " CSI-2 %u", index); + v4l2_set_subdevdata(&csi2->asd.sd, &csi2->asd); + + mutex_lock(&csi2->asd.mutex); + rval = v4l2_device_register_subdev(&isys->v4l2_dev, &csi2->asd.sd); + if (rval) { + mutex_unlock(&csi2->asd.mutex); + dev_info(&isys->adev->dev, "can't register v4l2 subdev\n"); + goto fail; + } + + __ipu_isys_subdev_set_ffmt(&csi2->asd.sd, NULL, &fmt); + __ipu_isys_subdev_set_ffmt(&csi2->asd.sd, NULL, &fmt_meta); + + /* create default route information */ + for (i = 0; i < NR_OF_CSI2_STREAMS; i++) { + csi2->asd.route[i].sink = CSI2_PAD_SINK; + csi2->asd.route[i].source = CSI2_PAD_SOURCE(i); + csi2->asd.route[i].flags = 0; + } + + for (i = 0; i < NR_OF_CSI2_SOURCE_PADS; i++) { + csi2->asd.stream[CSI2_PAD_SINK].stream_id[i] = i; + csi2->asd.stream[CSI2_PAD_SOURCE(i)].stream_id[CSI2_PAD_SINK] + = i; + } + csi2->asd.route[0].flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE | + V4L2_SUBDEV_ROUTE_FL_IMMUTABLE; + bitmap_set(csi2->asd.stream[CSI2_PAD_SINK].streams_stat, 0, 1); + bitmap_set(csi2->asd.stream[CSI2_PAD_SOURCE(0)].streams_stat, 0, 1); + + mutex_unlock(&csi2->asd.mutex); + + for (i = 0; i < NR_OF_CSI2_SOURCE_PADS; i++) { + snprintf(csi2->av[i].vdev.name, sizeof(csi2->av[i].vdev.name), + IPU_ISYS_ENTITY_PREFIX " CSI-2 %u capture %d", + index, i); + csi2->av[i].isys = isys; + csi2->av[i].aq.css_pin_type = IPU_FW_ISYS_PIN_TYPE_MIPI; + csi2->av[i].pfmts = ipu_isys_pfmts_packed; + csi2->av[i].try_fmt_vid_mplane = csi2_try_fmt; + csi2->av[i].prepare_firmware_stream_cfg = + ipu_isys_prepare_firmware_stream_cfg_default; + csi2->av[i].packed = true; + csi2->av[i].line_header_length = + IPU_ISYS_CSI2_LONG_PACKET_HEADER_SIZE; + csi2->av[i].line_footer_length = + IPU_ISYS_CSI2_LONG_PACKET_FOOTER_SIZE; + csi2->av[i].aq.buf_prepare = ipu_isys_buf_prepare; + csi2->av[i].aq.fill_frame_buff_set_pin = + ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set_pin; + csi2->av[i].aq.link_fmt_validate = ipu_isys_link_fmt_validate; + csi2->av[i].aq.vbq.buf_struct_size = + sizeof(struct ipu_isys_video_buffer); + + rval = ipu_isys_video_init(&csi2->av[i], + &csi2->asd.sd.entity, + CSI2_PAD_SOURCE(i), + MEDIA_PAD_FL_SINK, 0); + if (rval) { + dev_info(&isys->adev->dev, "can't init video node\n"); + goto fail; + } + } + + snprintf(csi2->av_meta.vdev.name, sizeof(csi2->av_meta.vdev.name), + IPU_ISYS_ENTITY_PREFIX " CSI-2 %u meta", index); + csi2->av_meta.isys = isys; + csi2->av_meta.aq.css_pin_type = IPU_FW_ISYS_PIN_TYPE_MIPI; + csi2->av_meta.pfmts = csi2_meta_pfmts; + csi2->av_meta.try_fmt_vid_mplane = csi2_try_fmt; + csi2->av_meta.prepare_firmware_stream_cfg = + csi2_meta_prepare_firmware_stream_cfg_default; + csi2->av_meta.packed = true; + csi2->av_meta.line_header_length = + IPU_ISYS_CSI2_LONG_PACKET_HEADER_SIZE; + csi2->av_meta.line_footer_length = + IPU_ISYS_CSI2_LONG_PACKET_FOOTER_SIZE; + csi2->av_meta.aq.buf_prepare = ipu_isys_buf_prepare; + csi2->av_meta.aq.fill_frame_buff_set_pin = + ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set_pin; + csi2->av_meta.aq.link_fmt_validate = ipu_isys_link_fmt_validate; + csi2->av_meta.aq.vbq.buf_struct_size = + sizeof(struct ipu_isys_video_buffer); + + rval = ipu_isys_video_init(&csi2->av_meta, &csi2->asd.sd.entity, + CSI2_PAD_META, MEDIA_PAD_FL_SINK, 0); + if (rval) { + dev_info(&isys->adev->dev, "can't init metadata node\n"); + goto fail; + } + return 0; + +fail: + ipu_isys_csi2_cleanup(csi2); + + return rval; +} + +void ipu_isys_csi2_sof_event(struct ipu_isys_csi2 *csi2, unsigned int vc) +{ + struct ipu_isys_pipeline *ip = NULL; + struct v4l2_event ev = { + .type = V4L2_EVENT_FRAME_SYNC, + }; + struct video_device *vdev = csi2->asd.sd.devnode; + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&csi2->isys->lock, flags); + csi2->in_frame[vc] = true; + + for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) { + if (csi2->isys->pipes[i] && + csi2->isys->pipes[i]->vc == vc && + csi2->isys->pipes[i]->csi2 == csi2) { + ip = csi2->isys->pipes[i]; + break; + } + } + + /* Pipe already vanished */ + if (!ip) { + spin_unlock_irqrestore(&csi2->isys->lock, flags); + return; + } + + ev.u.frame_sync.frame_sequence = atomic_inc_return(&ip->sequence) - 1; + ev.id = ip->stream_id; + spin_unlock_irqrestore(&csi2->isys->lock, flags); + + trace_ipu_sof_seqid(ev.u.frame_sync.frame_sequence, csi2->index, vc); + v4l2_event_queue(vdev, &ev); + dev_dbg(&csi2->isys->adev->dev, + "sof_event::csi2-%i CPU-timestamp:%lld, sequence:%i, vc:%d, stream_id:%d\n", + csi2->index, ktime_get_ns(), ev.u.frame_sync.frame_sequence, vc, ip->stream_id); +} + +void ipu_isys_csi2_eof_event(struct ipu_isys_csi2 *csi2, unsigned int vc) +{ + struct ipu_isys_pipeline *ip = NULL; + unsigned long flags; + unsigned int i; + u32 frame_sequence; + + spin_lock_irqsave(&csi2->isys->lock, flags); + csi2->in_frame[vc] = false; + if (csi2->wait_for_sync[vc]) + complete(&csi2->eof_completion); + spin_unlock_irqrestore(&csi2->isys->lock, flags); + + for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) { + if (csi2->isys->pipes[i] && + csi2->isys->pipes[i]->vc == vc && + csi2->isys->pipes[i]->csi2 == csi2) { + ip = csi2->isys->pipes[i]; + break; + } + } + + if (ip) { + frame_sequence = atomic_read(&ip->sequence); + + trace_ipu_eof_seqid(frame_sequence, csi2->index, vc); + + dev_dbg(&csi2->isys->adev->dev, + "eof_event::csi2-%i sequence: %i, vc: %d, stream_id: %d\n", + csi2->index, frame_sequence, vc, ip->stream_id); + } +} + +/* Call this function only _after_ the sensor has been stopped */ +void ipu_isys_csi2_wait_last_eof(struct ipu_isys_csi2 *csi2) +{ + unsigned long flags, tout; + unsigned int i; + + for (i = 0; i < NR_OF_CSI2_VC; i++) { + spin_lock_irqsave(&csi2->isys->lock, flags); + + if (!csi2->in_frame[i]) { + spin_unlock_irqrestore(&csi2->isys->lock, flags); + continue; + } + + reinit_completion(&csi2->eof_completion); + csi2->wait_for_sync[i] = true; + spin_unlock_irqrestore(&csi2->isys->lock, flags); + tout = wait_for_completion_timeout(&csi2->eof_completion, + IPU_EOF_TIMEOUT_JIFFIES); + if (!tout) + dev_err(&csi2->isys->adev->dev, + "csi2-%d: timeout at sync to eof of vc %d\n", + csi2->index, i); + csi2->wait_for_sync[i] = false; + } +} + +struct ipu_isys_buffer *ipu_isys_csi2_get_short_packet_buffer(struct + ipu_isys_pipeline + *ip) +{ + struct ipu_isys_buffer *ib; + struct ipu_isys_private_buffer *pb; + struct ipu_isys_mipi_packet_header *ph; + + if (list_empty(&ip->short_packet_incoming)) + return NULL; + ib = list_last_entry(&ip->short_packet_incoming, + struct ipu_isys_buffer, head); + pb = ipu_isys_buffer_to_private_buffer(ib); + ph = (struct ipu_isys_mipi_packet_header *)pb->buffer; + + /* Fill the packet header with magic number. */ + ph->word_count = 0xffff; + ph->dtype = 0xff; + + dma_sync_single_for_cpu(&ip->isys->adev->dev, pb->dma_addr, + sizeof(*ph), DMA_BIDIRECTIONAL); + return ib; +} diff --git a/drivers/media/pci/intel/ipu-isys-csi2.h b/drivers/media/pci/intel/ipu-isys-csi2.h new file mode 100644 index 0000000000000..d7f2df3eb805e --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-csi2.h @@ -0,0 +1,177 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_ISYS_CSI2_H +#define IPU_ISYS_CSI2_H + +#include +#include + +#include "ipu-isys-queue.h" +#include "ipu-isys-subdev.h" +#include "ipu-isys-video.h" +#include "ipu-platform-isys.h" + +struct ipu_isys_csi2_timing; +struct ipu_isys_csi2_pdata; +struct ipu_isys; + +#define NR_OF_CSI2_SINK_PADS 1 +#define CSI2_PAD_SINK 0 +#define NR_OF_CSI2_STREAMS NR_OF_CSI2_VC +#define NR_OF_CSI2_SOURCE_PADS NR_OF_CSI2_STREAMS +#define CSI2_PAD_SOURCE(n) \ + ({ typeof(n) __n = (n); \ + (__n >= NR_OF_CSI2_SOURCE_PADS ? \ + (NR_OF_CSI2_PADS - 2) : \ + (__n + NR_OF_CSI2_SINK_PADS)); }) +#define NR_OF_CSI2_META_PADS 1 +#define NR_OF_CSI2_PADS \ + (NR_OF_CSI2_SINK_PADS + NR_OF_CSI2_SOURCE_PADS + NR_OF_CSI2_META_PADS) +#define CSI2_PAD_META (NR_OF_CSI2_PADS - 1) + +#define IPU_ISYS_SHORT_PACKET_BUFFER_NUM VIDEO_MAX_FRAME +#define IPU_ISYS_SHORT_PACKET_WIDTH 32 +#define IPU_ISYS_SHORT_PACKET_FRAME_PACKETS 2 +#define IPU_ISYS_SHORT_PACKET_EXTRA_PACKETS 64 +#define IPU_ISYS_SHORT_PACKET_UNITSIZE 8 +#define IPU_ISYS_SHORT_PACKET_GENERAL_DT 0 +#define IPU_ISYS_SHORT_PACKET_PT 0 +#define IPU_ISYS_SHORT_PACKET_FT 0 + +#define IPU_ISYS_SHORT_PACKET_STRIDE \ + (IPU_ISYS_SHORT_PACKET_WIDTH * \ + IPU_ISYS_SHORT_PACKET_UNITSIZE) +#define IPU_ISYS_SHORT_PACKET_NUM(num_lines) \ + ((num_lines) * 2 + IPU_ISYS_SHORT_PACKET_FRAME_PACKETS + \ + IPU_ISYS_SHORT_PACKET_EXTRA_PACKETS) +#define IPU_ISYS_SHORT_PACKET_PKT_LINES(num_lines) \ + DIV_ROUND_UP(IPU_ISYS_SHORT_PACKET_NUM(num_lines) * \ + IPU_ISYS_SHORT_PACKET_UNITSIZE, \ + IPU_ISYS_SHORT_PACKET_STRIDE) +#define IPU_ISYS_SHORT_PACKET_BUF_SIZE(num_lines) \ + (IPU_ISYS_SHORT_PACKET_WIDTH * \ + IPU_ISYS_SHORT_PACKET_PKT_LINES(num_lines) * \ + IPU_ISYS_SHORT_PACKET_UNITSIZE) + +#define IPU_ISYS_SHORT_PACKET_TRACE_MSG_NUMBER 256 +#define IPU_ISYS_SHORT_PACKET_TRACE_MSG_SIZE 16 +#define IPU_ISYS_SHORT_PACKET_TRACE_BUFFER_SIZE \ + (IPU_ISYS_SHORT_PACKET_TRACE_MSG_NUMBER * \ + IPU_ISYS_SHORT_PACKET_TRACE_MSG_SIZE) + +#define IPU_ISYS_SHORT_PACKET_FROM_RECEIVER 0 +#define IPU_ISYS_SHORT_PACKET_FROM_TUNIT 1 + +#define IPU_ISYS_SHORT_PACKET_TRACE_MAX_TIMESHIFT 100 +#define IPU_ISYS_SHORT_PACKET_TRACE_EVENT_MASK 0x2082 +#define IPU_SKEW_CAL_LIMIT_HZ (1500000000ul / 2) + +#define CSI2_CSI_RX_DLY_CNT_TERMEN_CLANE_A 0 +#define CSI2_CSI_RX_DLY_CNT_TERMEN_CLANE_B 0 +#define CSI2_CSI_RX_DLY_CNT_SETTLE_CLANE_A 95 +#define CSI2_CSI_RX_DLY_CNT_SETTLE_CLANE_B -8 + +#define CSI2_CSI_RX_DLY_CNT_TERMEN_DLANE_A 0 +#define CSI2_CSI_RX_DLY_CNT_TERMEN_DLANE_B 0 +#define CSI2_CSI_RX_DLY_CNT_SETTLE_DLANE_A 85 +#define CSI2_CSI_RX_DLY_CNT_SETTLE_DLANE_B -2 + +#define IPU_EOF_TIMEOUT 300 +#define IPU_EOF_TIMEOUT_JIFFIES msecs_to_jiffies(IPU_EOF_TIMEOUT) + +/* + * struct ipu_isys_csi2 + * + * @nlanes: number of lanes in the receiver + */ +struct ipu_isys_csi2 { + struct ipu_isys_csi2_pdata *pdata; + struct ipu_isys *isys; + struct ipu_isys_subdev asd; + struct ipu_isys_video av[NR_OF_CSI2_SOURCE_PADS]; + struct ipu_isys_video av_meta; + struct completion eof_completion; + + void __iomem *base; + u32 receiver_errors; + unsigned int nlanes; + unsigned int index; + atomic_t sof_sequence; + bool in_frame[NR_OF_CSI2_VC]; + bool wait_for_sync[NR_OF_CSI2_VC]; + + unsigned int remote_streams; + unsigned int stream_count; + + struct v4l2_ctrl *store_csi2_header; +}; + +struct ipu_isys_csi2_timing { + u32 ctermen; + u32 csettle; + u32 dtermen; + u32 dsettle; +}; + +/* + * This structure defines the MIPI packet header output + * from IPU MIPI receiver. Due to hardware conversion, + * this structure is not the same as defined in CSI-2 spec. + */ +struct ipu_isys_mipi_packet_header { + u32 word_count:16, dtype:13, sync:2, stype:1; + u32 sid:4, port_id:4, reserved:23, odd_even:1; +} __packed; + +/* + * This structure defines the trace message content + * for CSI2 receiver monitor messages. + */ +struct ipu_isys_csi2_monitor_message { + u64 fe:1, + fs:1, + pe:1, + ps:1, + le:1, + ls:1, + reserved1:2, + sequence:2, + reserved2:2, + flash_shutter:4, + error_cause:12, + fifo_overrun:1, + crc_error:2, + reserved3:1, + timestamp_l:16, + port:4, vc:2, reserved4:2, frame_sync:4, reserved5:4; + u64 reserved6:3, + cmd:2, reserved7:1, monitor_id:7, reserved8:1, timestamp_h:50; +} __packed; + +#define to_ipu_isys_csi2(sd) container_of(to_ipu_isys_subdev(sd), \ + struct ipu_isys_csi2, asd) + +int ipu_isys_csi2_get_link_freq(struct ipu_isys_csi2 *csi2, __s64 *link_freq); +int ipu_isys_csi2_init(struct ipu_isys_csi2 *csi2, + struct ipu_isys *isys, + void __iomem *base, unsigned int index); +void ipu_isys_csi2_cleanup(struct ipu_isys_csi2 *csi2); +struct ipu_isys_buffer * +ipu_isys_csi2_get_short_packet_buffer(struct ipu_isys_pipeline *ip); +void ipu_isys_csi2_sof_event(struct ipu_isys_csi2 *csi2, unsigned int vc); +void ipu_isys_csi2_eof_event(struct ipu_isys_csi2 *csi2, unsigned int vc); +void ipu_isys_csi2_wait_last_eof(struct ipu_isys_csi2 *csi2); + +/* interface for platform specific */ +int ipu_isys_csi2_set_stream(struct v4l2_subdev *sd, + struct ipu_isys_csi2_timing timing, + unsigned int nlanes, int enable); +unsigned int ipu_isys_csi2_get_current_field(struct ipu_isys_pipeline *ip, + unsigned int *timestamp); +void ipu_isys_csi2_isr(struct ipu_isys_csi2 *csi2); +void ipu_isys_csi2_error(struct ipu_isys_csi2 *csi2); +bool ipu_isys_csi2_skew_cal_required(struct ipu_isys_csi2 *csi2); +int ipu_isys_csi2_set_skew_cal(struct ipu_isys_csi2 *csi2, int enable); + +#endif /* IPU_ISYS_CSI2_H */ diff --git a/drivers/media/pci/intel/ipu-isys-media.h b/drivers/media/pci/intel/ipu-isys-media.h new file mode 100644 index 0000000000000..ccda9b6fef9a9 --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-media.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2016 - 2018 Intel Corporation */ + +#ifndef IPU_ISYS_MEDIA_H +#define IPU_ISYS_MEDIA_H + +#include +#include + +struct __packed media_request_cmd { + __u32 cmd; + __u32 request; + __u32 flags; +}; + +struct __packed media_event_request_complete { + __u32 id; +}; + +#define MEDIA_EVENT_TYPE_REQUEST_COMPLETE 1 + +struct __packed media_event { + __u32 type; + __u32 sequence; + __u32 reserved[4]; + + union { + struct media_event_request_complete req_complete; + }; +}; + +enum media_device_request_state { + MEDIA_DEVICE_REQUEST_STATE_IDLE, + MEDIA_DEVICE_REQUEST_STATE_QUEUED, + MEDIA_DEVICE_REQUEST_STATE_DELETED, + MEDIA_DEVICE_REQUEST_STATE_COMPLETE, +}; + +struct media_kevent { + struct list_head list; + struct media_event ev; +}; + +struct media_device_request { + u32 id; + struct media_device *mdev; + struct file *filp; + struct media_kevent *kev; + struct kref kref; + struct list_head list; + struct list_head fh_list; + enum media_device_request_state state; + struct list_head data; + u32 flags; +}; + + +#endif /* IPU_ISYS_MEDIA_H */ diff --git a/drivers/media/pci/intel/ipu-isys-queue.c b/drivers/media/pci/intel/ipu-isys-queue.c new file mode 100644 index 0000000000000..ee735487bba07 --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-queue.c @@ -0,0 +1,1426 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include +#include +#include + +#include +#include +#include + +#include "ipu.h" +#include "ipu-bus.h" +#include "ipu-buttress.h" +#include "ipu-isys.h" +#include "ipu-isys-csi2.h" +#include "ipu-isys-video.h" + +static bool wall_clock_ts_on; +module_param(wall_clock_ts_on, bool, 0660); +MODULE_PARM_DESC(wall_clock_ts_on, "Timestamp based on REALTIME clock"); + +static int queue_setup(struct vb2_queue *q, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], + struct device *alloc_devs[] + ) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(q); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + bool use_fmt = false; + unsigned int i; + + /* num_planes == 0: we're being called through VIDIOC_REQBUFS */ + if (!*num_planes) { + use_fmt = true; + *num_planes = av->mpix.num_planes; + } + + for (i = 0; i < *num_planes; i++) { + if (use_fmt) + sizes[i] = av->mpix.plane_fmt[i].sizeimage; + alloc_devs[i] = aq->dev; + dev_dbg(&av->isys->adev->dev, + "%s: queue setup: plane %d size %u\n", + av->vdev.name, i, sizes[i]); + } + + return 0; +} + +void ipu_isys_queue_lock(struct vb2_queue *q) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(q); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + + dev_dbg(&av->isys->adev->dev, "%s: queue lock\n", av->vdev.name); + mutex_lock(&av->mutex); +} + +void ipu_isys_queue_unlock(struct vb2_queue *q) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(q); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + + dev_dbg(&av->isys->adev->dev, "%s: queue unlock\n", av->vdev.name); + mutex_unlock(&av->mutex); +} + +static int buf_init(struct vb2_buffer *vb) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + + dev_dbg(&av->isys->adev->dev, "buffer: %s: %s\n", av->vdev.name, + __func__); + + if (aq->buf_init) + return aq->buf_init(vb); + + return 0; +} + +int ipu_isys_buf_prepare(struct vb2_buffer *vb) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + + dev_dbg(&av->isys->adev->dev, + "buffer: %s: configured size %u, buffer size %lu\n", + av->vdev.name, + av->mpix.plane_fmt[0].sizeimage, vb2_plane_size(vb, 0)); + + if (av->mpix.plane_fmt[0].sizeimage > vb2_plane_size(vb, 0)) + return -EINVAL; + + vb2_set_plane_payload(vb, 0, av->mpix.plane_fmt[0].bytesperline * + av->mpix.height); + vb->planes[0].data_offset = av->line_header_length / BITS_PER_BYTE; + + return 0; +} + +static int buf_prepare(struct vb2_buffer *vb) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct ipu_isys_buffer *ib = vb2_buffer_to_ipu_isys_buffer(vb); + struct vb2_v4l2_buffer *b = to_vb2_v4l2_buffer(vb); + struct ipu_isys_request *ireq; + u32 request_state; + unsigned long flags; + int rval; + + if (av->isys->adev->isp->flr_done) + return -EIO; + + if (b->flags & V4L2_BUF_FLAG_REQUEST_FD) { + ib->req = media_request_get_by_fd(&av->isys->media_dev, b->request_fd); + if (IS_ERR(ib->req)) { + dev_err(&av->isys->adev->dev, + "can't find request %u (%ld)\n", b->request_fd, PTR_ERR(ib->req)); + return ib->req; + } else if (!ib->req) { + dev_dbg(&av->isys->adev->dev, + "can't find request %u\n", b->request_fd); + return -ENOENT; + } + } + + rval = aq->buf_prepare(vb); + if (!ib->req) + return rval; + if (rval) + goto out_put_request; + + ireq = to_ipu_isys_request(ib->req); + + spin_lock_irqsave(&ireq->lock, flags); + spin_lock(&ib->req->lock); + request_state = ib->req->state; + if (request_state == MEDIA_DEVICE_REQUEST_STATE_IDLE) + list_add(&ib->req_head, &ireq->buffers); + spin_unlock(&ib->req->lock); + spin_unlock_irqrestore(&ireq->lock, flags); + if (request_state != MEDIA_DEVICE_REQUEST_STATE_IDLE) { + dev_dbg(&av->isys->adev->dev, + "%s[%s]: request state %u\n", __func__, ib->req->debug_str, + request_state); + rval = -EINVAL; + } else { + dev_dbg(&av->isys->adev->dev, + "%s[%s]: request\n", __func__, ib->req->debug_str); + } + + if (!rval) + return 0; + +out_put_request: + media_request_put(ib->req); + ib->req = NULL; + + return rval; +} + +static void buf_finish(struct vb2_buffer *vb) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct ipu_isys_buffer *ib = vb2_buffer_to_ipu_isys_buffer(vb); + + dev_dbg(&av->isys->adev->dev, "buffer: %s: %s\n", av->vdev.name, + __func__); + + if (ib->req) { + struct ipu_isys_request *ireq = to_ipu_isys_request(ib->req); + unsigned long flags; + bool done; + + spin_lock_irqsave(&ireq->lock, flags); + list_del(&ib->req_head); + done = list_empty(&ireq->buffers); + spin_unlock_irqrestore(&ireq->lock, flags); + dev_dbg(&av->isys->adev->dev, "%s: request complete %s\n", + ib->req->debug_str, done ? "true" : "false"); + if (done) { + v4l2_ctrl_request_complete(ib->req, + av->vdev.ctrl_handler); + mutex_lock(&av->isys->stream_mutex); + list_del(&ireq->head); + mutex_unlock(&av->isys->stream_mutex); + } + media_request_put(ib->req); + ib->req = NULL; + } +} + +static void buf_cleanup(struct vb2_buffer *vb) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + + dev_dbg(&av->isys->adev->dev, "buffer: %s: %s\n", av->vdev.name, + __func__); + + if (aq->buf_cleanup) + return aq->buf_cleanup(vb); +} + +/* + * Queue a buffer list back to incoming or active queues. The buffers + * are removed from the buffer list. + */ +void ipu_isys_buffer_list_queue(struct ipu_isys_buffer_list *bl, + unsigned long op_flags, + enum vb2_buffer_state state) +{ + struct ipu_isys_buffer *ib, *ib_safe; + unsigned long flags; + bool first = true; + + if (!bl) + return; + + WARN_ON(!bl->nbufs); + WARN_ON(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 ipu_isys_video *av; + + if (ib->type == IPU_ISYS_VIDEO_BUFFER) { + struct vb2_buffer *vb = + ipu_isys_buffer_to_vb2_buffer(ib); + struct ipu_isys_queue *aq = + vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + + av = ipu_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); + } else if (ib->type == IPU_ISYS_SHORT_PACKET_BUFFER) { + struct ipu_isys_private_buffer *pb = + ipu_isys_buffer_to_private_buffer(ib); + struct ipu_isys_pipeline *ip = pb->ip; + + av = container_of(ip, struct ipu_isys_video, ip); + spin_lock_irqsave(&ip->short_packet_queue_lock, flags); + list_del(&ib->head); + if (op_flags & IPU_ISYS_BUFFER_LIST_FL_ACTIVE) + list_add(&ib->head, &ip->short_packet_active); + else if (op_flags & IPU_ISYS_BUFFER_LIST_FL_INCOMING) + list_add(&ib->head, &ip->short_packet_incoming); + spin_unlock_irqrestore(&ip->short_packet_queue_lock, + flags); + } else { + WARN_ON(1); + return; + } + + if (first) { + dev_dbg(&av->isys->adev->dev, + "queue buffer list %p op_flags %lx, state %d, %d buffers\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 ipu_isys_pipeline *ip) +{ + struct ipu_isys_video *pipe_av = + container_of(ip, struct ipu_isys_video, ip); + struct ipu_isys_queue *aq; + unsigned long flags; + + lockdep_assert_held(&pipe_av->mutex); + + list_for_each_entry(aq, &ip->queues, node) { + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct ipu_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 = + ipu_isys_buffer_to_vb2_buffer(ib); + + list_del(&ib->head); + if (av->streaming) { + dev_dbg(&av->isys->adev->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(&av->isys->adev->dev, + "%s: return %u back to videobuf2\n", + av->vdev.name, + vb->index); + vb2_buffer_done(ipu_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 + * all queues have no buffers, the buffers that were already dequeued + * are returned to their queues. + */ +static int buffer_list_get(struct ipu_isys_pipeline *ip, + struct ipu_isys_buffer_list *bl) +{ + struct ipu_isys_queue *aq; + struct ipu_isys_buffer *ib; + unsigned long flags; + int ret = 0; + + bl->nbufs = 0; + INIT_LIST_HEAD(&bl->head); + + list_for_each_entry(aq, &ip->queues, node) { + struct ipu_isys_buffer *ib; + + spin_lock_irqsave(&aq->lock, flags); + if (list_empty(&aq->incoming)) { + spin_unlock_irqrestore(&aq->lock, flags); + ret = -ENODATA; + goto error; + } + + ib = list_last_entry(&aq->incoming, + struct ipu_isys_buffer, head); + if (ib->req) { + spin_unlock_irqrestore(&aq->lock, flags); + ret = -ENODATA; + goto error; + } + + dev_dbg(&ip->isys->adev->dev, "buffer: %s: buffer %u\n", + ipu_isys_queue_to_video(aq)->vdev.name, + ipu_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++; + } + + list_for_each_entry(ib, &bl->head, head) { + struct vb2_buffer *vb = ipu_isys_buffer_to_vb2_buffer(ib); + + aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + if (aq->prepare_frame_buff_set) + aq->prepare_frame_buff_set(vb); + } + + /* Get short packet buffer. */ + if (ip->interlaced && ip->isys->short_packet_source == + IPU_ISYS_SHORT_PACKET_FROM_RECEIVER) { + spin_lock_irqsave(&ip->short_packet_queue_lock, flags); + ib = ipu_isys_csi2_get_short_packet_buffer(ip); + if (!ib) { + spin_unlock_irqrestore(&ip->short_packet_queue_lock, + flags); + ret = -ENODATA; + dev_err(&ip->isys->adev->dev, + "No more short packet buffers. Driver bug?"); + WARN_ON(1); + goto error; + } + list_move(&ib->head, &bl->head); + spin_unlock_irqrestore(&ip->short_packet_queue_lock, flags); + bl->nbufs++; + } + + dev_dbg(&ip->isys->adev->dev, "get buffer list %p, %u buffers\n", bl, + bl->nbufs); + return ret; + +error: + if (!list_empty(&bl->head)) + ipu_isys_buffer_list_queue(bl, + IPU_ISYS_BUFFER_LIST_FL_INCOMING, 0); + return ret; +} + +void ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set_pin( + struct vb2_buffer *vb, + struct ipu_fw_isys_frame_buff_set_abi *set) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + + set->output_pins[aq->fw_output].addr = + vb2_dma_contig_plane_dma_addr(vb, 0); + set->output_pins[aq->fw_output].out_buf_id = + vb->index + 1; +} + +/* + * Convert a buffer list to a isys fw ABI framebuffer set. The + * buffer list is not modified. + */ +void ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set( + struct ipu_fw_isys_frame_buff_set_abi *set, + struct ipu_isys_pipeline *ip, + struct ipu_isys_buffer_list *bl) +{ + struct ipu_isys_buffer *ib; + + WARN_ON(!bl->nbufs); + + set->send_irq_sof = 1; + set->send_resp_sof = 1; + +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + set->send_irq_capture_ack = 1; + set->send_irq_capture_done = 1; + set->send_irq_eof = 1; + set->send_resp_eof = 1; +#else + set->send_irq_eof = 0; + set->send_resp_eof = 0; +#endif + + list_for_each_entry(ib, &bl->head, head) { + if (ib->type == IPU_ISYS_VIDEO_BUFFER) { + struct vb2_buffer *vb = + ipu_isys_buffer_to_vb2_buffer(ib); + struct ipu_isys_queue *aq = + vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + + if (aq->fill_frame_buff_set_pin) + aq->fill_frame_buff_set_pin(vb, set); + } else if (ib->type == IPU_ISYS_SHORT_PACKET_BUFFER) { + struct ipu_isys_private_buffer *pb = + ipu_isys_buffer_to_private_buffer(ib); + struct ipu_fw_isys_output_pin_payload_abi *output_pin = + &set->output_pins[ip->short_packet_output_pin]; + + output_pin->addr = pb->dma_addr; + output_pin->out_buf_id = pb->index + 1; + } else { + WARN_ON(1); + } + } +} + +static void +ipu_isys_req_dispatch(struct media_device *mdev, + struct ipu_isys_request *ireq, + struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_frame_buff_set_abi *set, + dma_addr_t dma_addr); + +struct ipu_isys_request *ipu_isys_next_queued_request(struct ipu_isys_pipeline + *ip) +{ + struct ipu_isys *isys = + container_of(ip, struct ipu_isys_video, ip)->isys; + struct ipu_isys_request *ireq; + struct ipu_isys_buffer *ib; + unsigned long flags; + + lockdep_assert_held(&isys->stream_mutex); + + if (list_empty(&isys->requests)) { + dev_dbg(&isys->adev->dev, "%s: no requests found\n", __func__); + return NULL; + } + + list_for_each_entry_reverse(ireq, &isys->requests, head) { + /* Does the request belong to this pipeline? */ + bool is_ours = false; + bool is_others = false; + + dev_dbg(&isys->adev->dev, "%s[%s]: checking request\n", + __func__, ireq->req.debug_str); + + spin_lock_irqsave(&ireq->lock, flags); + list_for_each_entry(ib, &ireq->buffers, req_head) { + struct vb2_buffer *vb = + ipu_isys_buffer_to_vb2_buffer(ib); + struct ipu_isys_queue *aq = + vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + + dev_dbg(&isys->adev->dev, "%s: buffer in vdev %s\n", + __func__, av->vdev.name); + + if (media_entity_enum_test(&ip->entity_enum, + &av->vdev.entity)) + is_ours = true; + else + is_others = true; + } + spin_unlock_irqrestore(&ireq->lock, flags); + + dev_dbg(&isys->adev->dev, "%s: is%s ours, is%s others'\n", + __func__, is_ours ? "" : "n't", is_others ? "" : "n't"); + + if (!is_ours || WARN_ON(is_others)) + continue; + + list_del_init(&ireq->head); + + return ireq; + } + + return NULL; +} + +/* Start streaming for real. The buffer list must be available. */ +static int ipu_isys_stream_start(struct ipu_isys_pipeline *ip, + struct ipu_isys_buffer_list *bl, bool error) +{ + struct ipu_isys_video *pipe_av = + container_of(ip, struct ipu_isys_video, ip); + struct media_device *mdev = &pipe_av->isys->media_dev; + struct ipu_isys_buffer_list __bl; + struct ipu_isys_request *ireq; + int rval; + + mutex_lock(&pipe_av->isys->stream_mutex); + + rval = ipu_isys_video_set_streaming(pipe_av, 1, bl); + if (rval) { + mutex_unlock(&pipe_av->isys->stream_mutex); + goto out_requeue; + } + + ip->streaming = 1; + + dev_dbg(&pipe_av->isys->adev->dev, "dispatching queued requests\n"); + + while ((ireq = ipu_isys_next_queued_request(ip))) { + struct ipu_fw_isys_frame_buff_set_abi *set; + struct isys_fw_msgs *msg; + + msg = ipu_get_fw_msg_buf(ip); + if (!msg) { + /* TODO: A PROPER CLEAN UP */ + mutex_unlock(&pipe_av->isys->stream_mutex); + return -ENOMEM; + } + + set = to_frame_msg_buf(msg); + + rval = ipu_isys_req_prepare(mdev, ireq, ip, set); + if (rval) { + mutex_unlock(&pipe_av->isys->stream_mutex); + goto out_requeue; + } + + ipu_fw_isys_dump_frame_buff_set(&pipe_av->isys->adev->dev, set, + ip->nr_output_pins); + ipu_isys_req_dispatch(mdev, ireq, ip, set, to_dma_addr(msg)); + } + + dev_dbg(&pipe_av->isys->adev->dev, + "done dispatching queued requests\n"); + + mutex_unlock(&pipe_av->isys->stream_mutex); + + bl = &__bl; + + do { + struct ipu_fw_isys_frame_buff_set_abi *buf = NULL; + struct isys_fw_msgs *msg; + + rval = buffer_list_get(ip, bl); + if (rval == -EINVAL) + goto out_requeue; + else if (rval < 0) + break; + + msg = ipu_get_fw_msg_buf(ip); + if (!msg) + /* TODO: PROPER CLEANUP */ + return -ENOMEM; + + buf = to_frame_msg_buf(msg); + + ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set(buf, ip, bl); + + ipu_fw_isys_dump_frame_buff_set(&pipe_av->isys->adev->dev, buf, + ip->nr_output_pins); + + ipu_isys_buffer_list_queue(bl, + IPU_ISYS_BUFFER_LIST_FL_ACTIVE, 0); + + rval = ipu_fw_isys_complex_cmd(pipe_av->isys, + ip->stream_handle, + buf, to_dma_addr(msg), + sizeof(*buf), + IPU_FW_ISYS_SEND_TYPE_STREAM_CAPTURE); + ipu_put_fw_mgs_buffer(pipe_av->isys, (uintptr_t) buf); + } while (!WARN_ON(rval)); + + return 0; + +out_requeue: + if (bl && bl->nbufs) + ipu_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(ip); + + return rval; +} + +static void __buf_queue(struct vb2_buffer *vb, bool force) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct ipu_isys_buffer *ib = vb2_buffer_to_ipu_isys_buffer(vb); + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + struct ipu_isys_buffer_list bl; + + struct ipu_fw_isys_frame_buff_set_abi *buf = NULL; + struct isys_fw_msgs *msg; + + struct ipu_isys_video *pipe_av = + container_of(ip, struct ipu_isys_video, ip); + unsigned long flags; + unsigned int i; + int rval; + + dev_dbg(&av->isys->adev->dev, "buffer: %s: buf_queue %u\n", + av->vdev.name, + vb->index + ); + + for (i = 0; i < vb->num_planes; i++) + dev_dbg(&av->isys->adev->dev, "iova: plane %u iova 0x%x\n", i, + (u32) vb2_dma_contig_plane_dma_addr(vb, i)); + + spin_lock_irqsave(&aq->lock, flags); + list_add(&ib->head, &aq->incoming); + spin_unlock_irqrestore(&aq->lock, flags); + + if (ib->req) + return; + + if (!pipe_av || !vb->vb2_queue->streaming) { + dev_dbg(&av->isys->adev->dev, + "not pipe_av set, adding to incoming\n"); + return; + } + + mutex_unlock(&av->mutex); + mutex_lock(&pipe_av->mutex); + + if (!force && ip->nr_streaming != ip->nr_queues) { + dev_dbg(&av->isys->adev->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. + */ + rval = buffer_list_get(ip, &bl); + if (rval < 0) { + if (rval == -EINVAL) { + dev_err(&av->isys->adev->dev, + "error: should not happen\n"); + WARN_ON(1); + } else { + dev_dbg(&av->isys->adev->dev, + "not enough buffers available\n"); + } + goto out; + } + + msg = ipu_get_fw_msg_buf(ip); + if (!msg) { + rval = -ENOMEM; + goto out; + } + buf = to_frame_msg_buf(msg); + + ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set(buf, ip, &bl); + + ipu_fw_isys_dump_frame_buff_set(&pipe_av->isys->adev->dev, buf, + ip->nr_output_pins); + + if (!ip->streaming) { + dev_dbg(&av->isys->adev->dev, + "Wow! Got a buffer to start streaming!\n"); + rval = ipu_isys_stream_start(ip, &bl, true); + if (rval) + dev_err(&av->isys->adev->dev, + "Ouch. 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. + */ + ipu_isys_buffer_list_queue(&bl, IPU_ISYS_BUFFER_LIST_FL_ACTIVE, 0); + + rval = ipu_fw_isys_complex_cmd(pipe_av->isys, + ip->stream_handle, + buf, to_dma_addr(msg), + sizeof(*buf), + IPU_FW_ISYS_SEND_TYPE_STREAM_CAPTURE); + ipu_put_fw_mgs_buffer(pipe_av->isys, (uintptr_t) buf); + /* + * FIXME: mark the buffers in the buffer list if the queue + * operation fails. + */ + if (!WARN_ON(rval < 0)) + dev_dbg(&av->isys->adev->dev, "queued buffer\n"); + +out: + mutex_unlock(&pipe_av->mutex); + mutex_lock(&av->mutex); +} + +static void buf_queue(struct vb2_buffer *vb) +{ + __buf_queue(vb, false); +} + +int ipu_isys_link_fmt_validate(struct ipu_isys_queue *aq) +{ + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct v4l2_subdev_format fmt = { 0 }; + struct media_pad *pad = media_pad_remote_pad_first(av->vdev.entity.pads); + struct v4l2_subdev *sd; + int rval; + + if (!pad) { + dev_dbg(&av->isys->adev->dev, + "video node %s pad not connected\n", av->vdev.name); + return -ENOTCONN; + } + + sd = media_entity_to_v4l2_subdev(pad->entity); + + fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + fmt.pad = pad->index; + fmt.stream = 0; + rval = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); + if (rval) + return rval; + + if (fmt.format.width != av->mpix.width || + fmt.format.height != av->mpix.height) { + dev_dbg(&av->isys->adev->dev, + "wrong width or height %ux%u (%ux%u expected)\n", + av->mpix.width, av->mpix.height, + fmt.format.width, fmt.format.height); + return -EINVAL; + } + + if (fmt.format.field != av->mpix.field) { + dev_dbg(&av->isys->adev->dev, + "wrong field value 0x%8.8x (0x%8.8x expected)\n", + av->mpix.field, fmt.format.field); + return -EINVAL; + } + + if (fmt.format.code != av->pfmt->code) { + dev_dbg(&av->isys->adev->dev, + "wrong media bus code 0x%8.8x (0x%8.8x expected)\n", + av->pfmt->code, fmt.format.code); + return -EINVAL; + } + + return 0; +} + +/* Return buffers back to videobuf2. */ +static void return_buffers(struct ipu_isys_queue *aq, + enum vb2_buffer_state state) +{ + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + int reset_needed = 0; + unsigned long flags; + + spin_lock_irqsave(&aq->lock, flags); + while (!list_empty(&aq->incoming)) { + struct ipu_isys_buffer *ib = list_first_entry(&aq->incoming, + struct + ipu_isys_buffer, + head); + struct vb2_buffer *vb = ipu_isys_buffer_to_vb2_buffer(ib); + + list_del(&ib->head); + spin_unlock_irqrestore(&aq->lock, flags); + + vb2_buffer_done(vb, state); + + dev_dbg(&av->isys->adev->dev, + "%s: stop_streaming incoming %u\n", + ipu_isys_queue_to_video(vb2_queue_to_ipu_isys_queue + (vb->vb2_queue))->vdev.name, + vb->index); + + 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)) { + struct ipu_isys_buffer *ib = list_first_entry(&aq->active, + struct + ipu_isys_buffer, + head); + struct vb2_buffer *vb = ipu_isys_buffer_to_vb2_buffer(ib); + + list_del(&ib->head); + spin_unlock_irqrestore(&aq->lock, flags); + + vb2_buffer_done(vb, state); + + dev_warn(&av->isys->adev->dev, "%s: cleaning active queue %u\n", + ipu_isys_queue_to_video(vb2_queue_to_ipu_isys_queue + (vb->vb2_queue))->vdev.name, + vb->index); + + spin_lock_irqsave(&aq->lock, flags); + reset_needed = 1; + } + + spin_unlock_irqrestore(&aq->lock, flags); + + if (reset_needed) { + mutex_lock(&av->isys->mutex); + av->isys->reset_needed = true; + mutex_unlock(&av->isys->mutex); + } +} + +static int start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(q); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct ipu_isys_video *pipe_av; + struct ipu_isys_pipeline *ip; + struct ipu_isys_buffer_list __bl, *bl = NULL; + bool first; + int rval; + + dev_dbg(&av->isys->adev->dev, + "stream: %s: width %u, height %u, css pixelformat %u\n", + av->vdev.name, av->mpix.width, av->mpix.height, + av->pfmt->css_pixelformat); + + mutex_lock(&av->isys->stream_mutex); + + first = !media_entity_pipeline(&av->vdev.entity); + + if (first) { + rval = ipu_isys_video_prepare_streaming(av, 1); + if (rval) + goto out_return_buffers; + } + + mutex_unlock(&av->isys->stream_mutex); + + rval = aq->link_fmt_validate(aq); + if (rval) { + dev_dbg(&av->isys->adev->dev, + "%s: link format validation failed (%d)\n", + av->vdev.name, rval); + goto out_unprepare_streaming; + } + + ip = to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + pipe_av = container_of(ip, struct ipu_isys_video, ip); + mutex_unlock(&av->mutex); + + mutex_lock(&pipe_av->mutex); + ip->nr_streaming++; + dev_dbg(&av->isys->adev->dev, "queue %u of %u\n", ip->nr_streaming, + ip->nr_queues); + list_add(&aq->node, &ip->queues); + if (ip->nr_streaming != ip->nr_queues) + goto out; + + if (list_empty(&av->isys->requests)) { + bl = &__bl; + rval = buffer_list_get(ip, bl); + if (rval == -EINVAL) { + goto out_stream_start; + } else if (rval < 0) { + dev_dbg(&av->isys->adev->dev, + "no request available --- postponing streamon\n"); + dev_dbg(&av->isys->adev->dev, + "stream postpone details: rval=%d nr_streaming=%u nr_queues=%u requests_empty=%d\n", + rval, ip->nr_streaming, ip->nr_queues, + list_empty(&av->isys->requests)); + goto out; + } + } + + rval = ipu_isys_stream_start(ip, bl, false); + if (rval) + goto out_stream_start; + +out: + mutex_unlock(&pipe_av->mutex); + mutex_lock(&av->mutex); + + return 0; + +out_stream_start: + list_del(&aq->node); + ip->nr_streaming--; + mutex_unlock(&pipe_av->mutex); + mutex_lock(&av->mutex); + +out_unprepare_streaming: + mutex_lock(&av->isys->stream_mutex); + if (first) + ipu_isys_video_prepare_streaming(av, 0); + +out_return_buffers: + mutex_unlock(&av->isys->stream_mutex); + return_buffers(aq, VB2_BUF_STATE_QUEUED); + + return rval; +} + +static void stop_streaming(struct vb2_queue *q) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(q); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + struct ipu_isys_video *pipe_av = + container_of(ip, struct ipu_isys_video, ip); + + if (pipe_av != av) { + mutex_unlock(&av->mutex); + mutex_lock(&pipe_av->mutex); + } + + mutex_lock(&av->isys->stream_mutex); + if (ip->nr_streaming == ip->nr_queues && ip->streaming) + ipu_isys_video_set_streaming(av, 0, NULL); + if (ip->nr_streaming == 1) + ipu_isys_video_prepare_streaming(av, 0); + mutex_unlock(&av->isys->stream_mutex); + + ip->nr_streaming--; + list_del(&aq->node); + ip->streaming = 0; + + if (pipe_av != av) { + mutex_unlock(&pipe_av->mutex); + mutex_lock(&av->mutex); + } + + return_buffers(aq, VB2_BUF_STATE_ERROR); +} + +static unsigned int +get_sof_sequence_by_timestamp(struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_resp_info_abi *info) +{ + struct ipu_isys *isys = + container_of(ip, struct ipu_isys_video, ip)->isys; + u64 time = (u64) info->timestamp[1] << 32 | info->timestamp[0]; + unsigned int i; + + for (i = 0; i < IPU_ISYS_MAX_PARALLEL_SOF; i++) + if (time == ip->seq[i].timestamp) { + dev_dbg(&isys->adev->dev, + "sof: using sequence number %u for timestamp 0x%16.16llx\n", + ip->seq[i].sequence, time); + return ip->seq[i].sequence; + } + + dev_dbg(&isys->adev->dev, "SOF: looking for 0x%16.16llx\n", time); + for (i = 0; i < IPU_ISYS_MAX_PARALLEL_SOF; i++) + dev_dbg(&isys->adev->dev, + "SOF: sequence %u, timestamp value 0x%16.16llx\n", + ip->seq[i].sequence, ip->seq[i].timestamp); + dev_dbg(&isys->adev->dev, "SOF sequence number not found\n"); + + return 0; +} + +static u64 get_sof_ns_delta(struct ipu_isys_video *av, + struct ipu_fw_isys_resp_info_abi *info) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(&av->isys->adev->dev); + struct ipu_device *isp = adev->isp; + u64 delta, tsc_now; + + if (!ipu4_buttress_tsc_read(isp, &tsc_now)) + delta = tsc_now - + ((u64) info->timestamp[1] << 32 | info->timestamp[0]); + else + delta = 0; + + return ipu4_buttress_tsc_ticks_to_ns(delta); +} + +void +ipu_isys_buf_calc_sequence_time(struct ipu_isys_buffer *ib, + struct ipu_fw_isys_resp_info_abi *info) +{ + struct vb2_buffer *vb = ipu_isys_buffer_to_vb2_buffer(ib); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + u64 ns; + u32 sequence; + + if (ip->has_sof) { + ns = (wall_clock_ts_on) ? ktime_get_real_ns() : ktime_get_ns(); + ns -= get_sof_ns_delta(av, info); + sequence = get_sof_sequence_by_timestamp(ip, info); + } else { + ns = ((wall_clock_ts_on) ? ktime_get_real_ns() : + ktime_get_ns()); + sequence = (atomic_inc_return(&ip->sequence) - 1) + / ip->nr_queues; + } + + vbuf->vb2_buf.timestamp = ns; + vbuf->sequence = sequence; + + dev_dbg(&av->isys->adev->dev, "buffer: %s: buffer done, CPU-timestamp:%lld, sequence:%d, vc:%d, index:%d, vbuf timestamp:%lld, endl\n", + av->vdev.name, ktime_get_ns(), sequence, ip->vc, vb->index, vbuf->vb2_buf.timestamp); +} + +void ipu_isys_queue_buf_done(struct ipu_isys_buffer *ib) +{ + struct vb2_buffer *vb = ipu_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 ipu_isys_queue_buf_ready(struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_resp_info_abi *info) +{ + struct ipu_isys *isys = + container_of(ip, struct ipu_isys_video, ip)->isys; + struct ipu_isys_queue *aq = ip->output_pins[info->pin_id].aq; + struct ipu_isys_buffer *ib; + struct vb2_buffer *vb; + unsigned long flags; + bool first = true; + struct vb2_v4l2_buffer *buf; + + dev_dbg(&isys->adev->dev, "buffer: %s: received buffer %8.8x\n", + ipu_isys_queue_to_video(aq)->vdev.name, info->pin.addr); + + spin_lock_irqsave(&aq->lock, flags); + if (list_empty(&aq->active)) { + spin_unlock_irqrestore(&aq->lock, flags); + dev_err(&isys->adev->dev, "active queue empty\n"); + return; + } + + list_for_each_entry_reverse(ib, &aq->active, head) { + dma_addr_t addr; + + vb = ipu_isys_buffer_to_vb2_buffer(ib); + addr = vb2_dma_contig_plane_dma_addr(vb, 0); + + if (info->pin.addr != addr) { + if (first) + dev_err(&isys->adev->dev, + "WARNING: buffer address %pad expected!\n", + &addr); + first = false; + continue; + } + + if (info->error_info.error == + IPU_FW_ISYS_ERROR_HW_REPORTED_STR2MMIO) { + /* + * Check for error message: + * 'IPU_FW_ISYS_ERROR_HW_REPORTED_STR2MMIO' + */ + atomic_set(&ib->str2mmio_flag, 1); + } + dev_dbg(&isys->adev->dev, "buffer: found buffer %pad\n", &addr); + + buf = to_vb2_v4l2_buffer(vb); + buf->field = V4L2_FIELD_NONE; + + /* + * Use "reserved" field to pass csi2 index and vc. + * May need to change to other approach. + */ + buf->reserved &= 0xFFFFFF00; + if (ip->csi2) + buf->reserved |= ip->csi2->index << 4; + buf->reserved |= ip->vc; + + list_del(&ib->head); + spin_unlock_irqrestore(&aq->lock, flags); + + ipu_isys_buf_calc_sequence_time(ib, info); + + /* + * For interlaced buffers, the notification to user space + * is postponed to capture_done event since the field + * information is available only at that time. + */ + if (ip->interlaced) { + spin_lock_irqsave(&ip->short_packet_queue_lock, flags); + list_add(&ib->head, &ip->pending_interlaced_bufs); + spin_unlock_irqrestore(&ip->short_packet_queue_lock, + flags); + } else { + ipu_isys_queue_buf_done(ib); + } + + return; + } + + dev_err(&isys->adev->dev, + "WARNING: cannot find a matching video buffer!\n"); + + spin_unlock_irqrestore(&aq->lock, flags); +} + +void +ipu_isys_queue_short_packet_ready(struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_resp_info_abi *info) +{ + struct ipu_isys *isys = + container_of(ip, struct ipu_isys_video, ip)->isys; + unsigned long flags; + + dev_dbg(&isys->adev->dev, "receive short packet buffer %8.8x\n", + info->pin.addr); + spin_lock_irqsave(&ip->short_packet_queue_lock, flags); + ip->cur_field = ipu_isys_csi2_get_current_field(ip, info->timestamp); + spin_unlock_irqrestore(&ip->short_packet_queue_lock, flags); +} + +void ipu_isys_req_free(struct media_request *req) +{ + struct ipu_isys_request *ireq = to_ipu_isys_request(req); + + kfree(ireq); +} + +struct +media_request *ipu_isys_req_alloc(struct media_device *mdev) +{ + struct ipu_isys_request *ireq; + + ireq = kzalloc(sizeof(*ireq), GFP_KERNEL); + if (!ireq) + return NULL; + + INIT_LIST_HEAD(&ireq->buffers); + spin_lock_init(&ireq->lock); + INIT_LIST_HEAD(&ireq->head); + + return &ireq->req; +} + +int ipu_isys_req_prepare(struct media_device *mdev, + struct ipu_isys_request *ireq, + struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_frame_buff_set_abi *set) +{ + struct ipu_isys *isys = + container_of(ip, struct ipu_isys_video, ip)->isys; + struct media_request *req = &ireq->req; + struct ipu_isys_buffer *ib; + unsigned long flags; + + dev_dbg(&isys->adev->dev, "%s: preparing request\n", req->debug_str); + + set->send_irq_sof = 1; + set->send_resp_sof = 1; + set->send_irq_eof = 1; + set->send_resp_eof = 1; +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + set->send_irq_capture_ack = 1; + set->send_irq_capture_done = 1; +#endif + + spin_lock_irqsave(&ireq->lock, flags); + + list_for_each_entry(ib, &ireq->buffers, req_head) { + struct vb2_buffer *vb = ipu_isys_buffer_to_vb2_buffer(ib); + struct ipu_isys_queue *aq = + vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + + if (aq->prepare_frame_buff_set) + aq->prepare_frame_buff_set(vb); + + if (aq->fill_frame_buff_set_pin) + aq->fill_frame_buff_set_pin(vb, set); + + spin_lock(&aq->lock); + list_move(&ib->head, &aq->active); + spin_unlock(&aq->lock); + } + + spin_unlock_irqrestore(&ireq->lock, flags); + + return 0; +} + +static void +ipu_isys_req_dispatch(struct media_device *mdev, + struct ipu_isys_request *ireq, + struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_frame_buff_set_abi *set, + dma_addr_t dma_addr) +{ + struct ipu_isys_video *pipe_av = + container_of(ip, struct ipu_isys_video, ip); + int rval; + + rval = ipu_fw_isys_complex_cmd(pipe_av->isys, + ip->stream_handle, + set, dma_addr, sizeof(*set), + IPU_FW_ISYS_SEND_TYPE_STREAM_CAPTURE); + ipu_put_fw_mgs_buffer(pipe_av->isys, (uintptr_t) set); + + WARN_ON(rval); +} + +void ipu_isys_req_queue(struct media_request *req) +{ + struct media_device *mdev = req->mdev; + struct ipu_isys *isys = container_of(mdev, struct ipu_isys, media_dev); + struct ipu_isys_request *ireq = to_ipu_isys_request(req); + struct ipu_isys_pipeline *ip; + struct ipu_isys_buffer *ib; + struct media_pipeline *pipe = NULL; + unsigned long flags; + bool no_pipe = false; + int rval = 0; + + spin_lock_irqsave(&ireq->lock, flags); + if (list_empty(&ireq->buffers)) { + rval = -ENODATA; + goto out_list_empty; + } + + /* Verify that all buffers are related to a single pipeline. */ + list_for_each_entry(ib, &ireq->buffers, req_head) { + struct vb2_buffer *vb = ipu_isys_buffer_to_vb2_buffer(ib); + struct ipu_isys_queue *aq = + vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + + dev_dbg(&isys->adev->dev, "%s: device %s, id %u\n", __func__, + av->vdev.name, vb-> + index); + if (!pipe) { + if (!media_entity_pipeline(&av->vdev.entity)) { + no_pipe = true; + continue; + } + + pipe = media_entity_pipeline(&av->vdev.entity); + dev_dbg(&isys->adev->dev, "%s: pipe %p\n", + av->vdev.name, pipe); + continue; + } + + if (media_entity_pipeline(&av->vdev.entity) != pipe) { + dev_dbg(&isys->adev->dev, + "%s: request includes buffers in multiple pipelines\n", + req->debug_str); + rval = -EINVAL; + goto out_list_empty; + } + } + + spin_unlock_irqrestore(&ireq->lock, flags); + + mutex_lock(&isys->stream_mutex); + + ip = to_ipu_isys_pipeline(pipe); + + if (pipe && ip->streaming) { + struct isys_fw_msgs *msg; + struct ipu_fw_isys_frame_buff_set_abi *set; + + msg = ipu_get_fw_msg_buf(ip); + if (!msg) { + rval = -ENOMEM; + goto out_mutex_unlock; + } + + set = to_frame_msg_buf(msg); + + if (no_pipe) { + dev_dbg(&isys->adev->dev, + "%s: request includes buffers in and outside pipelines\n", + req->debug_str); + rval = -EINVAL; + goto out_mutex_unlock; + } + + dev_dbg(&isys->adev->dev, + "request has a pipeline, dispatching\n"); + rval = ipu_isys_req_prepare(mdev, ireq, ip, set); + if (rval) + goto out_mutex_unlock; + + ipu_fw_isys_dump_frame_buff_set(&isys->adev->dev, set, + ip->nr_output_pins); + ipu_isys_req_dispatch(mdev, ireq, ip, set, to_dma_addr(msg)); + } else { + dev_dbg(&isys->adev->dev, + "%s[%s]: adding request to the mdev queue\n", __func__, + req->debug_str); + + list_add(&ireq->head, &isys->requests); + } + +out_mutex_unlock: + mutex_unlock(&isys->stream_mutex); + + return; + +out_list_empty: + spin_unlock_irqrestore(&ireq->lock, flags); + + return; +} + +struct vb2_ops ipu_isys_queue_ops = { + .queue_setup = queue_setup, + .wait_prepare = ipu_isys_queue_unlock, + .wait_finish = ipu_isys_queue_lock, + .buf_init = buf_init, + .buf_prepare = buf_prepare, + .buf_finish = buf_finish, + .buf_cleanup = buf_cleanup, + .start_streaming = start_streaming, + .stop_streaming = stop_streaming, + .buf_queue = buf_queue, +}; + +int ipu_isys_queue_init(struct ipu_isys_queue *aq) +{ + struct ipu_isys *isys = ipu_isys_queue_to_video(aq)->isys; + int rval; + + if (!aq->vbq.io_modes) + aq->vbq.io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF; + aq->vbq.drv_priv = aq; +// aq->vbq.allow_requests = true; + aq->vbq.ops = &ipu_isys_queue_ops; + aq->vbq.mem_ops = &vb2_dma_contig_memops; + aq->vbq.timestamp_flags = (wall_clock_ts_on) ? + V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN : V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + + rval = vb2_queue_init(&aq->vbq); + if (rval) + return rval; + + aq->dev = &isys->adev->dev; + aq->vbq.dev = &isys->adev->dev; + spin_lock_init(&aq->lock); + INIT_LIST_HEAD(&aq->active); + INIT_LIST_HEAD(&aq->incoming); + + return 0; +} + +void ipu_isys_queue_cleanup(struct ipu_isys_queue *aq) +{ + if (!aq->vbq.ops) + return; + + vb2_queue_release(&aq->vbq); +} diff --git a/drivers/media/pci/intel/ipu-isys-queue.h b/drivers/media/pci/intel/ipu-isys-queue.h new file mode 100644 index 0000000000000..5dabf759d2965 --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-queue.h @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_ISYS_QUEUE_H +#define IPU_ISYS_QUEUE_H + +#include +#include + +#include + +#include "ipu-isys-media.h" + +struct ipu_isys_video; +struct ipu_isys_pipeline; +struct ipu_fw_isys_resp_info_abi; +struct ipu_fw_isys_frame_buff_set_abi; + +enum ipu_isys_buffer_type { + IPU_ISYS_VIDEO_BUFFER, + IPU_ISYS_SHORT_PACKET_BUFFER, +}; + +struct ipu_isys_queue { + struct list_head node; /* struct ipu_isys_pipeline.queues */ + struct vb2_queue vbq; + struct device *dev; + /* + * @lock: serialise access to queued and pre_streamon_queued + */ + spinlock_t lock; + struct list_head active; + struct list_head incoming; + u32 css_pin_type; + unsigned int fw_output; + int (*buf_init)(struct vb2_buffer *vb); + void (*buf_cleanup)(struct vb2_buffer *vb); + int (*buf_prepare)(struct vb2_buffer *vb); + void (*prepare_frame_buff_set)(struct vb2_buffer *vb); + void (*fill_frame_buff_set_pin)(struct vb2_buffer *vb, + struct ipu_fw_isys_frame_buff_set_abi * + set); + int (*link_fmt_validate)(struct ipu_isys_queue *aq); +}; + +struct ipu_isys_buffer { + struct list_head head; + enum ipu_isys_buffer_type type; + struct list_head req_head; + struct media_request *req; + atomic_t str2mmio_flag; +}; + +struct ipu_isys_video_buffer { + struct vb2_v4l2_buffer vb_v4l2; + struct ipu_isys_buffer ib; +}; + +struct ipu_isys_private_buffer { + struct ipu_isys_buffer ib; + struct ipu_isys_pipeline *ip; + unsigned int index; + unsigned int bytesused; + dma_addr_t dma_addr; + void *buffer; +}; + +#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 ipu_isys_buffer_list { + struct list_head head; + unsigned int nbufs; +}; + +#define vb2_queue_to_ipu_isys_queue(__vb2) \ + container_of(__vb2, struct ipu_isys_queue, vbq) + +#define ipu_isys_to_isys_video_buffer(__ib) \ + container_of(__ib, struct ipu_isys_video_buffer, ib) + +#define vb2_buffer_to_ipu_isys_video_buffer(__vb) \ + container_of(to_vb2_v4l2_buffer(__vb), \ + struct ipu_isys_video_buffer, vb_v4l2) + +#define ipu_isys_buffer_to_vb2_buffer(__ib) \ + (&ipu_isys_to_isys_video_buffer(__ib)->vb_v4l2.vb2_buf) + +#define vb2_buffer_to_ipu_isys_buffer(__vb) \ + (&vb2_buffer_to_ipu_isys_video_buffer(__vb)->ib) + +#define ipu_isys_buffer_to_private_buffer(__ib) \ + container_of(__ib, struct ipu_isys_private_buffer, ib) + +struct ipu_isys_request { + struct media_request req; + /* serialise access to buffers */ + spinlock_t lock; + struct list_head buffers; /* struct ipu_isys_buffer.head */ + bool dispatched; + /* + * struct ipu_isys.requests; + * struct ipu_isys_pipeline.struct.* + */ + struct list_head head; +}; + +#define to_ipu_isys_request(__req) \ + container_of(__req, struct ipu_isys_request, req) + +void ipu_isys_queue_lock(struct vb2_queue *q); +void ipu_isys_queue_unlock(struct vb2_queue *q); + +int ipu_isys_buf_prepare(struct vb2_buffer *vb); + +void ipu_isys_buffer_list_queue(struct ipu_isys_buffer_list *bl, + unsigned long op_flags, + enum vb2_buffer_state state); +struct ipu_isys_request *ipu_isys_next_queued_request( + struct ipu_isys_pipeline *ip); +void ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set_pin( + struct vb2_buffer *vb, + struct ipu_fw_isys_frame_buff_set_abi *set); +void ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set( + struct ipu_fw_isys_frame_buff_set_abi *set, + struct ipu_isys_pipeline *ip, + struct ipu_isys_buffer_list *bl); +int ipu_isys_link_fmt_validate(struct ipu_isys_queue *aq); + +void +ipu_isys_buf_calc_sequence_time(struct ipu_isys_buffer *ib, + struct ipu_fw_isys_resp_info_abi *info); +void ipu_isys_queue_buf_done(struct ipu_isys_buffer *ib); +void ipu_isys_queue_buf_ready(struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_resp_info_abi *info); +void +ipu_isys_queue_short_packet_ready(struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_resp_info_abi *inf); + +void ipu_isys_req_free(struct media_request *req); +struct media_request *ipu_isys_req_alloc(struct media_device *mdev); +int ipu_isys_req_prepare(struct media_device *mdev, + struct ipu_isys_request *ireq, + struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_frame_buff_set_abi *set); +void ipu_isys_req_queue(struct media_request *req); + +int ipu_isys_queue_init(struct ipu_isys_queue *aq); +void ipu_isys_queue_cleanup(struct ipu_isys_queue *aq); + +#endif /* IPU_ISYS_QUEUE_H */ diff --git a/drivers/media/pci/intel/ipu-isys-subdev.c b/drivers/media/pci/intel/ipu-isys-subdev.c new file mode 100644 index 0000000000000..c3094e0a907b1 --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-subdev.c @@ -0,0 +1,984 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include + +#include + +#include + +#include "ipu-isys.h" +#include "ipu-isys-video.h" +#include "ipu-isys-subdev.h" + +unsigned int ipu_isys_mbus_code_to_bpp(u32 code) +{ + switch (code) { + case MEDIA_BUS_FMT_RGB888_1X24: + return 24; + case MEDIA_BUS_FMT_YUYV10_1X20: + return 20; + case MEDIA_BUS_FMT_Y10_1X10: + case MEDIA_BUS_FMT_RGB565_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: + return 16; + case MEDIA_BUS_FMT_SBGGR14_1X14: + case MEDIA_BUS_FMT_SGBRG14_1X14: + case MEDIA_BUS_FMT_SGRBG14_1X14: + case MEDIA_BUS_FMT_SRGGB14_1X14: + return 14; + 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 12; + 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 10; + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8: + return 8; + default: + WARN_ON(1); + return -EINVAL; + } +} + +unsigned int ipu_isys_mbus_code_to_mipi(u32 code) +{ + switch (code) { + case MEDIA_BUS_FMT_RGB565_1X16: + return IPU_ISYS_MIPI_CSI2_TYPE_RGB565; + case MEDIA_BUS_FMT_RGB888_1X24: + return IPU_ISYS_MIPI_CSI2_TYPE_RGB888; + case MEDIA_BUS_FMT_YUYV10_1X20: + return IPU_ISYS_MIPI_CSI2_TYPE_YUV422_10; + case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: + return IPU_ISYS_MIPI_CSI2_TYPE_YUV422_8; + case MEDIA_BUS_FMT_SBGGR14_1X14: + case MEDIA_BUS_FMT_SGBRG14_1X14: + case MEDIA_BUS_FMT_SGRBG14_1X14: + case MEDIA_BUS_FMT_SRGGB14_1X14: + return IPU_ISYS_MIPI_CSI2_TYPE_RAW14; + 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 IPU_ISYS_MIPI_CSI2_TYPE_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 IPU_ISYS_MIPI_CSI2_TYPE_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 IPU_ISYS_MIPI_CSI2_TYPE_RAW8; + case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8: + return IPU_ISYS_MIPI_CSI2_TYPE_USER_DEF(1); + default: + WARN_ON(1); + return -EINVAL; + } +} + +enum ipu_isys_subdev_pixelorder ipu_isys_subdev_get_pixelorder(u32 code) +{ + switch (code) { + case MEDIA_BUS_FMT_SBGGR14_1X14: + case MEDIA_BUS_FMT_SBGGR12_1X12: + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8: + return IPU_ISYS_SUBDEV_PIXELORDER_BGGR; + case MEDIA_BUS_FMT_SGBRG14_1X14: + case MEDIA_BUS_FMT_SGBRG12_1X12: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8: + return IPU_ISYS_SUBDEV_PIXELORDER_GBRG; + case MEDIA_BUS_FMT_SGRBG14_1X14: + case MEDIA_BUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + return IPU_ISYS_SUBDEV_PIXELORDER_GRBG; + case MEDIA_BUS_FMT_SRGGB14_1X14: + case MEDIA_BUS_FMT_SRGGB12_1X12: + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8: + return IPU_ISYS_SUBDEV_PIXELORDER_RGGB; + default: + WARN_ON(1); + return -EINVAL; + } +} + +u32 ipu_isys_subdev_code_to_uncompressed(u32 sink_code) +{ + switch (sink_code) { + case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8: + return MEDIA_BUS_FMT_SBGGR10_1X10; + case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8: + return MEDIA_BUS_FMT_SGBRG10_1X10; + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + return MEDIA_BUS_FMT_SGRBG10_1X10; + case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8: + return MEDIA_BUS_FMT_SRGGB10_1X10; + default: + return sink_code; + } +} + +struct v4l2_mbus_framefmt *__ipu_isys_get_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + unsigned int pad, + unsigned int stream, + unsigned int which) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + + if (which == V4L2_SUBDEV_FORMAT_ACTIVE) + return &asd->ffmt[pad][stream]; + + struct v4l2_mbus_framefmt *ffmt = v4l2_subdev_state_get_format(cfg, pad); + if (!ffmt) + ffmt = &asd->ffmt[pad][stream]; + return ffmt; +} + +struct v4l2_rect *__ipu_isys_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + unsigned int target, + unsigned int pad, unsigned int which) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + + if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { + switch (target) { + case V4L2_SEL_TGT_CROP: + return &asd->crop[pad]; + case V4L2_SEL_TGT_COMPOSE: + return &asd->compose[pad]; + } + } else { + struct v4l2_rect *rect; + + switch (target) { + case V4L2_SEL_TGT_CROP: + rect = v4l2_subdev_state_get_crop(cfg, pad); + return rect ? rect : &asd->crop[pad]; + case V4L2_SEL_TGT_COMPOSE: + rect = v4l2_subdev_state_get_compose(cfg, pad); + return rect ? rect : &asd->compose[pad]; + } + } + WARN_ON(1); + return NULL; +} + +static int target_valid(struct v4l2_subdev *sd, unsigned int target, + unsigned int pad) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + + switch (target) { + case V4L2_SEL_TGT_CROP: + return asd->valid_tgts[pad].crop; + case V4L2_SEL_TGT_COMPOSE: + return asd->valid_tgts[pad].compose; + default: + return 0; + } +} + +int ipu_isys_subdev_fmt_propagate(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_mbus_framefmt *ffmt, + struct v4l2_rect *r, + enum isys_subdev_prop_tgt tgt, + unsigned int pad, unsigned int which) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + struct v4l2_mbus_framefmt **ffmts = NULL; + struct v4l2_rect **crops = NULL; + struct v4l2_rect **compose = NULL; + unsigned int i; + int rval = 0; + + if (tgt == IPU_ISYS_SUBDEV_PROP_TGT_NR_OF) + return 0; + + if (WARN_ON(pad >= sd->entity.num_pads)) + return -EINVAL; + + ffmts = kcalloc(sd->entity.num_pads, + sizeof(*ffmts), GFP_KERNEL); + if (!ffmts) { + rval = -ENOMEM; + goto out_subdev_fmt_propagate; + } + crops = kcalloc(sd->entity.num_pads, + sizeof(*crops), GFP_KERNEL); + if (!crops) { + rval = -ENOMEM; + goto out_subdev_fmt_propagate; + } + compose = kcalloc(sd->entity.num_pads, + sizeof(*compose), GFP_KERNEL); + if (!compose) { + rval = -ENOMEM; + goto out_subdev_fmt_propagate; + } + + for (i = 0; i < sd->entity.num_pads; i++) { + ffmts[i] = __ipu_isys_get_ffmt(sd, state, i, 0, which); + crops[i] = __ipu_isys_get_selection(sd, state, V4L2_SEL_TGT_CROP, + i, which); + compose[i] = __ipu_isys_get_selection(sd, state, + V4L2_SEL_TGT_COMPOSE, + i, which); + } + + switch (tgt) { + case IPU_ISYS_SUBDEV_PROP_TGT_SINK_FMT: + crops[pad]->left = 0; + crops[pad]->top = 0; + crops[pad]->width = ffmt->width; + crops[pad]->height = ffmt->height; + rval = ipu_isys_subdev_fmt_propagate(sd, state, ffmt, crops[pad], + tgt + 1, pad, which); + goto out_subdev_fmt_propagate; + case IPU_ISYS_SUBDEV_PROP_TGT_SINK_CROP: + if (WARN_ON(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE)) + goto out_subdev_fmt_propagate; + + compose[pad]->left = 0; + compose[pad]->top = 0; + compose[pad]->width = r->width; + compose[pad]->height = r->height; + rval = ipu_isys_subdev_fmt_propagate(sd, state, ffmt, + compose[pad], tgt + 1, + pad, which); + goto out_subdev_fmt_propagate; + case IPU_ISYS_SUBDEV_PROP_TGT_SINK_COMPOSE: + if (WARN_ON(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE)) { + rval = -EINVAL; + goto out_subdev_fmt_propagate; + } + + for (i = 1; i < sd->entity.num_pads; i++) { + if (!(sd->entity.pads[i].flags & + MEDIA_PAD_FL_SOURCE)) + continue; + + compose[i]->left = 0; + compose[i]->top = 0; + compose[i]->width = r->width; + compose[i]->height = r->height; + rval = ipu_isys_subdev_fmt_propagate(sd, state, + ffmt, + compose[i], + tgt + 1, i, + which); + if (rval) + goto out_subdev_fmt_propagate; + } + goto out_subdev_fmt_propagate; + case IPU_ISYS_SUBDEV_PROP_TGT_SOURCE_COMPOSE: + if (WARN_ON(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SINK)) { + rval = -EINVAL; + goto out_subdev_fmt_propagate; + } + + crops[pad]->left = 0; + crops[pad]->top = 0; + crops[pad]->width = r->width; + crops[pad]->height = r->height; + rval = ipu_isys_subdev_fmt_propagate(sd, state, ffmt, + crops[pad], tgt + 1, + pad, which); + goto out_subdev_fmt_propagate; + case IPU_ISYS_SUBDEV_PROP_TGT_SOURCE_CROP:{ + struct v4l2_subdev_format fmt = { + .which = which, + .pad = pad, + .format = { + .width = r->width, + .height = r->height, + /* + * Either use the code from sink pad + * or the current one. + */ + .code = ffmt ? ffmt->code : + ffmts[pad]->code, + .field = ffmt ? ffmt->field : + ffmts[pad]->field, + }, + }; + + asd->set_ffmt(sd, state, &fmt); + goto out_subdev_fmt_propagate; + } + } + +out_subdev_fmt_propagate: + kfree(ffmts); + kfree(crops); + kfree(compose); + return rval; +} + +int ipu_isys_subdev_set_ffmt_default(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt) +{ + struct v4l2_mbus_framefmt *ffmt = + __ipu_isys_get_ffmt(sd, cfg, fmt->pad, fmt->stream, + fmt->which); + + /* No propagation for non-zero pads. */ + if (fmt->pad) { + struct v4l2_mbus_framefmt *sink_ffmt = + __ipu_isys_get_ffmt(sd, cfg, 0, fmt->stream, + fmt->which); + + ffmt->width = sink_ffmt->width; + ffmt->height = sink_ffmt->height; + ffmt->code = sink_ffmt->code; + ffmt->field = sink_ffmt->field; + } + + ffmt->width = fmt->format.width; + ffmt->height = fmt->format.height; + ffmt->code = fmt->format.code; + ffmt->field = fmt->format.field; + + return ipu_isys_subdev_fmt_propagate(sd, cfg, &fmt->format, NULL, + IPU_ISYS_SUBDEV_PROP_TGT_SINK_FMT, + fmt->pad, fmt->which); +} + +int __ipu_isys_subdev_set_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + struct v4l2_mbus_framefmt *ffmt = + __ipu_isys_get_ffmt(sd, cfg, fmt->pad, fmt->stream, + fmt->which); + u32 code = asd->supported_codes[fmt->pad][0]; + unsigned int i; + + WARN_ON(!mutex_is_locked(&asd->mutex)); + + fmt->format.width = clamp(fmt->format.width, IPU_ISYS_MIN_WIDTH, + IPU_ISYS_MAX_WIDTH); + fmt->format.height = clamp(fmt->format.height, + IPU_ISYS_MIN_HEIGHT, IPU_ISYS_MAX_HEIGHT); + + for (i = 0; asd->supported_codes[fmt->pad][i]; i++) { + if (asd->supported_codes[fmt->pad][i] == fmt->format.code) { + code = asd->supported_codes[fmt->pad][i]; + break; + } + } + + fmt->format.code = code; + + asd->set_ffmt(sd, cfg, fmt); + + fmt->format = *ffmt; + + return 0; +} + +int ipu_isys_subdev_set_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + int rval; + + if (fmt->stream >= asd->nstreams) + return -EINVAL; + + mutex_lock(&asd->mutex); + rval = __ipu_isys_subdev_set_ffmt(sd, cfg, fmt); + mutex_unlock(&asd->mutex); + + return rval; +} + +int ipu_isys_subdev_get_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + + if (fmt->stream >= asd->nstreams) + return -EINVAL; + + mutex_lock(&asd->mutex); + fmt->format = *__ipu_isys_get_ffmt(sd, cfg, fmt->pad, + fmt->stream, + fmt->which); + mutex_unlock(&asd->mutex); + + return 0; +} + +int ipu_isys_subdev_get_frame_desc(struct v4l2_subdev *sd, + struct v4l2_mbus_frame_desc *desc) +{ + int i, rval = 0; + + for (i = 0; i < sd->entity.num_pads; i++) { + if (!(sd->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)) + continue; + + rval = v4l2_subdev_call(sd, pad, get_frame_desc, i, desc); + if (!rval) + return rval; + } + + if (i == sd->entity.num_pads) + rval = -EINVAL; + + return rval; +} + +u32 ipu_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad) +{ + struct v4l2_subdev_state *state; + struct v4l2_subdev_route *routes; + unsigned int i; + u32 source_stream = 0; + + 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; +} + +bool ipu_isys_subdev_has_route(struct media_entity *entity, + unsigned int pad0, unsigned int pad1, int *stream) +{ + struct ipu_isys_subdev *asd; + int i; + + if (!entity) { + WARN_ON(1); + return false; + } + asd = to_ipu_isys_subdev(media_entity_to_v4l2_subdev(entity)); + + /* Two sinks are never connected together. */ + if (pad0 < asd->nsinks && pad1 < asd->nsinks) + return false; + + for (i = 0; i < asd->nstreams; i++) { + if ((asd->route[i].flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) && + ((asd->route[i].sink == pad0 && + asd->route[i].source == pad1) || + (asd->route[i].sink == pad1 && + asd->route[i].source == pad0))) { + if (stream) + *stream = i; + return true; + } + } + + return false; +} + +int ipu_isys_subdev_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + enum v4l2_subdev_format_whence which, + struct v4l2_subdev_krouting *route) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + int i, j, ret = 0; + + WARN_ON(!mutex_is_locked(&sd->entity. + graph_obj.mdev + ->graph_mutex)); + + for (i = 0; i < min(route->num_routes, asd->nstreams); ++i) { + struct v4l2_subdev_route *t = &route->routes[i]; + + if (t->sink_stream > asd->nstreams - 1 || + t->source_stream > asd->nstreams - 1) + continue; + + for (j = 0; j < asd->nstreams; j++) { + if (t->sink_pad == asd->route[j].sink && + t->source_pad == asd->route[j].source) + break; + } + + if (j == asd->nstreams) + continue; + + if (asd->route[j].flags & V4L2_SUBDEV_ROUTE_FL_IMMUTABLE) + continue; + + if ((t->flags & V4L2_SUBDEV_ROUTE_FL_SOURCE) && asd->nsinks) + continue; + + if (!(t->flags & V4L2_SUBDEV_ROUTE_FL_SOURCE)) { + int source_pad = 0; + + if (sd->entity.pads[t->sink_pad].flags & + MEDIA_PAD_FL_MULTIPLEX) + source_pad = t->source_pad - asd->nsinks; + + asd->stream[t->sink_pad].stream_id[source_pad] = + t->sink_stream; + } + + if (sd->entity.pads[t->source_pad].flags & + MEDIA_PAD_FL_MULTIPLEX) + asd->stream[t->source_pad].stream_id[t->sink_pad] = + t->source_stream; + else + asd->stream[t->source_pad].stream_id[0] = + t->source_stream; + + if (t->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) { + bitmap_set(asd->stream[t->source_pad].streams_stat, + t->source_stream, 1); + if (!(t->flags & V4L2_SUBDEV_ROUTE_FL_SOURCE)) + bitmap_set(asd->stream[t->sink_pad] + .streams_stat, t->sink_stream, 1); + asd->route[j].flags |= V4L2_SUBDEV_ROUTE_FL_ACTIVE; + } else if (!(t->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE)) { + bitmap_clear(asd->stream[t->source_pad].streams_stat, + t->source_stream, 1); + if (!(t->flags & V4L2_SUBDEV_ROUTE_FL_SOURCE)) + bitmap_clear(asd->stream[t->sink_pad] + .streams_stat, t->sink_stream, 1); + asd->route[j].flags &= (~V4L2_SUBDEV_ROUTE_FL_ACTIVE); + } + } + + return ret; +} + +int ipu_isys_subdev_get_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_routing *route) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + struct v4l2_subdev_route *routes = (struct v4l2_subdev_route *)(uintptr_t)route->routes; + int i, j; + + for (i = 0, j = 0; i < min(asd->nstreams, route->num_routes); ++i) { + routes[j].sink_pad = asd->route[i].sink; + + if (sd->entity.pads[asd->route[i].sink].flags & + MEDIA_PAD_FL_MULTIPLEX) { + int source_pad = asd->route[i].source - asd->nsinks; + + routes[j].sink_stream = + asd->stream[asd->route[i].sink]. + stream_id[source_pad]; + } else { + routes[j].sink_stream = + asd->stream[asd->route[i].sink].stream_id[0]; + } + + routes[j].source_pad = asd->route[i].source; + + if (sd->entity.pads[asd->route[i].source].flags & + MEDIA_PAD_FL_MULTIPLEX) { + routes[j].source_stream = + asd->stream[asd->route[i].source].stream_id[asd-> + route + [i]. + sink]; + } else { + routes[j].source_stream = + asd->stream[asd->route[i].source].stream_id[0]; + } + routes[j++].flags = asd->route[i].flags; + } + + route->num_routes = j; + + return 0; +} + +int ipu_isys_subdev_set_sel(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_selection *sel) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + struct media_pad *pad = &asd->sd.entity.pads[sel->pad]; + struct v4l2_rect *r, __r = { 0 }; + unsigned int tgt; + + if (!target_valid(sd, sel->target, sel->pad)) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + if (pad->flags & MEDIA_PAD_FL_SINK) { + struct v4l2_mbus_framefmt *ffmt = + __ipu_isys_get_ffmt(sd, cfg, sel->pad, 0, + sel->which); + + __r.width = ffmt->width; + __r.height = ffmt->height; + r = &__r; + tgt = IPU_ISYS_SUBDEV_PROP_TGT_SINK_CROP; + } else { + /* 0 is the sink pad. */ + r = __ipu_isys_get_selection(sd, cfg, sel->target, 0, + sel->which); + tgt = IPU_ISYS_SUBDEV_PROP_TGT_SOURCE_CROP; + } + + break; + case V4L2_SEL_TGT_COMPOSE: + if (pad->flags & MEDIA_PAD_FL_SINK) { + r = __ipu_isys_get_selection(sd, cfg, V4L2_SEL_TGT_CROP, + sel->pad, sel->which); + tgt = IPU_ISYS_SUBDEV_PROP_TGT_SINK_COMPOSE; + } else { + r = __ipu_isys_get_selection(sd, cfg, + V4L2_SEL_TGT_COMPOSE, 0, + sel->which); + tgt = IPU_ISYS_SUBDEV_PROP_TGT_SOURCE_COMPOSE; + } + break; + default: + return -EINVAL; + } + + sel->r.width = clamp(sel->r.width, IPU_ISYS_MIN_WIDTH, r->width); + sel->r.height = clamp(sel->r.height, IPU_ISYS_MIN_HEIGHT, r->height); + *__ipu_isys_get_selection(sd, cfg, sel->target, sel->pad, + sel->which) = sel->r; + return ipu_isys_subdev_fmt_propagate(sd, cfg, NULL, &sel->r, tgt, + sel->pad, sel->which); +} + +int ipu_isys_subdev_get_sel(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_selection *sel) +{ + if (!target_valid(sd, sel->target, sel->pad)) + return -EINVAL; + + sel->r = *__ipu_isys_get_selection(sd, cfg, sel->target, + sel->pad, sel->which); + + return 0; +} + +int ipu_isys_subdev_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + const u32 *supported_codes = asd->supported_codes[code->pad]; + u32 index; + bool next_stream = false; + + if (sd->entity.pads[code->pad].flags & MEDIA_PAD_FL_MULTIPLEX) { + if (code->stream & V4L2_SUBDEV_FLAG_NEXT_STREAM) { + next_stream = true; + code->stream &= ~V4L2_SUBDEV_FLAG_NEXT_STREAM; + } + + if (code->stream > asd->nstreams - 1) + return -EINVAL; + + if (next_stream && code->stream < asd->nstreams) { + code->stream++; + return 0; + } + + return -EINVAL; + } + + for (index = 0; supported_codes[index]; index++) { + if (index == code->index) { + code->code = supported_codes[index]; + return 0; + } + } + + return -EINVAL; +} + +#if !defined(CONFIG_VIDEO_INTEL_IPU4) && !defined(CONFIG_VIDEO_INTEL_IPU4P) +/* + * IPU private link validation + * In advanced IPU and special case, there will be format change between + * sink/source pads in ISYS. + * Format code checking is not necessary for these features. + */ +static int ipu_isys_subdev_link_validate_private( + struct v4l2_subdev *sd, + struct media_link *link, + struct v4l2_subdev_format *source_fmt, + struct v4l2_subdev_format *sink_fmt) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + + /* The width and height must match. */ + if (source_fmt->format.width != sink_fmt->format.width + || source_fmt->format.height != sink_fmt->format.height) + return -EPIPE; + + /* + * The field order must match, or the sink field order must be NONE + * to support interlaced hardware connected to bridges that support + * progressive formats only. + */ + if (source_fmt->format.field != sink_fmt->format.field && + sink_fmt->format.field != V4L2_FIELD_NONE) + return -EPIPE; + + if (source_fmt->stream != sink_fmt->stream) + return -EINVAL; + + /* + * For new IPU special case, YUV format changing in BE-SOC, + * from YUV422 to I420, which is used to adapt multiple + * YUV sensors and provide I420 to BB for partial processing. + * If this entity doing format convert, ignore format check + */ + if (source_fmt->format.code != sink_fmt->format.code) { + if (source_fmt->format.code == MEDIA_BUS_FMT_UYVY8_2X8 && + (sink_fmt->format.code == MEDIA_BUS_FMT_YUYV8_1X16 || + sink_fmt->format.code == MEDIA_BUS_FMT_UYVY8_1X16)) + dev_warn(&asd->isys->adev->dev, + "YUV format change, ignore code check\n"); + else + return -EINVAL; + } + + return 0; +} +#endif + +/* + * Besides validating the link, figure out the external pad and the + * ISYS FW ABI source. + */ +int ipu_isys_subdev_link_validate(struct v4l2_subdev *sd, + struct media_link *link, + struct v4l2_subdev_format *source_fmt, + struct v4l2_subdev_format *sink_fmt) +{ + struct v4l2_subdev *source_sd = + media_entity_to_v4l2_subdev(link->source->entity); + struct ipu_isys_pipeline *ip = container_of(media_entity_pipeline(&sd->entity), + struct ipu_isys_pipeline, + pipe); + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + + if (!source_sd) + return -ENODEV; + if (strncmp(source_sd->name, IPU_ISYS_ENTITY_PREFIX, + strlen(IPU_ISYS_ENTITY_PREFIX)) != 0) { + /* + * source_sd isn't ours --- sd must be the external + * sub-device. + */ + ip->external = link->source; + ip->source = to_ipu_isys_subdev(sd)->source; + dev_dbg(&asd->isys->adev->dev, "%s: using source %d\n", + sd->entity.name, ip->source); + } else if (source_sd->entity.num_pads == 1) { + /* All internal sources have a single pad. */ + ip->external = link->source; + ip->source = to_ipu_isys_subdev(source_sd)->source; + + dev_dbg(&asd->isys->adev->dev, "%s: using source %d\n", + sd->entity.name, ip->source); + } + + if (asd->isl_mode != IPU_ISL_OFF) + ip->isl_mode = asd->isl_mode; + +#if !defined(CONFIG_VIDEO_INTEL_IPU4) && !defined(CONFIG_VIDEO_INTEL_IPU4P) + return ipu_isys_subdev_link_validate_private(sd, link, source_fmt, + sink_fmt); +#else + return v4l2_subdev_link_validate_default(sd, link, source_fmt, + sink_fmt); +#endif +} + +int ipu_isys_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(sd); + unsigned int i; + + mutex_lock(&asd->mutex); + + for (i = 0; i < asd->sd.entity.num_pads; i++) { + struct v4l2_mbus_framefmt *try_fmt = + v4l2_subdev_state_get_format(fh->state, i); + struct v4l2_rect *try_crop = + v4l2_subdev_state_get_crop(fh->state, i); + struct v4l2_rect *try_compose = + v4l2_subdev_state_get_compose(fh->state, i); + + if (try_fmt) + *try_fmt = asd->ffmt[i][0]; + if (try_crop) + *try_crop = asd->crop[i]; + if (try_compose) + *try_compose = asd->compose[i]; + } + + mutex_unlock(&asd->mutex); + + return 0; +} + +int ipu_isys_subdev_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + return 0; +} + +int ipu_isys_subdev_init(struct ipu_isys_subdev *asd, + struct v4l2_subdev_ops *ops, + unsigned int nr_ctrls, + unsigned int num_pads, + unsigned int num_streams, + unsigned int num_source, + unsigned int num_sink, + unsigned int sd_flags) +{ + int i; + int rval = -EINVAL; + + mutex_init(&asd->mutex); + + v4l2_subdev_init(&asd->sd, ops); + + asd->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | sd_flags; + asd->sd.owner = THIS_MODULE; + + asd->nstreams = num_streams; + asd->nsources = num_source; + asd->nsinks = num_sink; + + asd->pad = devm_kcalloc(&asd->isys->adev->dev, num_pads, + sizeof(*asd->pad), GFP_KERNEL); + + asd->ffmt = (struct v4l2_mbus_framefmt **) + devm_kcalloc(&asd->isys->adev->dev, num_pads, + sizeof(struct v4l2_mbus_framefmt *), + GFP_KERNEL); + + asd->crop = devm_kcalloc(&asd->isys->adev->dev, num_pads, + sizeof(*asd->crop), GFP_KERNEL); + + asd->compose = devm_kcalloc(&asd->isys->adev->dev, num_pads, + sizeof(*asd->compose), GFP_KERNEL); + + asd->valid_tgts = devm_kcalloc(&asd->isys->adev->dev, num_pads, + sizeof(*asd->valid_tgts), GFP_KERNEL); + asd->route = devm_kcalloc(&asd->isys->adev->dev, num_streams, + sizeof(*asd->route), GFP_KERNEL); + + asd->stream = devm_kcalloc(&asd->isys->adev->dev, num_pads, + sizeof(*asd->stream), GFP_KERNEL); + + if (!asd->pad || !asd->ffmt || !asd->crop || !asd->compose || + !asd->valid_tgts || !asd->route || !asd->stream) + return -ENOMEM; + + for (i = 0; i < num_pads; i++) { + asd->ffmt[i] = (struct v4l2_mbus_framefmt *) + devm_kcalloc(&asd->isys->adev->dev, num_streams, + sizeof(struct v4l2_mbus_framefmt), GFP_KERNEL); + if (!asd->ffmt[i]) + return -ENOMEM; + + asd->stream[i].stream_id = + devm_kcalloc(&asd->isys->adev->dev, num_source, + sizeof(*asd->stream[i].stream_id), GFP_KERNEL); + if (!asd->stream[i].stream_id) + return -ENOMEM; + } + + for (i = 0; i < num_sink; i++) + asd->pad[i].flags = MEDIA_PAD_FL_SINK; + for (i = num_sink; i < num_pads; i++) + asd->pad[i].flags = MEDIA_PAD_FL_SOURCE; + + rval = media_entity_pads_init(&asd->sd.entity, num_pads, asd->pad); + if (rval) + goto out_mutex_destroy; + + if (asd->ctrl_init) { + rval = v4l2_ctrl_handler_init(&asd->ctrl_handler, nr_ctrls); + if (rval) + goto out_media_entity_cleanup; + + asd->ctrl_init(&asd->sd); + if (asd->ctrl_handler.error) { + rval = 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); + +out_mutex_destroy: + mutex_destroy(&asd->mutex); + + return rval; +} + +void ipu_isys_subdev_cleanup(struct ipu_isys_subdev *asd) +{ + media_entity_cleanup(&asd->sd.entity); + v4l2_ctrl_handler_free(&asd->ctrl_handler); + mutex_destroy(&asd->mutex); +} diff --git a/drivers/media/pci/intel/ipu-isys-subdev.h b/drivers/media/pci/intel/ipu-isys-subdev.h new file mode 100644 index 0000000000000..ab225db113f29 --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-subdev.h @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_ISYS_SUBDEV_H +#define IPU_ISYS_SUBDEV_H + +#include + +#include +#include +#include + +#include "ipu-isys-queue.h" + +#define IPU_ISYS_MIPI_CSI2_TYPE_NULL 0x10 +#define IPU_ISYS_MIPI_CSI2_TYPE_BLANKING 0x11 +#define IPU_ISYS_MIPI_CSI2_TYPE_EMBEDDED8 0x12 +#define IPU_ISYS_MIPI_CSI2_TYPE_YUV422_8 0x1e +#define IPU_ISYS_MIPI_CSI2_TYPE_YUV422_10 0x1f +#define IPU_ISYS_MIPI_CSI2_TYPE_RGB565 0x22 +#define IPU_ISYS_MIPI_CSI2_TYPE_RGB888 0x24 +#define IPU_ISYS_MIPI_CSI2_TYPE_RAW6 0x28 +#define IPU_ISYS_MIPI_CSI2_TYPE_RAW7 0x29 +#define IPU_ISYS_MIPI_CSI2_TYPE_RAW8 0x2a +#define IPU_ISYS_MIPI_CSI2_TYPE_RAW10 0x2b +#define IPU_ISYS_MIPI_CSI2_TYPE_RAW12 0x2c +#define IPU_ISYS_MIPI_CSI2_TYPE_RAW14 0x2d +/* 1-8 */ +#define IPU_ISYS_MIPI_CSI2_TYPE_USER_DEF(i) (0x30 + (i) - 1) + +#define FMT_ENTRY (struct ipu_isys_fmt_entry []) + +enum isys_subdev_prop_tgt { + IPU_ISYS_SUBDEV_PROP_TGT_SINK_FMT, + IPU_ISYS_SUBDEV_PROP_TGT_SINK_CROP, + IPU_ISYS_SUBDEV_PROP_TGT_SINK_COMPOSE, + IPU_ISYS_SUBDEV_PROP_TGT_SOURCE_COMPOSE, + IPU_ISYS_SUBDEV_PROP_TGT_SOURCE_CROP, +}; + +#define IPU_ISYS_SUBDEV_PROP_TGT_NR_OF \ + (IPU_ISYS_SUBDEV_PROP_TGT_SOURCE_CROP + 1) + +enum ipu_isl_mode { + IPU_ISL_OFF = 0, /* IPU_FW_ISYS_USE_NO_ISL_NO_ISA */ + IPU_ISL_CSI2_BE, /* IPU_FW_ISYS_USE_SINGLE_DUAL_ISL */ + IPU_ISL_ISA /* IPU_FW_ISYS_USE_SINGLE_ISA */ +}; + +enum ipu_be_mode { + IPU_BE_RAW = 0, + IPU_BE_SOC +}; + +enum ipu_isys_subdev_pixelorder { + IPU_ISYS_SUBDEV_PIXELORDER_BGGR = 0, + IPU_ISYS_SUBDEV_PIXELORDER_GBRG, + IPU_ISYS_SUBDEV_PIXELORDER_GRBG, + IPU_ISYS_SUBDEV_PIXELORDER_RGGB, +}; + +struct ipu_isys; + +struct ipu_isys_subdev { + /* Serialise access to any other field in the struct */ + struct mutex mutex; + struct v4l2_subdev sd; + struct ipu_isys *isys; + u32 const *const *supported_codes; + struct media_pad *pad; + struct v4l2_mbus_framefmt **ffmt; + struct v4l2_rect *crop; + struct v4l2_rect *compose; + struct { + unsigned int *stream_id; + DECLARE_BITMAP(streams_stat, 32); + } *stream; /* stream enable/disable status, indexed by pad */ + struct { + unsigned int sink; + unsigned int source; + int flags; + } *route; /* pad level info, indexed by stream */ + unsigned int nstreams; + unsigned int nsinks; + unsigned int nsources; + struct v4l2_ctrl_handler ctrl_handler; + void (*ctrl_init)(struct v4l2_subdev *sd); + void (*set_ffmt)(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt); + struct { + bool crop; + bool compose; + } *valid_tgts; + enum ipu_isl_mode isl_mode; + enum ipu_be_mode be_mode; + int source; /* SSI stream source; -1 if unset */ +}; + +#define to_ipu_isys_subdev(__sd) \ + container_of(__sd, struct ipu_isys_subdev, sd) + +struct v4l2_mbus_framefmt *__ipu_isys_get_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + unsigned int pad, + unsigned int stream, + unsigned int which); + +unsigned int ipu_isys_mbus_code_to_bpp(u32 code); +unsigned int ipu_isys_mbus_code_to_mipi(u32 code); +u32 ipu_isys_subdev_code_to_uncompressed(u32 sink_code); + +enum ipu_isys_subdev_pixelorder ipu_isys_subdev_get_pixelorder(u32 code); + +int ipu_isys_subdev_fmt_propagate(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_mbus_framefmt *ffmt, + struct v4l2_rect *r, + enum isys_subdev_prop_tgt tgt, + unsigned int pad, unsigned int which); + +int ipu_isys_subdev_set_ffmt_default(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt); +int __ipu_isys_subdev_set_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt); +struct v4l2_rect *__ipu_isys_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + unsigned int target, + unsigned int pad, + unsigned int which); +int ipu_isys_subdev_set_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt); +int ipu_isys_subdev_get_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt); +int ipu_isys_subdev_get_sel(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_selection *sel); +int ipu_isys_subdev_set_sel(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_selection *sel); +int ipu_isys_subdev_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_mbus_code_enum + *code); +int ipu_isys_subdev_link_validate(struct v4l2_subdev *sd, + struct media_link *link, + struct v4l2_subdev_format *source_fmt, + struct v4l2_subdev_format *sink_fmt); + +int ipu_isys_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); +int ipu_isys_subdev_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); +int ipu_isys_subdev_init(struct ipu_isys_subdev *asd, + struct v4l2_subdev_ops *ops, + unsigned int nr_ctrls, + unsigned int num_pads, + unsigned int num_streams, + unsigned int num_source, + unsigned int num_sink, + unsigned int sd_flags); +void ipu_isys_subdev_cleanup(struct ipu_isys_subdev *asd); +int ipu_isys_subdev_get_frame_desc(struct v4l2_subdev *sd, + struct v4l2_mbus_frame_desc *desc); +u32 ipu_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad); +int ipu_isys_subdev_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + enum v4l2_subdev_format_whence which, + struct v4l2_subdev_krouting *route); +int ipu_isys_subdev_get_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_routing *route); +bool ipu_isys_subdev_has_route(struct media_entity *entity, + unsigned int pad0, unsigned int pad1, int *stream); +#endif /* IPU_ISYS_SUBDEV_H */ diff --git a/drivers/media/pci/intel/ipu-isys-tpg.c b/drivers/media/pci/intel/ipu-isys-tpg.c new file mode 100644 index 0000000000000..10aeec19d09c4 --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-tpg.c @@ -0,0 +1,343 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include + +#include +#include +#include + +#include "ipu.h" +#include "ipu-bus.h" +#include "ipu-isys.h" +#include "ipu-isys-subdev.h" +#include "ipu-isys-tpg.h" +#include "ipu-isys-video.h" +#include "ipu-platform-isys-csi2-reg.h" + +#define V4L2_CID_CRLMODULE_BASE (V4L2_CID_USER_BASE + 0x2050) +#define V4L2_CID_FRAME_LENGTH_LINES (V4L2_CID_CRLMODULE_BASE + 1) +#define V4L2_CID_LINE_LENGTH_PIXELS (V4L2_CID_CRLMODULE_BASE + 2) + +static const u32 tpg_supported_codes_pad[] = { + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + 0, +}; + +static const u32 *tpg_supported_codes[] = { + tpg_supported_codes_pad, +}; + +static struct v4l2_subdev_internal_ops tpg_sd_internal_ops = { + .open = ipu_isys_subdev_open, + .close = ipu_isys_subdev_close, +}; + +static const struct v4l2_subdev_video_ops tpg_sd_video_ops = { + .s_stream = tpg_set_stream, +}; + +static int ipu_isys_tpg_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct ipu_isys_tpg *tpg = container_of(container_of(ctrl->handler, + struct + ipu_isys_subdev, + ctrl_handler), + struct ipu_isys_tpg, asd); + + switch (ctrl->id) { + case V4L2_CID_HBLANK: + writel(ctrl->val, tpg->base + MIPI_GEN_REG_SYNG_HBLANK_CYC); + break; + case V4L2_CID_VBLANK: + writel(ctrl->val, tpg->base + MIPI_GEN_REG_SYNG_VBLANK_CYC); + break; + case V4L2_CID_LINE_LENGTH_PIXELS: + if (ctrl->val > tpg->asd.ffmt[TPG_PAD_SOURCE][0].width) + writel(ctrl->val - + tpg->asd.ffmt[TPG_PAD_SOURCE][0].width, + tpg->base + MIPI_GEN_REG_SYNG_HBLANK_CYC); + break; + case V4L2_CID_FRAME_LENGTH_LINES: + if (ctrl->val > tpg->asd.ffmt[TPG_PAD_SOURCE][0].height) + writel(ctrl->val - + tpg->asd.ffmt[TPG_PAD_SOURCE][0].height, + tpg->base + MIPI_GEN_REG_SYNG_VBLANK_CYC); + break; + case V4L2_CID_TEST_PATTERN: + writel(ctrl->val, tpg->base + MIPI_GEN_REG_TPG_MODE); + break; + } + + return 0; +} + +static const struct v4l2_ctrl_ops ipu_isys_tpg_ctrl_ops = { + .s_ctrl = ipu_isys_tpg_s_ctrl, +}; + +static s64 ipu_isys_tpg_rate(struct ipu_isys_tpg *tpg, unsigned int bpp) +{ + return MIPI_GEN_PPC * IPU_ISYS_FREQ; +} + +static const char *const tpg_mode_items[] = { + "Ramp", + "Checkerboard", /* Does not work, disabled. */ + "Frame Based Colour", +}; + +static struct v4l2_ctrl_config tpg_mode = { + .ops = &ipu_isys_tpg_ctrl_ops, + .id = V4L2_CID_TEST_PATTERN, + .name = "Test Pattern", + .type = V4L2_CTRL_TYPE_MENU, + .min = 0, + .max = ARRAY_SIZE(tpg_mode_items) - 1, + .def = 0, + .menu_skip_mask = 0x2, + .qmenu = tpg_mode_items, +}; + +static const struct v4l2_ctrl_config csi2_header_cfg = { + .id = V4L2_CID_IPU_STORE_CSI2_HEADER, + .name = "Store CSI-2 Headers", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = 0, + .max = 1, + .step = 1, + .def = 1, +}; + +static void ipu_isys_tpg_init_controls(struct v4l2_subdev *sd) +{ + struct ipu_isys_tpg *tpg = to_ipu_isys_tpg(sd); + int hblank; + struct v4l2_ctrl_config cfg = { + .ops = &ipu_isys_tpg_ctrl_ops, + .type = V4L2_CTRL_TYPE_INTEGER, + .max = 65535, + .min = 8, + .step = 1, + .qmenu = NULL, + .elem_size = 0, + }; + + hblank = 1024; + + tpg->hblank = v4l2_ctrl_new_std(&tpg->asd.ctrl_handler, + &ipu_isys_tpg_ctrl_ops, + V4L2_CID_HBLANK, 8, 65535, 1, hblank); + + tpg->vblank = v4l2_ctrl_new_std(&tpg->asd.ctrl_handler, + &ipu_isys_tpg_ctrl_ops, + V4L2_CID_VBLANK, 8, 65535, 1, 1024); + + cfg.id = V4L2_CID_LINE_LENGTH_PIXELS; + cfg.name = "Line Length Pixels"; + cfg.def = 1024 + 4096; + + tpg->llp = v4l2_ctrl_new_custom(&tpg->asd.ctrl_handler, &cfg, NULL); + + cfg.id = V4L2_CID_FRAME_LENGTH_LINES; + cfg.name = "Frame Length Lines"; + cfg.def = 1024 + 3072; + tpg->fll = v4l2_ctrl_new_custom(&tpg->asd.ctrl_handler, &cfg, NULL); + + tpg->pixel_rate = v4l2_ctrl_new_std(&tpg->asd.ctrl_handler, + &ipu_isys_tpg_ctrl_ops, + V4L2_CID_PIXEL_RATE, 0, 0, 1, 0); + + if (tpg->pixel_rate) { + tpg->pixel_rate->cur.val = ipu_isys_tpg_rate(tpg, 8); + tpg->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY; + } + + v4l2_ctrl_new_custom(&tpg->asd.ctrl_handler, &tpg_mode, NULL); + tpg->store_csi2_header = + v4l2_ctrl_new_custom(&tpg->asd.ctrl_handler, &csi2_header_cfg, NULL); +} + +static void tpg_set_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt) +{ + fmt->format.field = V4L2_FIELD_NONE; + *__ipu_isys_get_ffmt(sd, cfg, fmt->pad, fmt->stream, + fmt->which) = fmt->format; +} + +static int ipu_isys_tpg_set_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt) +{ + struct ipu_isys_tpg *tpg = to_ipu_isys_tpg(sd); + __u32 code = tpg->asd.ffmt[TPG_PAD_SOURCE][0].code; + unsigned int bpp = ipu_isys_mbus_code_to_bpp(code); + s64 tpg_rate = ipu_isys_tpg_rate(tpg, bpp); + int rval; + + mutex_lock(&tpg->asd.mutex); + rval = __ipu_isys_subdev_set_ffmt(sd, cfg, fmt); + mutex_unlock(&tpg->asd.mutex); + + if (rval || fmt->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return rval; + + v4l2_ctrl_s_ctrl_int64(tpg->pixel_rate, tpg_rate); + + return 0; +} + +static const struct ipu_isys_pixelformat *ipu_isys_tpg_try_fmt( + struct ipu_isys_video *av, + struct v4l2_pix_format_mplane *mpix) +{ + struct media_link *link = list_first_entry(&av->vdev.entity.links, + struct media_link, list); + struct v4l2_subdev *sd = + media_entity_to_v4l2_subdev(link->source->entity); + struct ipu_isys_tpg *tpg; + + if (!sd) + return NULL; + + tpg = to_ipu_isys_tpg(sd); + + return ipu_isys_video_try_fmt_vid_mplane(av, mpix, + v4l2_ctrl_g_ctrl(tpg->store_csi2_header)); +} + +static const struct v4l2_subdev_pad_ops tpg_sd_pad_ops = { + .get_fmt = ipu_isys_subdev_get_ffmt, + .set_fmt = ipu_isys_tpg_set_ffmt, + .enum_mbus_code = ipu_isys_subdev_enum_mbus_code, +}; + +static int subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, + struct v4l2_event_subscription *sub) +{ + switch (sub->type) { + case V4L2_EVENT_CTRL: + return v4l2_ctrl_subscribe_event(fh, sub); + default: + return -EINVAL; + } +}; + +/* V4L2 subdev core operations */ +static const struct v4l2_subdev_core_ops tpg_sd_core_ops = { + .subscribe_event = subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, +}; + +static struct v4l2_subdev_ops tpg_sd_ops = { + .core = &tpg_sd_core_ops, + .video = &tpg_sd_video_ops, + .pad = &tpg_sd_pad_ops, +}; + +static struct media_entity_operations tpg_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +void ipu_isys_tpg_cleanup(struct ipu_isys_tpg *tpg) +{ + if (!tpg->asd.sd.v4l2_dev) + return; + + v4l2_device_unregister_subdev(&tpg->asd.sd); + ipu_isys_subdev_cleanup(&tpg->asd); + ipu_isys_video_cleanup(&tpg->av); +} + +int ipu_isys_tpg_init(struct ipu_isys_tpg *tpg, + struct ipu_isys *isys, + void __iomem *base, void __iomem *sel, + unsigned int index) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = TPG_PAD_SOURCE, + .format = { + .width = 4096, + .height = 3072, + }, + }; + int rval; + + tpg->isys = isys; + tpg->base = base; + tpg->sel = sel; + tpg->index = index; + + tpg->asd.sd.entity.ops = &tpg_entity_ops; + tpg->asd.ctrl_init = ipu_isys_tpg_init_controls; + tpg->asd.isys = isys; + + rval = ipu_isys_subdev_init(&tpg->asd, &tpg_sd_ops, 5, + NR_OF_TPG_PADS, + NR_OF_TPG_STREAMS, + NR_OF_TPG_SOURCE_PADS, + NR_OF_TPG_SINK_PADS, + V4L2_SUBDEV_FL_HAS_EVENTS); + if (rval) + return rval; + + tpg->asd.sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; + tpg->asd.pad[TPG_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + + tpg->asd.source = IPU_FW_ISYS_STREAM_SRC_MIPIGEN_PORT0 + index; + tpg->asd.supported_codes = tpg_supported_codes; + tpg->asd.set_ffmt = tpg_set_ffmt; + ipu_isys_subdev_set_ffmt(&tpg->asd.sd, NULL, &fmt); + + tpg->asd.sd.internal_ops = &tpg_sd_internal_ops; + snprintf(tpg->asd.sd.name, sizeof(tpg->asd.sd.name), + IPU_ISYS_ENTITY_PREFIX " TPG %u", index); + v4l2_set_subdevdata(&tpg->asd.sd, &tpg->asd); + rval = v4l2_device_register_subdev(&isys->v4l2_dev, &tpg->asd.sd); + if (rval) { + dev_info(&isys->adev->dev, "can't register v4l2 subdev\n"); + goto fail; + } + + snprintf(tpg->av.vdev.name, sizeof(tpg->av.vdev.name), + IPU_ISYS_ENTITY_PREFIX " TPG %u capture", index); + tpg->av.isys = isys; + tpg->av.aq.css_pin_type = IPU_FW_ISYS_PIN_TYPE_MIPI; + tpg->av.pfmts = ipu_isys_pfmts_packed; + tpg->av.try_fmt_vid_mplane = ipu_isys_tpg_try_fmt; + tpg->av.prepare_firmware_stream_cfg = + ipu_isys_prepare_firmware_stream_cfg_default; + tpg->av.packed = true; + tpg->av.line_header_length = IPU_ISYS_CSI2_LONG_PACKET_HEADER_SIZE; + tpg->av.line_footer_length = IPU_ISYS_CSI2_LONG_PACKET_FOOTER_SIZE; + tpg->av.aq.buf_prepare = ipu_isys_buf_prepare; + tpg->av.aq.fill_frame_buff_set_pin = + ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set_pin; + tpg->av.aq.link_fmt_validate = ipu_isys_link_fmt_validate; + tpg->av.aq.vbq.buf_struct_size = sizeof(struct ipu_isys_video_buffer); + + rval = ipu_isys_video_init(&tpg->av, &tpg->asd.sd.entity, + TPG_PAD_SOURCE, MEDIA_PAD_FL_SINK, 0); + if (rval) { + dev_info(&isys->adev->dev, "can't init video node\n"); + goto fail; + } + + return 0; + +fail: + ipu_isys_tpg_cleanup(tpg); + + return rval; +} diff --git a/drivers/media/pci/intel/ipu-isys-tpg.h b/drivers/media/pci/intel/ipu-isys-tpg.h new file mode 100644 index 0000000000000..29ce5002219ff --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-tpg.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_ISYS_TPG_H +#define IPU_ISYS_TPG_H + +#include +#include +#include + +#include "ipu-isys-subdev.h" +#include "ipu-isys-video.h" +#include "ipu-isys-queue.h" + +struct ipu_isys_tpg_pdata; +struct ipu_isys; + +#define TPG_PAD_SOURCE 0 +#define NR_OF_TPG_PADS 1 +#define NR_OF_TPG_SOURCE_PADS 1 +#define NR_OF_TPG_SINK_PADS 0 +#define NR_OF_TPG_STREAMS 1 + +/* + * PPC is 4 pixels for clock for RAW8, RAW10 and RAW12. + * Source: FW validation test code. + */ +#define MIPI_GEN_PPC 4 + +#define MIPI_GEN_REG_COM_ENABLE 0x0 +#define MIPI_GEN_REG_COM_DTYPE 0x4 +/* RAW8, RAW10 or RAW12 */ +#define MIPI_GEN_COM_DTYPE_RAW(n) (((n) - 8) / 2) +#define MIPI_GEN_REG_COM_VTYPE 0x8 +#define MIPI_GEN_REG_COM_VCHAN 0xc +#define MIPI_GEN_REG_COM_WCOUNT 0x10 +#define MIPI_GEN_REG_PRBS_RSTVAL0 0x14 +#define MIPI_GEN_REG_PRBS_RSTVAL1 0x18 +#define MIPI_GEN_REG_SYNG_FREE_RUN 0x1c +#define MIPI_GEN_REG_SYNG_PAUSE 0x20 +#define MIPI_GEN_REG_SYNG_NOF_FRAMES 0x24 +#define MIPI_GEN_REG_SYNG_NOF_PIXELS 0x28 +#define MIPI_GEN_REG_SYNG_NOF_LINES 0x2c +#define MIPI_GEN_REG_SYNG_HBLANK_CYC 0x30 +#define MIPI_GEN_REG_SYNG_VBLANK_CYC 0x34 +#define MIPI_GEN_REG_SYNG_STAT_HCNT 0x38 +#define MIPI_GEN_REG_SYNG_STAT_VCNT 0x3c +#define MIPI_GEN_REG_SYNG_STAT_FCNT 0x40 +#define MIPI_GEN_REG_SYNG_STAT_DONE 0x44 +#define MIPI_GEN_REG_TPG_MODE 0x48 +#define MIPI_GEN_REG_TPG_HCNT_MASK 0x4c +#define MIPI_GEN_REG_TPG_VCNT_MASK 0x50 +#define MIPI_GEN_REG_TPG_XYCNT_MASK 0x54 +#define MIPI_GEN_REG_TPG_HCNT_DELTA 0x58 +#define MIPI_GEN_REG_TPG_VCNT_DELTA 0x5c +#define MIPI_GEN_REG_TPG_R1 0x60 +#define MIPI_GEN_REG_TPG_G1 0x64 +#define MIPI_GEN_REG_TPG_B1 0x68 +#define MIPI_GEN_REG_TPG_R2 0x6c +#define MIPI_GEN_REG_TPG_G2 0x70 +#define MIPI_GEN_REG_TPG_B2 0x74 + +/* + * struct ipu_isys_tpg + * + * @nlanes: number of lanes in the receiver + */ +struct ipu_isys_tpg { + struct ipu_isys_tpg_pdata *pdata; + struct ipu_isys *isys; + struct ipu_isys_subdev asd; + struct ipu_isys_video av; + + void __iomem *base; + void __iomem *sel; + unsigned int index; + int streaming; + + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *llp; + struct v4l2_ctrl *fll; + struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *store_csi2_header; +}; + +#define to_ipu_isys_tpg(sd) \ + container_of(to_ipu_isys_subdev(sd), \ + struct ipu_isys_tpg, asd) +int ipu_isys_tpg_init(struct ipu_isys_tpg *tpg, + struct ipu_isys *isys, + void __iomem *base, void __iomem *sel, + unsigned int index); +void ipu_isys_tpg_cleanup(struct ipu_isys_tpg *tpg); +int tpg_set_stream(struct v4l2_subdev *sd, int enable); + +#endif /* IPU_ISYS_TPG_H */ diff --git a/drivers/media/pci/intel/ipu-isys-video.c b/drivers/media/pci/intel/ipu-isys-video.c new file mode 100644 index 0000000000000..51a8a80296a5b --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-video.c @@ -0,0 +1,2486 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "ipu.h" +#include "ipu-bus.h" +#include "ipu-cpd.h" +#include "ipu-isys.h" +#include "ipu-isys-csi2.h" +#include "ipu-isys-video.h" +#include "ipu-platform.h" +#include "ipu-platform-regs.h" +#include "ipu-platform-buttress-regs.h" +#include "ipu-trace.h" +#include "ipu-fw-isys.h" +#include "ipu-fw-com.h" + +static unsigned int num_stream_support = IPU_ISYS_NUM_STREAMS; +module_param(num_stream_support, uint, 0660); +MODULE_PARM_DESC(num_stream_support, "IPU project support number of stream"); + +static bool use_stream_stop; +module_param(use_stream_stop, bool, 0660); +MODULE_PARM_DESC(use_stream_stop, "Use STOP command if running in CSI capture mode"); + +static void ipu_isys_log_csi2_state(struct device *dev, + struct ipu_isys_pipeline *ip, + const char *tag) +{ + struct ipu_isys_csi2 *csi2 = ip->csi2; + + if (!csi2) + return; + + dev_dbg(dev, + "%s: csi2 index=%u source=%u stream_handle=%d vc=%u stream_id=%u stream_count=%u remote_streams=%u receiver_errors=0x%x in_frame={%u,%u,%u,%u} wait_for_sync={%u,%u,%u,%u}\n", + tag, csi2->index, ip->source, ip->stream_handle, ip->vc, + ip->stream_id, csi2->stream_count, csi2->remote_streams, + csi2->receiver_errors, csi2->in_frame[0], csi2->in_frame[1], + csi2->in_frame[2], csi2->in_frame[3], csi2->wait_for_sync[0], + csi2->wait_for_sync[1], csi2->wait_for_sync[2], + csi2->wait_for_sync[3]); +} + +const struct ipu_isys_pixelformat ipu_isys_pfmts[] = { + {V4L2_PIX_FMT_Y10, 10, 10, 0, MEDIA_BUS_FMT_Y10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW10}, + /* YUV vector format */ + {V4L2_PIX_FMT_YUYV420_V32, 24, 24, 0, MEDIA_BUS_FMT_YUYV12_1X24, + IPU_FW_ISYS_FRAME_FORMAT_YUV420_16}, + /* Bayer formats. */ + {V4L2_PIX_FMT_SBGGR12, 16, 12, 0, MEDIA_BUS_FMT_SBGGR12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGBRG12, 16, 12, 0, MEDIA_BUS_FMT_SGBRG12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGRBG12, 16, 12, 0, MEDIA_BUS_FMT_SGRBG12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SRGGB12, 16, 12, 0, MEDIA_BUS_FMT_SRGGB12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SBGGR10, 16, 10, 0, MEDIA_BUS_FMT_SBGGR10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGBRG10, 16, 10, 0, MEDIA_BUS_FMT_SGBRG10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGRBG10, 16, 10, 0, MEDIA_BUS_FMT_SGRBG10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SRGGB10, 16, 10, 0, MEDIA_BUS_FMT_SRGGB10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SBGGR8, 8, 8, 0, MEDIA_BUS_FMT_SBGGR8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SGBRG8, 8, 8, 0, MEDIA_BUS_FMT_SGBRG8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SGRBG8, 8, 8, 0, MEDIA_BUS_FMT_SGRBG8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SRGGB8, 8, 8, 0, MEDIA_BUS_FMT_SRGGB8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + /* Raw bayer vector formats. */ + {V4L2_PIX_FMT_SBGGR14V32, 16, 14, 0, MEDIA_BUS_FMT_SBGGR14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGBRG14V32, 16, 14, 0, MEDIA_BUS_FMT_SGBRG14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGRBG14V32, 16, 14, 0, MEDIA_BUS_FMT_SGRBG14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SRGGB14V32, 16, 14, 0, MEDIA_BUS_FMT_SRGGB14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SBGGR12V32, 16, 12, 0, MEDIA_BUS_FMT_SBGGR12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGBRG12V32, 16, 12, 0, MEDIA_BUS_FMT_SGBRG12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGRBG12V32, 16, 12, 0, MEDIA_BUS_FMT_SGRBG12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SRGGB12V32, 16, 12, 0, MEDIA_BUS_FMT_SRGGB12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SBGGR10V32, 16, 10, 0, MEDIA_BUS_FMT_SBGGR10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGBRG10V32, 16, 10, 0, MEDIA_BUS_FMT_SGBRG10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGRBG10V32, 16, 10, 0, MEDIA_BUS_FMT_SGRBG10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SRGGB10V32, 16, 10, 0, MEDIA_BUS_FMT_SRGGB10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SBGGR8_16V32, 16, 8, 0, MEDIA_BUS_FMT_SBGGR8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGBRG8_16V32, 16, 8, 0, MEDIA_BUS_FMT_SGBRG8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGRBG8_16V32, 16, 8, 0, MEDIA_BUS_FMT_SGRBG8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SRGGB8_16V32, 16, 8, 0, MEDIA_BUS_FMT_SRGGB8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_FMT_IPU_ISYS_META, 8, 8, 0, MEDIA_BUS_FMT_FIXED, + IPU_FW_ISYS_MIPI_DATA_TYPE_EMBEDDED}, + {} +}; + +const struct ipu_isys_pixelformat ipu_isys_pfmts_be_soc[] = { + {V4L2_PIX_FMT_Y10, 16, 10, 0, MEDIA_BUS_FMT_Y10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_UYVY, 16, 16, 0, MEDIA_BUS_FMT_UYVY8_1X16, + IPU_FW_ISYS_FRAME_FORMAT_UYVY}, + {V4L2_PIX_FMT_YUYV, 16, 16, 0, MEDIA_BUS_FMT_YUYV8_1X16, + IPU_FW_ISYS_FRAME_FORMAT_YUYV}, + {V4L2_PIX_FMT_NV16, 16, 16, 8, MEDIA_BUS_FMT_UYVY8_1X16, + IPU_FW_ISYS_FRAME_FORMAT_NV16}, + {V4L2_PIX_FMT_YUV420, 12, 0, 8, MEDIA_BUS_FMT_UYVY8_2X8, + IPU_FW_ISYS_FRAME_FORMAT_YUV420}, + {V4L2_PIX_FMT_XRGB32, 32, 32, 0, MEDIA_BUS_FMT_RGB565_1X16, + IPU_FW_ISYS_FRAME_FORMAT_RGBA888}, + {V4L2_PIX_FMT_XBGR32, 32, 32, 0, MEDIA_BUS_FMT_RGB888_1X24, + IPU_FW_ISYS_FRAME_FORMAT_RGBA888}, + /* Raw bayer formats. */ + {V4L2_PIX_FMT_SBGGR14, 16, 14, 0, MEDIA_BUS_FMT_SBGGR14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGBRG14, 16, 14, 0, MEDIA_BUS_FMT_SGBRG14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGRBG14, 16, 14, 0, MEDIA_BUS_FMT_SGRBG14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SRGGB14, 16, 14, 0, MEDIA_BUS_FMT_SRGGB14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SBGGR12, 16, 12, 0, MEDIA_BUS_FMT_SBGGR12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGBRG12, 16, 12, 0, MEDIA_BUS_FMT_SGBRG12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGRBG12, 16, 12, 0, MEDIA_BUS_FMT_SGRBG12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SRGGB12, 16, 12, 0, MEDIA_BUS_FMT_SRGGB12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SBGGR10, 16, 10, 0, MEDIA_BUS_FMT_SBGGR10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGBRG10, 16, 10, 0, MEDIA_BUS_FMT_SGBRG10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SGRBG10, 16, 10, 0, MEDIA_BUS_FMT_SGRBG10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SRGGB10, 16, 10, 0, MEDIA_BUS_FMT_SRGGB10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW16}, + {V4L2_PIX_FMT_SBGGR8, 8, 8, 0, MEDIA_BUS_FMT_SBGGR8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SGBRG8, 8, 8, 0, MEDIA_BUS_FMT_SGBRG8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SGRBG8, 8, 8, 0, MEDIA_BUS_FMT_SGRBG8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SRGGB8, 8, 8, 0, MEDIA_BUS_FMT_SRGGB8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + {} +}; + +const struct ipu_isys_pixelformat ipu_isys_pfmts_packed[] = { + {V4L2_PIX_FMT_Y10, 10, 10, 0, MEDIA_BUS_FMT_Y10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW10}, + {V4L2_PIX_FMT_Y210, 20, 20, 0, MEDIA_BUS_FMT_YUYV10_1X20, + IPU_FW_ISYS_FRAME_FORMAT_YUYV}, + {V4L2_PIX_FMT_UYVY, 16, 16, 0, MEDIA_BUS_FMT_UYVY8_1X16, + IPU_FW_ISYS_FRAME_FORMAT_UYVY}, + {V4L2_PIX_FMT_YUYV, 16, 16, 0, MEDIA_BUS_FMT_YUYV8_1X16, + IPU_FW_ISYS_FRAME_FORMAT_YUYV}, + {V4L2_PIX_FMT_RGB565, 16, 16, 0, MEDIA_BUS_FMT_RGB565_1X16, + IPU_FW_ISYS_FRAME_FORMAT_RGB565}, + {V4L2_PIX_FMT_BGR24, 24, 24, 0, MEDIA_BUS_FMT_RGB888_1X24, + IPU_FW_ISYS_FRAME_FORMAT_RGBA888}, +#ifndef V4L2_PIX_FMT_SBGGR12P + {V4L2_PIX_FMT_SBGGR12, 12, 12, 0, MEDIA_BUS_FMT_SBGGR12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SGBRG12, 12, 12, 0, MEDIA_BUS_FMT_SGBRG12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SGRBG12, 12, 12, 0, MEDIA_BUS_FMT_SGRBG12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SRGGB12, 12, 12, 0, MEDIA_BUS_FMT_SRGGB12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SBGGR14, 14, 14, 0, MEDIA_BUS_FMT_SBGGR14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW14}, + {V4L2_PIX_FMT_SGBRG14, 14, 14, 0, MEDIA_BUS_FMT_SGBRG14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW14}, + {V4L2_PIX_FMT_SGRBG14, 14, 14, 0, MEDIA_BUS_FMT_SGRBG14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW14}, + {V4L2_PIX_FMT_SRGGB14, 14, 14, 0, MEDIA_BUS_FMT_SRGGB14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW14}, +#else /* V4L2_PIX_FMT_SBGGR12P */ + {V4L2_PIX_FMT_SBGGR12P, 12, 12, 0, MEDIA_BUS_FMT_SBGGR12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SGBRG12P, 12, 12, 0, MEDIA_BUS_FMT_SGBRG12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SGRBG12P, 12, 12, 0, MEDIA_BUS_FMT_SGRBG12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SRGGB12P, 12, 12, 0, MEDIA_BUS_FMT_SRGGB12_1X12, + IPU_FW_ISYS_FRAME_FORMAT_RAW12}, + {V4L2_PIX_FMT_SBGGR14P, 14, 14, 0, MEDIA_BUS_FMT_SBGGR14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW14}, + {V4L2_PIX_FMT_SGBRG14P, 14, 14, 0, MEDIA_BUS_FMT_SGBRG14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW14}, + {V4L2_PIX_FMT_SGRBG14P, 14, 14, 0, MEDIA_BUS_FMT_SGRBG14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW14}, + {V4L2_PIX_FMT_SRGGB14P, 14, 14, 0, MEDIA_BUS_FMT_SRGGB14_1X14, + IPU_FW_ISYS_FRAME_FORMAT_RAW14}, +#endif /* V4L2_PIX_FMT_SBGGR12P */ + {V4L2_PIX_FMT_SBGGR10P, 10, 10, 0, MEDIA_BUS_FMT_SBGGR10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW10}, + {V4L2_PIX_FMT_SGBRG10P, 10, 10, 0, MEDIA_BUS_FMT_SGBRG10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW10}, + {V4L2_PIX_FMT_SGRBG10P, 10, 10, 0, MEDIA_BUS_FMT_SGRBG10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW10}, + {V4L2_PIX_FMT_SRGGB10P, 10, 10, 0, MEDIA_BUS_FMT_SRGGB10_1X10, + IPU_FW_ISYS_FRAME_FORMAT_RAW10}, + {V4L2_PIX_FMT_SBGGR8, 8, 8, 0, MEDIA_BUS_FMT_SBGGR8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SGBRG8, 8, 8, 0, MEDIA_BUS_FMT_SGBRG8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SGRBG8, 8, 8, 0, MEDIA_BUS_FMT_SGRBG8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + {V4L2_PIX_FMT_SRGGB8, 8, 8, 0, MEDIA_BUS_FMT_SRGGB8_1X8, + IPU_FW_ISYS_FRAME_FORMAT_RAW8}, + {} +}; + +static int video_open(struct file *file) +{ + struct ipu_isys_video *av = video_drvdata(file); + struct ipu_isys *isys = av->isys; + struct ipu_bus_device *adev = to_ipu_bus_device(&isys->adev->dev); + struct ipu_device *isp = adev->isp; + int rval; + int retries = 3; + + mutex_lock(&isys->mutex); + + if (isys->reset_needed || isp->flr_done) { + mutex_unlock(&isys->mutex); + dev_warn(&isys->adev->dev, "isys power cycle required\n"); + return -EIO; + } + mutex_unlock(&isys->mutex); + + do { + rval = ipu_buttress_authenticate(isp); + if (rval == 0) + break; + + dev_warn(&isys->adev->dev, + "FW authentication failed, retrying... (%d attempts left)\n", + retries); + + /* delay between retries to allow hardware to settle */ + usleep_range(1000, 2000); + + } while (retries-- > 0); + + if (rval) { + dev_err(&isys->adev->dev, "FW authentication failed\n"); + return rval; + } + + rval = pm_runtime_get_sync(&isys->adev->dev); + if (rval < 0) { + pm_runtime_put_noidle(&isys->adev->dev); + return rval; + } + + rval = v4l2_fh_open(file); + if (rval) + goto out_power_down; + + rval = v4l2_pipeline_pm_get(&av->vdev.entity); + if (rval) + goto out_v4l2_fh_release; + + mutex_lock(&isys->mutex); + + if (isys->video_opened++) { + /* Already open */ + mutex_unlock(&isys->mutex); + return 0; + } + + ipu_configure_spc(adev->isp, + &isys->pdata->ipdata->hw_variant, + IPU_CPD_PKG_DIR_ISYS_SERVER_IDX, + isys->pdata->base, isys->pkg_dir, + isys->pkg_dir_dma_addr); + + /* + * Buffers could have been left to wrong queue at last closure. + * Move them now back to empty buffer queue. + */ + ipu_cleanup_fw_msg_bufs(isys); + + if (isys->fwcom) { + /* + * Something went wrong in previous shutdown. As we are now + * restarting isys we can safely delete old context. + */ + dev_err(&isys->adev->dev, "Clearing old context\n"); + ipu_fw_isys_cleanup(isys); + } + + + rval = ipu_fw_isys_init(av->isys, num_stream_support); + if (rval < 0) + goto out_lib_init; + + mutex_unlock(&isys->mutex); + + return 0; + +out_lib_init: + isys->video_opened--; + mutex_unlock(&isys->mutex); + v4l2_pipeline_pm_put(&av->vdev.entity); + +out_v4l2_fh_release: + v4l2_fh_release(file); +out_power_down: + pm_runtime_put(&isys->adev->dev); + + return rval; +} + +static int video_release(struct file *file) +{ + struct ipu_isys_video *av = video_drvdata(file); + int ret = 0; + + vb2_fop_release(file); + + mutex_lock(&av->isys->mutex); + + if (!--av->isys->video_opened) { + ipu_fw_isys_close(av->isys); + if (av->isys->fwcom) { + av->isys->reset_needed = true; + ret = -EIO; + } + } + + mutex_unlock(&av->isys->mutex); + + v4l2_pipeline_pm_put(&av->vdev.entity); + + if (av->isys->reset_needed) + pm_runtime_put_sync(&av->isys->adev->dev); + else + pm_runtime_put(&av->isys->adev->dev); + + return ret; +} + +const struct ipu_isys_pixelformat * +ipu_isys_get_isys_format(u32 pixelformat, u32 type) +{ + const struct ipu_isys_pixelformat *default_pfmt = NULL; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(ipu_isys_pfmts); i++) { + const struct ipu_isys_pixelformat *pfmt = &ipu_isys_pfmts[i]; + + if (type && ((!pfmt->is_meta && + type != V4L2_BUF_TYPE_VIDEO_CAPTURE) || + (pfmt->is_meta && + type != V4L2_BUF_TYPE_META_CAPTURE))) + continue; + + if (!default_pfmt) + default_pfmt = pfmt; + + if (pfmt->pixelformat != pixelformat) + continue; + + return pfmt; + } + + return default_pfmt; +} + +static struct media_pad *other_pad(struct media_pad *pad) +{ + struct media_link *link; + + list_for_each_entry(link, &pad->entity->links, list) { + if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) + != MEDIA_LNK_FL_DATA_LINK) + continue; + + return link->source == pad ? link->sink : link->source; + } + + WARN_ON(1); + return NULL; +} + +const struct ipu_isys_pixelformat *ipu_isys_get_pixelformat( + struct ipu_isys_video *av, + u32 pixelformat) +{ + struct media_pad *pad = other_pad(&av->vdev.entity.pads[0]); + struct v4l2_subdev *sd; + const u32 *supported_codes; + const struct ipu_isys_pixelformat *pfmt; + + if (!pad || !pad->entity) { + WARN_ON(1); + return NULL; + } + + sd = media_entity_to_v4l2_subdev(pad->entity); + supported_codes = to_ipu_isys_subdev(sd)->supported_codes[pad->index]; + + for (pfmt = av->pfmts; pfmt->bpp; pfmt++) { + unsigned int i; + + if (pfmt->pixelformat != pixelformat) + continue; + + for (i = 0; supported_codes[i]; i++) { + if (pfmt->code == supported_codes[i]) + return pfmt; + } + } + + /* Not found. Get the default, i.e. the first defined one. */ + for (pfmt = av->pfmts; pfmt->bpp; pfmt++) { + if (pfmt->code == *supported_codes) + return pfmt; + } + + WARN_ON(1); + return NULL; +} + +int ipu_isys_vidioc_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) +{ + struct ipu_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)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", + av->isys->media_dev.bus_info); + + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE + | V4L2_CAP_VIDEO_CAPTURE_MPLANE + | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING + | V4L2_CAP_DEVICE_CAPS | V4L2_CAP_META_CAPTURE | + V4L2_CAP_IO_MC; + + cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_CAPTURE | + V4L2_CAP_IO_MC; + + switch (av->aq.vbq.type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE_MPLANE; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + cap->device_caps |= V4L2_CAP_VIDEO_OUTPUT_MPLANE; + break; + default: + WARN_ON(1); + } + + return 0; +} + +int ipu_isys_vidioc_enum_fmt(struct file *file, void *fh, + struct v4l2_fmtdesc *f) +{ + struct ipu_isys_video *av = video_drvdata(file); + const struct ipu_isys_pixelformat *pfmt; + unsigned int num_found; + + for (pfmt = av->pfmts, num_found = 0; pfmt->bpp; pfmt++) { + if ((pfmt->is_meta && + f->type != V4L2_BUF_TYPE_META_CAPTURE) || + (!pfmt->is_meta && + f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) + continue; + + if (f->mbus_code && f->mbus_code != pfmt->code) + continue; + + if (num_found < f->index) { + num_found++; + continue; + } + + f->flags = 0; + f->pixelformat = pfmt->pixelformat; + + return 0; + } + + return -EINVAL; +} + +static int ipu_isys_vidioc_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + struct ipu_isys_video *av = video_drvdata(file); + const struct ipu_isys_pixelformat *pfmt; + + if (fsize->index > 0) + return -EINVAL; + + for (pfmt = av->pfmts; pfmt->bpp; pfmt++) { + if (fsize->pixel_format != pfmt->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 vidioc_g_fmt_vid_cap_mplane(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct ipu_isys_video *av = video_drvdata(file); + + fmt->fmt.pix_mp = av->mpix; + + return 0; +} + +const struct ipu_isys_pixelformat * +ipu_isys_video_try_fmt_vid_mplane_default(struct ipu_isys_video *av, + struct v4l2_pix_format_mplane *mpix) +{ + return ipu_isys_video_try_fmt_vid_mplane(av, mpix, 0); +} + +const struct ipu_isys_pixelformat *ipu_isys_video_try_fmt_vid_mplane( + struct ipu_isys_video *av, + struct v4l2_pix_format_mplane *mpix, + int store_csi2_header) +{ + const struct ipu_isys_pixelformat *pfmt = + ipu_isys_get_pixelformat(av, mpix->pixelformat); + + if (!pfmt) + return NULL; + mpix->pixelformat = pfmt->pixelformat; + mpix->num_planes = 1; + + mpix->width = clamp(mpix->width, IPU_ISYS_MIN_WIDTH, + IPU_ISYS_MAX_WIDTH); + mpix->height = clamp(mpix->height, IPU_ISYS_MIN_HEIGHT, + IPU_ISYS_MAX_HEIGHT); + + if (!av->packed) + mpix->plane_fmt[0].bytesperline = + mpix->width * DIV_ROUND_UP(pfmt->bpp_planar ? + pfmt->bpp_planar : pfmt->bpp, + BITS_PER_BYTE); + else if (store_csi2_header) + mpix->plane_fmt[0].bytesperline = + DIV_ROUND_UP(av->line_header_length + + av->line_footer_length + + (unsigned int)mpix->width * pfmt->bpp, + BITS_PER_BYTE); + else + mpix->plane_fmt[0].bytesperline = + DIV_ROUND_UP((unsigned int)mpix->width * pfmt->bpp, + BITS_PER_BYTE); + + mpix->plane_fmt[0].bytesperline = ALIGN(mpix->plane_fmt[0].bytesperline, + av->isys->line_align); + if (pfmt->bpp_planar) + mpix->plane_fmt[0].bytesperline = + mpix->plane_fmt[0].bytesperline * + pfmt->bpp / pfmt->bpp_planar; + /* + * (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 limition is the GDA allocation unit size. For low + * resolution it gives a bigger number. Use larger one to avoid + * memory corruption. + */ + mpix->plane_fmt[0].sizeimage = + max(max(mpix->plane_fmt[0].sizeimage, + mpix->plane_fmt[0].bytesperline * mpix->height + + max(mpix->plane_fmt[0].bytesperline, + av->isys->pdata->ipdata->isys_dma_overshoot)), 1U); + + memset(mpix->plane_fmt[0].reserved, 0, + sizeof(mpix->plane_fmt[0].reserved)); + + if (mpix->field == V4L2_FIELD_ANY) + mpix->field = V4L2_FIELD_NONE; + /* Use defaults */ + mpix->colorspace = V4L2_COLORSPACE_RAW; + mpix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + mpix->quantization = V4L2_QUANTIZATION_DEFAULT; + mpix->xfer_func = V4L2_XFER_FUNC_DEFAULT; + + return pfmt; +} + +static int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct ipu_isys_video *av = video_drvdata(file); + + if (av->aq.vbq.streaming) + return -EBUSY; + + av->pfmt = av->try_fmt_vid_mplane(av, &f->fmt.pix_mp); + av->mpix = f->fmt.pix_mp; + + return 0; +} + +static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct ipu_isys_video *av = video_drvdata(file); + + av->try_fmt_vid_mplane(av, &f->fmt.pix_mp); + + return 0; +} + +static void fmt_sp_to_mp(struct v4l2_pix_format_mplane *mpix, + struct v4l2_pix_format *pix) +{ + mpix->width = pix->width; + mpix->height = pix->height; + mpix->pixelformat = pix->pixelformat; + mpix->field = pix->field; + mpix->num_planes = 1; + mpix->plane_fmt[0].bytesperline = pix->bytesperline; + mpix->plane_fmt[0].sizeimage = pix->sizeimage; + mpix->flags = pix->flags; +} + +static void fmt_mp_to_sp(struct v4l2_pix_format *pix, + struct v4l2_pix_format_mplane *mpix) +{ + pix->width = mpix->width; + pix->height = mpix->height; + pix->pixelformat = mpix->pixelformat; + pix->field = mpix->field; + WARN_ON(mpix->num_planes != 1); + pix->bytesperline = mpix->plane_fmt[0].bytesperline; + pix->sizeimage = mpix->plane_fmt[0].sizeimage; + pix->flags = mpix->flags; + pix->colorspace = mpix->colorspace; + pix->ycbcr_enc = mpix->ycbcr_enc; + pix->quantization = mpix->quantization; + pix->xfer_func = mpix->xfer_func; +} + +static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct ipu_isys_video *av = video_drvdata(file); + + fmt_mp_to_sp(&f->fmt.pix, &av->mpix); + + return 0; +} + +static int vidioc_s_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct ipu_isys_video *av = video_drvdata(file); + struct v4l2_pix_format_mplane mpix = { 0 }; + + if (av->aq.vbq.streaming) + return -EBUSY; + + fmt_sp_to_mp(&mpix, &f->fmt.pix); + + av->pfmt = av->try_fmt_vid_mplane(av, &mpix); + av->mpix = mpix; + + fmt_mp_to_sp(&f->fmt.pix, &mpix); + + return 0; +} + +static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct ipu_isys_video *av = video_drvdata(file); + struct v4l2_pix_format_mplane mpix = { 0 }; + + fmt_sp_to_mp(&mpix, &f->fmt.pix); + + av->try_fmt_vid_mplane(av, &mpix); + + fmt_mp_to_sp(&f->fmt.pix, &mpix); + + return 0; +} + +static long ipu_isys_vidioc_private(struct file *file, void *fh, + bool valid_prio, unsigned int cmd, + void *arg) +{ + struct ipu_isys_video *av = video_drvdata(file); + int ret = 0; + + switch (cmd) { + case VIDIOC_IPU_GET_DRIVER_VERSION: + *(u32 *)arg = IPU_DRIVER_VERSION; + break; + + default: + dev_dbg(&av->isys->adev->dev, "unsupported private ioctl %x\n", + cmd); + } + + return ret; +} + +static int vidioc_enum_input(struct file *file, void *fh, + struct v4l2_input *input) +{ + if (input->index > 0) + return -EINVAL; + strscpy(input->name, "camera", sizeof(input->name)); + input->type = V4L2_INPUT_TYPE_CAMERA; + + return 0; +} + +static int vidioc_g_input(struct file *file, void *fh, unsigned int *input) +{ + *input = 0; + + return 0; +} + +static int vidioc_s_input(struct file *file, void *fh, unsigned int input) +{ + return input == 0 ? 0 : -EINVAL; +} + +static int link_validate(struct media_link *link) +{ + struct ipu_isys_video *av = + container_of(link->sink, struct ipu_isys_video, pad); + struct device *dev = &av->isys->adev->dev; + struct v4l2_subdev_state *s_state; + struct v4l2_subdev *s_sd; + struct v4l2_mbus_framefmt *s_fmt; + 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); + + 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 = ipu_isys_get_src_stream_by_src_pad(s_sd, s_pad->index); + + s_state = v4l2_subdev_get_unlocked_active_state(s_sd); + if (s_state) { + v4l2_subdev_lock_state(s_state); + s_fmt = v4l2_subdev_state_get_format(s_state, s_pad->index, + s_stream); + v4l2_subdev_unlock_state(s_state); + } else { + s_fmt = NULL; + } + + if (!s_fmt) { + /* + * The subdev has no V4L2 active state (IPU4 manages formats + * internally), or the state accessor returned NULL for a + * stream-aware subdev without routing. Fall back to the + * subdev's internal active format. + */ + struct ipu_isys_subdev *asd = to_ipu_isys_subdev(s_sd); + + dev_dbg(dev, "using internal format for pad %u stream %u\n", + s_pad->index, s_stream); + s_fmt = &asd->ffmt[s_pad->index][s_stream]; + } + + { + const struct ipu_isys_pixelformat *pfmt; + u32 pixfmt = ipu_isys_get_format(av); + + code = 0; + for (pfmt = av->pfmts; pfmt->bpp; pfmt++) { + if (pfmt->pixelformat == pixfmt) { + code = pfmt->code; + break; + } + } + if (!code) + code = ipu_isys_get_isys_format(pixfmt, 0)->code; + } + + if (s_fmt->width != ipu_isys_get_frame_width(av) || + s_fmt->height != ipu_isys_get_frame_height(av) || + 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, + ipu_isys_get_frame_width(av), + ipu_isys_get_frame_height(av), code); + return ret; + } + + return 0; +} + +static void get_stream_opened(struct ipu_isys_video *av) +{ + unsigned long flags; + + spin_lock_irqsave(&av->isys->lock, flags); + av->isys->stream_opened++; + spin_unlock_irqrestore(&av->isys->lock, flags); +} + +static void put_stream_opened(struct ipu_isys_video *av) +{ + unsigned long flags; + + spin_lock_irqsave(&av->isys->lock, flags); + av->isys->stream_opened--; + spin_unlock_irqrestore(&av->isys->lock, flags); +} + +static int get_stream_handle(struct ipu_isys_video *av) +{ + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + unsigned int stream_handle; + unsigned long flags; + + spin_lock_irqsave(&av->isys->lock, flags); + for (stream_handle = 0; + stream_handle < IPU_ISYS_MAX_STREAMS; stream_handle++) + if (!av->isys->pipes[stream_handle]) + break; + if (stream_handle == IPU_ISYS_MAX_STREAMS) { + spin_unlock_irqrestore(&av->isys->lock, flags); + return -EBUSY; + } + av->isys->pipes[stream_handle] = ip; + ip->stream_handle = stream_handle; + spin_unlock_irqrestore(&av->isys->lock, flags); + return 0; +} + +static void put_stream_handle(struct ipu_isys_video *av) +{ + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + unsigned long flags; + + spin_lock_irqsave(&av->isys->lock, flags); + av->isys->pipes[ip->stream_handle] = NULL; + ip->stream_handle = -1; + spin_unlock_irqrestore(&av->isys->lock, flags); +} + +static int get_external_facing_format(struct ipu_isys_pipeline *ip, + struct v4l2_subdev_format *format) +{ + struct ipu_isys_video *av = container_of(ip, struct ipu_isys_video, ip); + struct v4l2_subdev *sd; + struct media_pad *external_facing; + + if (!ip->external->entity) { + WARN_ON(1); + return -ENODEV; + } + sd = media_entity_to_v4l2_subdev(ip->external->entity); + external_facing = (strncmp(sd->name, IPU_ISYS_ENTITY_PREFIX, + strlen(IPU_ISYS_ENTITY_PREFIX)) == 0) ? + ip->external : media_pad_remote_pad_first(ip->external); + if (WARN_ON(!external_facing)) { + dev_warn(&av->isys->adev->dev, + "no external facing pad --- driver bug?\n"); + return -EINVAL; + } + + format->which = V4L2_SUBDEV_FORMAT_ACTIVE; + format->pad = 0; + format->stream = ip->stream_id; + sd = media_entity_to_v4l2_subdev(external_facing->entity); + + return v4l2_subdev_call(sd, pad, get_fmt, NULL, format); +} + +static void short_packet_queue_destroy(struct ipu_isys_pipeline *ip) +{ + struct ipu_isys_video *av = container_of(ip, struct ipu_isys_video, ip); + unsigned long attrs; + unsigned int i; + + if (!ip->short_packet_bufs) + return; + for (i = 0; i < IPU_ISYS_SHORT_PACKET_BUFFER_NUM; i++) { + if (ip->short_packet_bufs[i].buffer) + dma_free_attrs(&av->isys->adev->dev, + ip->short_packet_buffer_size, + ip->short_packet_bufs[i].buffer, + ip->short_packet_bufs[i].dma_addr, + attrs + ); + } + kfree(ip->short_packet_bufs); + ip->short_packet_bufs = NULL; +} + +static int short_packet_queue_setup(struct ipu_isys_pipeline *ip) +{ + struct ipu_isys_video *av = container_of(ip, struct ipu_isys_video, ip); + struct v4l2_subdev_format source_fmt = { 0 }; + unsigned long attrs; + unsigned int i; + int rval; + size_t buf_size; + + INIT_LIST_HEAD(&ip->pending_interlaced_bufs); + ip->cur_field = V4L2_FIELD_TOP; + + if (ip->isys->short_packet_source == IPU_ISYS_SHORT_PACKET_FROM_TUNIT) { + ip->short_packet_trace_index = 0; + return 0; + } + + rval = get_external_facing_format(ip, &source_fmt); + if (rval) + return rval; + buf_size = IPU_ISYS_SHORT_PACKET_BUF_SIZE(source_fmt.format.height); + ip->short_packet_buffer_size = buf_size; + ip->num_short_packet_lines = + IPU_ISYS_SHORT_PACKET_PKT_LINES(source_fmt.format.height); + + /* Initialize short packet queue. */ + INIT_LIST_HEAD(&ip->short_packet_incoming); + INIT_LIST_HEAD(&ip->short_packet_active); + + ip->short_packet_bufs = + kzalloc(sizeof(struct ipu_isys_private_buffer) * + IPU_ISYS_SHORT_PACKET_BUFFER_NUM, GFP_KERNEL); + if (!ip->short_packet_bufs) + return -ENOMEM; + + for (i = 0; i < IPU_ISYS_SHORT_PACKET_BUFFER_NUM; i++) { + struct ipu_isys_private_buffer *buf = &ip->short_packet_bufs[i]; + + buf->index = (unsigned int)i; + buf->ip = ip; + buf->ib.type = IPU_ISYS_SHORT_PACKET_BUFFER; + buf->bytesused = buf_size; + buf->buffer = dma_alloc_attrs(&av->isys->adev->dev, buf_size, + &buf->dma_addr, GFP_KERNEL, + attrs + ); + if (!buf->buffer) { + short_packet_queue_destroy(ip); + return -ENOMEM; + } + list_add(&buf->ib.head, &ip->short_packet_incoming); + } + + return 0; +} + +static void csi_short_packet_prepare_firmware_stream_cfg( + struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_stream_cfg_data_abi *cfg) +{ + int input_pin = cfg->nof_input_pins++; + int output_pin = cfg->nof_output_pins++; + struct ipu_fw_isys_input_pin_info_abi *input_info = + &cfg->input_pins[input_pin]; + struct ipu_fw_isys_output_pin_info_abi *output_info = + &cfg->output_pins[output_pin]; + + /* + * Setting dt as IPU_ISYS_SHORT_PACKET_GENERAL_DT will cause + * MIPI receiver to receive all MIPI short packets. + */ + input_info->dt = IPU_ISYS_SHORT_PACKET_GENERAL_DT; + input_info->input_res.width = IPU_ISYS_SHORT_PACKET_WIDTH; + input_info->input_res.height = ip->num_short_packet_lines; + + ip->output_pins[output_pin].pin_ready = + ipu_isys_queue_short_packet_ready; + ip->output_pins[output_pin].aq = NULL; + ip->short_packet_output_pin = output_pin; + + output_info->input_pin_id = input_pin; + output_info->output_res.width = IPU_ISYS_SHORT_PACKET_WIDTH; + output_info->output_res.height = ip->num_short_packet_lines; + output_info->stride = IPU_ISYS_SHORT_PACKET_WIDTH * + IPU_ISYS_SHORT_PACKET_UNITSIZE; + output_info->pt = IPU_ISYS_SHORT_PACKET_PT; + output_info->ft = IPU_ISYS_SHORT_PACKET_FT; + output_info->send_irq = 1; +#if !defined(CONFIG_VIDEO_INTEL_IPU4) && !defined(CONFIG_VIDEO_INTEL_IPU4P) + output_info->snoopable = true; + output_info->sensor_type = IPU_FW_ISYS_SENSOR_METADATA; +#endif +} + +#define MEDIA_ENTITY_MAX_PADS 512 + +static bool is_support_vc(struct media_pad *source_pad, + struct ipu_isys_pipeline *ip) +{ + struct media_pad *remote_pad = source_pad; + struct media_pad *extern_pad = NULL; + struct v4l2_subdev *sd = NULL; + struct v4l2_query_ext_ctrl qm_ctrl = { + .id = V4L2_CID_IPU_QUERY_SUB_STREAM, }; + int i; + + while ((remote_pad = + media_pad_remote_pad_first(&remote_pad->entity->pads[0]) + )) { + /* Non-subdev nodes can be safely ignored here. */ + if (!is_media_entity_v4l2_subdev(remote_pad->entity)) + continue; + + /* Don't start truly external devices quite yet. */ + if (strncmp(remote_pad->entity->name, + IPU_ISYS_CSI2_ENTITY_PREFIX, + strlen(IPU_ISYS_CSI2_ENTITY_PREFIX)) != 0) + continue; + + dev_dbg(remote_pad->entity->graph_obj.mdev->dev, + "It finds CSI2 %s\n", remote_pad->entity->name); + extern_pad = + media_pad_remote_pad_first(&remote_pad->entity->pads[0]); + if (!extern_pad) { + dev_dbg(remote_pad->entity->graph_obj.mdev->dev, + "extern_pad is null\n"); + return false; + } + sd = media_entity_to_v4l2_subdev(extern_pad->entity); + break; + } + + if (!sd) { + dev_dbg(source_pad->entity->graph_obj.mdev->dev, + "It doesn't find extern entity\n"); + return false; + } + + if (v4l2_query_ext_ctrl(sd->ctrl_handler, &qm_ctrl)) { + dev_dbg(source_pad->entity->graph_obj.mdev->dev, + "%s, No vc\n", __func__); + for (i = 0; i < CSI2_BE_SOC_SOURCE_PADS_NUM; i++) + ip->asv[i].vc = 0; + + return false; + } + + return true; +} + +static int ipu_isys_query_sensor_info(struct media_pad *source_pad, + struct ipu_isys_pipeline *ip) +{ + int i; + int ret = -ENOLINK; + bool flag = false; + unsigned int pad_id = source_pad->index; + struct media_pad *remote_pad = source_pad; + struct media_pad *extern_pad = NULL; + struct v4l2_subdev *sd = NULL; + struct v4l2_querymenu qm = {.id = V4L2_CID_IPU_QUERY_SUB_STREAM, }; + + while ((remote_pad = + media_pad_remote_pad_first(&remote_pad->entity->pads[0]) + )) { + /* Non-subdev nodes can be safely ignored here. */ + if (!is_media_entity_v4l2_subdev(remote_pad->entity)) + continue; + + /* Don't start truly external devices quite yet. */ + if (strncmp(remote_pad->entity->name, + IPU_ISYS_CSI2_ENTITY_PREFIX, + strlen(IPU_ISYS_CSI2_ENTITY_PREFIX)) != 0) + continue; + + dev_dbg(remote_pad->entity->graph_obj.mdev->dev, + "It finds CSI2 %s\n", remote_pad->entity->name); + extern_pad = + media_pad_remote_pad_first(&remote_pad->entity->pads[0]); + if (!extern_pad) { + dev_dbg(remote_pad->entity->graph_obj.mdev->dev, + "extern_pad is null\n"); + return -ENOLINK; + } + sd = media_entity_to_v4l2_subdev(extern_pad->entity); + break; + } + + if (!sd) { + dev_dbg(source_pad->entity->graph_obj.mdev->dev, + "It doesn't find extern entity\n"); + return -ENOLINK; + } + + /* Get the sub stream info and set the current pipe's vc id */ + for (i = 0; i < CSI2_BE_SOC_SOURCE_PADS_NUM; i++) { + /* + * index is sub stream id. sub stream id is + * equalto BE SOC source pad id - sink pad count + */ + qm.index = i; + ret = v4l2_querymenu(sd->ctrl_handler, &qm); + if (ret) + continue; + + /* get sub stream info by sub stream id */ + ip->asv[qm.index].substream = qm.index; + ip->asv[qm.index].code = SUB_STREAM_CODE(qm.value); + ip->asv[qm.index].height = SUB_STREAM_H(qm.value); + ip->asv[qm.index].width = SUB_STREAM_W(qm.value); + ip->asv[qm.index].dt = SUB_STREAM_DT(qm.value); + ip->asv[qm.index].vc = SUB_STREAM_VC_ID(qm.value); + if (ip->asv[qm.index].substream == + (pad_id - NR_OF_CSI2_BE_SOC_SINK_PADS)) { + ip->vc = ip->asv[qm.index].vc; + flag = true; + pr_info("The current entity vc:id:%d\n", ip->vc); + } + dev_dbg(source_pad->entity->graph_obj.mdev->dev, + "dentity vc:%d, dt:%x, substream:%d\n", + ip->vc, ip->asv[qm.index].dt, + ip->asv[qm.index].substream); + } + + if (flag) + return 0; + + return ret; +} + +void ipu_isys_prepare_firmware_stream_cfg_default( + struct ipu_isys_video *av, + struct ipu_fw_isys_stream_cfg_data_abi *cfg) +{ + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + struct ipu_isys_queue *aq = &av->aq; + struct ipu_fw_isys_output_pin_info_abi *pin_info; +#if !defined(CONFIG_VIDEO_INTEL_IPU4) && !defined(CONFIG_VIDEO_INTEL_IPU4P) + struct ipu_isys *isys = av->isys; + unsigned int type_index; +#endif + int pin = cfg->nof_output_pins++; + + aq->fw_output = pin; + ip->output_pins[pin].pin_ready = ipu_isys_queue_buf_ready; + ip->output_pins[pin].aq = aq; + + pin_info = &cfg->output_pins[pin]; + pin_info->input_pin_id = 0; + pin_info->output_res.width = av->mpix.width; + pin_info->output_res.height = av->mpix.height; + + if (!av->pfmt->bpp_planar) + pin_info->stride = av->mpix.plane_fmt[0].bytesperline; + else + pin_info->stride = ALIGN(DIV_ROUND_UP(av->mpix.width * + av->pfmt->bpp_planar, + BITS_PER_BYTE), + av->isys->line_align); + + pin_info->pt = aq->css_pin_type; + pin_info->ft = av->pfmt->css_pixelformat; + pin_info->send_irq = 1; + cfg->vc = ip->vc; + +#if !defined(CONFIG_VIDEO_INTEL_IPU4) && !defined(CONFIG_VIDEO_INTEL_IPU4P) + switch (pin_info->pt) { + /* non-snoopable sensor data to PSYS */ + case IPU_FW_ISYS_PIN_TYPE_RAW_DUAL_SOC: + case IPU_FW_ISYS_PIN_TYPE_RAW_NS: + case IPU_FW_ISYS_PIN_TYPE_RAW_S: + type_index = IPU_FW_ISYS_VC1_SENSOR_DATA; + pin_info->sensor_type = isys->sensor_types[type_index]++; + pin_info->snoopable = false; + + if (isys->sensor_types[type_index] > + IPU_FW_ISYS_VC1_SENSOR_DATA_END) + isys->sensor_types[type_index] = + IPU_FW_ISYS_VC1_SENSOR_DATA_START; + + break; + /* non-snoopable PDAF data */ + case IPU_FW_ISYS_PIN_TYPE_PAF_FF: + type_index = IPU_FW_ISYS_VC1_SENSOR_PDAF; + pin_info->sensor_type = isys->sensor_types[type_index]++; + pin_info->snoopable = false; + + if (isys->sensor_types[type_index] > + IPU_FW_ISYS_VC1_SENSOR_PDAF_END) + isys->sensor_types[type_index] = + IPU_FW_ISYS_VC1_SENSOR_PDAF_START; + + break; + /* snoopable META/Stats data to CPU */ + case IPU_FW_ISYS_PIN_TYPE_METADATA_0: + case IPU_FW_ISYS_PIN_TYPE_METADATA_1: + case IPU_FW_ISYS_PIN_TYPE_AWB_STATS: + case IPU_FW_ISYS_PIN_TYPE_AF_STATS: + case IPU_FW_ISYS_PIN_TYPE_HIST_STATS: + pin_info->sensor_type = IPU_FW_ISYS_SENSOR_METADATA; + pin_info->snoopable = true; + break; + /* snoopable sensor data to CPU */ + case IPU_FW_ISYS_PIN_TYPE_MIPI: + case IPU_FW_ISYS_PIN_TYPE_RAW_SOC: + type_index = IPU_FW_ISYS_VC0_SENSOR_DATA; + pin_info->sensor_type = isys->sensor_types[type_index]++; + pin_info->snoopable = true; + + if (isys->sensor_types[type_index] > + IPU_FW_ISYS_VC0_SENSOR_DATA_END) + isys->sensor_types[type_index] = + IPU_FW_ISYS_VC0_SENSOR_DATA_START; + + break; + default: + dev_err(&av->isys->adev->dev, + "Unknown pin type, use metadata type as default\n"); + + pin_info->sensor_type = IPU_FW_ISYS_SENSOR_METADATA; + pin_info->snoopable = true; + } +#endif +} + +static void media_pipeline_stop_for_vc(struct ipu_isys_video *av) +{ + struct media_pipeline *pipe = av->pad.pipe; + struct media_entity *entity = &av->vdev.entity; + struct media_device *mdev = entity->graph_obj.mdev; + struct media_graph graph; + int ret; + + /* + * If the following check fails, the driver has performed an + * unbalanced call to media_pipeline_stop() + */ + if (WARN_ON(!pipe)) + return; + + if (--pipe->start_count) + return; + + ret = media_graph_walk_init(&graph, mdev); + if (ret) + return; + + media_graph_walk_start(&graph, entity); + while ((entity = media_graph_walk_next(&graph))) + entity->pads[0].pipe = NULL; + + media_graph_walk_cleanup(&graph); +} + +static int media_pipeline_walk_by_vc(struct ipu_isys_video *av, + struct media_pipeline *pipe) +{ + int ret = -ENOLINK; + int i; + int entity_vc = INVALID_VC_ID; + u32 n; + struct media_entity *entity = &av->vdev.entity; + struct media_device *mdev = entity->graph_obj.mdev; + struct media_graph graph; + struct media_entity *entity_err = entity; + struct media_link *link; + struct ipu_isys_pipeline *ip = to_ipu_isys_pipeline(pipe); + struct media_pad *source_pad = media_pad_remote_pad_first(&av->pad); + unsigned int pad_id; + bool is_vc = false; + + if (!source_pad) { + dev_err(entity->graph_obj.mdev->dev, "no remote pad found\n"); + return ret; + } + + if (pipe->start_count) { + pipe->start_count++; + return 0; + } + + is_vc = is_support_vc(source_pad, ip); + if (is_vc) { + ret = ipu_isys_query_sensor_info(source_pad, ip); + if (ret) { + dev_err(entity->graph_obj.mdev->dev, + "query sensor info failed\n"); + return ret; + } + } + + ret = media_graph_walk_init(&graph, mdev); + if (ret) + return ret; + + media_graph_walk_start(&graph, entity); + while ((entity = media_graph_walk_next(&graph))) { + DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS); + DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS); + + dev_dbg(entity->graph_obj.mdev->dev, "entity name:%s\n", + entity->name); + + if (entity->pads[0].pipe && entity->pads[0].pipe == pipe) { + dev_dbg(entity->graph_obj.mdev->dev, + "Pipe active for %s. when start for %s\n", + entity->name, entity_err->name); + } + /* + * If entity's pipe is not null and it is video device, it has + * be enabled. + */ + if (entity->pads[0].pipe && + is_media_entity_v4l2_video_device(entity)) + continue; + + /* + * If it is video device and its vc id is not equal to curren + * video device's vc id, it should continue. + */ + if (is_vc && is_media_entity_v4l2_video_device(entity)) { + source_pad = + media_pad_remote_pad_first(entity->pads); + + if (!source_pad) { + dev_warn(entity->graph_obj.mdev->dev, + "no remote pad found\n"); + continue; + } + pad_id = source_pad->index; + for (i = 0; i < CSI2_BE_SOC_SOURCE_PADS_NUM; i++) { + if (ip->asv[i].substream == + (pad_id - NR_OF_CSI2_BE_SOC_SINK_PADS)) { + entity_vc = ip->asv[i].vc; + break; + } + } + + if (entity_vc != ip->vc) + continue; + } + + entity->pads[0].pipe = pipe; + + if (!entity->ops || !entity->ops->link_validate) + continue; + + bitmap_zero(active, entity->num_pads); + bitmap_fill(has_no_links, entity->num_pads); + + list_for_each_entry(link, &entity->links, list) { + struct media_pad *pad = link->sink->entity == entity + ? link->sink : link->source; + + /* Mark that a pad is connected by a link. */ + bitmap_clear(has_no_links, pad->index, 1); + + /* + * Pads that either do not need to connect or + * are connected through an enabled link are + * fine. + */ + if (!(pad->flags & MEDIA_PAD_FL_MUST_CONNECT) || + link->flags & MEDIA_LNK_FL_ENABLED) + bitmap_set(active, pad->index, 1); + + /* + * Link validation will only take place for + * sink ends of the link that are enabled. + */ + if (link->sink != pad || + !(link->flags & MEDIA_LNK_FL_ENABLED)) + continue; + + ret = entity->ops->link_validate(link); + if (ret < 0 && ret != -ENOIOCTLCMD) { + dev_dbg(entity->graph_obj.mdev->dev, + "link failed for %s:%u->%s:%u,ret:%d\n", + link->source->entity->name, + link->source->index, + entity->name, link->sink->index, ret); + goto error; + } + } + + /* Either no links or validated links are fine. */ + bitmap_or(active, active, has_no_links, entity->num_pads); + + if (!bitmap_full(active, entity->num_pads)) { + ret = -ENOLINK; + n = (u32)find_first_zero_bit(active, entity->num_pads); + dev_dbg(entity->graph_obj.mdev->dev, + "%s:%u must be connected by an enabled link\n", + entity->name, n); + goto error; + } + } + + media_graph_walk_cleanup(&graph); + pipe->start_count++; + + return 0; + +error: + /* + * Link validation on graph failed. We revert what we did and + * return the error. + */ + media_graph_walk_start(&graph, entity_err); + while ((entity_err = media_graph_walk_next(&graph))) { + entity_err->pads[0].pipe = NULL; + if (entity_err == entity) + break; + } + + media_graph_walk_cleanup(&graph); + + return ret; +} + +static int media_pipeline_start_by_vc(struct ipu_isys_video *av, + struct media_pipeline *pipe) +{ + struct media_device *mdev = av->vdev.entity.graph_obj.mdev; + int ret; + + mutex_lock(&mdev->graph_mutex); + ret = media_pipeline_walk_by_vc(av, pipe); + mutex_unlock(&mdev->graph_mutex); + + return ret; +} + +static unsigned int ipu_isys_get_compression_scheme(u32 code) +{ + switch (code) { + case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8: + return 3; + default: + return 0; + } +} + +static unsigned int get_comp_format(u32 code) +{ + unsigned int predictor = 0; /* currently hard coded */ + unsigned int udt = ipu_isys_mbus_code_to_mipi(code); + unsigned int scheme = ipu_isys_get_compression_scheme(code); + + /* if data type is not user defined return here */ + if (udt < IPU_ISYS_MIPI_CSI2_TYPE_USER_DEF(1) || + udt > IPU_ISYS_MIPI_CSI2_TYPE_USER_DEF(8)) + return 0; + + /* + * For each user defined type (1..8) there is configuration bitfield for + * decompression. + * + * | bit 3 | bits 2:0 | + * | predictor | scheme | + * compression schemes: + * 000 = no compression + * 001 = 10 - 6 - 10 + * 010 = 10 - 7 - 10 + * 011 = 10 - 8 - 10 + * 100 = 12 - 6 - 12 + * 101 = 12 - 7 - 12 + * 110 = 12 - 8 - 12 + */ + + return ((predictor << 3) | scheme) << + ((udt - IPU_ISYS_MIPI_CSI2_TYPE_USER_DEF(1)) * 4); +} + +/* Create stream and start it using the CSS FW ABI. */ +static int start_stream_firmware(struct ipu_isys_video *av, + struct ipu_isys_buffer_list *bl) +{ + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + struct device *dev = &av->isys->adev->dev; + struct v4l2_subdev_selection sel_fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = V4L2_SEL_TGT_CROP, + .pad = CSI2_BE_PAD_SOURCE, + }; + struct ipu_fw_isys_stream_cfg_data_abi *stream_cfg; + struct isys_fw_msgs *msg = NULL; + struct ipu_fw_isys_frame_buff_set_abi *buf = NULL; + struct ipu_isys_queue *aq; + struct ipu_isys_video *isl_av = NULL; + struct ipu_isys_request *ireq = NULL; + struct v4l2_subdev_format source_fmt = { 0 }; + struct v4l2_subdev *be_sd = NULL; + struct media_pad *source_pad = media_pad_remote_pad_first(&av->pad); + int rval, rvalout, tout; + + rval = get_external_facing_format(ip, &source_fmt); + if (rval) + return rval; + + msg = ipu_get_fw_msg_buf(ip); + if (!msg) + return -ENOMEM; + + stream_cfg = to_stream_cfg_msg_buf(msg); + stream_cfg->compfmt = get_comp_format(source_fmt.format.code); + stream_cfg->input_pins[0].input_res.width = source_fmt.format.width; + stream_cfg->input_pins[0].input_res.height = source_fmt.format.height; + stream_cfg->input_pins[0].dt = + ipu_isys_mbus_code_to_mipi(source_fmt.format.code); + stream_cfg->input_pins[0].mapped_dt = N_IPU_FW_ISYS_MIPI_DATA_TYPE; + + if (ip->csi2 && !v4l2_ctrl_g_ctrl(ip->csi2->store_csi2_header)) + stream_cfg->input_pins[0].mipi_store_mode = + IPU_FW_ISYS_MIPI_STORE_MODE_DISCARD_LONG_HEADER; + else if (ip->tpg && !v4l2_ctrl_g_ctrl(ip->tpg->store_csi2_header)) + stream_cfg->input_pins[0].mipi_store_mode = + IPU_FW_ISYS_MIPI_STORE_MODE_DISCARD_LONG_HEADER; + + stream_cfg->src = ip->source; + stream_cfg->vc = 0; + stream_cfg->isl_use = ip->isl_mode; + stream_cfg->nof_input_pins = 1; + + /* + * Only CSI2-BE and SOC BE has the capability to do crop, + * so get the crop info from csi2-be or csi2-be-soc. + */ + if (ip->csi2_be) { + be_sd = &ip->csi2_be->asd.sd; + } else if (ip->csi2_be_soc) { + be_sd = &ip->csi2_be_soc->asd.sd; + if (source_pad) + sel_fmt.pad = source_pad->index; + } + if (be_sd && + !v4l2_subdev_call(be_sd, pad, get_selection, NULL, &sel_fmt)) { + stream_cfg->crop[0].left_offset = sel_fmt.r.left; + stream_cfg->crop[0].top_offset = sel_fmt.r.top; + stream_cfg->crop[0].right_offset = sel_fmt.r.left + + sel_fmt.r.width; + stream_cfg->crop[0].bottom_offset = sel_fmt.r.top + + sel_fmt.r.height; + + } else { + stream_cfg->crop[0].right_offset = source_fmt.format.width; + stream_cfg->crop[0].bottom_offset = source_fmt.format.height; + } + + /* + * If the CSI-2 backend's video node is part of the pipeline + * it must be arranged first in the output pin list. This is + * the most probably a firmware requirement. + */ + if (ip->isl_mode == IPU_ISL_CSI2_BE) + isl_av = &ip->csi2_be->av; + else if (ip->isl_mode == IPU_ISL_ISA) + isl_av = &av->isys->isa.av; + + if (isl_av) { + struct ipu_isys_queue *safe; + + list_for_each_entry_safe(aq, safe, &ip->queues, node) { + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + + if (av != isl_av) + continue; + + list_del(&aq->node); + list_add(&aq->node, &ip->queues); + break; + } + } + + list_for_each_entry(aq, &ip->queues, node) { + struct ipu_isys_video *__av = ipu_isys_queue_to_video(aq); + + __av->prepare_firmware_stream_cfg(__av, stream_cfg); + } + + if (ip->interlaced && ip->isys->short_packet_source == + IPU_ISYS_SHORT_PACKET_FROM_RECEIVER) + csi_short_packet_prepare_firmware_stream_cfg(ip, stream_cfg); + + dev_dbg(dev, "stream cfg before set_params:\n"); + ipu_fw_isys_dump_stream_cfg(dev, stream_cfg); + + ip->nr_output_pins = stream_cfg->nof_output_pins; + + rval = get_stream_handle(av); + if (rval) { + dev_dbg(dev, "Can't get stream_handle\n"); + return rval; + } + + reinit_completion(&ip->stream_open_completion); + + ipu_fw_isys_set_params(stream_cfg); + dev_dbg(dev, "stream cfg after set_params:\n"); + ipu_fw_isys_dump_stream_cfg(dev, stream_cfg); + + rval = ipu_fw_isys_complex_cmd(av->isys, + ip->stream_handle, + stream_cfg, + to_dma_addr(msg), + sizeof(*stream_cfg), + IPU_FW_ISYS_SEND_TYPE_STREAM_OPEN); + ipu_put_fw_mgs_buffer(av->isys, (uintptr_t) stream_cfg); + + if (rval < 0) { + dev_err(dev, "can't open stream (%d)\n", rval); + goto out_put_stream_handle; + } + + get_stream_opened(av); + + tout = wait_for_completion_timeout(&ip->stream_open_completion, + IPU_LIB_CALL_TIMEOUT_JIFFIES); + if (!tout) { + dev_err(dev, + "stream open time out (source=%u handle=%d vc=%u stream_id=%u)\n", + ip->source, ip->stream_handle, ip->vc, ip->stream_id); + rval = -ETIMEDOUT; + goto out_put_stream_opened; + } + if (ip->error) { + dev_err(dev, "stream open error: %d\n", ip->error); + rval = -EIO; + goto out_put_stream_opened; + } + dev_dbg(dev, "start stream: open complete\n"); + + ireq = ipu_isys_next_queued_request(ip); + + if (bl || ireq) { + msg = ipu_get_fw_msg_buf(ip); + if (!msg) { + rval = -ENOMEM; + goto out_put_stream_opened; + } + buf = to_frame_msg_buf(msg); + } + + if (bl) { + ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set(buf, ip, bl); + ipu_isys_buffer_list_queue(bl, + IPU_ISYS_BUFFER_LIST_FL_ACTIVE, 0); + } else if (ireq) { + rval = ipu_isys_req_prepare(&av->isys->media_dev, + ireq, ip, buf); + if (rval) + goto out_put_stream_opened; + } + + reinit_completion(&ip->stream_start_completion); + + if (bl || ireq) { + ipu_fw_isys_dump_frame_buff_set(dev, buf, + stream_cfg->nof_output_pins); + rval = ipu_fw_isys_complex_cmd(av->isys, + ip->stream_handle, + buf, to_dma_addr(msg), + sizeof(*buf), + IPU_FW_ISYS_SEND_TYPE_STREAM_START_AND_CAPTURE); + ipu_put_fw_mgs_buffer(av->isys, (uintptr_t) buf); + } else { + rval = ipu_fw_isys_simple_cmd(av->isys, + ip->stream_handle, + IPU_FW_ISYS_SEND_TYPE_STREAM_START); + } + + if (rval < 0) { + dev_err(dev, "can't start streaming (%d)\n", rval); + goto out_stream_close; + } + + tout = wait_for_completion_timeout(&ip->stream_start_completion, + IPU_LIB_CALL_TIMEOUT_JIFFIES); + if (!tout) { + dev_err(dev, + "stream start time out (source=%u handle=%d vc=%u stream_id=%u output_pins=%u)\n", + ip->source, ip->stream_handle, ip->vc, ip->stream_id, + ip->nr_output_pins); + rval = -ETIMEDOUT; + goto out_stream_close; + } + if (ip->error) { + dev_err(dev, "stream start error: %d\n", ip->error); + rval = -EIO; + goto out_stream_close; + } + dev_dbg(dev, "start stream: complete\n"); + ipu_isys_log_csi2_state(dev, ip, "start stream complete state"); + + return 0; + +out_stream_close: + reinit_completion(&ip->stream_close_completion); + + rvalout = ipu_fw_isys_simple_cmd(av->isys, + ip->stream_handle, + IPU_FW_ISYS_SEND_TYPE_STREAM_CLOSE); + if (rvalout < 0) { + dev_dbg(dev, "can't close stream (%d)\n", rvalout); + goto out_put_stream_opened; + } + + tout = wait_for_completion_timeout(&ip->stream_close_completion, + IPU_LIB_CALL_TIMEOUT_JIFFIES); + if (!tout) { + dev_err(dev, + "stream close time out (source=%u handle=%d vc=%u stream_id=%u)\n", + ip->source, ip->stream_handle, ip->vc, ip->stream_id); + if (ip->csi2) + ipu_isys_csi2_error(ip->csi2); + ipu_isys_log_csi2_state(dev, ip, "stream close timeout state"); + } else if (ip->error) { + dev_err(dev, "stream close error: %d\n", ip->error); + } else { + dev_dbg(dev, "stream close complete\n"); + } + +out_put_stream_opened: + put_stream_opened(av); + +out_put_stream_handle: + put_stream_handle(av); + return rval; +} + +static void stop_streaming_firmware(struct ipu_isys_video *av) +{ + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + struct device *dev = &av->isys->adev->dev; + int rval, tout; + enum ipu_fw_isys_send_type send_type = + IPU_FW_ISYS_SEND_TYPE_STREAM_FLUSH; + + reinit_completion(&ip->stream_stop_completion); + + /* Use STOP command if running in CSI capture mode */ + if (use_stream_stop) + send_type = IPU_FW_ISYS_SEND_TYPE_STREAM_STOP; + + rval = ipu_fw_isys_simple_cmd(av->isys, ip->stream_handle, + send_type); + + if (rval < 0) { + dev_err(dev, "can't stop stream (%d)\n", rval); + return; + } + + tout = wait_for_completion_timeout(&ip->stream_stop_completion, + IPU_LIB_CALL_TIMEOUT_JIFFIES); + if (!tout) { + dev_err(dev, + "stream stop time out (source=%u handle=%d vc=%u stream_id=%u send_type=%u)\n", + ip->source, ip->stream_handle, ip->vc, ip->stream_id, + send_type); + if (ip->csi2) + ipu_isys_csi2_error(ip->csi2); + ipu_isys_log_csi2_state(dev, ip, "stream stop timeout state"); + } else if (ip->error) { + dev_err(dev, "stream stop error: %d\n", ip->error); + } else { + dev_dbg(dev, "stop stream: complete\n"); + } +} + +static void close_streaming_firmware(struct ipu_isys_video *av) +{ + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + struct device *dev = &av->isys->adev->dev; + int rval, tout; + + reinit_completion(&ip->stream_close_completion); + + rval = ipu_fw_isys_simple_cmd(av->isys, ip->stream_handle, + IPU_FW_ISYS_SEND_TYPE_STREAM_CLOSE); + if (rval < 0) { + dev_err(dev, "can't close stream (%d)\n", rval); + return; + } + + tout = wait_for_completion_timeout(&ip->stream_close_completion, + IPU_LIB_CALL_TIMEOUT_JIFFIES); + if (!tout) { + dev_err(dev, + "stream close time out (source=%u handle=%d vc=%u stream_id=%u)\n", + ip->source, ip->stream_handle, ip->vc, ip->stream_id); + if (ip->csi2) + ipu_isys_csi2_error(ip->csi2); + ipu_isys_log_csi2_state(dev, ip, "stream close timeout state"); + } else if (ip->error) { + dev_err(dev, "stream close error: %d\n", ip->error); + } else { + dev_dbg(dev, "close stream: complete\n"); + } + + put_stream_opened(av); + put_stream_handle(av); +} + +void +ipu_isys_video_add_capture_done(struct ipu_isys_pipeline *ip, + void (*capture_done) + (struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_resp_info_abi *resp)) +{ + unsigned int i; + + /* Different instances may register same function. Add only once */ + for (i = 0; i < IPU_NUM_CAPTURE_DONE; i++) + if (ip->capture_done[i] == capture_done) + return; + + for (i = 0; i < IPU_NUM_CAPTURE_DONE; i++) { + if (!ip->capture_done[i]) { + ip->capture_done[i] = capture_done; + return; + } + } + /* + * Too many call backs registered. Change to IPU_NUM_CAPTURE_DONE + * constant probably required. + */ + WARN_ON(1); +} + +int ipu_isys_video_prepare_streaming(struct ipu_isys_video *av, + unsigned int state) +{ + struct ipu_isys *isys = av->isys; + struct device *dev = &isys->adev->dev; + struct ipu_isys_pipeline *ip; + struct media_graph graph; + struct media_entity *entity; + struct media_device *mdev = &av->isys->media_dev; + int rval; + unsigned int i; + + dev_dbg(dev, "prepare stream: %d\n", state); + + if (!state) { + ip = to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + + if (ip->interlaced && isys->short_packet_source == + IPU_ISYS_SHORT_PACKET_FROM_RECEIVER) + short_packet_queue_destroy(ip); + media_pipeline_stop_for_vc(av); + av->vdev.entity.pads[0].pipe = NULL; + media_entity_enum_cleanup(&ip->entity_enum); + return 0; + } + + ip = &av->ip; + + WARN_ON(ip->nr_streaming); + ip->has_sof = false; + ip->nr_queues = 0; + ip->external = NULL; + atomic_set(&ip->sequence, 0); + ip->isl_mode = IPU_ISL_OFF; + + for (i = 0; i < IPU_NUM_CAPTURE_DONE; i++) + ip->capture_done[i] = NULL; + ip->csi2_be = NULL; + ip->csi2_be_soc = NULL; + ip->csi2 = NULL; + ip->tpg = NULL; + ip->seq_index = 0; + memset(ip->seq, 0, sizeof(ip->seq)); + + WARN_ON(!list_empty(&ip->queues)); + ip->interlaced = false; + + rval = media_entity_enum_init(&ip->entity_enum, mdev); + if (rval) + return rval; + + rval = media_pipeline_start_by_vc(av, &ip->pipe); + if (rval < 0) { + dev_dbg(dev, "pipeline start failed\n"); + goto out_enum_cleanup; + } + + if (!ip->external) { + dev_err(dev, "no external entity set! Driver bug?\n"); + rval = -EINVAL; + goto out_pipeline_stop; + } + + rval = media_graph_walk_init(&graph, mdev); + if (rval) + goto out_pipeline_stop; + + /* Gather all entities in the graph and count video queues. */ + mutex_lock(&mdev->graph_mutex); + media_graph_walk_start(&graph, &av->vdev.entity); + while ((entity = media_graph_walk_next(&graph))) { + media_entity_enum_set(&ip->entity_enum, entity); + if (is_media_entity_v4l2_video_device(entity)) + ip->nr_queues++; + } + + mutex_unlock(&mdev->graph_mutex); + + media_graph_walk_cleanup(&graph); + + if (ip->interlaced) { + rval = short_packet_queue_setup(ip); + if (rval) { + dev_err(&isys->adev->dev, + "Failed to setup short packet buffer.\n"); + goto out_pipeline_stop; + } + } + + dev_dbg(dev, "prepare stream: external entity %s\n", + ip->external->entity->name); + + return 0; + +out_pipeline_stop: + media_pipeline_stop(av->vdev.entity.pads); + +out_enum_cleanup: + media_entity_enum_cleanup(&ip->entity_enum); + + return rval; +} + +static int perform_skew_cal(struct ipu_isys_pipeline *ip) +{ + struct v4l2_subdev *ext_sd = + media_entity_to_v4l2_subdev(ip->external->entity); + int rval; + + if (!ext_sd) { + WARN_ON(1); + return -ENODEV; + } + ipu_isys_csi2_set_skew_cal(ip->csi2, true); + + rval = v4l2_subdev_call(ext_sd, video, s_stream, true); + if (rval) + goto turn_off_skew_cal; + + /* TODO: do we have a better way available than waiting for a while ? */ + msleep(50); + + rval = v4l2_subdev_call(ext_sd, video, s_stream, false); + +turn_off_skew_cal: + ipu_isys_csi2_set_skew_cal(ip->csi2, false); + + /* TODO: do we have a better way available than waiting for a while ? */ + msleep(50); + + return rval; +} + +int ipu_isys_video_set_streaming(struct ipu_isys_video *av, + unsigned int state, + struct ipu_isys_buffer_list *bl) +{ + struct device *dev = &av->isys->adev->dev; + struct media_device *mdev = av->vdev.entity.graph_obj.mdev; + struct media_entity_enum entities; + + struct media_entity *entity, *entity2; + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + struct v4l2_subdev *sd, *esd; + int rval = 0; + + dev_dbg(dev, "set stream: %d\n", state); + + if (!ip->external->entity) { + WARN_ON(1); + return -ENODEV; + } + esd = media_entity_to_v4l2_subdev(ip->external->entity); + + if (state) { + rval = media_graph_walk_init(&ip->graph, mdev); + if (rval) + return rval; + rval = media_entity_enum_init(&entities, mdev); + if (rval) + goto out_media_entity_graph_init; + } + + if (!state) { + stop_streaming_firmware(av); + + /* stop external sub-device now. */ + dev_err(dev, "s_stream %s (ext)\n", ip->external->entity->name); + + if (ip->csi2) { + dev_dbg(dev, + "stream off ext: %s stream_count=%u remote_streams=%u\n", + ip->external->entity->name, ip->csi2->stream_count, + ip->csi2->remote_streams); + if (ip->csi2->stream_count == 1) { + v4l2_subdev_call(esd, video, s_stream, state); +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + ipu_isys_csi2_wait_last_eof(ip->csi2); +#endif + } + } else { + v4l2_subdev_call(esd, video, s_stream, state); + } + } + + mutex_lock(&mdev->graph_mutex); + + media_graph_walk_start(&ip->graph, + &av->vdev.entity); + + while ((entity = media_graph_walk_next(&ip->graph))) { + sd = media_entity_to_v4l2_subdev(entity); + + dev_dbg(dev, "set stream: entity %s\n", entity->name); + + /* Non-subdev nodes can be safely ignored here. */ + if (!is_media_entity_v4l2_subdev(entity)) + continue; + + /* Don't start truly external devices quite yet. */ + if (strncmp(sd->name, IPU_ISYS_ENTITY_PREFIX, + strlen(IPU_ISYS_ENTITY_PREFIX)) != 0 || + ip->external->entity == entity) + continue; + + dev_dbg(dev, "s_stream %s\n", entity->name); + rval = v4l2_subdev_call(sd, video, s_stream, state); + if (!state) + continue; + if (rval && rval != -ENOIOCTLCMD) { + mutex_unlock(&mdev->graph_mutex); + goto out_media_entity_stop_streaming; + } + + media_entity_enum_set(&entities, entity); + } + + mutex_unlock(&mdev->graph_mutex); + + /* Oh crap */ + if (state) { + if (ip->csi2) + dev_dbg(dev, + "stream on pre-fw: source=%u stream_count=%u remote_streams=%u vc=%u stream_id=%u\n", + ip->source, ip->csi2->stream_count, + ip->csi2->remote_streams, ip->vc, ip->stream_id); + + if (ipu_isys_csi2_skew_cal_required(ip->csi2) && + ip->csi2->remote_streams == ip->csi2->stream_count) + perform_skew_cal(ip); + + rval = start_stream_firmware(av, bl); + if (rval) + goto out_media_entity_stop_streaming; + + dev_dbg(dev, "set stream: source %d, stream_handle %d\n", + ip->source, ip->stream_handle); + + /* Start external sub-device now. */ + dev_dbg(dev, "set stream: s_stream %s (ext)\n", + ip->external->entity->name); + + if (ip->csi2 && + ip->csi2->remote_streams == ip->csi2->stream_count) { + ipu_isys_csi2_error(ip->csi2); + dev_dbg(dev, + "stream on ext: calling s_stream(1) for %s (remote_streams=%u stream_count=%u)\n", + ip->external->entity->name, + ip->csi2->remote_streams, ip->csi2->stream_count); + rval = v4l2_subdev_call(esd, video, s_stream, state); + } else if (!ip->csi2) { + dev_dbg(dev, + "stream on ext: calling s_stream(1) for non-csi2 path %s\n", + ip->external->entity->name); + rval = v4l2_subdev_call(esd, video, s_stream, state); + } else { + dev_warn(dev, + "stream on ext: SKIP s_stream(1) for %s due to remote_streams(%u) != stream_count(%u), source=%u vc=%u stream_id=%u\n", + ip->external->entity->name, + ip->csi2->remote_streams, ip->csi2->stream_count, + ip->source, ip->vc, ip->stream_id); + } + if (!rval) { + dev_dbg(dev, + "stream on ext: s_stream(1) succeeded for %s\n", + ip->external->entity->name); + if (ip->csi2) + ipu_isys_csi2_error(ip->csi2); + } else { + dev_err(dev, + "stream on ext: s_stream(1) failed for %s: %d\n", + ip->external->entity->name, rval); + } + ipu_isys_log_csi2_state(dev, ip, "post ext s_stream state"); + if (rval) + goto out_media_entity_stop_streaming_firmware; + } else { + close_streaming_firmware(av); + av->ip.stream_id = 0; + av->ip.vc = 0; + } + + if (state) + media_entity_enum_cleanup(&entities); + else + media_graph_walk_cleanup(&ip->graph); + av->streaming = state; + + return 0; + +out_media_entity_stop_streaming_firmware: + stop_streaming_firmware(av); + +out_media_entity_stop_streaming: + mutex_lock(&mdev->graph_mutex); + + media_graph_walk_start(&ip->graph, + &av->vdev.entity); + + while (state && (entity2 = media_graph_walk_next(&ip->graph)) && + entity2 != entity) { + sd = media_entity_to_v4l2_subdev(entity2); + + if (!media_entity_enum_test(&entities, entity2)) + continue; + + v4l2_subdev_call(sd, video, s_stream, 0); + } + + mutex_unlock(&mdev->graph_mutex); + + media_entity_enum_cleanup(&entities); + +out_media_entity_graph_init: + media_graph_walk_cleanup(&ip->graph); + + return rval; +} + +#ifdef CONFIG_COMPAT +static long ipu_isys_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + long ret = -ENOIOCTLCMD; + void __user *up = compat_ptr(arg); + + /* + * at present, there is not any private IOCTL need to compat handle + */ + if (file->f_op->unlocked_ioctl) + ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)up); + + return ret; +} +#endif + +static const struct v4l2_ioctl_ops ioctl_ops_splane = { + .vidioc_querycap = ipu_isys_vidioc_querycap, + .vidioc_enum_fmt_vid_cap = ipu_isys_vidioc_enum_fmt, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_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, + .vidioc_default = ipu_isys_vidioc_private, + .vidioc_enum_input = vidioc_enum_input, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, +}; + +static const struct v4l2_ioctl_ops ioctl_ops_mplane = { + .vidioc_querycap = ipu_isys_vidioc_querycap, + .vidioc_enum_fmt_vid_cap = ipu_isys_vidioc_enum_fmt, + .vidioc_enum_framesizes = ipu_isys_vidioc_enum_framesizes, + .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt_vid_cap_mplane, + .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt_vid_cap_mplane, + .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_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, + .vidioc_default = ipu_isys_vidioc_private, + .vidioc_enum_input = vidioc_enum_input, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, +}; + +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, +#ifdef CONFIG_COMPAT + .compat_ioctl32 = ipu_isys_compat_ioctl, +#endif + .mmap = vb2_fop_mmap, + .open = video_open, + .release = video_release, +}; + +/* + * 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 ipu_isys_video_init(struct ipu_isys_video *av, + struct media_entity *entity, + unsigned int pad, unsigned long pad_flags, + unsigned int flags) +{ + const struct v4l2_ioctl_ops *ioctl_ops = NULL; + int rval; + + mutex_init(&av->mutex); + init_completion(&av->ip.stream_open_completion); + init_completion(&av->ip.stream_close_completion); + init_completion(&av->ip.stream_start_completion); + init_completion(&av->ip.stream_stop_completion); + init_completion(&av->ip.capture_ack_completion); + INIT_LIST_HEAD(&av->ip.queues); + spin_lock_init(&av->ip.short_packet_queue_lock); + av->ip.isys = av->isys; + av->ip.stream_id = 0; + av->ip.vc = 0; + + if (pad_flags & MEDIA_PAD_FL_SINK) { + /* data_offset is available only for multi-plane buffers */ + if (av->line_header_length) { + av->aq.vbq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + ioctl_ops = &ioctl_ops_mplane; + } else { + av->aq.vbq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + ioctl_ops = &ioctl_ops_splane; + } + av->vdev.vfl_dir = VFL_DIR_RX; + } else { + av->aq.vbq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + av->vdev.vfl_dir = VFL_DIR_TX; + } + rval = ipu_isys_queue_init(&av->aq); + if (rval) + goto out_mutex_destroy; + + av->pad.flags = pad_flags | MEDIA_PAD_FL_MUST_CONNECT; + rval = media_entity_pads_init(&av->vdev.entity, 1, &av->pad); + if (rval) + goto out_ipu_isys_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; + if (!av->vdev.ioctl_ops) + av->vdev.ioctl_ops = ioctl_ops; + av->vdev.queue = &av->aq.vbq; + av->vdev.lock = &av->mutex; + + av->vdev.device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_CAPTURE | + V4L2_CAP_IO_MC; + + switch (av->aq.vbq.type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + av->vdev.device_caps |= V4L2_CAP_VIDEO_CAPTURE; + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + av->vdev.device_caps |= V4L2_CAP_VIDEO_CAPTURE_MPLANE; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + av->vdev.device_caps |= V4L2_CAP_VIDEO_OUTPUT_MPLANE; + break; + default: + WARN_ON(1); + } + + set_bit(V4L2_FL_USES_V4L2_FH, &av->vdev.flags); + video_set_drvdata(&av->vdev, av); + + mutex_lock(&av->mutex); + + rval = video_register_device(&av->vdev, VFL_TYPE_VIDEO, -1); + if (rval) + goto out_media_entity_cleanup; + + if (pad_flags & MEDIA_PAD_FL_SINK) + rval = media_create_pad_link(entity, pad, + &av->vdev.entity, 0, flags); + else + rval = media_create_pad_link(&av->vdev.entity, 0, entity, + pad, flags); + if (rval) { + dev_info(&av->isys->adev->dev, "can't create link\n"); + goto out_media_entity_cleanup; + } + + av->pfmt = av->try_fmt_vid_mplane(av, &av->mpix); + + mutex_unlock(&av->mutex); + + return rval; + +out_media_entity_cleanup: + video_unregister_device(&av->vdev); + mutex_unlock(&av->mutex); + media_entity_cleanup(&av->vdev.entity); + +out_ipu_isys_queue_cleanup: + ipu_isys_queue_cleanup(&av->aq); + +out_mutex_destroy: + mutex_destroy(&av->mutex); + + return rval; +} + +void ipu_isys_video_cleanup(struct ipu_isys_video *av) +{ + if (!av->aq.vbq.ops) + return; + + video_unregister_device(&av->vdev); + media_entity_cleanup(&av->vdev.entity); + mutex_destroy(&av->mutex); + ipu_isys_queue_cleanup(&av->aq); +} + +u32 ipu_isys_get_format(struct ipu_isys_video *av) +{ + if (av->aq.vbq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + return av->pix_fmt.pixelformat; + + if (av->aq.vbq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return av->mpix.pixelformat; + + if (av->aq.vbq.type == V4L2_BUF_TYPE_META_CAPTURE) + return av->meta_fmt.dataformat; + + return 0; +} + +u32 ipu_isys_get_data_size(struct ipu_isys_video *av) +{ + if (av->aq.vbq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + return av->pix_fmt.sizeimage; + + if (av->aq.vbq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return av->mpix.plane_fmt[0].sizeimage; + + if (av->aq.vbq.type == V4L2_BUF_TYPE_META_CAPTURE) + return av->meta_fmt.buffersize; + + return 0; +} + +u32 ipu_isys_get_bytes_per_line(struct ipu_isys_video *av) +{ + if (av->aq.vbq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + return av->pix_fmt.bytesperline; + + if (av->aq.vbq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return av->mpix.plane_fmt[0].bytesperline; + + if (av->aq.vbq.type == V4L2_BUF_TYPE_META_CAPTURE) + return av->meta_fmt.bytesperline; + + return 0; +} + +u32 ipu_isys_get_frame_width(struct ipu_isys_video *av) +{ + if (av->aq.vbq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + return av->pix_fmt.width; + + if (av->aq.vbq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return av->mpix.width; + + if (av->aq.vbq.type == V4L2_BUF_TYPE_META_CAPTURE) + return av->meta_fmt.width; + + return 0; +} + +u32 ipu_isys_get_frame_height(struct ipu_isys_video *av) +{ + if (av->aq.vbq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + return av->pix_fmt.height; + + if (av->aq.vbq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return av->mpix.height; + + if (av->aq.vbq.type == V4L2_BUF_TYPE_META_CAPTURE) + return av->meta_fmt.height; + + return 0; +} diff --git a/drivers/media/pci/intel/ipu-isys-video.h b/drivers/media/pci/intel/ipu-isys-video.h new file mode 100644 index 0000000000000..4f3f4415baabd --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys-video.h @@ -0,0 +1,218 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_ISYS_VIDEO_H +#define IPU_ISYS_VIDEO_H + +#include +#include +#include +#include +#include +#include + +#include "ipu-isys-queue.h" + +#define IPU_ISYS_OUTPUT_PINS 11 +#define IPU_NUM_CAPTURE_DONE 2 +#define IPU_ISYS_MAX_PARALLEL_SOF 2 +#define NR_OF_CSI2_BE_SOC_STREAMS 8 +#define CSI2_BE_SOC_SOURCE_PADS_NUM NR_OF_CSI2_BE_SOC_STREAMS + +struct ipu_isys; +struct ipu_isys_csi2_be_soc; +struct ipu_fw_isys_stream_cfg_data_abi; + +struct ipu_isys_pixelformat { + u32 pixelformat; + u32 bpp; + u32 bpp_packed; + u32 bpp_planar; + u32 code; + u32 css_pixelformat; + bool is_meta; +}; + +struct sequence_info { + unsigned int sequence; + u64 timestamp; +}; + +struct output_pin_data { + void (*pin_ready)(struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_resp_info_abi *info); + struct ipu_isys_queue *aq; +}; + +/* + * struct ipu_isys_sub_stream_vc + */ +struct ipu_isys_sub_stream_vc { + unsigned int substream; /* sub stream id */ + int vc; /* VC number */ + u32 width; + u32 height; + unsigned int dt; + unsigned int code; +}; + +#define SUB_STREAM_CODE(value) ((value) & 0xFFFF) +#define SUB_STREAM_H(value) (((value) >> 16) & 0xFFFF) +#define SUB_STREAM_W(value) (((value) >> 32) & 0xFFFF) +#define SUB_STREAM_DT(value) (((value) >> 48) & 0xFF) +#define SUB_STREAM_VC_ID(value) ((value) >> 56 & 0xFF) +#define SUB_STREAM_SET_VALUE(vc_id, stream_state) \ + ((((vc_id) << 8) & 0xFF00) | (stream_state)) + +struct ipu_isys_pipeline { + struct media_pipeline pipe; + struct media_pad *external; + atomic_t sequence; + int last_sequence; + unsigned int seq_index; + struct sequence_info seq[IPU_ISYS_MAX_PARALLEL_SOF]; + int source; /* SSI stream source */ + int stream_handle; /* stream handle for CSS API */ + unsigned int nr_output_pins; /* How many firmware pins? */ + enum ipu_isl_mode isl_mode; + struct ipu_isys_csi2_be *csi2_be; + struct ipu_isys_csi2_be_soc *csi2_be_soc; + struct ipu_isys_csi2 *csi2; + struct ipu_isys_tpg *tpg; + /* + * Number of capture queues, write access serialised using struct + * ipu_isys.stream_mutex + */ + /* If it supports vc, this is number of links for the same vc. */ + int nr_queues; + int nr_streaming; /* Number of capture queues streaming */ + int streaming; /* Has streaming been really started? */ + 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 completion capture_ack_completion; + struct ipu_isys *isys; + + void (*capture_done[IPU_NUM_CAPTURE_DONE]) + (struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_resp_info_abi *resp); + struct output_pin_data output_pins[IPU_ISYS_OUTPUT_PINS]; + bool has_sof; + bool interlaced; + int error; + struct ipu_isys_private_buffer *short_packet_bufs; + size_t short_packet_buffer_size; + unsigned int num_short_packet_lines; + unsigned int short_packet_output_pin; + unsigned int cur_field; + struct list_head short_packet_incoming; + struct list_head short_packet_active; + /* Serialize access to short packet active and incoming lists */ + spinlock_t short_packet_queue_lock; + struct list_head pending_interlaced_bufs; + unsigned int short_packet_trace_index; + unsigned int vc; + unsigned int stream_id; + struct media_graph graph; + struct media_entity_enum entity_enum; + struct ipu_isys_sub_stream_vc asv[CSI2_BE_SOC_SOURCE_PADS_NUM]; +}; + +#define to_ipu_isys_pipeline(__pipe) \ + container_of((__pipe), struct ipu_isys_pipeline, pipe) + +struct video_stream_watermark { + u32 width; + u32 height; + u32 hblank; + u32 frame_rate; + u64 pixel_rate; + u64 stream_data_rate; + u16 sram_gran_shift; + u16 sram_gran_size; + struct list_head stream_node; +}; + +struct ipu_isys_video { + /* Serialise access to other fields in the struct. */ + struct mutex mutex; + struct media_pad pad; + struct video_device vdev; + struct v4l2_pix_format_mplane mpix; + struct v4l2_pix_format pix_fmt; + struct v4l2_meta_format meta_fmt; + const struct ipu_isys_pixelformat *pfmts; + const struct ipu_isys_pixelformat *pfmt; + struct ipu_isys_queue aq; + struct ipu_isys *isys; + struct ipu_isys_pipeline ip; + struct ipu_isys_csi2 *csi2; + struct ipu_isys_stream *stream; + unsigned int streaming; + bool packed; + unsigned int line_header_length; /* bits */ + unsigned int line_footer_length; /* bits */ + struct video_stream_watermark watermark; + u32 source_stream; + u8 vc; + u8 dt; + const struct ipu_isys_pixelformat *(*try_fmt_vid_mplane)( + struct ipu_isys_video *av, + struct v4l2_pix_format_mplane *mpix); + void (*prepare_firmware_stream_cfg)(struct ipu_isys_video *av, + struct ipu_fw_isys_stream_cfg_data_abi *cfg); +}; + +#define ipu_isys_queue_to_video(__aq) \ + container_of(__aq, struct ipu_isys_video, aq) + +extern const struct ipu_isys_pixelformat ipu_isys_pfmts[]; +extern const struct ipu_isys_pixelformat ipu_isys_pfmts_be_soc[]; +extern const struct ipu_isys_pixelformat ipu_isys_pfmts_packed[]; + +const struct ipu_isys_pixelformat * +ipu_isys_get_isys_format(u32 pixelformat, u32 type); + +const struct ipu_isys_pixelformat * +ipu_isys_get_pixelformat(struct ipu_isys_video *av, u32 pixelformat); + +int ipu_isys_vidioc_querycap(struct file *file, void *fh, + struct v4l2_capability *cap); + +int ipu_isys_vidioc_enum_fmt(struct file *file, void *fh, + struct v4l2_fmtdesc *f); + +const struct ipu_isys_pixelformat * +ipu_isys_video_try_fmt_vid_mplane_default(struct ipu_isys_video *av, + struct v4l2_pix_format_mplane *mpix); + +const struct ipu_isys_pixelformat * +ipu_isys_video_try_fmt_vid_mplane(struct ipu_isys_video *av, + struct v4l2_pix_format_mplane *mpix, + int store_csi2_header); + +void ipu_isys_prepare_firmware_stream_cfg_default( + struct ipu_isys_video *av, + struct ipu_fw_isys_stream_cfg_data_abi *cfg); +int ipu_isys_video_prepare_streaming(struct ipu_isys_video *av, + unsigned int state); +int ipu_isys_video_set_streaming(struct ipu_isys_video *av, unsigned int state, + struct ipu_isys_buffer_list *bl); +int ipu_isys_video_init(struct ipu_isys_video *av, struct media_entity *source, + unsigned int source_pad, unsigned long pad_flags, + unsigned int flags); +void ipu_isys_video_cleanup(struct ipu_isys_video *av); +void ipu_isys_video_add_capture_done(struct ipu_isys_pipeline *ip, + void (*capture_done) + (struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_resp_info_abi *resp)); + +u32 ipu_isys_get_format(struct ipu_isys_video *av); +u32 ipu_isys_get_data_size(struct ipu_isys_video *av); +u32 ipu_isys_get_bytes_per_line(struct ipu_isys_video *av); +u32 ipu_isys_get_frame_width(struct ipu_isys_video *av); +u32 ipu_isys_get_frame_height(struct ipu_isys_video *av); + +#endif /* IPU_ISYS_VIDEO_H */ diff --git a/drivers/media/pci/intel/ipu-isys.c b/drivers/media/pci/intel/ipu-isys.c new file mode 100644 index 0000000000000..d781a4d91256e --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys.c @@ -0,0 +1,1318 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ipu.h" +#include "ipu-bus.h" +#include "ipu-cpd.h" +#include "ipu-mmu.h" +#include "ipu-dma.h" +#include "ipu-isys.h" +#include "ipu-isys-csi2.h" +#include "ipu-isys-tpg.h" +#include "ipu-isys-video.h" +#include "ipu-platform-regs.h" +#include "ipu-buttress.h" +#include "ipu-platform.h" +#include "ipu-platform-buttress-regs.h" + +#define ISYS_PM_QOS_VALUE 300 + +/* + * Convert firmware/ACPI CSI-2 port number to isys->csi2[] array index. + * + * On IPU4P, the physical CSI-2 receivers are numbered starting at firmware + * port 3, then 6-9 (see ipu_isys_csi2_init remapping). The isys->csi2[] + * array is compact (indices 0..nports-1), so ACPI port numbers cannot be + * used directly as array indices. + * + * Returns the array index, or -EINVAL if the port is not valid. + */ +static int ipu_isys_csi2_fw_port_to_index(unsigned int fw_port, + unsigned int nports) +{ + int index; + +#ifdef CONFIG_VIDEO_INTEL_IPU4P + /* Inverse of: src = index ? (index + 5) : (index + 3) */ + if (fw_port == 3) + index = 0; + else if (fw_port >= 6) + index = fw_port - 5; + else + return -EINVAL; +#else + index = fw_port; +#endif + if (index < 0 || index >= nports) + return -EINVAL; + + return index; +} + +/* + * The param was passed from module to indicate if port + * could be optimized. + */ +static bool csi2_port_optimized = true; +module_param(csi2_port_optimized, bool, 0660); +MODULE_PARM_DESC(csi2_port_optimized, "IPU CSI2 port optimization"); + +struct isys_i2c_test { + u8 bus_nr; + u16 addr; + struct i2c_client *client; +}; + +static int isys_i2c_test(struct device *dev, void *priv) +{ + struct i2c_client *client = i2c_verify_client(dev); + struct isys_i2c_test *test = priv; + + if (!client) + return 0; + + if (i2c_adapter_id(client->adapter) != test->bus_nr || + client->addr != test->addr) + return 0; + + test->client = client; + + return 0; +} + +static struct +i2c_client *isys_find_i2c_subdev(struct i2c_adapter *adapter, + struct ipu_isys_subdev_info *sd_info) +{ + struct i2c_board_info *info = &sd_info->i2c.board_info; + struct isys_i2c_test test = { + .bus_nr = i2c_adapter_id(adapter), + .addr = info->addr, + }; + int rval; + + rval = i2c_for_each_dev(&test, isys_i2c_test); + if (rval || !test.client) + return NULL; + return test.client; +} + +static int +isys_complete_ext_device_registration(struct ipu_isys *isys, + struct v4l2_subdev *sd, + struct ipu_isys_csi2_config *csi2) +{ + unsigned int i; + int rval, idx; + + idx = ipu_isys_csi2_fw_port_to_index(csi2->port, + isys->pdata->ipdata->csi2.nports); + if (idx < 0) { + dev_err(&isys->adev->dev, + "invalid csi2 fw port %u (no array mapping)\n", + csi2->port); + return -EINVAL; + } + + 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(&isys->adev->dev, + "no source pad in external entity\n"); + rval = -ENOENT; + goto skip_unregister_subdev; + } + + rval = media_create_pad_link(&sd->entity, i, + &isys->csi2[idx].asd.sd.entity, + 0, 0); + if (rval) { + dev_warn(&isys->adev->dev, "can't create link\n"); + goto skip_unregister_subdev; + } + + isys->csi2[idx].nlanes = csi2->nlanes; + return 0; + +skip_unregister_subdev: + v4l2_device_unregister_subdev(sd); + return rval; +} + +static int isys_register_ext_subdev(struct ipu_isys *isys, + struct ipu_isys_subdev_info *sd_info) +{ + struct i2c_adapter *adapter; + struct v4l2_subdev *sd; + struct i2c_client *client; + int rval; + int bus; + +#ifdef I2C_WA + bus = ipu_get_i2c_bus_id(sd_info->i2c.i2c_adapter_id); + if (bus < 0) { + dev_err(&isys->adev->dev, "Failed to find adapter!"); + return -ENOENT; + } +#else + bus = sd_info->i2c.i2c_adapter_id; +#endif + adapter = i2c_get_adapter(bus); + if (!adapter) { + dev_warn(&isys->adev->dev, "can't find adapter\n"); + return -ENOENT; + } + + dev_info(&isys->adev->dev, + "creating new i2c subdev for %s (address %2.2x, bus %d)", + sd_info->i2c.board_info.type, sd_info->i2c.board_info.addr, + bus); + + if (sd_info->csi2) { + int idx; + + dev_info(&isys->adev->dev, "sensor device on CSI port: %d\n", + sd_info->csi2->port); + idx = ipu_isys_csi2_fw_port_to_index( + sd_info->csi2->port, + isys->pdata->ipdata->csi2.nports); + if (idx < 0 || !isys->csi2[idx].isys) { + dev_warn(&isys->adev->dev, "isys_register_ext_subdev, %s: invalid csi2 port %u\n", + sd_info->acpiname, sd_info->csi2->port); + rval = -EINVAL; + goto skip_put_adapter; + } + } else { + dev_info(&isys->adev->dev, "non camera subdevice\n"); + } + + client = isys_find_i2c_subdev(adapter, sd_info); + if (client) { + dev_dbg(&isys->adev->dev, "Device exists\n"); + rval = 0; + goto skip_put_adapter; + } + + sd = v4l2_i2c_new_subdev_board(&isys->v4l2_dev, adapter, + &sd_info->i2c.board_info, NULL); + if (!sd) { + dev_warn(&isys->adev->dev, "can't create new i2c subdev\n"); + rval = -EINVAL; + goto skip_put_adapter; + } + + if (!sd_info->csi2) + return 0; + + return isys_complete_ext_device_registration(isys, sd, sd_info->csi2); + +skip_put_adapter: + i2c_put_adapter(adapter); + + return rval; +} + +static void isys_register_ext_subdevs(struct ipu_isys *isys) +{ + struct ipu_isys_subdev_pdata *spdata = isys->pdata->spdata; + struct ipu_isys_subdev_info **sd_info; + + if (!spdata) { + dev_info(&isys->adev->dev, "no subdevice info provided\n"); + return; + } + for (sd_info = spdata->subdevs; *sd_info; sd_info++) + isys_register_ext_subdev(isys, *sd_info); +} + +static void isys_unregister_subdevices(struct ipu_isys *isys) +{ + const struct ipu_isys_internal_tpg_pdata *tpg = + &isys->pdata->ipdata->tpg; + const struct ipu_isys_internal_csi2_pdata *csi2 = + &isys->pdata->ipdata->csi2; + unsigned int i; + + ipu_isys_csi2_be_cleanup(&isys->csi2_be); + ipu_isys_csi2_be_soc_cleanup(&isys->csi2_be_soc); + + ipu_isys_isa_cleanup(&isys->isa); + + if (isys->tpg) + for (i = 0; i < tpg->ntpgs; i++) + ipu_isys_tpg_cleanup(&isys->tpg[i]); + + if (isys->csi2) + for (i = 0; i < csi2->nports; i++) + ipu_isys_csi2_cleanup(&isys->csi2[i]); +} + +static int isys_register_subdevices(struct ipu_isys *isys) +{ + const struct ipu_isys_internal_tpg_pdata *tpg = + &isys->pdata->ipdata->tpg; + const struct ipu_isys_internal_csi2_pdata *csi2 = + &isys->pdata->ipdata->csi2; + struct ipu_isys_subdev_pdata *spdata = isys->pdata->spdata; + struct ipu_isys_subdev_info **sd_info; + DECLARE_BITMAP(csi2_enable, 32); + unsigned int i, j, k; + int rval; + + /* + * Here is somewhat a workaround, let each platform decide + * if csi2 port can be optimized, which means only registered + * port from pdata would be enabled. + */ + if (csi2_port_optimized && spdata) { + bitmap_zero(csi2_enable, 32); + for (sd_info = spdata->subdevs; *sd_info; sd_info++) { + if ((*sd_info)->csi2) { + int idx; + + idx = ipu_isys_csi2_fw_port_to_index( + (*sd_info)->csi2->port, + csi2->nports); + if (idx < 0) { + dev_warn(&isys->adev->dev, + "invalid csi2 port %u\n", + (*sd_info)->csi2->port); + continue; + } + bitmap_set(csi2_enable, idx, 1); + } + } + } else { + bitmap_fill(csi2_enable, 32); + } + + dev_info(&isys->adev->dev, + "registering subdevices: %u CSI-2 ports, %u TPGs\n", + csi2->nports, tpg->ntpgs); + + isys->csi2 = devm_kcalloc(&isys->adev->dev, csi2->nports, + sizeof(*isys->csi2), GFP_KERNEL); + if (!isys->csi2) { + rval = -ENOMEM; + goto fail; + } + + for (i = 0; i < csi2->nports; i++) { + if (!test_bit(i, csi2_enable)) + continue; + + dev_info(&isys->adev->dev, + "initializing CSI-2 port %u\n", i); + rval = ipu_isys_csi2_init(&isys->csi2[i], isys, + isys->pdata->base + + csi2->offsets[i], i); + if (rval) { + dev_err(&isys->adev->dev, + "CSI-2 port %u init failed: %d\n", i, rval); + goto fail; + } + + isys->isr_csi2_bits |= IPU_ISYS_UNISPART_IRQ_CSI2(i); + } + + isys->tpg = devm_kcalloc(&isys->adev->dev, tpg->ntpgs, + sizeof(*isys->tpg), GFP_KERNEL); + if (!isys->tpg) { + rval = -ENOMEM; + goto fail; + } + + for (i = 0; i < tpg->ntpgs; i++) { + rval = ipu_isys_tpg_init(&isys->tpg[i], isys, + isys->pdata->base + + tpg->offsets[i], + tpg->sels ? (isys->pdata->base + + tpg->sels[i]) : NULL, i); + if (rval) + goto fail; + } + + rval = ipu_isys_csi2_be_soc_init(&isys->csi2_be_soc, isys); + if (rval) { + dev_info(&isys->adev->dev, + "can't register soc csi2 be device\n"); + goto fail; + } + + rval = ipu_isys_csi2_be_init(&isys->csi2_be, isys); + if (rval) { + dev_info(&isys->adev->dev, + "can't register raw csi2 be device\n"); + goto fail; + } + rval = ipu_isys_isa_init(&isys->isa, isys, NULL); + if (rval) { + dev_info(&isys->adev->dev, "can't register isa device\n"); + goto fail; + } + + for (i = 0; i < csi2->nports; i++) { + if (!test_bit(i, csi2_enable)) + continue; + + for (j = CSI2_PAD_SOURCE(0); + j < (NR_OF_CSI2_SOURCE_PADS + CSI2_PAD_SOURCE(0)); j++) { + rval = + media_create_pad_link(&isys->csi2[i].asd.sd.entity, + j, + &isys->csi2_be.asd.sd.entity, + CSI2_BE_PAD_SINK, 0); + if (rval) { + dev_info(&isys->adev->dev, + "can't create link csi2 <=> csi2_be\n"); + goto fail; + } + + for (k = CSI2_BE_SOC_PAD_SINK(0); + k < NR_OF_CSI2_BE_SOC_SINK_PADS; k++) { + rval = + media_create_pad_link(&isys->csi2[i].asd.sd. + entity, j, + &isys->csi2_be_soc. + asd.sd.entity, k, + MEDIA_LNK_FL_DYNAMIC); + if (rval) { + dev_info(&isys->adev->dev, + "can't create link csi2->be_soc\n"); + goto fail; + } + } + } + } + + for (i = 0; i < tpg->ntpgs; i++) { + rval = media_create_pad_link(&isys->tpg[i].asd.sd.entity, + TPG_PAD_SOURCE, + &isys->csi2_be.asd.sd.entity, + CSI2_BE_PAD_SINK, 0); + if (rval) { + dev_info(&isys->adev->dev, + "can't create link between tpg and csi2_be\n"); + goto fail; + } + + for (k = CSI2_BE_SOC_PAD_SINK(0); + k < NR_OF_CSI2_BE_SOC_SINK_PADS; k++) { + rval = + media_create_pad_link(&isys->tpg[i].asd.sd.entity, + TPG_PAD_SOURCE, + &isys->csi2_be_soc.asd.sd. + entity, k, + MEDIA_LNK_FL_DYNAMIC); + if (rval) { + dev_info(&isys->adev->dev, + "can't create link tpg->be_soc\n"); + goto fail; + } + } + } + + rval = media_create_pad_link(&isys->csi2_be.asd.sd.entity, + CSI2_BE_PAD_SOURCE, + &isys->isa.asd.sd.entity, ISA_PAD_SINK, 0); + if (rval) { + dev_info(&isys->adev->dev, + "can't create link between CSI2 raw be and ISA\n"); + goto fail; + } + return 0; + +fail: + isys_unregister_subdevices(isys); + return rval; +} + +static struct media_device_ops isys_mdev_ops = { + .link_notify = v4l2_pipeline_link_notify, + .req_alloc = ipu_isys_req_alloc, + .req_free = ipu_isys_req_free, + .req_queue = ipu_isys_req_queue, +}; + +/* 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 *asd) +{ + struct ipu_isys *isys = + container_of(notifier, struct ipu_isys, notifier); + struct sensor_async_sd *s_asd = + container_of(asd, struct sensor_async_sd, asd); + int ret; + + ret = ipu_isys_csi2_fw_port_to_index(s_asd->csi2.port, + isys->pdata->ipdata->csi2.nports); + if (ret < 0) { + dev_err(&isys->adev->dev, "invalid csi2 fw port %u\n", + s_asd->csi2.port, isys->pdata->ipdata->csi2.nports); + return -EINVAL; + } + + ret = ipu_bridge_instantiate_vcm(sd->dev); + if (ret) { + dev_err(&isys->adev->dev, "instantiate vcm failed\n"); + return ret; + } + + dev_dbg(&isys->adev->dev, "bind %s nlanes is %d port is %d\n", + sd->name, s_asd->csi2.nlanes, s_asd->csi2.port); + ret = isys_complete_ext_device_registration(isys, sd, &s_asd->csi2); + if (ret) + return ret; + + return v4l2_device_register_subdev_nodes(&isys->v4l2_dev); +} + +static int isys_notifier_complete(struct v4l2_async_notifier *notifier) +{ + struct ipu_isys *isys = + container_of(notifier, struct ipu_isys, notifier); + + 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 ipu_isys *isys) +{ + struct ipu_device *isp = isys->adev->isp; + struct device *dev = &isp->pdev->dev; + struct fwnode_handle *ep; + int ret; + + v4l2_async_nf_init(&isys->notifier, &isys->v4l2_dev); + + fwnode_graph_for_each_endpoint(dev_fwnode(dev), ep) { + struct v4l2_fwnode_endpoint vep = { + .bus_type = V4L2_MBUS_CSI2_DPHY + }; + struct sensor_async_sd *s_asd; + + ret = v4l2_fwnode_endpoint_parse(ep, &vep); + if (ret) { + dev_err(dev, "fwnode endpoint parse failed: %d\n", ret); + return ret; + } + + /* Skip endpoints whose port has no physical CSI receiver */ + if (ipu_isys_csi2_fw_port_to_index( + vep.base.port, + isys->pdata->ipdata->csi2.nports) < 0) { + dev_info(dev, + "skipping endpoint at fw port %u (no receiver)\n", + vep.base.port); + continue; + } + + 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); + dev_err(dev, "add remove fwnode failed: %d\n", ret); + return ret; + } + + s_asd->csi2.port = vep.base.port; + s_asd->csi2.nlanes = vep.bus.mipi_csi2.num_data_lanes; + + dev_dbg(dev, "remote endpoint port %d with %d lanes added\n", + s_asd->csi2.port, s_asd->csi2.nlanes); + } + + 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 ipu_isys *isys) +{ + v4l2_async_nf_unregister(&isys->notifier); + v4l2_async_nf_cleanup(&isys->notifier); +} + +static int isys_register_devices(struct ipu_isys *isys) +{ + int rval; + + isys->media_dev.dev = &isys->adev->dev; + isys->media_dev.ops = &isys_mdev_ops; + strscpy(isys->media_dev.model, + IPU_MEDIA_DEV_MODEL_NAME, sizeof(isys->media_dev.model)); + snprintf(isys->media_dev.bus_info, sizeof(isys->media_dev.bus_info), + "pci:%s", dev_name(isys->adev->dev.parent->parent)); + strscpy(isys->v4l2_dev.name, isys->media_dev.model, + sizeof(isys->v4l2_dev.name)); + + media_device_init(&isys->media_dev); + + rval = media_device_register(&isys->media_dev); + if (rval < 0) { + dev_info(&isys->adev->dev, "can't register media device\n"); + goto out_media_device_unregister; + } + + isys->v4l2_dev.mdev = &isys->media_dev; + + rval = v4l2_device_register(&isys->adev->dev, &isys->v4l2_dev); + if (rval < 0) { + dev_info(&isys->adev->dev, "can't register v4l2 device\n"); + goto out_media_device_unregister; + } + + rval = isys_register_subdevices(isys); + if (rval) + goto out_v4l2_device_unregister; + + isys_register_ext_subdevs(isys); + + rval = v4l2_device_register_subdev_nodes(&isys->v4l2_dev); + if (rval) + goto out_isys_unregister_subdevices; + + rval = isys_notifier_init(isys); + if (rval) + goto out_isys_unregister_subdevices; + + return 0; + +out_isys_unregister_subdevices: + isys_unregister_subdevices(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); + + return rval; +} + +static void isys_unregister_devices(struct ipu_isys *isys) +{ + isys_unregister_subdevices(isys); + v4l2_device_unregister(&isys->v4l2_dev); + media_device_unregister(&isys->media_dev); + media_device_cleanup(&isys->media_dev); +} + +#ifdef CONFIG_PM +static int isys_runtime_pm_resume(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_device *isp = adev->isp; + struct ipu_isys *isys = ipu_bus_get_drvdata(adev); + unsigned long flags; + int ret; + + if (!isys) { + WARN(1, "%s called before probing. skipping.\n", __func__); + return 0; + } + + ipu_trace_restore(dev); + + cpu_latency_qos_update_request(&isys->pm_qos, ISYS_PM_QOS_VALUE); + + ret = ipu4_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); + + if (isys->short_packet_source == IPU_ISYS_SHORT_PACKET_FROM_TUNIT) { + mutex_lock(&isys->short_packet_tracing_mutex); + isys->short_packet_tracing_count = 0; + mutex_unlock(&isys->short_packet_tracing_mutex); + } + isys_setup_hw(isys); + + return 0; +} + +static int isys_runtime_pm_suspend(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_isys *isys = ipu_bus_get_drvdata(adev); + unsigned long flags; + + if (!isys) { + WARN(1, "%s called before probing. skipping.\n", __func__); + return 0; + } + + spin_lock_irqsave(&isys->power_lock, flags); + isys->power = 0; + spin_unlock_irqrestore(&isys->power_lock, flags); + + ipu_trace_stop(dev); + mutex_lock(&isys->mutex); + isys->reset_needed = false; + mutex_unlock(&isys->mutex); + + cpu_latency_qos_update_request(&isys->pm_qos, PM_QOS_DEFAULT_VALUE); + + return 0; +} + +static int isys_suspend(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_isys *isys = ipu_bus_get_drvdata(adev); + + /* 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, +}; + +#define ISYS_PM_OPS (&isys_pm_ops) +#else +#define ISYS_PM_OPS NULL +#endif + +static void isys_remove(struct ipu_bus_device *adev) +{ + struct ipu_isys *isys = ipu_bus_get_drvdata(adev); + struct ipu_device *isp = adev->isp; + struct isys_fw_msgs *fwmsg, *safe; + + dev_info(&adev->dev, "removed\n"); + if (isp->ipu_dir) + debugfs_remove_recursive(isys->debugfsdir); + + list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist, head) { + dma_free_coherent(&adev->dev, sizeof(struct isys_fw_msgs), + fwmsg, fwmsg->dma_addr + ); + } + + list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist_fw, head) { + dma_free_coherent(&adev->dev, sizeof(struct isys_fw_msgs), + fwmsg, fwmsg->dma_addr + ); + } + + ipu_trace_uninit(&adev->dev); + isys_unregister_devices(isys); + isys_notifier_cleanup(isys); + cpu_latency_qos_remove_request(&isys->pm_qos); + + if (!isp->secure_mode) { + ipu_cpd_free_pkg_dir(adev, isys->pkg_dir, + isys->pkg_dir_dma_addr, + isys->pkg_dir_size); + ipu_buttress_unmap_fw_image(adev, &isys->fw_sgt); + release_firmware(isys->fw); + } + + mutex_destroy(&isys->stream_mutex); + mutex_destroy(&isys->mutex); + + if (isys->short_packet_source == IPU_ISYS_SHORT_PACKET_FROM_TUNIT) { + u32 trace_size = IPU_ISYS_SHORT_PACKET_TRACE_BUFFER_SIZE; + unsigned long attrs = 0; + dma_free_attrs(&adev->dev, trace_size, + isys->short_packet_trace_buffer, + isys->short_packet_trace_buffer_dma_addr, attrs); + } +} + +static int ipu_isys_icache_prefetch_get(void *data, u64 *val) +{ + struct ipu_isys *isys = data; + + *val = isys->icache_prefetch; + return 0; +} + +static int ipu_isys_icache_prefetch_set(void *data, u64 val) +{ + struct ipu_isys *isys = data; + + if (val != !!val) + return -EINVAL; + + isys->icache_prefetch = val; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(isys_icache_prefetch_fops, + ipu_isys_icache_prefetch_get, + ipu_isys_icache_prefetch_set, "%llu\n"); + +static int ipu_isys_init_debugfs(struct ipu_isys *isys) +{ + struct dentry *file; + struct dentry *dir; + + dir = debugfs_create_dir("isys", isys->adev->isp->ipu_dir); + if (IS_ERR(dir)) + return -ENOMEM; + + file = debugfs_create_file("icache_prefetch", 0600, + dir, isys, &isys_icache_prefetch_fops); + if (IS_ERR(file)) + goto err; + + isys->debugfsdir = dir; + + + return 0; +err: + debugfs_remove_recursive(dir); + return -ENOMEM; +} + +static int alloc_fw_msg_buffers(struct ipu_isys *isys, int amount) +{ + dma_addr_t dma_addr; + struct isys_fw_msgs *addr; + unsigned int i; + unsigned long flags; + + for (i = 0; i < amount; i++) { + addr = dma_alloc_coherent(&isys->adev->dev, + sizeof(struct isys_fw_msgs), + &dma_addr, GFP_KERNEL); + 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); + dma_free_coherent(&isys->adev->dev, + sizeof(struct isys_fw_msgs), + addr, addr->dma_addr + ); + spin_lock_irqsave(&isys->listlock, flags); + } + spin_unlock_irqrestore(&isys->listlock, flags); + return -ENOMEM; +} + +struct isys_fw_msgs *ipu_get_fw_msg_buf(struct ipu_isys_pipeline *ip) +{ + struct ipu_isys_video *pipe_av = + container_of(ip, struct ipu_isys_video, ip); + struct ipu_isys *isys; + struct isys_fw_msgs *msg; + unsigned long flags; + + isys = pipe_av->isys; + + spin_lock_irqsave(&isys->listlock, flags); + if (list_empty(&isys->framebuflist)) { + spin_unlock_irqrestore(&isys->listlock, flags); + dev_dbg(&isys->adev->dev, "Frame list empty - Allocate more"); + + alloc_fw_msg_buffers(isys, 5); + + spin_lock_irqsave(&isys->listlock, flags); + if (list_empty(&isys->framebuflist)) { + dev_err(&isys->adev->dev, "Frame list empty"); + spin_unlock_irqrestore(&isys->listlock, flags); + 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 ipu_cleanup_fw_msg_bufs(struct ipu_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 ipu_put_fw_mgs_buffer(struct ipu_isys *isys, u64 data) +{ + struct isys_fw_msgs *msg; + u64 *ptr = (u64 *)(unsigned long)data; + + if (!ptr) + return; + + spin_lock(&isys->listlock); + msg = container_of(ptr, struct isys_fw_msgs, fw_msg.dummy); + list_move(&msg->head, &isys->framebuflist); + spin_unlock(&isys->listlock); +} +EXPORT_SYMBOL_GPL(ipu_put_fw_mgs_buffer); + +static int isys_probe(struct ipu_bus_device *adev) +{ + struct ipu_isys *isys; + struct ipu_device *isp = adev->isp; +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + const u32 trace_size = IPU_ISYS_SHORT_PACKET_TRACE_BUFFER_SIZE; + dma_addr_t *trace_dma_addr; + unsigned long attrs; +#endif + const struct firmware *fw; + int rval = 0; + + trace_printk("B|%d|TMWK\n", current->pid); + + /* Has the domain been attached? */ + if (!isp->secure_mode && !isp->pkg_dir_dma_addr) { + trace_printk("E|TMWK\n"); + return -EPROBE_DEFER; + } + + isys = devm_kzalloc(&adev->dev, sizeof(*isys), GFP_KERNEL); + if (!isys) + return -ENOMEM; + + /* By default, short packet is captured from T-Unit. */ +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + isys->short_packet_source = IPU_ISYS_SHORT_PACKET_FROM_TUNIT; + trace_dma_addr = &isys->short_packet_trace_buffer_dma_addr; + mutex_init(&isys->short_packet_tracing_mutex); + isys->short_packet_trace_buffer = + dma_alloc_attrs(&adev->dev, trace_size, trace_dma_addr, + GFP_KERNEL, attrs); + if (!isys->short_packet_trace_buffer) + return -ENOMEM; +#else + isys->short_packet_source = IPU_ISYS_SHORT_PACKET_FROM_RECEIVER; +#endif + isys->adev = adev; + isys->pdata = adev->pdata; + + INIT_LIST_HEAD(&isys->requests); + + spin_lock_init(&isys->lock); + spin_lock_init(&isys->power_lock); + isys->power = 0; + + mutex_init(&isys->mutex); + mutex_init(&isys->stream_mutex); + mutex_init(&isys->lib_mutex); + + spin_lock_init(&isys->listlock); + INIT_LIST_HEAD(&isys->framebuflist); + INIT_LIST_HEAD(&isys->framebuflist_fw); + + dev_info(&adev->dev, "isys probe %p %p\n", adev, &adev->dev); + ipu_bus_set_drvdata(adev, isys); + + isys->line_align = IPU_ISYS_2600_MEM_LINE_ALIGN; +#ifdef CONFIG_VIDEO_INTEL_IPU4 + isys->icache_prefetch = is_ipu_hw_bxtp_e0(isp); +#else + isys->icache_prefetch = 0; +#endif + +#ifndef CONFIG_PM + isys_setup_hw(isys); +#endif + + if (!isp->secure_mode) { + fw = isp->cpd_fw; + rval = ipu_buttress_map_fw_image(adev, fw, &isys->fw_sgt); + if (rval) + goto release_firmware; + + isys->pkg_dir = ipu_cpd_create_pkg_dir(adev, isp->cpd_fw->data, + sg_dma_address(isys-> + fw_sgt. + sgl), + &isys->pkg_dir_dma_addr, + &isys->pkg_dir_size); + if (!isys->pkg_dir) { + rval = -ENOMEM; + goto remove_shared_buffer; + } + } + + /* Debug fs failure is not fatal. */ + ipu_isys_init_debugfs(isys); + + ipu_trace_init(adev->isp, isys->pdata->base, &adev->dev, + isys_trace_blocks); + + cpu_latency_qos_add_request(&isys->pm_qos, PM_QOS_DEFAULT_VALUE); + alloc_fw_msg_buffers(isys, 20); + + pm_runtime_allow(&adev->dev); + pm_runtime_enable(&adev->dev); + + rval = isys_register_devices(isys); + if (rval) + goto out_remove_pkg_dir_shared_buffer; + + trace_printk("E|TMWK\n"); + return 0; + +out_remove_pkg_dir_shared_buffer: + if (!isp->secure_mode) + ipu_cpd_free_pkg_dir(adev, isys->pkg_dir, + isys->pkg_dir_dma_addr, + isys->pkg_dir_size); +remove_shared_buffer: + if (!isp->secure_mode) + ipu_buttress_unmap_fw_image(adev, &isys->fw_sgt); +release_firmware: + if (!isp->secure_mode) + release_firmware(isys->fw); + ipu_trace_uninit(&adev->dev); + + trace_printk("E|TMWK\n"); + + mutex_destroy(&isys->mutex); + mutex_destroy(&isys->stream_mutex); + + if (isys->short_packet_source == IPU_ISYS_SHORT_PACKET_FROM_TUNIT) { + mutex_destroy(&isys->short_packet_tracing_mutex); +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + dma_free_attrs(&adev->dev, trace_size, + isys->short_packet_trace_buffer, + isys->short_packet_trace_buffer_dma_addr, + attrs); +#endif + } + + return rval; +} + +struct fwmsg { + int type; + char *msg; + bool valid_ts; +}; + +static const struct fwmsg fw_msg[] = { + {IPU_FW_ISYS_RESP_TYPE_STREAM_OPEN_DONE, "STREAM_OPEN_DONE", 0}, + {IPU_FW_ISYS_RESP_TYPE_STREAM_CLOSE_ACK, "STREAM_CLOSE_ACK", 0}, + {IPU_FW_ISYS_RESP_TYPE_STREAM_START_ACK, "STREAM_START_ACK", 0}, + {IPU_FW_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK, + "STREAM_START_AND_CAPTURE_ACK", 0}, + {IPU_FW_ISYS_RESP_TYPE_STREAM_STOP_ACK, "STREAM_STOP_ACK", 0}, + {IPU_FW_ISYS_RESP_TYPE_STREAM_FLUSH_ACK, "STREAM_FLUSH_ACK", 0}, + {IPU_FW_ISYS_RESP_TYPE_PIN_DATA_READY, "PIN_DATA_READY", 1}, + {IPU_FW_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK, "STREAM_CAPTURE_ACK", 0}, + {IPU_FW_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE, + "STREAM_START_AND_CAPTURE_DONE", 1}, + {IPU_FW_ISYS_RESP_TYPE_STREAM_CAPTURE_DONE, "STREAM_CAPTURE_DONE", 1}, + {IPU_FW_ISYS_RESP_TYPE_FRAME_SOF, "FRAME_SOF", 1}, + {IPU_FW_ISYS_RESP_TYPE_FRAME_EOF, "FRAME_EOF", 1}, + {IPU_FW_ISYS_RESP_TYPE_STATS_DATA_READY, "STATS_READY", 1}, + {-1, "UNKNOWN MESSAGE", 0}, +}; + +static int resp_type_to_index(int type) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(fw_msg); i++) + if (fw_msg[i].type == type) + return i; + + return i - 1; +} + +int isys_isr_one(struct ipu_bus_device *adev) +{ + struct ipu_isys *isys = ipu_bus_get_drvdata(adev); + struct ipu_fw_isys_resp_info_abi resp_data; + struct ipu_fw_isys_resp_info_abi *resp; + struct ipu_isys_pipeline *pipe; + u64 ts; + unsigned int i; + + if (!isys->fwcom) + return 0; + + resp = ipu_fw_isys_get_resp(isys->fwcom, IPU_BASE_MSG_RECV_QUEUES, + &resp_data); + if (!resp) + return 1; + + ts = (u64) resp->timestamp[1] << 32 | resp->timestamp[0]; + + if (resp->error_info.error == IPU_FW_ISYS_ERROR_STREAM_IN_SUSPENSION) + /* Suspension is kind of special case: not enough buffers */ + dev_dbg(&adev->dev, + "hostlib: error resp %02d %s, stream %u, error SUSPENSION, details %d, timestamp 0x%16.16llx, pin %d\n", + resp->type, + fw_msg[resp_type_to_index(resp->type)].msg, + resp->stream_handle, + resp->error_info.error_details, + fw_msg[resp_type_to_index(resp->type)].valid_ts ? + ts : 0, resp->pin_id); + else if (resp->error_info.error) + dev_dbg(&adev->dev, + "hostlib: error resp %02d %s, stream %u, error %d, details %d, timestamp 0x%16.16llx, pin %d\n", + resp->type, + fw_msg[resp_type_to_index(resp->type)].msg, + resp->stream_handle, + resp->error_info.error, resp->error_info.error_details, + fw_msg[resp_type_to_index(resp->type)].valid_ts ? + ts : 0, resp->pin_id); + else + dev_dbg(&adev->dev, + "hostlib: resp %02d %s, stream %u, timestamp 0x%16.16llx, pin %d\n", + resp->type, + fw_msg[resp_type_to_index(resp->type)].msg, + resp->stream_handle, + fw_msg[resp_type_to_index(resp->type)].valid_ts ? + ts : 0, resp->pin_id); + + if (resp->stream_handle >= IPU_ISYS_MAX_STREAMS) { + dev_err(&adev->dev, "bad stream handle %u\n", + resp->stream_handle); + goto leave; + } + + pipe = isys->pipes[resp->stream_handle]; + if (!pipe) { + dev_err(&adev->dev, "no pipeline for stream %u\n", + resp->stream_handle); + goto leave; + } + pipe->error = resp->error_info.error; + + switch (resp->type) { + case IPU_FW_ISYS_RESP_TYPE_STREAM_OPEN_DONE: + ipu_put_fw_mgs_buffer(ipu_bus_get_drvdata(adev), resp->buf_id); + complete(&pipe->stream_open_completion); + break; + case IPU_FW_ISYS_RESP_TYPE_STREAM_CLOSE_ACK: + complete(&pipe->stream_close_completion); + break; + case IPU_FW_ISYS_RESP_TYPE_STREAM_START_ACK: + complete(&pipe->stream_start_completion); + break; + case IPU_FW_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK: + ipu_put_fw_mgs_buffer(ipu_bus_get_drvdata(adev), resp->buf_id); + complete(&pipe->stream_start_completion); + break; + case IPU_FW_ISYS_RESP_TYPE_STREAM_STOP_ACK: + complete(&pipe->stream_stop_completion); + break; + case IPU_FW_ISYS_RESP_TYPE_STREAM_FLUSH_ACK: + complete(&pipe->stream_stop_completion); + break; + case IPU_FW_ISYS_RESP_TYPE_PIN_DATA_READY: + if (resp->pin_id < IPU_ISYS_OUTPUT_PINS && + pipe->output_pins[resp->pin_id].pin_ready) + pipe->output_pins[resp->pin_id].pin_ready(pipe, resp); + else + dev_err(&adev->dev, + "%d:No data pin ready handler for pin id %d\n", + resp->stream_handle, resp->pin_id); + break; + case IPU_FW_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK: + ipu_put_fw_mgs_buffer(ipu_bus_get_drvdata(adev), resp->buf_id); + complete(&pipe->capture_ack_completion); + break; + case IPU_FW_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE: + case IPU_FW_ISYS_RESP_TYPE_STREAM_CAPTURE_DONE: + if (pipe->interlaced) { + struct ipu_isys_buffer *ib, *ib_safe; + struct list_head list; + unsigned long flags; + + if (pipe->isys->short_packet_source == + IPU_ISYS_SHORT_PACKET_FROM_TUNIT) + pipe->cur_field = + ipu_isys_csi2_get_current_field(pipe, + resp-> + timestamp); + /* + * Move the pending buffers to a local temp list. + * Then we do not need to handle the lock during + * the loop. + */ + spin_lock_irqsave(&pipe->short_packet_queue_lock, + flags); + list_cut_position(&list, + &pipe->pending_interlaced_bufs, + pipe->pending_interlaced_bufs.prev); + spin_unlock_irqrestore(&pipe->short_packet_queue_lock, + flags); + + list_for_each_entry_safe(ib, ib_safe, &list, head) { + struct vb2_buffer *vb; + + vb = ipu_isys_buffer_to_vb2_buffer(ib); + to_vb2_v4l2_buffer(vb)->field = pipe->cur_field; + list_del(&ib->head); + + ipu_isys_queue_buf_done(ib); + } + } + for (i = 0; i < IPU_NUM_CAPTURE_DONE; i++) + if (pipe->capture_done[i]) + pipe->capture_done[i] (pipe, resp); + + break; + case IPU_FW_ISYS_RESP_TYPE_FRAME_SOF: + pipe->seq[pipe->seq_index].sequence = + atomic_read(&pipe->sequence) - 1; + pipe->seq[pipe->seq_index].timestamp = ts; + dev_dbg(&adev->dev, + "sof: handle %d: (index %u), timestamp 0x%16.16llx\n", + resp->stream_handle, + pipe->seq[pipe->seq_index].sequence, ts); + pipe->seq_index = (pipe->seq_index + 1) + % IPU_ISYS_MAX_PARALLEL_SOF; + break; + case IPU_FW_ISYS_RESP_TYPE_FRAME_EOF: + + + dev_dbg(&adev->dev, + "eof: handle %d: (index %u), timestamp 0x%16.16llx\n", + resp->stream_handle, + pipe->seq[pipe->seq_index].sequence, ts); + break; + case IPU_FW_ISYS_RESP_TYPE_STATS_DATA_READY: + break; + default: + dev_err(&adev->dev, "%d:unknown response type %u\n", + resp->stream_handle, resp->type); + break; + } + +leave: + ipu_fw_isys_put_resp(isys->fwcom, IPU_BASE_MSG_RECV_QUEUES); + return 0; +} + +static void isys_isr_poll(struct ipu_bus_device *adev) +{ + struct ipu_isys *isys = ipu_bus_get_drvdata(adev); + + if (!isys->fwcom) { + dev_dbg(&isys->adev->dev, + "got interrupt but device not configured yet\n"); + return; + } + + mutex_lock(&isys->mutex); + isys_isr(adev); + mutex_unlock(&isys->mutex); +} + +int ipu_isys_isr_run(void *ptr) +{ + struct ipu_isys *isys = ptr; + + while (!kthread_should_stop()) { + usleep_range(500, 1000); + if (isys->stream_opened) + isys_isr_poll(isys->adev); + } + + return 0; +} + +static struct ipu_bus_driver isys_driver = { + .probe = isys_probe, + .remove = isys_remove, + .isr = isys_isr, + .wanted = IPU_ISYS_NAME, + .drv = { + .name = IPU_ISYS_NAME, + .owner = THIS_MODULE, + .pm = ISYS_PM_OPS, + }, +}; + +module_ipu_bus_driver(isys_driver); + +static const struct pci_device_id ipu_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU_PCI_ID)}, + {0,} +}; +MODULE_DEVICE_TABLE(pci, ipu_pci_tbl); + +MODULE_AUTHOR("Sakari Ailus "); +MODULE_AUTHOR("Samu Onkalo "); +MODULE_AUTHOR("Jouni Högander "); +MODULE_AUTHOR("Jouni Ukkonen "); +MODULE_AUTHOR("Jianxu Zheng "); +MODULE_AUTHOR("Tianshu Qiu "); +MODULE_AUTHOR("Renwei Wu "); +MODULE_AUTHOR("Bingbu Cao "); +MODULE_AUTHOR("Yunliang Ding "); +MODULE_AUTHOR("Zaikuo Wang "); +MODULE_AUTHOR("Leifu Zhao "); +MODULE_AUTHOR("Xia Wu "); +MODULE_AUTHOR("Kun Jiang "); +MODULE_AUTHOR("Yu Xia "); +MODULE_AUTHOR("Jerry Hu "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu input system driver"); +MODULE_IMPORT_NS("INTEL_IPU_BRIDGE"); diff --git a/drivers/media/pci/intel/ipu-isys.h b/drivers/media/pci/intel/ipu-isys.h new file mode 100644 index 0000000000000..3511faca318d9 --- /dev/null +++ b/drivers/media/pci/intel/ipu-isys.h @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_ISYS_H +#define IPU_ISYS_H + +#include +#include + +#include +#include + +#include + +#include "ipu.h" +#include "ipu-isys-media.h" +#include "ipu-isys-csi2.h" +#include "ipu-isys-csi2-be.h" +#include "ipu-isys-tpg.h" +#include "ipu-isys-video.h" +#include "ipu-pdata.h" +#include "ipu-fw-isys.h" +#include "ipu-platform-isys.h" + +#define IPU_ISYS_2600_MEM_LINE_ALIGN 64 + +/* for TPG */ +#define IPU_ISYS_FREQ 533000000UL + +/* + * 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 40 +#define IPU_ISYS_SIZE_SEND_QUEUE 40 +#define IPU_ISYS_SIZE_PROXY_RECV_QUEUE 5 +#define IPU_ISYS_SIZE_PROXY_SEND_QUEUE 5 +#define IPU_ISYS_NUM_RECV_QUEUE 1 + +/* + * Device close takes some time from last ack message to actual stopping + * of the SP processor. As long as the SP processor runs we can't proceed with + * clean up of resources. + */ +#define IPU_ISYS_OPEN_TIMEOUT_US 1000 +#define IPU_ISYS_OPEN_RETRY 1000 +#define IPU_ISYS_TURNOFF_DELAY_US 1000 +#define IPU_ISYS_TURNOFF_TIMEOUT 1000 +#define IPU_LIB_CALL_TIMEOUT_JIFFIES \ + msecs_to_jiffies(IPU_LIB_CALL_TIMEOUT_MS) + +#define IPU_ISYS_CSI2_LONG_PACKET_HEADER_SIZE 32 +#define IPU_ISYS_CSI2_LONG_PACKET_FOOTER_SIZE 32 + +#define IPU_ISYS_MIN_WIDTH 1U +#define IPU_ISYS_MIN_HEIGHT 1U +#define IPU_ISYS_MAX_WIDTH 16384U +#define IPU_ISYS_MAX_HEIGHT 16384U + +struct task_struct; + +struct ipu_isys_csi2_config { + unsigned int nlanes; + unsigned int port; +}; + +struct sensor_async_sd { + struct v4l2_async_connection asd; + struct ipu_isys_csi2_config csi2; +}; + +/* + * struct ipu_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 + * @lock: serialise access to pipes + * @pipes: pipelines per stream ID + * @fwcom: fw communication layer private pointer + * or optional external library private pointer + * @line_align: line alignment in memory + * @reset_needed: Isys requires d0i0->i3 transition + * @video_opened: total number of opened file handles on video nodes + * @mutex: serialise access isys video open/release related operations + * @stream_mutex: serialise stream start and stop, queueing requests + * @lib_mutex: optional external library mutex + * @pdata: platform data pointer + * @csi2: CSI-2 receivers + * @tpg: test pattern generators + * @csi2_be: CSI-2 back-ends + * @isa: Input system accelerator + * @fw: ISYS firmware binary (unsecure firmware) + * @fw_sgt: fw scatterlist + * @pkg_dir: host pointer to pkg_dir + * @pkg_dir_dma_addr: I/O virtual address for pkg_dir + * @pkg_dir_size: size of pkg_dir in bytes + * @short_packet_source: select short packet capture mode + */ +struct ipu_isys { + struct media_device media_dev; + struct v4l2_device v4l2_dev; + struct ipu_bus_device *adev; + + int power; + spinlock_t power_lock; /* Serialise access to power */ + u32 isr_csi2_bits; + u32 csi2_rx_ctrl_cached; + spinlock_t lock; /* Serialise access to pipes */ + struct ipu_isys_pipeline *pipes[IPU_ISYS_MAX_STREAMS]; + void *fwcom; + unsigned int line_align; + bool reset_needed; + bool icache_prefetch; + bool csi2_cse_ipc_not_supported; + unsigned int video_opened; + unsigned int stream_opened; +#if !defined(CONFIG_VIDEO_INTEL_IPU4) && !defined(CONFIG_VIDEO_INTEL_IPU4P) + unsigned int sensor_types[N_IPU_FW_ISYS_SENSOR_TYPE]; +#endif + + struct dentry *debugfsdir; + struct mutex mutex; /* Serialise isys video open/release related */ + struct mutex stream_mutex; /* Stream start, stop, queueing reqs */ + struct mutex lib_mutex; /* Serialise optional external library mutex */ + + struct ipu_isys_pdata *pdata; + + struct ipu_isys_csi2 *csi2; + struct ipu_isys_tpg *tpg; + struct ipu_isys_isa isa; + struct ipu_isys_csi2_be csi2_be; + struct ipu_isys_csi2_be_soc csi2_be_soc; + + const struct firmware *fw; + struct sg_table fw_sgt; + + u64 *pkg_dir; + dma_addr_t pkg_dir_dma_addr; + unsigned int pkg_dir_size; + + struct list_head requests; + struct pm_qos_request pm_qos; + unsigned int short_packet_source; + struct ipu_isys_csi2_monitor_message *short_packet_trace_buffer; + dma_addr_t short_packet_trace_buffer_dma_addr; + unsigned int short_packet_tracing_count; + struct mutex short_packet_tracing_mutex; /* For tracing count */ + u64 tsc_timer_base; + u64 tunit_timer_base; + spinlock_t listlock; /* Protect framebuflist */ + struct list_head framebuflist; + struct list_head framebuflist_fw; + struct v4l2_async_notifier notifier; +}; + +struct isys_fw_msgs { + union { + u64 dummy; + struct ipu_fw_isys_frame_buff_set_abi frame; + struct ipu_fw_isys_stream_cfg_data_abi stream; + } fw_msg; + struct list_head head; + dma_addr_t dma_addr; +}; + +#define to_frame_msg_buf(a) (&(a)->fw_msg.frame) +#define to_stream_cfg_msg_buf(a) (&(a)->fw_msg.stream) +#define to_dma_addr(a) ((a)->dma_addr) + +struct isys_fw_msgs *ipu_get_fw_msg_buf(struct ipu_isys_pipeline *ip); +void ipu_put_fw_mgs_buffer(struct ipu_isys *isys, u64 data); +void ipu_cleanup_fw_msg_bufs(struct ipu_isys *isys); + +extern const struct v4l2_ioctl_ops ipu_isys_ioctl_ops; + +void isys_setup_hw(struct ipu_isys *isys); +int isys_isr_one(struct ipu_bus_device *adev); +int ipu_isys_isr_run(void *ptr); +irqreturn_t isys_isr(struct ipu_bus_device *adev); + +#endif /* IPU_ISYS_H */ diff --git a/drivers/media/pci/intel/ipu-mmu.c b/drivers/media/pci/intel/ipu-mmu.c new file mode 100644 index 0000000000000..ec576168e9ada --- /dev/null +++ b/drivers/media/pci/intel/ipu-mmu.c @@ -0,0 +1,869 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include + +#include +#include +#include +#include +#include + +#include "ipu.h" +#include "ipu-platform.h" +#include "ipu-bus.h" +#include "ipu-dma.h" +#include "ipu-mmu.h" +#include "ipu-platform-regs.h" + +#define ISP_PAGE_SHIFT 12 +#define ISP_PAGE_SIZE BIT(ISP_PAGE_SHIFT) +#define ISP_PAGE_MASK (~(ISP_PAGE_SIZE - 1)) + +#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 1024 +#define ISP_L2PT_PTES 1024 + +#define ISP_PADDR_SHIFT 12 + +#define REG_TLB_INVALIDATE 0x0000 + +#define MMU0_TLB_INVALIDATE 1 + +#define MMU1_TLB_INVALIDATE 0xffff + +#define REG_L1_PHYS 0x0004 /* 27-bit pfn */ +#define REG_INFO 0x0008 + +/* The range of stream ID i in L1 cache is from 0 to 15 */ +#define MMUV2_REG_L1_STREAMID(i) (0x0c + ((i) * 4)) + +/* The range of stream ID i in L2 cache is from 0 to 15 */ +#define MMUV2_REG_L2_STREAMID(i) (0x4c + ((i) * 4)) + +/* ZLW Enable for each stream in L1 MMU AT where i : 0..15 */ +#define MMUV2_AT_REG_L1_ZLW_EN_SID(i) (0x100 + ((i) * 0x20)) + +/* ZLW 1D mode Enable for each stream in L1 MMU AT where i : 0..15 */ +#define MMUV2_AT_REG_L1_ZLW_1DMODE_SID(i) (0x100 + ((i) * 0x20) + 0x0004) + +/* Set ZLW insertion N pages ahead per stream 1D where i : 0..15 */ +#define MMUV2_AT_REG_L1_ZLW_INS_N_AHEAD_SID(i) (0x100 + ((i) * 0x20) + 0x0008) + +/* ZLW 2D mode Enable for each stream in L1 MMU AT where i : 0..15 */ +#define MMUV2_AT_REG_L1_ZLW_2DMODE_SID(i) (0x100 + ((i) * 0x20) + 0x0010) + +/* ZLW Insertion for each stream in L1 MMU AT where i : 0..15 */ +#define MMUV2_AT_REG_L1_ZLW_INSERTION(i) (0x100 + ((i) * 0x20) + 0x000c) + +#define MMUV2_AT_REG_L1_FW_ZLW_FIFO (0x100 + \ + (IPU_MMU_MAX_TLB_L1_STREAMS * 0x20) + 0x003c) + +/* FW ZLW has prioty - needed for ZLW invalidations */ +#define MMUV2_AT_REG_L1_FW_ZLW_PRIO (0x100 + \ + (IPU_MMU_MAX_TLB_L1_STREAMS * 0x20)) + +#define TBL_PHYS_ADDR(a) ((phys_addr_t)(a) << ISP_PADDR_SHIFT) +#define TBL_VIRT_ADDR(a) phys_to_virt(TBL_PHYS_ADDR(a)) + +static void zlw_invalidate(struct ipu_mmu *mmu, struct ipu_mmu_hw *mmu_hw) +{ + unsigned int retry = 0; + unsigned int i, j; + int ret; + + for (i = 0; i < mmu_hw->nr_l1streams; i++) { + /* We need to invalidate only the zlw enabled stream IDs */ + if (mmu_hw->l1_zlw_en[i]) { + /* + * Maximum 16 blocks per L1 stream + * Write trash buffer iova offset to the FW_ZLW + * register. This will trigger pre-fetching of next 16 + * pages from the page table. So we need to increment + * iova address by 16 * 4K to trigger the next 16 pages. + * Once this loop is completed, the L1 cache will be + * filled with trash buffer translation. + * + * TODO: Instead of maximum 16 blocks, use the allocated + * block size + */ + for (j = 0; j < mmu_hw->l1_block_sz[i]; j++) + writel(mmu->iova_addr_trash + + j * MMUV2_TRASH_L1_BLOCK_OFFSET, + mmu_hw->base + + MMUV2_AT_REG_L1_ZLW_INSERTION(i)); + + /* + * Now we need to fill the L2 cache entry. L2 cache + * entries will be automatically updated, based on the + * L1 entry. The above loop for L1 will update only one + * of the two entries in L2 as the L1 is under 4MB + * range. To force the other entry in L2 to update, we + * just need to trigger another pre-fetch which is + * outside the above 4MB range. + */ + writel(mmu->iova_addr_trash + + MMUV2_TRASH_L2_BLOCK_OFFSET, + mmu_hw->base + + MMUV2_AT_REG_L1_ZLW_INSERTION(0)); + } + } + + /* + * Wait until AT is ready. FIFO read should return 2 when AT is ready. + * Retry value of 1000 is just by guess work to avoid the forever loop. + */ + do { + if (retry > 1000) { + dev_err(mmu->dev, "zlw invalidation failed\n"); + return; + } + ret = readl(mmu_hw->base + MMUV2_AT_REG_L1_FW_ZLW_FIFO); + retry++; + } while (ret != 2); +} + +static void tlb_invalidate(struct ipu_mmu *mmu) +{ + unsigned int i; + unsigned long flags; + + 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++) { + u32 inv; + + /* + * To avoid the HW bug induced dead lock in some of the IPU4 + * MMUs on successive invalidate calls, we need to first do a + * read to the page table base before writing the invalidate + * register. MMUs which need to implement this WA, will have + * the insert_read_before_invalidate flasg set as true. + * Disregard the return value of the read. + */ + if (mmu->mmu_hw[i].insert_read_before_invalidate) + readl(mmu->mmu_hw[i].base + REG_L1_PHYS); + + /* Normal invalidate or zlw invalidate */ + if (mmu->mmu_hw[i].zlw_invalidate) { + /* trash buffer must be mapped by now, just in case! */ + WARN_ON(!mmu->iova_addr_trash); + + zlw_invalidate(mmu, &mmu->mmu_hw[i]); + } else { + if (mmu->mmu_hw[i].nr_l1streams == 32) + inv = 0xffffffff; + else if (mmu->mmu_hw[i].nr_l1streams == 0) + inv = MMU0_TLB_INVALIDATE; + else + inv = MMU1_TLB_INVALIDATE; + writel(inv, mmu->mmu_hw[i].base + + REG_TLB_INVALIDATE); + } + } + spin_unlock_irqrestore(&mmu->ready_lock, flags); +} + +#ifdef DEBUG +static void page_table_dump(struct ipu_mmu_info *mmu_info) +{ + u32 l1_idx; + + pr_debug("begin IOMMU page table dump\n"); + + for (l1_idx = 0; l1_idx < ISP_L1PT_PTES; l1_idx++) { + u32 l2_idx; + u32 iova = (phys_addr_t) l1_idx << ISP_L1PT_SHIFT; + + if (mmu_info->pgtbl[l1_idx] == mmu_info->dummy_l2_tbl) + continue; + pr_debug("l1 entry %u; iovas 0x%8.8x--0x%8.8x, at %p\n", + l1_idx, iova, iova + ISP_PAGE_SIZE, + (void *)TBL_PHYS_ADDR(mmu_info->pgtbl[l1_idx])); + + for (l2_idx = 0; l2_idx < ISP_L2PT_PTES; l2_idx++) { + u32 *l2_pt = TBL_VIRT_ADDR(mmu_info->pgtbl[l1_idx]); + u32 iova2 = iova + (l2_idx << ISP_L2PT_SHIFT); + + if (l2_pt[l2_idx] == mmu_info->dummy_page) + continue; + + pr_debug("\tl2 entry %u; iova 0x%8.8x, phys %p\n", + l2_idx, iova2, + (void *)TBL_PHYS_ADDR(l2_pt[l2_idx])); + } + } + + pr_debug("end IOMMU page table dump\n"); +} +#endif /* DEBUG */ + +static u32 *alloc_page_table(struct ipu_mmu_info *mmu_info, bool l1) +{ + u32 *pt = (u32 *) __get_free_page(GFP_KERNEL | GFP_DMA32); + int i; + + if (!pt) + return NULL; + + pr_debug("__get_free_page() == %p\n", pt); + + for (i = 0; i < ISP_L1PT_PTES; i++) + pt[i] = l1 ? mmu_info->dummy_l2_tbl : mmu_info->dummy_page; + + return pt; +} + +static int l2_map(struct ipu_mmu_info *mmu_info, unsigned long iova, + phys_addr_t paddr, size_t size) +{ + u32 l1_idx = iova >> ISP_L1PT_SHIFT; + u32 l1_entry = mmu_info->pgtbl[l1_idx]; + u32 *l2_pt; + u32 iova_start = iova; + unsigned int l2_idx; + unsigned long flags; + + pr_debug("mapping l2 page table for l1 index %u (iova %8.8x)\n", + l1_idx, (u32) iova); + + if (l1_entry == mmu_info->dummy_l2_tbl) { + u32 *l2_virt = alloc_page_table(mmu_info, false); + + if (!l2_virt) + return -ENOMEM; + + l1_entry = virt_to_phys(l2_virt) >> ISP_PADDR_SHIFT; + pr_debug("allocated page for l1_idx %u\n", l1_idx); + + spin_lock_irqsave(&mmu_info->lock, flags); + if (mmu_info->pgtbl[l1_idx] == mmu_info->dummy_l2_tbl) { + mmu_info->pgtbl[l1_idx] = l1_entry; +#ifdef CONFIG_X86 + clflush_cache_range(&mmu_info->pgtbl[l1_idx], + sizeof(mmu_info->pgtbl[l1_idx])); +#endif /* CONFIG_X86 */ + } else { + spin_unlock_irqrestore(&mmu_info->lock, flags); + free_page((unsigned long)TBL_VIRT_ADDR(l1_entry)); + spin_lock_irqsave(&mmu_info->lock, flags); + } + } else { + spin_lock_irqsave(&mmu_info->lock, flags); + } + + l2_pt = TBL_VIRT_ADDR(mmu_info->pgtbl[l1_idx]); + + pr_debug("l2_pt at %p\n", l2_pt); + + paddr = ALIGN(paddr, ISP_PAGE_SIZE); + + l2_idx = (iova_start & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT; + + pr_debug("l2_idx %u, phys 0x%8.8x\n", l2_idx, l2_pt[l2_idx]); + if (l2_pt[l2_idx] != mmu_info->dummy_page) { + spin_unlock_irqrestore(&mmu_info->lock, flags); + return -EBUSY; + } + + l2_pt[l2_idx] = paddr >> ISP_PADDR_SHIFT; + + spin_unlock_irqrestore(&mmu_info->lock, flags); + +#ifdef CONFIG_X86 + clflush_cache_range(&l2_pt[l2_idx], sizeof(l2_pt[l2_idx])); +#endif /* CONFIG_X86 */ + + pr_debug("l2 index %u mapped as 0x%8.8x\n", l2_idx, l2_pt[l2_idx]); + + return 0; +} + +static int __ipu_mmu_map(struct ipu_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); + + pr_debug + ("mapping iova 0x%8.8x--0x%8.8x, size %zu at paddr 0x%10.10llx\n", + iova_start, iova_end, size, paddr); + + return l2_map(mmu_info, iova_start, paddr, size); +} + +static size_t l2_unmap(struct ipu_mmu_info *mmu_info, unsigned long iova, + phys_addr_t dummy, size_t size) +{ + u32 l1_idx = iova >> ISP_L1PT_SHIFT; + u32 *l2_pt = TBL_VIRT_ADDR(mmu_info->pgtbl[l1_idx]); + u32 iova_start = iova; + unsigned int l2_idx; + size_t unmapped = 0; + + pr_debug("unmapping l2 page table for l1 index %u (iova 0x%8.8lx)\n", + l1_idx, iova); + + if (mmu_info->pgtbl[l1_idx] == mmu_info->dummy_l2_tbl) + return -EINVAL; + + pr_debug("l2_pt at %p\n", l2_pt); + + for (l2_idx = (iova_start & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT; + (iova_start & ISP_L1PT_MASK) + (l2_idx << ISP_PAGE_SHIFT) + < iova_start + size && l2_idx < ISP_L2PT_PTES; l2_idx++) { + unsigned long flags; + + pr_debug("l2 index %u unmapped, was 0x%10.10llx\n", + l2_idx, TBL_PHYS_ADDR(l2_pt[l2_idx])); + spin_lock_irqsave(&mmu_info->lock, flags); + l2_pt[l2_idx] = mmu_info->dummy_page; + spin_unlock_irqrestore(&mmu_info->lock, flags); +#ifdef CONFIG_X86 + clflush_cache_range(&l2_pt[l2_idx], sizeof(l2_pt[l2_idx])); +#endif /* CONFIG_X86 */ + unmapped++; + } + + return unmapped << ISP_PAGE_SHIFT; +} + +static size_t __ipu_mmu_unmap(struct ipu_mmu_info *mmu_info, + unsigned long iova, size_t size) +{ + return l2_unmap(mmu_info, iova, 0, size); +} + +static int allocate_trash_buffer(struct ipu_bus_device *adev) +{ + struct ipu_mmu *mmu = ipu_bus_get_drvdata(adev); + unsigned int n_pages = PAGE_ALIGN(IPU_MMUV2_TRASH_RANGE) >> PAGE_SHIFT; + struct iova *iova; + u32 iova_addr; + unsigned int i; + int ret; + + /* Allocate 8MB in iova range */ + iova = alloc_iova(&mmu->dmap->iovad, n_pages, + dma_get_mask(mmu->dev) >> PAGE_SHIFT, 0); + if (!iova) { + dev_err(&adev->dev, "cannot allocate iova range for trash\n"); + return -ENOMEM; + } + + /* + * 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 = ipu_mmu_map(mmu->dmap->mmu_info, iova_addr << PAGE_SHIFT, + page_to_phys(mmu->trash_page), PAGE_SIZE); + if (ret) { + dev_err(&adev->dev, + "mapping trash buffer range failed\n"); + goto out_unmap; + } + + iova_addr++; + } + + /* save the address for the ZLW invalidation */ + mmu->iova_addr_trash = iova->pfn_lo << PAGE_SHIFT; + dev_info(&adev->dev, "iova trash buffer for MMUID: %d is %u\n", + mmu->mmid, (unsigned int)mmu->iova_addr_trash); + return 0; + +out_unmap: + ipu_mmu_unmap(mmu->dmap->mmu_info, iova->pfn_lo << PAGE_SHIFT, + (iova->pfn_hi - iova->pfn_lo + 1) << PAGE_SHIFT); + __free_iova(&mmu->dmap->iovad, iova); + return ret; +} + +static int ipu_mmu_hw_init(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_mmu *mmu = ipu_bus_get_drvdata(adev); + unsigned int i; + unsigned long flags; + struct ipu_mmu_info *mmu_info; + + dev_dbg(dev, "mmu hw init\n"); + /* + * FIXME: following fix for null pointer check is not a complete one. + * if mmu is not powered cycled before being used, the page table + * address will still not be set into HW. + */ + if (!mmu->dmap) { + dev_warn(dev, "mmu is not ready yet. skipping.\n"); + return 0; + } + + mmu_info = mmu->dmap->mmu_info; + + /* Initialise the each MMU HW block */ + for (i = 0; i < mmu->nr_mmus; i++) { + struct ipu_mmu_hw *mmu_hw = &mmu->mmu_hw[i]; +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + bool zlw_invalidate = false; +#endif + unsigned int j; + u16 block_addr; + + /* Write page table address per MMU */ + writel((phys_addr_t) virt_to_phys(mmu_info->pgtbl) + >> ISP_PADDR_SHIFT, + mmu->mmu_hw[i].base + REG_L1_PHYS); + + /* Set info bits per MMU */ + writel(mmu->mmu_hw[i].info_bits, + mmu->mmu_hw[i].base + REG_INFO); + + /* Configure MMU TLB stream configuration for L1 */ + for (j = 0, block_addr = 0; j < mmu_hw->nr_l1streams; + block_addr += mmu->mmu_hw[i].l1_block_sz[j], j++) { + if (block_addr > IPU_MAX_LI_BLOCK_ADDR) { + dev_err(dev, "invalid L1 configuration\n"); + return -EINVAL; + } + + /* Write block start address for each streams */ + writel(block_addr, mmu_hw->base + + mmu_hw->l1_stream_id_reg_offset + 4 * j); + +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + /* Enable ZLW for streams based on the init table */ + writel(mmu->mmu_hw[i].l1_zlw_en[j], + mmu_hw->base + + MMUV2_AT_REG_L1_ZLW_EN_SID(j)); + + /* To track if zlw is enabled in any streams */ + zlw_invalidate |= mmu->mmu_hw[i].l1_zlw_en[j]; + + /* Enable ZLW 1D mode for streams from the init table */ + writel(mmu->mmu_hw[i].l1_zlw_1d_mode[j], + mmu_hw->base + + MMUV2_AT_REG_L1_ZLW_1DMODE_SID(j)); + + /* Set when the ZLW insertion will happen */ + writel(mmu->mmu_hw[i].l1_ins_zlw_ahead_pages[j], + mmu_hw->base + + MMUV2_AT_REG_L1_ZLW_INS_N_AHEAD_SID(j)); + + /* Set if ZLW 2D mode active for each streams */ + writel(mmu->mmu_hw[i].l1_zlw_2d_mode[j], + mmu_hw->base + + MMUV2_AT_REG_L1_ZLW_2DMODE_SID(j)); +#endif + } + +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) + /* + * If ZLW invalidate is enabled even for one stream in a MMU1, + * we need to set the FW ZLW operations have higher priority + * on that MMU1 + */ + if (zlw_invalidate) + writel(1, mmu_hw->base + + MMUV2_AT_REG_L1_FW_ZLW_PRIO); +#endif + /* Configure MMU TLB stream configuration for L2 */ + for (j = 0, block_addr = 0; j < mmu_hw->nr_l2streams; + block_addr += mmu->mmu_hw[i].l2_block_sz[j], j++) { + if (block_addr > IPU_MAX_L2_BLOCK_ADDR) { + dev_err(dev, "invalid L2 configuration\n"); + return -EINVAL; + } + + writel(block_addr, mmu_hw->base + + mmu_hw->l2_stream_id_reg_offset + 4 * j); + } + } + + /* Allocate trash buffer, if not allocated. Only once per MMU */ + if (!mmu->iova_addr_trash) { + int ret; + + ret = allocate_trash_buffer(adev); + if (ret) { + dev_err(dev, "trash buffer allocation failed\n"); + return ret; + } + + /* + * Update the domain pointer to trash buffer to release it on + * domain destroy + */ + mmu_info->iova_addr_trash = mmu->iova_addr_trash; + } + + spin_lock_irqsave(&mmu->ready_lock, flags); + mmu->ready = true; + spin_unlock_irqrestore(&mmu->ready_lock, flags); + + return 0; +} + +static void set_mapping(struct ipu_mmu *mmu, struct ipu_dma_mapping *dmap) +{ + mmu->dmap = dmap; + + if (!dmap) + return; + + pm_runtime_get_sync(mmu->dev); + ipu_mmu_hw_init(mmu->dev); + pm_runtime_put(mmu->dev); +} + +phys_addr_t ipu_mmu_iova_to_phys(struct ipu_mmu_info *mmu_info, + dma_addr_t iova) +{ + u32 *l2_pt = TBL_VIRT_ADDR(mmu_info->pgtbl[iova >> ISP_L1PT_SHIFT]); + + return (phys_addr_t) l2_pt[(iova & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT] + << ISP_PAGE_SHIFT; +} +EXPORT_SYMBOL(ipu_mmu_iova_to_phys); + +/** + * The following four functions are implemented based on iommu.c + * drivers/iommu/iommu.c/iommu_pgsize(). + */ +static size_t ipu_mmu_pgsize(unsigned long pgsize_bitmap, + unsigned long addr_merge, size_t size) +{ + unsigned int pgsize_idx; + size_t pgsize; + + /* Max page size that still fits into 'size' */ + pgsize_idx = __fls(size); + + /* need to consider alignment requirements ? */ + if (likely(addr_merge)) { + /* Max page size allowed by address */ + unsigned int align_pgsize_idx = __ffs(addr_merge); + + pgsize_idx = min(pgsize_idx, align_pgsize_idx); + } + + /* build a mask of acceptable page sizes */ + pgsize = (1UL << (pgsize_idx + 1)) - 1; + + /* throw away page sizes not supported by the hardware */ + pgsize &= pgsize_bitmap; + + /* make sure we're still sane */ + WARN_ON(!pgsize); + + /* pick the biggest page */ + pgsize_idx = __fls(pgsize); + pgsize = 1UL << pgsize_idx; + + return pgsize; +} + +/* drivers/iommu/iommu.c/iommu_unmap() */ +size_t ipu_mmu_unmap(struct ipu_mmu_info *mmu_info, unsigned long iova, + size_t size) +{ + size_t unmapped_page, unmapped = 0; + unsigned int min_pagesz; + + /* find out the minimum page size supported */ + min_pagesz = 1 << __ffs(mmu_info->pgsize_bitmap); + + /* + * The virtual address, 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 | size, min_pagesz)) { + dev_err(NULL, "unaligned: iova 0x%lx size 0x%zx min_pagesz 0x%x\n", + iova, size, min_pagesz); + return -EINVAL; + } + + /* + * Keep iterating until we either unmap 'size' bytes (or more) + * or we hit an area that isn't mapped. + */ + while (unmapped < size) { + size_t pgsize = ipu_mmu_pgsize(mmu_info->pgsize_bitmap, + iova, size - unmapped); + + unmapped_page = __ipu_mmu_unmap(mmu_info, iova, pgsize); + if (!unmapped_page) + break; + + dev_dbg(NULL, "unmapped: iova 0x%lx size 0x%zx\n", + iova, unmapped_page); + + iova += unmapped_page; + unmapped += unmapped_page; + } + + return unmapped; +} +EXPORT_SYMBOL(ipu_mmu_unmap); + +/* drivers/iommu/iommu.c/iommu_map() */ +int ipu_mmu_map(struct ipu_mmu_info *mmu_info, unsigned long iova, + phys_addr_t paddr, size_t size) +{ + unsigned long orig_iova = iova; + unsigned int min_pagesz; + size_t orig_size = size; + int ret = 0; + + if (mmu_info->pgsize_bitmap == 0UL) + return -ENODEV; + + /* find out the minimum page size supported */ + min_pagesz = 1 << __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)) { + pr_err("unaligned: iova 0x%lx pa %pa size 0x%zx min_pagesz 0x%x\n", + iova, &paddr, size, min_pagesz); + return -EINVAL; + } + + pr_debug("map: iova 0x%lx pa %pa size 0x%zx\n", iova, &paddr, size); + + while (size) { + size_t pgsize + = ipu_mmu_pgsize(mmu_info->pgsize_bitmap, + iova | paddr, size); + + pr_debug("mapping: iova 0x%lx pa %pa pgsize 0x%zx\n", + iova, &paddr, pgsize); + + ret = __ipu_mmu_map(mmu_info, iova, paddr, pgsize); + if (ret) + break; + + iova += pgsize; + paddr += pgsize; + size -= pgsize; + } + + /* unroll mapping in case something went wrong */ + if (ret) + ipu_mmu_unmap(mmu_info, orig_iova, orig_size - size); + + return ret; +} +EXPORT_SYMBOL(ipu_mmu_map); + +struct ipu_mmu_info *ipu_mmu_alloc(void) +{ + struct ipu_mmu_info *mmu_info; + void *ptr; + + mmu_info = kzalloc(sizeof(*mmu_info), GFP_KERNEL); + if (!mmu_info) + return NULL; + + mmu_info->aperture_start = 0; + mmu_info->aperture_end = DMA_BIT_MASK(IPU_MMU_ADDRESS_BITS); + mmu_info->pgsize_bitmap = SZ_4K; + + ptr = (void *)__get_free_page(GFP_KERNEL | GFP_DMA32); + if (!ptr) + goto err_mem; + + mmu_info->dummy_page = virt_to_phys(ptr) >> ISP_PAGE_SHIFT; + + ptr = alloc_page_table(mmu_info, false); + if (!ptr) + goto err; + + mmu_info->dummy_l2_tbl = virt_to_phys(ptr) >> ISP_PAGE_SHIFT; + + /* + * We always map the L1 page table (a single page as well as + * the L2 page tables). + */ + mmu_info->pgtbl = alloc_page_table(mmu_info, true); + if (!mmu_info->pgtbl) + goto err; + + spin_lock_init(&mmu_info->lock); + + pr_debug("domain initialised\n"); + + return mmu_info; + +err: + free_page((unsigned long)TBL_VIRT_ADDR(mmu_info->dummy_page)); + free_page((unsigned long)TBL_VIRT_ADDR(mmu_info->dummy_l2_tbl)); +err_mem: + kfree(mmu_info); + + return NULL; +} +EXPORT_SYMBOL(ipu_mmu_alloc); + +void ipu_mmu_destroy(struct ipu_mmu_info *mmu_info) +{ + struct iova *iova; + u32 l1_idx; + + if (mmu_info->iova_addr_trash) { + iova = find_iova(&mmu_info->dmap->iovad, + mmu_info->iova_addr_trash >> PAGE_SHIFT); + /* unmap and free the corresponding trash buffer iova */ + ipu_mmu_unmap(mmu_info, iova->pfn_lo << PAGE_SHIFT, + (iova->pfn_hi - iova->pfn_lo + 1) << PAGE_SHIFT); + __free_iova(&mmu_info->dmap->iovad, iova); + + /* + * Set iova_addr_trash in mmu to 0, so that on next HW init + * this will be mapped again. + */ + mmu_info->iova_addr_trash = 0; + } + + for (l1_idx = 0; l1_idx < ISP_L1PT_PTES; l1_idx++) + if (mmu_info->pgtbl[l1_idx] != mmu_info->dummy_l2_tbl) + free_page((unsigned long) + TBL_VIRT_ADDR(mmu_info->pgtbl[l1_idx])); + + free_page((unsigned long)TBL_VIRT_ADDR(mmu_info->dummy_page)); + free_page((unsigned long)TBL_VIRT_ADDR(mmu_info->dummy_l2_tbl)); + free_page((unsigned long)mmu_info->pgtbl); + kfree(mmu_info); +} +EXPORT_SYMBOL(ipu_mmu_destroy); + +static int ipu_mmu_probe(struct ipu_bus_device *adev) +{ + struct ipu_mmu_pdata *pdata; + struct ipu_mmu *mmu; + + mmu = devm_kzalloc(&adev->dev, sizeof(*mmu), GFP_KERNEL); + if (!mmu) + return -ENOMEM; + + dev_dbg(&adev->dev, "mmu probe %p %p\n", adev, &adev->dev); + ipu_bus_set_drvdata(adev, mmu); + + pdata = adev->pdata; + + mmu->mmid = pdata->mmid; + + mmu->mmu_hw = pdata->mmu_hw; + mmu->nr_mmus = pdata->nr_mmus; + mmu->tlb_invalidate = tlb_invalidate; + mmu->set_mapping = set_mapping; + mmu->dev = &adev->dev; + mmu->ready = false; + INIT_LIST_HEAD(&mmu->vma_list); + mutex_init(&mmu->vma_lock); + spin_lock_init(&mmu->ready_lock); + + /* + * Allocate 1 page of physical memory for the trash buffer + * + * TODO! Could be further optimized by allocating only one page per ipu + * instance instead of per mmu + */ + mmu->trash_page = alloc_page(GFP_KERNEL); + if (!mmu->trash_page) { + dev_err(&adev->dev, "insufficient memory for trash buffer\n"); + return -ENOMEM; + } + dev_info(&adev->dev, "MMU: %d, allocated page for trash: 0x%p\n", + mmu->mmid, mmu->trash_page); + + pm_runtime_allow(&adev->dev); + pm_runtime_enable(&adev->dev); + + /* + * FIXME: We can't unload this --- bus_set_iommu() will + * register a notifier which must stay until the devices are + * gone. + */ + __module_get(THIS_MODULE); + + return 0; +} + +/* + * Leave iommu ops as they were --- this means we must be called as + * the very last. + */ +static void ipu_mmu_remove(struct ipu_bus_device *adev) +{ + struct ipu_mmu *mmu = ipu_bus_get_drvdata(adev); + + __free_page(mmu->trash_page); + dev_dbg(&adev->dev, "removed\n"); +} + +static irqreturn_t ipu_mmu_isr(struct ipu_bus_device *adev) +{ + dev_info(&adev->dev, "Yeah!\n"); + return IRQ_NONE; +} + +#ifdef CONFIG_PM +static int ipu_mmu_suspend(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_mmu *mmu = ipu_bus_get_drvdata(adev); + unsigned long flags; + + spin_lock_irqsave(&mmu->ready_lock, flags); + mmu->ready = false; + spin_unlock_irqrestore(&mmu->ready_lock, flags); + + return 0; +} + +static const struct dev_pm_ops ipu_mmu_pm_ops = { + .resume = ipu_mmu_hw_init, + .suspend = ipu_mmu_suspend, + .runtime_resume = ipu_mmu_hw_init, + .runtime_suspend = ipu_mmu_suspend, +}; + +#define IPU_MMU_PM_OPS (&ipu_mmu_pm_ops) + +#else /* !CONFIG_PM */ + +#define IPU_MMU_PM_OPS NULL + +#endif /* !CONFIG_PM */ + +struct ipu_bus_driver ipu_mmu_driver = { + .probe = ipu_mmu_probe, + .remove = ipu_mmu_remove, + .isr = ipu_mmu_isr, + .wanted = IPU_MMU_NAME, + .drv = { + .name = IPU_MMU_NAME, + .owner = THIS_MODULE, + .pm = IPU_MMU_PM_OPS, + }, +}; + +MODULE_AUTHOR("Sakari Ailus "); +MODULE_AUTHOR("Samu Onkalo "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu mmu driver"); diff --git a/drivers/media/pci/intel/ipu-mmu.h b/drivers/media/pci/intel/ipu-mmu.h new file mode 100644 index 0000000000000..4a63691062c19 --- /dev/null +++ b/drivers/media/pci/intel/ipu-mmu.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_MMU_H +#define IPU_MMU_H + +#include +#include +#include + +#include "ipu.h" +#include "ipu-pdata.h" + +#define ISYS_MMID 1 +#define PSYS_MMID 0 + +extern struct ipu_bus_driver ipu_mmu_driver; +/* + * @pgtbl: virtual address of the l1 page table (one page) + */ +struct ipu_mmu_info { + u32 __iomem *pgtbl; + dma_addr_t aperture_start; + dma_addr_t aperture_end; + unsigned long pgsize_bitmap; + + spinlock_t lock; /* Serialize access to users */ + unsigned int users; + struct ipu_dma_mapping *dmap; + u32 dummy_l2_tbl; + u32 dummy_page; + + /* Reference to the trash address to unmap on domain destroy */ + dma_addr_t iova_addr_trash; +}; + +/* + * @pgtbl: physical address of the l1 page table + */ +struct ipu_mmu { + struct list_head node; + unsigned int users; + + struct ipu_mmu_hw *mmu_hw; + unsigned int nr_mmus; + int mmid; + + phys_addr_t pgtbl; + struct device *dev; + + struct ipu_dma_mapping *dmap; + struct list_head vma_list; + struct mutex vma_lock; + + struct page *trash_page; + dma_addr_t iova_addr_trash; + + bool ready; + spinlock_t ready_lock; /* Serialize access to bool ready */ + + void (*tlb_invalidate)(struct ipu_mmu *mmu); + void (*set_mapping)(struct ipu_mmu *mmu, + struct ipu_dma_mapping *dmap); +}; + +struct ipu_mmu_info *ipu_mmu_alloc(void); +void ipu_mmu_destroy(struct ipu_mmu_info *mmu_info); +int ipu_mmu_map(struct ipu_mmu_info *mmu_info, unsigned long iova, + phys_addr_t paddr, size_t size); +size_t ipu_mmu_unmap(struct ipu_mmu_info *mmu_info, unsigned long iova, + size_t size); +phys_addr_t ipu_mmu_iova_to_phys(struct ipu_mmu_info *mmu_info, + dma_addr_t iova); +#endif diff --git a/drivers/media/pci/intel/ipu-pdata.h b/drivers/media/pci/intel/ipu-pdata.h new file mode 100644 index 0000000000000..0996f19d1c80c --- /dev/null +++ b/drivers/media/pci/intel/ipu-pdata.h @@ -0,0 +1,284 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_PDATA_H +#define IPU_PDATA_H + +#define IPU_MMU_NAME IPU_NAME "-mmu" +#define IPU_ISYS_CSI2_NAME IPU_NAME "-csi2" +// #define IPU_ISYS_NAME IPU_NAME "-isys" +#define IPU_ISYS_NAME "intel-ipu6" +#define IPU_PSYS_NAME IPU_NAME "-psys" +#define IPU_BUTTRESS_NAME IPU_NAME "-buttress" + +#define IPU_MMU_MAX_DEVICES 4 +#define IPU_MMU_ADDRESS_BITS 32 +/* The firmware is accessible within the first 2 GiB only in non-secure mode. */ +#define IPU_MMU_ADDRESS_BITS_NON_SECURE 31 + +#if defined(CONFIG_VIDEO_INTEL_IPU4) || defined(CONFIG_VIDEO_INTEL_IPU4P) +#define IPU_MMU_MAX_TLB_L1_STREAMS 16 +#define IPU_MMU_MAX_TLB_L2_STREAMS 16 +#define IPU_MAX_LI_BLOCK_ADDR 64 +#define IPU_MAX_L2_BLOCK_ADDR 32 +#else +#define IPU_MMU_MAX_TLB_L1_STREAMS 32 +#define IPU_MMU_MAX_TLB_L2_STREAMS 32 +#define IPU_MAX_LI_BLOCK_ADDR 128 +#define IPU_MAX_L2_BLOCK_ADDR 64 +#endif + +#define IPU_ISYS_MAX_CSI2_LEGACY_PORTS 4 +#define IPU_ISYS_MAX_CSI2_COMBO_PORTS 2 + +#define IPU_MAX_FRAME_COUNTER 0xff + +/* + * 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 IPU4 + */ +#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 + +struct ipu_isys_subdev_pdata; + +/* + * MMU Invalidation HW bug workaround by ZLW mechanism + * + * IPU4 MMUV2 has a bug in the invalidation mechanism which might result in + * wrong translation or replication of the translation. This will cause data + * corruption. So we cannot directly use the MMU V2 invalidation registers + * to invalidate the MMU. Instead, whenever an invalidate is called, we need to + * clear the TLB by evicting all the valid translations by filling it with trash + * buffer (which is guaranteed not to be used by any other processes). ZLW is + * used to fill the L1 and L2 caches with the trash buffer translations. ZLW + * or Zero length write, is pre-fetch mechanism to pre-fetch the pages in + * advance to the L1 and L2 caches without triggering any memory operations. + * + * In MMU V2, L1 -> 16 streams and 64 blocks, maximum 16 blocks per stream + * One L1 block has 16 entries, hence points to 16 * 4K pages + * L2 -> 16 streams and 32 blocks. 2 blocks per streams + * One L2 block maps to 1024 L1 entries, hence points to 4MB address range + * 2 blocks per L2 stream means, 1 stream points to 8MB range + * + * As we need to clear the caches and 8MB being the biggest cache size, we need + * to have trash buffer which points to 8MB address range. As these trash + * buffers are not used for any memory transactions, we need only the least + * amount of physical memory. So we reserve 8MB IOVA address range but only + * one page is reserved from physical memory. Each of this 8MB IOVA address + * range is then mapped to the same physical memory page. + */ +/* 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 + +/* + * In some of the IPU4 MMUs, there is provision to configure L1 and L2 page + * table caches. Both these L1 and L2 caches are divided into multiple sections + * called streams. There is maximum 16 streams for both caches. Each of these + * sections are subdivided into multiple blocks. When nr_l1streams = 0 and + * nr_l2streams = 0, means the MMU is of type MMU_V1 and do not support + * L1/L2 page table caches. + * + * L1 stream per block sizes are configurable and varies per usecase. + * L2 has constant block sizes - 2 blocks per stream. + * + * MMU1 support pre-fetching of the pages to have less cache lookup misses. To + * enable the pre-fetching, MMU1 AT (Address Translator) device registers + * need to be configured. + * + * There are four types of memory accesses which requires ZLW configuration. + * ZLW(Zero Length Write) is a mechanism to enable VT-d pre-fetching on IOMMU. + * + * 1. Sequential Access or 1D mode + * Set ZLW_EN -> 1 + * set ZLW_PAGE_CROSS_1D -> 1 + * Set ZLW_N to "N" pages so that ZLW will be inserte N pages ahead where + * N is pre-defined and hardcoded in the platform data + * Set ZLW_2D -> 0 + * + * 2. ZLW 2D mode + * Set ZLW_EN -> 1 + * set ZLW_PAGE_CROSS_1D -> 1, + * Set ZLW_N -> 0 + * Set ZLW_2D -> 1 + * + * 3. ZLW Enable (no 1D or 2D mode) + * Set ZLW_EN -> 1 + * set ZLW_PAGE_CROSS_1D -> 0, + * Set ZLW_N -> 0 + * Set ZLW_2D -> 0 + * + * 4. ZLW disable + * Set ZLW_EN -> 0 + * set ZLW_PAGE_CROSS_1D -> 0, + * Set ZLW_N -> 0 + * Set ZLW_2D -> 0 + * + * To configure the ZLW for the above memory access, four registers are + * available. Hence to track these four settings, we have the following entries + * in the struct ipu_mmu_hw. Each of these entries are per stream and + * available only for the L1 streams. + * + * a. l1_zlw_en -> To track zlw enabled per stream (ZLW_EN) + * b. l1_zlw_1d_mode -> Track 1D mode per stream. ZLW inserted at page boundary + * c. l1_ins_zlw_ahead_pages -> to track how advance the ZLW need to be inserted + * Insert ZLW request N pages ahead address. + * d. l1_zlw_2d_mode -> To track 2D mode per stream (ZLW_2D) + * + * + * Currently L1/L2 streams, blocks, AT ZLW configurations etc. are pre-defined + * as per the usecase specific calculations. Any change to this pre-defined + * table has to happen in sync with IPU4 FW. + */ +struct ipu_mmu_hw { + union { + unsigned long offset; + void __iomem *base; + }; + unsigned int info_bits; + u8 nr_l1streams; + /* + * L1 has variable blocks per stream - total of 64 blocks and maximum of + * 16 blocks per stream. Configurable by using the block start address + * per stream. Block start address is calculated from the block size + */ + u8 l1_block_sz[IPU_MMU_MAX_TLB_L1_STREAMS]; + /* Is ZLW is enabled in each stream */ + bool l1_zlw_en[IPU_MMU_MAX_TLB_L1_STREAMS]; + bool l1_zlw_1d_mode[IPU_MMU_MAX_TLB_L1_STREAMS]; + u8 l1_ins_zlw_ahead_pages[IPU_MMU_MAX_TLB_L1_STREAMS]; + bool l1_zlw_2d_mode[IPU_MMU_MAX_TLB_L1_STREAMS]; + + u32 l1_stream_id_reg_offset; + u32 l2_stream_id_reg_offset; + + u8 nr_l2streams; + /* + * L2 has fixed 2 blocks per stream. Block address is calculated + * from the block size + */ + u8 l2_block_sz[IPU_MMU_MAX_TLB_L2_STREAMS]; + /* flag to track if WA is needed for successive invalidate HW bug */ + bool insert_read_before_invalidate; + /* flag to track if zlw based mmu invalidation is needed */ + bool zlw_invalidate; +}; + +struct ipu_mmu_pdata { + unsigned int nr_mmus; + struct ipu_mmu_hw mmu_hw[IPU_MMU_MAX_DEVICES]; + int mmid; +}; + +struct ipu_isys_csi2_pdata { + void __iomem *base; +}; + +#define IPU_EV_AUTO 0xff + +struct ipu_combo_receiver_params { + u8 crc_val; + u8 drc_val; + u8 drc_val_combined; + u8 ctle_val; +}; + +struct ipu_receiver_electrical_params { + u64 min_freq; + u64 max_freq; + unsigned short device; /* PCI DEVICE ID */ + u8 revision; /* PCI REVISION */ + /* base settings at first receiver power on */ + u8 rcomp_val_combo; + u8 rcomp_val_legacy; + + /* Combo per receiver settings */ + struct ipu_combo_receiver_params ports[2]; +}; + +struct ipu_isys_internal_csi2_pdata { + unsigned int nports; + unsigned int *offsets; + struct ipu_receiver_electrical_params *evparams; + u32 evsetmask0; + u32 evsetmask1; + unsigned char *evlanecombine; +}; + +struct ipu_isys_internal_tpg_pdata { + unsigned int ntpgs; + unsigned int *offsets; + unsigned int *sels; +}; + +/* + * One place to handle all the IPU HW variations + */ +struct ipu_hw_variants { + unsigned long offset; + unsigned int nr_mmus; + struct ipu_mmu_hw mmu_hw[IPU_MMU_MAX_DEVICES]; + 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 ipu_isys_internal_csi2_pdata csi2; + struct ipu_isys_internal_tpg_pdata tpg; + struct ipu_hw_variants hw_variant; + u32 num_parallel_streams; + u32 isys_dma_overshoot; +}; + +struct ipu_isys_pdata { + void __iomem *base; + const struct ipu_isys_internal_pdata *ipdata; + struct ipu_isys_subdev_pdata *spdata; +}; + +struct ipu_psys_internal_pdata { + struct ipu_hw_variants hw_variant; +}; + +struct ipu_psys_pdata { + void __iomem *base; + const struct ipu_psys_internal_pdata *ipdata; +}; + +#endif diff --git a/drivers/media/pci/intel/ipu-psys-compat32.c b/drivers/media/pci/intel/ipu-psys-compat32.c new file mode 100644 index 0000000000000..0687f3f506900 --- /dev/null +++ b/drivers/media/pci/intel/ipu-psys-compat32.c @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include +#include + +#include + +#include "ipu-psys.h" + +static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret = -ENOTTY; + + if (file->f_op->unlocked_ioctl) + ret = file->f_op->unlocked_ioctl(file, cmd, arg); + + return ret; +} + +struct ipu_psys_buffer32 { + u64 len; + union { + int fd; + compat_uptr_t userptr; + u64 reserved; + } base; + u32 data_offset; + u32 bytes_used; + u32 flags; + u32 reserved[2]; +} __packed; + +struct ipu_psys_command32 { + u64 issue_id; + u64 user_token; + u32 priority; + compat_uptr_t pg_manifest; + compat_uptr_t buffers; + int pg; + u32 pg_manifest_size; + u32 bufcount; + u32 min_psys_freq; + u32 frame_counter; + u32 reserved[2]; +} __packed; + +struct ipu_psys_manifest32 { + u32 index; + u32 size; + compat_uptr_t manifest; + u32 reserved[5]; +} __packed; + +static int +get_ipu_psys_command32(struct ipu_psys_command *kp, + struct ipu_psys_command32 __user *up) +{ + compat_uptr_t pgm, bufs; + + if (!access_ok(up, + sizeof(struct ipu_psys_command32)) || + get_user(kp->issue_id, &up->issue_id) || + get_user(kp->user_token, &up->user_token) || + get_user(kp->priority, &up->priority) || + get_user(pgm, &up->pg_manifest) || + get_user(bufs, &up->buffers) || + get_user(kp->pg, &up->pg) || + get_user(kp->pg_manifest_size, &up->pg_manifest_size) || + get_user(kp->bufcount, &up->bufcount) || + get_user(kp->min_psys_freq, &up->min_psys_freq) + || get_user(kp->frame_counter, &up->frame_counter) + ) + return -EFAULT; + + kp->pg_manifest = compat_ptr(pgm); + kp->buffers = compat_ptr(bufs); + return 0; +} + +static int +put_ipu_psys_command32(struct ipu_psys_command *kp, + struct ipu_psys_command32 __user *up) +{ + compat_uptr_t pgm = (u32)((unsigned long)kp->pg_manifest); + compat_uptr_t bufs = (u32)((unsigned long)kp->buffers); + + if (!access_ok(up, + sizeof(struct ipu_psys_command32)) || + put_user(kp->issue_id, &up->issue_id) || + put_user(kp->user_token, &up->user_token) || + put_user(kp->priority, &up->priority) || + put_user(pgm, &up->pg_manifest) || + put_user(bufs, &up->buffers) || + put_user(kp->pg, &up->pg) || + put_user(kp->pg_manifest_size, &up->pg_manifest_size) || + put_user(kp->bufcount, &up->bufcount) || + put_user(kp->min_psys_freq, &up->min_psys_freq) + || put_user(kp->frame_counter, &up->frame_counter) + ) + return -EFAULT; + + return 0; +} + +static int +get_ipu_psys_buffer32(struct ipu_psys_buffer *kp, + struct ipu_psys_buffer32 __user *up) +{ + compat_uptr_t ptr; + + if (!access_ok(up, + sizeof(struct ipu_psys_buffer32)) || + get_user(kp->len, &up->len) || + get_user(ptr, &up->base.userptr) || + get_user(kp->data_offset, &up->data_offset) || + get_user(kp->bytes_used, &up->bytes_used) || + get_user(kp->flags, &up->flags)) + return -EFAULT; + + kp->base.userptr = compat_ptr(ptr); + + return 0; +} + +static int +put_ipu_psys_buffer32(struct ipu_psys_buffer *kp, + struct ipu_psys_buffer32 __user *up) +{ + if (!access_ok(up, + sizeof(struct ipu_psys_buffer32)) || + put_user(kp->len, &up->len) || + put_user(kp->base.fd, &up->base.fd) || + put_user(kp->data_offset, &up->data_offset) || + put_user(kp->bytes_used, &up->bytes_used) || + put_user(kp->flags, &up->flags)) + return -EFAULT; + + return 0; +} + +static int +get_ipu_psys_manifest32(struct ipu_psys_manifest *kp, + struct ipu_psys_manifest32 __user *up) +{ + compat_uptr_t ptr; + + if (!access_ok(up, + sizeof(struct ipu_psys_manifest32)) || + get_user(kp->index, &up->index) || + get_user(kp->size, &up->size) || get_user(ptr, &up->manifest)) + return -EFAULT; + + kp->manifest = compat_ptr(ptr); + + return 0; +} + +static int +put_ipu_psys_manifest32(struct ipu_psys_manifest *kp, + struct ipu_psys_manifest32 __user *up) +{ + compat_uptr_t ptr = (u32)((unsigned long)kp->manifest); + + if (!access_ok(up, + sizeof(struct ipu_psys_manifest32)) || + put_user(kp->index, &up->index) || + put_user(kp->size, &up->size) || put_user(ptr, &up->manifest)) + return -EFAULT; + + return 0; +} + +#define IPU_IOC_GETBUF32 _IOWR('A', 4, struct ipu_psys_buffer32) +#define IPU_IOC_PUTBUF32 _IOWR('A', 5, struct ipu_psys_buffer32) +#define IPU_IOC_QCMD32 _IOWR('A', 6, struct ipu_psys_command32) +#define IPU_IOC_CMD_CANCEL32 _IOWR('A', 8, struct ipu_psys_command32) +#define IPU_IOC_GET_MANIFEST32 _IOWR('A', 9, struct ipu_psys_manifest32) + +long ipu_psys_compat_ioctl32(struct file *file, unsigned int cmd, + unsigned long arg) +{ + union { + struct ipu_psys_buffer buf; + struct ipu_psys_command cmd; + struct ipu_psys_event ev; + struct ipu_psys_manifest m; + } karg; + int compatible_arg = 1; + int err = 0; + int copy_to_user_size = 0; + void __user *up = compat_ptr(arg); + + switch (cmd) { + case IPU_IOC_GETBUF32: + cmd = IPU_IOC_GETBUF; + break; + case IPU_IOC_PUTBUF32: + cmd = IPU_IOC_PUTBUF; + break; + case IPU_IOC_QCMD32: + cmd = IPU_IOC_QCMD; + break; + case IPU_IOC_GET_MANIFEST32: + cmd = IPU_IOC_GET_MANIFEST; + break; + } + + switch (cmd) { + case IPU_IOC_GETBUF: + case IPU_IOC_PUTBUF: + err = get_ipu_psys_buffer32(&karg.buf, up); + compatible_arg = 0; + break; + case IPU_IOC_QCMD: + err = get_ipu_psys_command32(&karg.cmd, up); + copy_to_user_size = sizeof(struct ipu_psys_command32); + compatible_arg = 0; + break; + case IPU_IOC_GET_MANIFEST: + err = get_ipu_psys_manifest32(&karg.m, up); + copy_to_user_size = sizeof(struct ipu_psys_manifest32); + compatible_arg = 0; + break; + } + if (err) + return err; + + if (compatible_arg) { + err = native_ioctl(file, cmd, (unsigned long)up); + } else { + // This will lose 4/8 bytes from the end of the 64bit struct. + err = copy_to_user(up, &karg, copy_to_user_size ? copy_to_user_size : _IOC_SIZE(cmd)); + if (err) + return err; + err = native_ioctl(file, cmd, (unsigned long)up); + if (err) + return err; + err = copy_from_user(&karg, up, _IOC_SIZE(cmd)); + } + + if (err) + return err; + + switch (cmd) { + case IPU_IOC_GETBUF: + err = put_ipu_psys_buffer32(&karg.buf, up); + break; + case IPU_IOC_GET_MANIFEST: + err = put_ipu_psys_manifest32(&karg.m, up); + break; + case IPU_IOC_QCMD: + err = put_ipu_psys_command32(&karg.cmd, up); + break; + } + return err; +} +EXPORT_SYMBOL_GPL(ipu_psys_compat_ioctl32); diff --git a/drivers/media/pci/intel/ipu-psys.c b/drivers/media/pci/intel/ipu-psys.c new file mode 100644 index 0000000000000..9b7dc01dba01c --- /dev/null +++ b/drivers/media/pci/intel/ipu-psys.c @@ -0,0 +1,1580 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ipu.h" +#include "ipu-bus.h" +#include "ipu-platform.h" +#include "ipu-buttress.h" +#include "ipu-cpd.h" +#include "ipu-fw-psys.h" +#include "ipu-psys.h" +#include "ipu-platform-psys.h" +#include "ipu-platform-regs.h" +#include "ipu-fw-isys.h" +#include "ipu-fw-com.h" + +static bool async_fw_init; +module_param(async_fw_init, bool, 0664); +MODULE_PARM_DESC(async_fw_init, "Enable asynchronous firmware initialization"); + +#define IPU_PSYS_NUM_DEVICES 4 +#define IPU_PSYS_AUTOSUSPEND_DELAY 2000 + +#ifdef CONFIG_PM +static int psys_runtime_pm_resume(struct device *dev); +static int psys_runtime_pm_suspend(struct device *dev); +#else +#define pm_runtime_dont_use_autosuspend(d) +#define pm_runtime_use_autosuspend(d) +#define pm_runtime_set_autosuspend_delay(d, f) 0 +#define pm_runtime_get_sync(d) 0 +#define pm_runtime_put(d) 0 +#define pm_runtime_put_sync(d) 0 +#define pm_runtime_put_noidle(d) 0 +#define pm_runtime_put_autosuspend(d) 0 +#endif + +static dev_t ipu_psys_dev_t; +static DECLARE_BITMAP(ipu_psys_devices, IPU_PSYS_NUM_DEVICES); +static DEFINE_MUTEX(ipu_psys_mutex); + +static struct fw_init_task { + struct delayed_work work; + struct ipu_psys *psys; +} fw_init_task; + +static void ipu_psys_remove(struct ipu_bus_device *adev); + +static struct bus_type ipu_psys_bus = { + .name = IPU_PSYS_NAME, +}; + +static struct ipu_psys_capability caps = { + .version = 1, + .driver = "ipu-psys", +}; + +struct ipu_psys_pg *__get_pg_buf(struct ipu_psys *psys, size_t pg_size) +{ + struct ipu_psys_pg *kpg; + unsigned long flags; + + spin_lock_irqsave(&psys->pgs_lock, flags); + list_for_each_entry(kpg, &psys->pgs, list) { + if (!kpg->pg_size && kpg->size >= pg_size) { + kpg->pg_size = pg_size; + spin_unlock_irqrestore(&psys->pgs_lock, flags); + return kpg; + } + } + spin_unlock_irqrestore(&psys->pgs_lock, flags); + /* no big enough buffer available, allocate new one */ + kpg = kzalloc(sizeof(*kpg), GFP_KERNEL); + if (!kpg) + return NULL; + + kpg->pg = dma_alloc_coherent(&psys->adev->dev, pg_size, + &kpg->pg_dma_addr, GFP_KERNEL); + if (!kpg->pg) { + kfree(kpg); + return NULL; + } + + kpg->pg_size = pg_size; + kpg->size = pg_size; + spin_lock_irqsave(&psys->pgs_lock, flags); + list_add(&kpg->list, &psys->pgs); + spin_unlock_irqrestore(&psys->pgs_lock, flags); + + return kpg; +} + +struct ipu_psys_kbuffer *ipu_psys_lookup_kbuffer(struct ipu_psys_fh *fh, int fd) +{ + struct ipu_psys_kbuffer *kbuffer; + + list_for_each_entry(kbuffer, &fh->bufmap, list) { + if (kbuffer->fd == fd) + return kbuffer; + } + + return NULL; +} + +struct ipu_psys_kbuffer * +ipu_psys_lookup_kbuffer_by_kaddr(struct ipu_psys_fh *fh, void *kaddr) +{ + struct ipu_psys_kbuffer *kbuffer; + + list_for_each_entry(kbuffer, &fh->bufmap, list) { + if (kbuffer->kaddr == kaddr) + return kbuffer; + } + + return NULL; +} + +static int ipu_psys_get_userpages(struct ipu_dma_buf_attach *attach) +{ + struct vm_area_struct *vma; + unsigned long start, end; + int npages, array_size; + struct page **pages; + struct sg_table *sgt; + int ret = -ENOMEM; + int nr = 0; + u32 flags; + + start = attach->userptr; + end = PAGE_ALIGN(start + attach->len); + npages = (end - (start & PAGE_MASK)) >> PAGE_SHIFT; + array_size = npages * sizeof(struct page *); + + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) + return -ENOMEM; + + WARN_ON_ONCE(attach->npages); + + pages = kvzalloc(array_size, GFP_KERNEL); + if (!pages) + goto free_sgt; + + mmap_read_lock(current->mm); + vma = vma_lookup(current->mm, start); + if (unlikely(!vma)) { + ret = -EFAULT; + goto error_up_read; + } + mmap_read_unlock(current->mm); + + flags = FOLL_WRITE | FOLL_FORCE | FOLL_LONGTERM; + nr = pin_user_pages_fast(start & PAGE_MASK, npages, + flags, pages); + if (nr < npages) + goto error; + + attach->pages = pages; + attach->npages = npages; + + ret = sg_alloc_table_from_pages(sgt, pages, npages, + start & ~PAGE_MASK, attach->len, + GFP_KERNEL); + if (ret < 0) + goto error; + + attach->sgt = sgt; + + return 0; + +error_up_read: + mmap_read_unlock(current->mm); +error: + if (nr) + unpin_user_pages(pages, nr); + kvfree(pages); +free_sgt: + kfree(sgt); + + pr_err("failed to get userpages:%d\n", ret); + + return ret; +} + +static void ipu_psys_put_userpages(struct ipu_dma_buf_attach *attach) +{ + if (!attach || !attach->userptr || !attach->sgt) + return; + + unpin_user_pages(attach->pages, attach->npages); + kvfree(attach->pages); + + sg_free_table(attach->sgt); + kfree(attach->sgt); + attach->sgt = NULL; +} + +static int ipu_dma_buf_attach(struct dma_buf *dbuf, + struct dma_buf_attachment *attach) +{ + struct ipu_psys_kbuffer *kbuf = dbuf->priv; + struct ipu_dma_buf_attach *ipu_attach; + + ipu_attach = kzalloc(sizeof(*ipu_attach), GFP_KERNEL); + if (!ipu_attach) + return -ENOMEM; + + ipu_attach->len = kbuf->len; + ipu_attach->userptr = kbuf->userptr; + + attach->priv = ipu_attach; + return 0; +} + +static void ipu_dma_buf_detach(struct dma_buf *dbuf, + struct dma_buf_attachment *attach) +{ + struct ipu_dma_buf_attach *ipu_attach = attach->priv; + + kfree(ipu_attach); + attach->priv = NULL; +} + +static struct sg_table *ipu_dma_buf_map(struct dma_buf_attachment *attach, + enum dma_data_direction dir) +{ + struct ipu_dma_buf_attach *ipu_attach = attach->priv; + unsigned long attrs; + int ret; + + ret = ipu_psys_get_userpages(ipu_attach); + if (ret) + return NULL; + + attrs = DMA_ATTR_SKIP_CPU_SYNC; + ret = dma_map_sg_attrs(attach->dev, ipu_attach->sgt->sgl, + ipu_attach->sgt->orig_nents, dir, attrs); + if (ret < ipu_attach->sgt->orig_nents) { + ipu_psys_put_userpages(ipu_attach); + dev_dbg(attach->dev, "buf map failed\n"); + + return ERR_PTR(-EIO); + } + + /* + * Initial cache flush to avoid writing dirty pages for buffers which + * are later marked as IPU_BUFFER_FLAG_NO_FLUSH. + */ + dma_sync_sg_for_device(attach->dev, ipu_attach->sgt->sgl, + ipu_attach->sgt->orig_nents, DMA_BIDIRECTIONAL); + + return ipu_attach->sgt; +} + +static void ipu_dma_buf_unmap(struct dma_buf_attachment *attach, + struct sg_table *sg, enum dma_data_direction dir) +{ + struct ipu_dma_buf_attach *ipu_attach = attach->priv; + + dma_unmap_sg(attach->dev, sg->sgl, sg->orig_nents, dir); + ipu_psys_put_userpages(ipu_attach); +} + +static int ipu_dma_buf_mmap(struct dma_buf *dbuf, struct vm_area_struct *vma) +{ + return -ENOTTY; +} + +static void ipu_dma_buf_release(struct dma_buf *buf) +{ + struct ipu_psys_kbuffer *kbuf = buf->priv; + + if (!kbuf) + return; + + if (kbuf->db_attach) { + dev_dbg(kbuf->db_attach->dev, + "releasing buffer %d\n", kbuf->fd); + ipu_psys_put_userpages(kbuf->db_attach->priv); + } + kfree(kbuf); +} + +static int ipu_dma_buf_begin_cpu_access(struct dma_buf *dma_buf, + enum dma_data_direction dir) +{ + return -ENOTTY; +} + +static int ipu_dma_buf_vmap(struct dma_buf *dmabuf, struct iosys_map *map) +{ + struct dma_buf_attachment *attach; + struct ipu_dma_buf_attach *ipu_attach; + + if (list_empty(&dmabuf->attachments)) + return -EINVAL; + + attach = list_last_entry(&dmabuf->attachments, + struct dma_buf_attachment, node); + ipu_attach = attach->priv; + + if (!ipu_attach || !ipu_attach->pages || !ipu_attach->npages) + return -EINVAL; + + map->vaddr = vm_map_ram(ipu_attach->pages, ipu_attach->npages, 0); + map->is_iomem = false; + if (!map->vaddr) + return -EINVAL; + + return 0; +} + +static void ipu_dma_buf_vunmap(struct dma_buf *dmabuf, struct iosys_map *map) +{ + struct dma_buf_attachment *attach; + struct ipu_dma_buf_attach *ipu_attach; + + if (WARN_ON(list_empty(&dmabuf->attachments))) + return; + + attach = list_last_entry(&dmabuf->attachments, + struct dma_buf_attachment, node); + ipu_attach = attach->priv; + + if (WARN_ON(!ipu_attach || !ipu_attach->pages || !ipu_attach->npages)) + return; + + vm_unmap_ram(map->vaddr, ipu_attach->npages); +} + +struct dma_buf_ops ipu_dma_buf_ops = { + .attach = ipu_dma_buf_attach, + .detach = ipu_dma_buf_detach, + .map_dma_buf = ipu_dma_buf_map, + .unmap_dma_buf = ipu_dma_buf_unmap, + .release = ipu_dma_buf_release, + .begin_cpu_access = ipu_dma_buf_begin_cpu_access, + .mmap = ipu_dma_buf_mmap, + .vmap = ipu_dma_buf_vmap, + .vunmap = ipu_dma_buf_vunmap, +}; + +static int ipu_psys_open(struct inode *inode, struct file *file) +{ + struct ipu_psys *psys = inode_to_ipu_psys(inode); + struct ipu_device *isp = psys->adev->isp; + struct ipu_psys_fh *fh; + int rval; + + if (isp->flr_done) + return -EIO; + + rval = ipu_buttress_authenticate(isp); + if (rval) { + dev_err(&psys->adev->dev, "FW authentication failed\n"); + return rval; + } + + fh = kzalloc(sizeof(*fh), GFP_KERNEL); + if (!fh) + return -ENOMEM; + + fh->psys = psys; + file->private_data = fh; + + mutex_init(&fh->mutex); + INIT_LIST_HEAD(&fh->bufmap); + init_waitqueue_head(&fh->wait); + + rval = ipu_psys_fh_init(fh); + if (rval) + goto open_failed; + + mutex_lock(&psys->mutex); + list_add_tail(&fh->list, &psys->fhs); + mutex_unlock(&psys->mutex); + + return 0; + +open_failed: + mutex_destroy(&fh->mutex); + kfree(fh); + return rval; +} + +static inline void ipu_psys_kbuf_unmap(struct ipu_psys_kbuffer *kbuf) +{ + if (!kbuf) + return; + + kbuf->valid = false; + if (kbuf->kaddr) { + struct iosys_map dmap; + + iosys_map_set_vaddr(&dmap, kbuf->kaddr); + dma_buf_vunmap(kbuf->dbuf, &dmap); + } + if (kbuf->sgt) + dma_buf_unmap_attachment(kbuf->db_attach, + kbuf->sgt, + DMA_BIDIRECTIONAL); + if (kbuf->db_attach) + dma_buf_detach(kbuf->dbuf, kbuf->db_attach); + dma_buf_put(kbuf->dbuf); + + kbuf->db_attach = NULL; + kbuf->dbuf = NULL; + kbuf->sgt = NULL; +} + +static int ipu_psys_release(struct inode *inode, struct file *file) +{ + struct ipu_psys *psys = inode_to_ipu_psys(inode); + struct ipu_psys_fh *fh = file->private_data; + struct ipu_psys_kbuffer *kbuf, *kbuf0; + + mutex_lock(&fh->mutex); + /* clean up buffers */ + if (!list_empty(&fh->bufmap)) { + list_for_each_entry_safe(kbuf, kbuf0, &fh->bufmap, list) { + list_del(&kbuf->list); + /* Unmap and release buffers */ + if (kbuf->dbuf && kbuf->db_attach) { + struct dma_buf *dbuf; + + kbuf->valid = false; + if (kbuf->kaddr) { + struct iosys_map dmap; + + iosys_map_set_vaddr(&dmap, kbuf->kaddr); + dma_buf_vunmap(kbuf->dbuf, &dmap); + } + dma_buf_unmap_attachment(kbuf->db_attach, + kbuf->sgt, + DMA_BIDIRECTIONAL); + dma_buf_detach(kbuf->dbuf, kbuf->db_attach); + dbuf = kbuf->dbuf; + kbuf->dbuf = NULL; + kbuf->db_attach = NULL; + dma_buf_put(dbuf); + } else { + if (kbuf->db_attach) + ipu_psys_put_userpages( + kbuf->db_attach->priv); + kfree(kbuf); + } + } + } + mutex_unlock(&fh->mutex); + + mutex_lock(&psys->mutex); + list_del(&fh->list); + + mutex_unlock(&psys->mutex); + + ipu_psys_fh_deinit(fh); + mutex_destroy(&fh->mutex); + kfree(fh); + + return 0; +} + +static int ipu_psys_getbuf(struct ipu_psys_buffer *buf, struct ipu_psys_fh *fh) +{ + struct ipu_psys_kbuffer *kbuf; + struct ipu_psys *psys = fh->psys; + + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct dma_buf *dbuf; + int ret; + + if (!buf->base.userptr) { + dev_err(&psys->adev->dev, "Buffer allocation not supported\n"); + return -EINVAL; + } + + kbuf = kzalloc(sizeof(*kbuf), GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + + kbuf->len = buf->len; + kbuf->userptr = buf->base.userptr; + kbuf->flags = buf->flags; + + exp_info.ops = &ipu_dma_buf_ops; + exp_info.size = kbuf->len; + exp_info.flags = O_RDWR; + exp_info.priv = kbuf; + + dbuf = dma_buf_export(&exp_info); + if (IS_ERR(dbuf)) { + kfree(kbuf); + return PTR_ERR(dbuf); + } + + ret = dma_buf_fd(dbuf, 0); + if (ret < 0) { + kfree(kbuf); + return ret; + } + + dev_dbg(&psys->adev->dev, "IOC_GETBUF: userptr %p", buf->base.userptr); + + kbuf->fd = ret; + buf->base.fd = ret; + kbuf->flags = buf->flags &= ~IPU_BUFFER_FLAG_USERPTR; + kbuf->flags = buf->flags |= IPU_BUFFER_FLAG_DMA_HANDLE; + + mutex_lock(&fh->mutex); + list_add_tail(&kbuf->list, &fh->bufmap); + mutex_unlock(&fh->mutex); + + dev_dbg(&psys->adev->dev, "to %d\n", buf->base.fd); + + return 0; +} + +static int ipu_psys_putbuf(struct ipu_psys_buffer *buf, struct ipu_psys_fh *fh) +{ + return 0; +} + +static long ipu_psys_mapbuf(int fd, struct ipu_psys_fh *fh) +{ + struct ipu_psys *psys = fh->psys; + struct ipu_psys_kbuffer *kbuf; + struct dma_buf *dbuf; + struct iosys_map dmap = { + .is_iomem = false, + }; + int ret; + + mutex_lock(&fh->mutex); + kbuf = ipu_psys_lookup_kbuffer(fh, fd); + + if (!kbuf) { + /* This fd isn't generated by ipu_psys_getbuf, it + * is a new fd. Create a new kbuf item for this fd, and + * add this kbuf to bufmap list. + */ + kbuf = kzalloc(sizeof(*kbuf), GFP_KERNEL); + if (!kbuf) { + mutex_unlock(&fh->mutex); + return -ENOMEM; + } + + list_add_tail(&kbuf->list, &fh->bufmap); + } + + if (kbuf->sgt) { + dev_dbg(&psys->adev->dev, "has been mapped!\n"); + goto mapbuf_end; + } + + kbuf->dbuf = dma_buf_get(fd); + if (IS_ERR(kbuf->dbuf)) { + if (!kbuf->userptr) { + list_del(&kbuf->list); + kfree(kbuf); + } + mutex_unlock(&fh->mutex); + return -EINVAL; + } + + if (kbuf->len == 0) + kbuf->len = kbuf->dbuf->size; + + kbuf->fd = fd; + + kbuf->db_attach = dma_buf_attach(kbuf->dbuf, &psys->adev->dev); + if (IS_ERR(kbuf->db_attach)) { + ret = PTR_ERR(kbuf->db_attach); + goto error_put; + } + + kbuf->sgt = dma_buf_map_attachment(kbuf->db_attach, DMA_BIDIRECTIONAL); + if (IS_ERR_OR_NULL(kbuf->sgt)) { + ret = -EINVAL; + kbuf->sgt = NULL; + dev_dbg(&psys->adev->dev, "map attachment failed\n"); + goto error_detach; + } + + kbuf->dma_addr = sg_dma_address(kbuf->sgt->sgl); + + ret = dma_buf_vmap(kbuf->dbuf, &dmap); + if (ret) { + ret = -EINVAL; + goto error_unmap; + } + kbuf->kaddr = dmap.vaddr; + +mapbuf_end: + + kbuf->valid = true; + + mutex_unlock(&fh->mutex); + + dev_dbg(&psys->adev->dev, "IOC_MAPBUF: mapped fd %d\n", fd); + + return 0; + +error_unmap: + dma_buf_unmap_attachment(kbuf->db_attach, kbuf->sgt, DMA_BIDIRECTIONAL); +error_detach: + dma_buf_detach(kbuf->dbuf, kbuf->db_attach); + kbuf->db_attach = NULL; +error_put: + list_del(&kbuf->list); + dbuf = kbuf->dbuf; + + if (!kbuf->userptr) + kfree(kbuf); + + mutex_unlock(&fh->mutex); + dma_buf_put(dbuf); + + return ret; +} + +static long ipu_psys_unmapbuf(int fd, struct ipu_psys_fh *fh) +{ + struct ipu_psys_kbuffer *kbuf; + struct ipu_psys *psys = fh->psys; + struct dma_buf *dmabuf; + struct iosys_map dmap = { + .is_iomem = false, + }; + + mutex_lock(&fh->mutex); + kbuf = ipu_psys_lookup_kbuffer(fh, fd); + if (!kbuf) { + dev_dbg(&psys->adev->dev, "buffer %d not found\n", fd); + mutex_unlock(&fh->mutex); + return -EINVAL; + } + + /* From now on it is not safe to use this kbuffer */ + kbuf->valid = false; + + dma_buf_vunmap(kbuf->dbuf, &dmap); + dma_buf_unmap_attachment(kbuf->db_attach, kbuf->sgt, DMA_BIDIRECTIONAL); + + dma_buf_detach(kbuf->dbuf, kbuf->db_attach); + + dmabuf = kbuf->dbuf; + + kbuf->db_attach = NULL; + kbuf->dbuf = NULL; + + list_del(&kbuf->list); + + if (!kbuf->userptr) + kfree(kbuf); + + mutex_unlock(&fh->mutex); + dma_buf_put(dmabuf); + + dev_dbg(&psys->adev->dev, "IOC_UNMAPBUF: fd %d\n", fd); + + return 0; +} + +static unsigned int ipu_psys_poll(struct file *file, + struct poll_table_struct *wait) +{ + struct ipu_psys_fh *fh = file->private_data; + struct ipu_psys *psys = fh->psys; + unsigned int res = 0; + + dev_dbg(&psys->adev->dev, "ipu psys poll\n"); + + poll_wait(file, &fh->wait, wait); + + if (ipu_get_completed_kcmd(fh)) + res = POLLIN; + + dev_dbg(&psys->adev->dev, "ipu psys poll res %u\n", res); + + return res; +} + +static long ipu_get_manifest(struct ipu_psys_manifest *manifest, + struct ipu_psys_fh *fh) +{ + struct ipu_psys *psys = fh->psys; + struct ipu_device *isp = psys->adev->isp; + struct ipu_cpd_client_pkg_hdr *client_pkg; + u32 entries; + void *host_fw_data; + dma_addr_t dma_fw_data; + u32 client_pkg_offset; + + host_fw_data = (void *)isp->cpd_fw->data; + dma_fw_data = sg_dma_address(psys->fw_sgt.sgl); + + entries = ipu_cpd_pkg_dir_get_num_entries(psys->pkg_dir); + if (!manifest || manifest->index > entries - 1) { + dev_err(&psys->adev->dev, "invalid argument\n"); + return -EINVAL; + } + + if (!ipu_cpd_pkg_dir_get_size(psys->pkg_dir, manifest->index) || + ipu_cpd_pkg_dir_get_type(psys->pkg_dir, manifest->index) < + IPU_CPD_PKG_DIR_CLIENT_PG_TYPE) { + dev_dbg(&psys->adev->dev, "invalid pkg dir entry\n"); + return -ENOENT; + } + + client_pkg_offset = ipu_cpd_pkg_dir_get_address(psys->pkg_dir, + manifest->index); + client_pkg_offset -= dma_fw_data; + + client_pkg = host_fw_data + client_pkg_offset; + manifest->size = client_pkg->pg_manifest_size; + + if (!manifest->manifest) + return 0; + + if (copy_to_user(manifest->manifest, + (uint8_t *) client_pkg + client_pkg->pg_manifest_offs, + manifest->size)) { + return -EFAULT; + } + + return 0; +} + +static long ipu_psys_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + union { + struct ipu_psys_buffer buf; + struct ipu_psys_command cmd; + struct ipu_psys_event ev; + struct ipu_psys_capability caps; + struct ipu_psys_manifest m; + } karg; + struct ipu_psys_fh *fh = file->private_data; + int err = 0; + void __user *up = (void __user *)arg; + bool copy = (cmd != IPU_IOC_MAPBUF && cmd != IPU_IOC_UNMAPBUF); + + if (copy) { + if (_IOC_SIZE(cmd) > sizeof(karg)) + return -ENOTTY; + + if (_IOC_DIR(cmd) & _IOC_WRITE) { + err = copy_from_user(&karg, up, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + } + } + + switch (cmd) { + case IPU_IOC_MAPBUF: + err = ipu_psys_mapbuf(arg, fh); + break; + case IPU_IOC_UNMAPBUF: + err = ipu_psys_unmapbuf(arg, fh); + break; + case IPU_IOC_QUERYCAP: + karg.caps = caps; + break; + case IPU_IOC_GETBUF: + err = ipu_psys_getbuf(&karg.buf, fh); + break; + case IPU_IOC_PUTBUF: + err = ipu_psys_putbuf(&karg.buf, fh); + break; + case IPU_IOC_QCMD: + err = ipu_psys_kcmd_new(&karg.cmd, fh); + break; + case IPU_IOC_DQEVENT: + err = ipu_ioctl_dqevent(&karg.ev, fh, file->f_flags); + break; + case IPU_IOC_GET_MANIFEST: + err = ipu_get_manifest(&karg.m, fh); + break; + default: + err = -ENOTTY; + break; + } + + if (err) + return err; + + if (copy && _IOC_DIR(cmd) & _IOC_READ) + if (copy_to_user(up, &karg, _IOC_SIZE(cmd))) + return -EFAULT; + + return 0; +} + +static const struct file_operations ipu_psys_fops = { + .open = ipu_psys_open, + .release = ipu_psys_release, + .unlocked_ioctl = ipu_psys_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ipu_psys_compat_ioctl32, +#endif + .poll = ipu_psys_poll, + .owner = THIS_MODULE, +}; + +static void ipu_psys_dev_release(struct device *dev) +{ +} + +#ifdef CONFIG_PM +static int psys_runtime_pm_resume(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_psys *psys = ipu_bus_get_drvdata(adev); + unsigned long flags; + int retval; + + if (!psys) { + WARN(1, "%s called before probing. skipping.\n", __func__); + return 0; + } + /* + * In runtime autosuspend mode, if the psys is in power on state, no + * need to resume again. + */ + spin_lock_irqsave(&psys->power_lock, flags); + if (psys->power) { + spin_unlock_irqrestore(&psys->power_lock, flags); + return 0; + } + spin_unlock_irqrestore(&psys->power_lock, flags); + + if (async_fw_init && !psys->fwcom) { + dev_err(dev, + "%s: asynchronous firmware init not finished, skipping\n", + __func__); + return 0; + } + + if (!ipu4_buttress_auth_done(adev->isp)) { + dev_err(dev, "%s: not yet authenticated, skipping\n", __func__); + return 0; + } + + ipu_psys_setup_hw(psys); + + ipu_trace_restore(&psys->adev->dev); + + ipu_configure_spc(adev->isp, + &psys->pdata->ipdata->hw_variant, + IPU_CPD_PKG_DIR_PSYS_SERVER_IDX, + psys->pdata->base, psys->pkg_dir, + psys->pkg_dir_dma_addr); + + retval = ipu_fw_psys_open(psys); + if (retval) { + dev_err(&psys->adev->dev, "Failed to open abi.\n"); + return retval; + } + + spin_lock_irqsave(&psys->power_lock, flags); + psys->power = 1; + spin_unlock_irqrestore(&psys->power_lock, flags); + + return 0; +} + +static int psys_runtime_pm_suspend(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_psys *psys = ipu_bus_get_drvdata(adev); + unsigned long flags; + int rval; + + if (!psys) { + WARN(1, "%s called before probing. skipping.\n", __func__); + return 0; + } + + if (!psys->power) + return 0; + + spin_lock_irqsave(&psys->power_lock, flags); + psys->power = 0; + spin_unlock_irqrestore(&psys->power_lock, flags); + + /* + * We can trace failure but better to not return an error. + * At suspend we are progressing towards psys power gated state. + * Any hang / failure inside psys will be forgotten soon. + */ + rval = ipu_fw_psys_close(psys); + if (rval) + dev_err(dev, "Device close failure: %d\n", rval); + + return 0; +} + +static const struct dev_pm_ops psys_pm_ops = { + .runtime_suspend = psys_runtime_pm_suspend, + .runtime_resume = psys_runtime_pm_resume, +}; + +#define PSYS_PM_OPS (&psys_pm_ops) +#else +#define PSYS_PM_OPS NULL +#endif + +static int cpd_fw_reload(struct ipu_device *isp) +{ + struct ipu_psys *psys = ipu_bus_get_drvdata(isp->psys); + int rval; + + if (!isp->secure_mode) { + dev_warn(&isp->pdev->dev, + "CPD firmware reload was only supported for secure mode.\n"); + return -EINVAL; + } + + if (isp->cpd_fw) { + ipu_cpd_free_pkg_dir(isp->psys, psys->pkg_dir, + psys->pkg_dir_dma_addr, + psys->pkg_dir_size); + + ipu_buttress_unmap_fw_image(isp->psys, &psys->fw_sgt); + release_firmware(isp->cpd_fw); + isp->cpd_fw = NULL; + dev_info(&isp->pdev->dev, "Old FW removed\n"); + } + + rval = request_cpd_fw(&isp->cpd_fw, isp->cpd_fw_name, + &isp->pdev->dev); + if (rval) { + dev_err(&isp->pdev->dev, "Requesting firmware(%s) failed\n", + IPU_CPD_FIRMWARE_NAME); + return rval; + } + + rval = ipu_cpd_validate_cpd_file(isp, isp->cpd_fw->data, + isp->cpd_fw->size); + if (rval) { + dev_err(&isp->pdev->dev, "Failed to validate cpd file\n"); + goto out_release_firmware; + } + + rval = ipu_buttress_map_fw_image(isp->psys, isp->cpd_fw, &psys->fw_sgt); + if (rval) + goto out_release_firmware; + + psys->pkg_dir = ipu_cpd_create_pkg_dir(isp->psys, + isp->cpd_fw->data, + sg_dma_address(psys->fw_sgt.sgl), + &psys->pkg_dir_dma_addr, + &psys->pkg_dir_size); + + if (!psys->pkg_dir) { + rval = -EINVAL; + goto out_unmap_fw_image; + } + + isp->pkg_dir = psys->pkg_dir; + isp->pkg_dir_dma_addr = psys->pkg_dir_dma_addr; + isp->pkg_dir_size = psys->pkg_dir_size; + + if (!isp->secure_mode) + return 0; + + rval = ipu_fw_authenticate(isp, 1); + if (rval) + goto out_free_pkg_dir; + + return 0; + +out_free_pkg_dir: + ipu_cpd_free_pkg_dir(isp->psys, psys->pkg_dir, + psys->pkg_dir_dma_addr, psys->pkg_dir_size); +out_unmap_fw_image: + ipu_buttress_unmap_fw_image(isp->psys, &psys->fw_sgt); +out_release_firmware: + release_firmware(isp->cpd_fw); + isp->cpd_fw = NULL; + + return rval; +} + +static int ipu_psys_icache_prefetch_sp_get(void *data, u64 *val) +{ + struct ipu_psys *psys = data; + + *val = psys->icache_prefetch_sp; + return 0; +} + +static int ipu_psys_icache_prefetch_sp_set(void *data, u64 val) +{ + struct ipu_psys *psys = data; + + if (val != !!val) + return -EINVAL; + + psys->icache_prefetch_sp = val; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(psys_icache_prefetch_sp_fops, + ipu_psys_icache_prefetch_sp_get, + ipu_psys_icache_prefetch_sp_set, "%llu\n"); + +static int ipu_psys_icache_prefetch_isp_get(void *data, u64 *val) +{ + struct ipu_psys *psys = data; + + *val = psys->icache_prefetch_isp; + return 0; +} + +static int ipu_psys_icache_prefetch_isp_set(void *data, u64 val) +{ + struct ipu_psys *psys = data; + + if (val != !!val) + return -EINVAL; + + psys->icache_prefetch_isp = val; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(psys_icache_prefetch_isp_fops, + ipu_psys_icache_prefetch_isp_get, + ipu_psys_icache_prefetch_isp_set, "%llu\n"); + +static int ipu_psys_init_debugfs(struct ipu_psys *psys) +{ + struct dentry *file; + struct dentry *dir; + + dir = debugfs_create_dir("psys", psys->adev->isp->ipu_dir); + if (IS_ERR(dir)) + return -ENOMEM; + + file = debugfs_create_file("icache_prefetch_sp", 0600, + dir, psys, &psys_icache_prefetch_sp_fops); + if (IS_ERR(file)) + goto err; + + file = debugfs_create_file("icache_prefetch_isp", 0600, + dir, psys, &psys_icache_prefetch_isp_fops); + if (IS_ERR(file)) + goto err; + + psys->debugfsdir = dir; + + + return 0; +err: + debugfs_remove_recursive(dir); + return -ENOMEM; +} + +static int ipu_psys_sched_cmd(void *ptr) +{ + struct ipu_psys *psys = ptr; + size_t pending = 0; + + while (1) { + wait_event_interruptible(psys->sched_cmd_wq, + (kthread_should_stop() || (pending = + atomic_read(&psys->wakeup_sched_thread_count)))); + + if (kthread_should_stop()) + break; + + if (pending == 0) + continue; + + mutex_lock(&psys->mutex); + atomic_set(&psys->wakeup_sched_thread_count, 0); + ipu_psys_run_next(psys); + mutex_unlock(&psys->mutex); + } + + return 0; +} + +static void start_sp(struct ipu_bus_device *adev) +{ + struct ipu_psys *psys = ipu_bus_get_drvdata(adev); + void __iomem *spc_regs_base = psys->pdata->base + + psys->pdata->ipdata->hw_variant.spc_offset; + u32 val = 0; + + val |= IPU_ISYS_SPC_STATUS_START | + IPU_ISYS_SPC_STATUS_RUN | + IPU_ISYS_SPC_STATUS_CTRL_ICACHE_INVALIDATE; + val |= psys->icache_prefetch_sp ? + IPU_ISYS_SPC_STATUS_ICACHE_PREFETCH : 0; + writel(val, spc_regs_base + IPU_ISYS_REG_SPC_STATUS_CTRL); +} + +static int query_sp(struct ipu_bus_device *adev) +{ + struct ipu_psys *psys = ipu_bus_get_drvdata(adev); + void __iomem *spc_regs_base = psys->pdata->base + + psys->pdata->ipdata->hw_variant.spc_offset; + u32 val = readl(spc_regs_base + IPU_ISYS_REG_SPC_STATUS_CTRL); + + /* return true when READY == 1, START == 0 */ + val &= IPU_ISYS_SPC_STATUS_READY | IPU_ISYS_SPC_STATUS_START; + + return val == IPU_ISYS_SPC_STATUS_READY; +} + +static int ipu_psys_fw_init(struct ipu_psys *psys) +{ + struct ipu_fw_syscom_queue_config + fw_psys_cmd_queue_cfg[IPU_FW_PSYS_N_PSYS_CMD_QUEUE_ID]; + struct ipu_fw_syscom_queue_config fw_psys_event_queue_cfg[] = { + { + IPU_FW_PSYS_EVENT_QUEUE_SIZE, + sizeof(struct ipu_fw_psys_event) + } + }; + struct ipu_fw_psys_srv_init server_init = { + .ddr_pkg_dir_address = 0, + .host_ddr_pkg_dir = NULL, + .pkg_dir_size = 0, + .icache_prefetch_sp = psys->icache_prefetch_sp, + .icache_prefetch_isp = psys->icache_prefetch_isp, + }; + struct ipu_fw_com_cfg fwcom = { + .num_input_queues = IPU_FW_PSYS_N_PSYS_CMD_QUEUE_ID, + .num_output_queues = IPU_FW_PSYS_N_PSYS_EVENT_QUEUE_ID, + .output = fw_psys_event_queue_cfg, + .specific_addr = &server_init, + .specific_size = sizeof(server_init), + .cell_start = start_sp, + .cell_ready = query_sp, + }; + int rval, i; + + for (i = 0; i < IPU_FW_PSYS_N_PSYS_CMD_QUEUE_ID; i++) { + fw_psys_cmd_queue_cfg[i].queue_size = + IPU_FW_PSYS_CMD_QUEUE_SIZE; + fw_psys_cmd_queue_cfg[i].token_size = + sizeof(struct ipu_fw_psys_cmd); + } + + fwcom.input = fw_psys_cmd_queue_cfg; + + fwcom.dmem_addr = psys->pdata->ipdata->hw_variant.dmem_offset; + + rval = ipu_buttress_authenticate(psys->adev->isp); + if (rval) { + dev_err(&psys->adev->dev, "FW authentication failed(%d)\n", + rval); + return rval; + } + + psys->fwcom = ipu_fw_com_prepare(&fwcom, psys->adev, psys->pdata->base); + if (!psys->fwcom) { + dev_err(&psys->adev->dev, "psys fw com prepare failed\n"); + return -EIO; + } + + return 0; +} + +static void run_fw_init_work(struct work_struct *work) +{ + struct fw_init_task *task = (struct fw_init_task *)work; + struct ipu_psys *psys = task->psys; + int rval; + + rval = ipu_psys_fw_init(psys); + + if (rval) { + dev_err(&psys->adev->dev, "FW init failed(%d)\n", rval); + ipu_psys_remove(psys->adev); + } else { + dev_info(&psys->adev->dev, "FW init done\n"); + } +} + +static int ipu_psys_probe(struct ipu_bus_device *adev) +{ + struct ipu_device *isp = adev->isp; + struct ipu_psys_pg *kpg, *kpg0; + struct ipu_psys *psys; + const struct firmware *fw; + unsigned int minor; + int i, rval = -E2BIG; + + trace_printk("B|%d|TMWK\n", current->pid); + + + mutex_lock(&ipu_psys_mutex); + + minor = find_next_zero_bit(ipu_psys_devices, IPU_PSYS_NUM_DEVICES, 0); + if (minor == IPU_PSYS_NUM_DEVICES) { + dev_err(&adev->dev, "too many devices\n"); + goto out_unlock; + } + + psys = devm_kzalloc(&adev->dev, sizeof(*psys), GFP_KERNEL); + if (!psys) { + rval = -ENOMEM; + goto out_unlock; + } + + psys->adev = adev; + psys->pdata = adev->pdata; +#ifdef CONFIG_VIDEO_INTEL_IPU4 + psys->icache_prefetch_sp = is_ipu_hw_bxtp_e0(isp); +#else + psys->icache_prefetch_sp = 0; +#endif + + ipu_trace_init(adev->isp, psys->pdata->base, &adev->dev, + psys_trace_blocks); + + cdev_init(&psys->cdev, &ipu_psys_fops); + psys->cdev.owner = ipu_psys_fops.owner; + + rval = cdev_add(&psys->cdev, MKDEV(MAJOR(ipu_psys_dev_t), minor), 1); + if (rval) { + dev_err(&adev->dev, "cdev_add failed (%d)\n", rval); + goto out_unlock; + } + + set_bit(minor, ipu_psys_devices); + + spin_lock_init(&psys->power_lock); + spin_lock_init(&psys->pgs_lock); + psys->power = 0; + psys->timeout = IPU_PSYS_CMD_TIMEOUT_MS; + + mutex_init(&psys->mutex); + INIT_LIST_HEAD(&psys->fhs); + INIT_LIST_HEAD(&psys->pgs); + INIT_LIST_HEAD(&psys->started_kcmds_list); + INIT_WORK(&psys->watchdog_work, ipu_psys_watchdog_work); + + init_waitqueue_head(&psys->sched_cmd_wq); + atomic_set(&psys->wakeup_sched_thread_count, 0); + /* + * Create a thread to schedule commands sent to IPU firmware. + * The thread reduces the coupling between the command scheduler + * and queueing commands from the user to driver. + */ + psys->sched_cmd_thread = kthread_run(ipu_psys_sched_cmd, psys, + "psys_sched_cmd"); + + if (IS_ERR(psys->sched_cmd_thread)) { + psys->sched_cmd_thread = NULL; + mutex_destroy(&psys->mutex); + goto out_unlock; + } + + ipu_bus_set_drvdata(adev, psys); + + rval = ipu_psys_resource_pool_init(&psys->resource_pool_started); + if (rval < 0) { + dev_err(&psys->dev, + "unable to alloc process group resources\n"); + goto out_mutex_destroy; + } + + rval = ipu_psys_resource_pool_init(&psys->resource_pool_running); + if (rval < 0) { + dev_err(&psys->dev, + "unable to alloc process group resources\n"); + goto out_resources_started_free; + } + + fw = adev->isp->cpd_fw; + + rval = ipu_buttress_map_fw_image(adev, fw, &psys->fw_sgt); + if (rval) + goto out_resources_running_free; + + psys->pkg_dir = ipu_cpd_create_pkg_dir(adev, fw->data, + sg_dma_address(psys->fw_sgt.sgl), + &psys->pkg_dir_dma_addr, + &psys->pkg_dir_size); + if (!psys->pkg_dir) { + rval = -ENOMEM; + goto out_unmap_fw_image; + } + + /* allocate and map memory for process groups */ + for (i = 0; i < IPU_PSYS_PG_POOL_SIZE; i++) { + kpg = kzalloc(sizeof(*kpg), GFP_KERNEL); + if (!kpg) + goto out_free_pgs; + kpg->pg = dma_alloc_coherent(&adev->dev, + IPU_PSYS_PG_MAX_SIZE, + &kpg->pg_dma_addr, + GFP_KERNEL); + if (!kpg->pg) { + kfree(kpg); + goto out_free_pgs; + } + kpg->size = IPU_PSYS_PG_MAX_SIZE; + list_add(&kpg->list, &psys->pgs); + } + + isp->pkg_dir = psys->pkg_dir; + isp->pkg_dir_dma_addr = psys->pkg_dir_dma_addr; + isp->pkg_dir_size = psys->pkg_dir_size; + + caps.pg_count = ipu_cpd_pkg_dir_get_num_entries(psys->pkg_dir); + + dev_info(&adev->dev, "pkg_dir entry count:%d\n", caps.pg_count); + if (async_fw_init) { + INIT_DELAYED_WORK((struct delayed_work *)&fw_init_task, + run_fw_init_work); + fw_init_task.psys = psys; + schedule_delayed_work((struct delayed_work *)&fw_init_task, 0); + } else { + rval = ipu_psys_fw_init(psys); + } + + if (rval) { + dev_err(&adev->dev, "FW init failed(%d)\n", rval); + goto out_free_pgs; + } + + psys->dev.parent = &adev->dev; + psys->dev.bus = &ipu_psys_bus; + psys->dev.devt = MKDEV(MAJOR(ipu_psys_dev_t), minor); + psys->dev.release = ipu_psys_dev_release; + dev_set_name(&psys->dev, "ipu-psys%d", minor); + rval = device_register(&psys->dev); + if (rval < 0) { + dev_err(&psys->dev, "psys device_register failed\n"); + goto out_release_fw_com; + } + + /* Add the hw stepping information to caps */ + strscpy(caps.dev_model, IPU_MEDIA_DEV_MODEL_NAME, + sizeof(caps.dev_model)); + + pm_runtime_allow(&adev->dev); + pm_runtime_enable(&adev->dev); + + pm_runtime_set_autosuspend_delay(&psys->adev->dev, + IPU_PSYS_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(&psys->adev->dev); + pm_runtime_mark_last_busy(&psys->adev->dev); + + mutex_unlock(&ipu_psys_mutex); + + /* Debug fs failure is not fatal. */ + ipu_psys_init_debugfs(psys); + + adev->isp->cpd_fw_reload = &cpd_fw_reload; + + dev_info(&adev->dev, "psys probe minor: %d\n", minor); + + trace_printk("E|TMWK\n"); + return 0; + +out_release_fw_com: + ipu_fw_com_release(psys->fwcom, 1); +out_free_pgs: + list_for_each_entry_safe(kpg, kpg0, &psys->pgs, list) { + dma_free_coherent(&adev->dev, kpg->size, kpg->pg, + kpg->pg_dma_addr); + kfree(kpg); + } + + if (!isp->secure_mode) + ipu_cpd_free_pkg_dir(adev, psys->pkg_dir, + psys->pkg_dir_dma_addr, + psys->pkg_dir_size); +out_unmap_fw_image: + ipu_buttress_unmap_fw_image(adev, &psys->fw_sgt); +out_resources_running_free: + ipu_psys_resource_pool_cleanup(&psys->resource_pool_running); +out_resources_started_free: + ipu_psys_resource_pool_cleanup(&psys->resource_pool_started); +out_mutex_destroy: + mutex_destroy(&psys->mutex); + cdev_del(&psys->cdev); + if (psys->sched_cmd_thread) { + kthread_stop(psys->sched_cmd_thread); + psys->sched_cmd_thread = NULL; + } +out_unlock: + /* Safe to call even if the init is not called */ + ipu_trace_uninit(&adev->dev); + mutex_unlock(&ipu_psys_mutex); + + trace_printk("E|TMWK\n"); + return rval; +} + +static void ipu_psys_remove(struct ipu_bus_device *adev) +{ + struct ipu_device *isp = adev->isp; + struct ipu_psys *psys = ipu_bus_get_drvdata(adev); + struct ipu_psys_pg *kpg, *kpg0; + + if (isp->ipu_dir) + debugfs_remove_recursive(psys->debugfsdir); + + flush_workqueue(IPU_PSYS_WORK_QUEUE); + + if (psys->sched_cmd_thread) { + kthread_stop(psys->sched_cmd_thread); + psys->sched_cmd_thread = NULL; + } + + pm_runtime_dont_use_autosuspend(&psys->adev->dev); + + mutex_lock(&ipu_psys_mutex); + + list_for_each_entry_safe(kpg, kpg0, &psys->pgs, list) { + dma_free_coherent(&adev->dev, kpg->size, kpg->pg, + kpg->pg_dma_addr); + kfree(kpg); + } + + if (psys->fwcom && ipu_fw_com_release(psys->fwcom, 1)) + dev_err(&adev->dev, "fw com release failed.\n"); + + isp->pkg_dir = NULL; + isp->pkg_dir_dma_addr = 0; + isp->pkg_dir_size = 0; + + ipu_cpd_free_pkg_dir(adev, psys->pkg_dir, + psys->pkg_dir_dma_addr, psys->pkg_dir_size); + + ipu_buttress_unmap_fw_image(adev, &psys->fw_sgt); + + kfree(psys->server_init); + kfree(psys->syscom_config); + + ipu_trace_uninit(&adev->dev); + + ipu_psys_resource_pool_cleanup(&psys->resource_pool_started); + ipu_psys_resource_pool_cleanup(&psys->resource_pool_running); + + device_unregister(&psys->dev); + + clear_bit(MINOR(psys->cdev.dev), ipu_psys_devices); + cdev_del(&psys->cdev); + + mutex_unlock(&ipu_psys_mutex); + + mutex_destroy(&psys->mutex); + + dev_info(&adev->dev, "removed\n"); +} + +static irqreturn_t psys_isr_threaded(struct ipu_bus_device *adev) +{ + struct ipu_psys *psys = ipu_bus_get_drvdata(adev); + void __iomem *base = psys->pdata->base; + u32 status; + int r; + + mutex_lock(&psys->mutex); +#ifdef CONFIG_PM + if (!READ_ONCE(psys->power)) { + mutex_unlock(&psys->mutex); + return IRQ_NONE; + } + + r = pm_runtime_get_sync(&psys->adev->dev); + if (r < 0) { + pm_runtime_put(&psys->adev->dev); + mutex_unlock(&psys->mutex); + return IRQ_NONE; + } +#endif + + status = readl(base + IPU_REG_PSYS_GPDEV_IRQ_STATUS); + writel(status, base + IPU_REG_PSYS_GPDEV_IRQ_CLEAR); + + if (status & IPU_PSYS_GPDEV_IRQ_FWIRQ(IPU_PSYS_GPDEV_FWIRQ0)) { + writel(0, base + IPU_REG_PSYS_GPDEV_FWIRQ(0)); + ipu_psys_handle_events(psys); + } + + pm_runtime_mark_last_busy(&psys->adev->dev); + pm_runtime_put_autosuspend(&psys->adev->dev); + mutex_unlock(&psys->mutex); + + return status ? IRQ_HANDLED : IRQ_NONE; +} + + +static struct ipu_bus_driver ipu_psys_driver = { + .probe = ipu_psys_probe, + .remove = ipu_psys_remove, + .isr_threaded = psys_isr_threaded, + .wanted = IPU_PSYS_NAME, + .drv = { + .name = IPU_PSYS_NAME, + .owner = THIS_MODULE, + .pm = PSYS_PM_OPS, + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, +}; + +static int __init ipu_psys_init(void) +{ + int rval = alloc_chrdev_region(&ipu_psys_dev_t, 0, + IPU_PSYS_NUM_DEVICES, IPU_PSYS_NAME); + if (rval) { + pr_err("can't alloc psys chrdev region (%d)\n", rval); + return rval; + } + + rval = bus_register(&ipu_psys_bus); + if (rval) { + pr_warn("can't register psys bus (%d)\n", rval); + goto out_bus_register; + } + + ipu_bus_register_driver(&ipu_psys_driver); + + return rval; + +out_bus_register: + unregister_chrdev_region(ipu_psys_dev_t, IPU_PSYS_NUM_DEVICES); + + return rval; +} + +static void __exit ipu_psys_exit(void) +{ + ipu_bus_unregister_driver(&ipu_psys_driver); + bus_unregister(&ipu_psys_bus); + unregister_chrdev_region(ipu_psys_dev_t, IPU_PSYS_NUM_DEVICES); +} + +static const struct pci_device_id ipu_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU_PCI_ID)}, + {0,} +}; +MODULE_DEVICE_TABLE(pci, ipu_pci_tbl); + +module_init(ipu_psys_init); +module_exit(ipu_psys_exit); + +MODULE_AUTHOR("Antti Laakso "); +MODULE_AUTHOR("Bin Han "); +MODULE_AUTHOR("Renwei Wu "); +MODULE_AUTHOR("Jianxu Zheng "); +MODULE_AUTHOR("Xia Wu "); +MODULE_AUTHOR("Bingbu Cao "); +MODULE_AUTHOR("Zaikuo Wang "); +MODULE_AUTHOR("Yunliang Ding "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu processing system driver"); +MODULE_IMPORT_NS("DMA_BUF"); diff --git a/drivers/media/pci/intel/ipu-psys.h b/drivers/media/pci/intel/ipu-psys.h new file mode 100644 index 0000000000000..b0eef0685c9a3 --- /dev/null +++ b/drivers/media/pci/intel/ipu-psys.h @@ -0,0 +1,222 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2020 Intel Corporation */ + +#ifndef IPU_PSYS_H +#define IPU_PSYS_H + +#include +#include + +#include "ipu.h" +#include "ipu-pdata.h" +#include "ipu-fw-psys.h" +#include "ipu-platform-psys.h" + +#define IPU_PSYS_PG_POOL_SIZE 16 +#define IPU_PSYS_PG_MAX_SIZE 2048 +#define IPU_MAX_PSYS_CMD_BUFFERS 32 +#define IPU_PSYS_EVENT_CMD_COMPLETE IPU_FW_PSYS_EVENT_TYPE_SUCCESS +#define IPU_PSYS_EVENT_FRAGMENT_COMPLETE IPU_FW_PSYS_EVENT_TYPE_SUCCESS +#define IPU_PSYS_CLOSE_TIMEOUT_US 50 +#define IPU_PSYS_CLOSE_TIMEOUT (100000 / IPU_PSYS_CLOSE_TIMEOUT_US) +#define IPU_PSYS_WORK_QUEUE system_power_efficient_wq +#define IPU_MAX_RESOURCES 128 + +/* Opaque structure. Do not access fields. */ +struct ipu_resource { + u32 id; + int elements; /* Number of elements available to allocation */ + unsigned long *bitmap; /* Allocation bitmap, a bit for each element */ +}; + +enum ipu_resource_type { + IPU_RESOURCE_DEV_CHN = 0, + IPU_RESOURCE_EXT_MEM, + IPU_RESOURCE_DFM +}; + +/* Allocation of resource(s) */ +/* Opaque structure. Do not access fields. */ +struct ipu_resource_alloc { + enum ipu_resource_type type; + struct ipu_resource *resource; + int elements; + int pos; +}; + +/* + * This struct represents all of the currently allocated + * resources from IPU model. It is used also for allocating + * resources for the next set of PGs to be run on IPU + * (ie. those PGs which are not yet being run and which don't + * yet reserve real IPU resources). + */ +#define IPU_PSYS_RESOURCE_OVERALLOC 2 /* Some room for ABI / ext lib delta */ +/* resource size may need expand for new resource model */ +struct ipu_psys_resource_pool { + u32 cells; /* Bitmask of cells allocated */ + struct ipu_resource dev_channels[IPU_FW_PSYS_N_DEV_CHN_ID + + IPU_PSYS_RESOURCE_OVERALLOC]; + struct ipu_resource ext_memory[IPU_FW_PSYS_N_MEM_ID + + IPU_PSYS_RESOURCE_OVERALLOC]; + struct ipu_resource dfms[IPU_FW_PSYS_N_DEV_DFM_ID + + IPU_PSYS_RESOURCE_OVERALLOC]; + DECLARE_BITMAP(cmd_queues, 32); + /* Protects cmd_queues bitmap */ + spinlock_t queues_lock; +}; + +/* + * This struct keeps book of the resources allocated for a specific PG. + * It is used for freeing up resources from struct ipu_psys_resources + * when the PG is released from IPU (or model of IPU). + */ +struct ipu_psys_resource_alloc { + u32 cells; /* Bitmask of cells needed */ + struct ipu_resource_alloc + resource_alloc[IPU_MAX_RESOURCES]; + int resources; +}; + +struct task_struct; +struct ipu_psys { + struct cdev cdev; + struct device dev; + + struct mutex mutex; /* Psys various */ + int power; + bool icache_prefetch_sp; + bool icache_prefetch_isp; + spinlock_t power_lock; /* Serialize access to power */ + spinlock_t pgs_lock; /* Protect pgs list access */ + struct list_head fhs; + struct list_head pgs; + struct list_head started_kcmds_list; + struct ipu_psys_pdata *pdata; + struct ipu_bus_device *adev; + struct ia_css_syscom_context *dev_ctx; + struct ia_css_syscom_config *syscom_config; + struct ia_css_psys_server_init *server_init; + struct task_struct *sched_cmd_thread; + struct work_struct watchdog_work; + wait_queue_head_t sched_cmd_wq; + atomic_t wakeup_sched_thread_count; /* Psys schedule thread wakeup count */ +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfsdir; +#endif + + /* Resources needed to be managed for process groups */ + struct ipu_psys_resource_pool resource_pool_running; + struct ipu_psys_resource_pool resource_pool_started; + + const struct firmware *fw; + struct sg_table fw_sgt; + u64 *pkg_dir; + dma_addr_t pkg_dir_dma_addr; + unsigned int pkg_dir_size; + unsigned long timeout; + + int active_kcmds, started_kcmds; + void *fwcom; + + int power_gating; +}; + +struct ipu_psys_fh { + struct ipu_psys *psys; + struct mutex mutex; /* Protects bufmap & kcmds fields */ + struct list_head list; + struct list_head bufmap; + wait_queue_head_t wait; + struct ipu_psys_scheduler sched; +}; + +struct ipu_psys_pg { + struct ipu_fw_psys_process_group *pg; + size_t size; + size_t pg_size; + dma_addr_t pg_dma_addr; + struct list_head list; + struct ipu_psys_resource_alloc resource_alloc; +}; + +struct ipu_psys_kcmd { + struct ipu_psys_fh *fh; + struct list_head list; + struct list_head started_list; + struct ipu_psys_buffer_set *kbuf_set; + enum ipu_psys_cmd_state state; + void *pg_manifest; + size_t pg_manifest_size; + struct ipu_psys_kbuffer **kbufs; + struct ipu_psys_buffer *buffers; + size_t nbuffers; + struct ipu_fw_psys_process_group *pg_user; + struct ipu_psys_pg *kpg; + u64 user_token; + u64 issue_id; + u32 priority; + u32 kernel_enable_bitmap[4]; + u32 terminal_enable_bitmap[4]; + u32 routing_enable_bitmap[4]; + u32 rbm[5]; + struct ipu_buttress_constraint constraint; + struct ipu_psys_event ev; + struct timer_list watchdog; +}; + +struct ipu_dma_buf_attach { + struct device *dev; + u64 len; + void *userptr; + struct sg_table *sgt; + bool vma_is_io; + struct page **pages; + size_t npages; +}; + +struct ipu_psys_kbuffer { + u64 len; + void *userptr; + u32 flags; + int fd; + void *kaddr; + struct list_head list; + dma_addr_t dma_addr; + struct sg_table *sgt; + struct dma_buf_attachment *db_attach; + struct dma_buf *dbuf; + bool valid; /* True when buffer is usable */ +}; + +#define inode_to_ipu_psys(inode) \ + container_of((inode)->i_cdev, struct ipu_psys, cdev) + +#ifdef CONFIG_COMPAT +long ipu_psys_compat_ioctl32(struct file *file, unsigned int cmd, + unsigned long arg); +#endif + +void ipu_psys_setup_hw(struct ipu_psys *psys); +void ipu_psys_subdomains_power(struct ipu_psys *psys, bool on); +void ipu_psys_handle_events(struct ipu_psys *psys); +int ipu_psys_kcmd_new(struct ipu_psys_command *cmd, struct ipu_psys_fh *fh); +void ipu_psys_run_next(struct ipu_psys *psys); +void ipu_psys_watchdog_work(struct work_struct *work); +struct ipu_psys_pg *__get_pg_buf(struct ipu_psys *psys, size_t pg_size); +struct ipu_psys_kbuffer * +ipu_psys_lookup_kbuffer(struct ipu_psys_fh *fh, int fd); +int ipu_psys_mapbuf_locked(int fd, struct ipu_psys_fh *fh, + struct ipu_psys_kbuffer *kbuf); +struct ipu_psys_kbuffer * +ipu_psys_lookup_kbuffer_by_kaddr(struct ipu_psys_fh *fh, void *kaddr); +#ifdef IPU_PSYS_GPC +int ipu_psys_gpc_init_debugfs(struct ipu_psys *psys); +#endif +int ipu_psys_resource_pool_init(struct ipu_psys_resource_pool *pool); +void ipu_psys_resource_pool_cleanup(struct ipu_psys_resource_pool *pool); +struct ipu_psys_kcmd *ipu_get_completed_kcmd(struct ipu_psys_fh *fh); +long ipu_ioctl_dqevent(struct ipu_psys_event *event, + struct ipu_psys_fh *fh, unsigned int f_flags); + +#endif /* IPU_PSYS_H */ diff --git a/drivers/media/pci/intel/ipu-trace-event.h b/drivers/media/pci/intel/ipu-trace-event.h new file mode 100644 index 0000000000000..39df80e3a4d4a --- /dev/null +++ b/drivers/media/pci/intel/ipu-trace-event.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2015 - 2018 Intel Corporation */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ipu + +#if !defined(IPU_TRACE_EVENT_H) || defined(TRACE_HEADER_MULTI_READ) +#define IPU_EVENT_H + +#include + +#ifdef IPU_SOF_SEQID_TRACE +TRACE_EVENT(ipu_sof_seqid, + TP_PROTO(unsigned int seqid, unsigned int csiport, + unsigned int csivc), + TP_ARGS(seqid, csiport, csivc), + TP_STRUCT__entry(__field(unsigned int, seqid) + __field(unsigned int, csiport) + __field(unsigned int, csivc) + ), + TP_fast_assign(__entry->seqid = seqid; + __entry->csiport = csiport; + __entry->csivc = csivc;), + TP_printk("seqid<%u>,csiport<%u>,csivc<%u>", __entry->seqid, + __entry->csiport, __entry->csivc) + ); +#endif + +#ifdef IPU_EOF_SEQID_TRACE +TRACE_EVENT(ipu_eof_seqid, + TP_PROTO(unsigned int seqid, unsigned int csiport, + unsigned int csivc), + TP_ARGS(seqid, csiport, csivc), + TP_STRUCT__entry(__field(unsigned int, seqid) + __field(unsigned int, csiport) + __field(unsigned int, csivc) + ), + TP_fast_assign(__entry->seqid = seqid; + __entry->csiport = csiport; + __entry->csivc = csivc;), + TP_printk("seqid<%u>,csiport<%u>,csivc<%u>", __entry->seqid, + __entry->csiport, __entry->csivc) + ); +#endif + +#ifdef IPU_PERF_REG_TRACE +TRACE_EVENT(ipu_perf_reg, + TP_PROTO(unsigned int addr, unsigned int val), + TP_ARGS(addr, val), TP_STRUCT__entry(__field(unsigned int, addr) + __field(unsigned int, val) + ), + TP_fast_assign(__entry->addr = addr; + __entry->val = val;), + TP_printk("addr=%u,val=%u", __entry->addr, __entry->val) + ); +#endif + +#ifdef IPU_PG_KCMD_TRACE +TRACE_EVENT(ipu_pg_kcmd, + TP_PROTO(const char *func, unsigned int id, + unsigned long long issue_id, unsigned int pri, + unsigned int pg_id, unsigned int load_cycles, + unsigned int init_cycles, + unsigned int processing_cycles), + TP_ARGS(func, id, issue_id, pri, pg_id, load_cycles, init_cycles, + processing_cycles), + TP_STRUCT__entry(__field(const char *, func) + __field(unsigned int, id) + __field(unsigned long long, issue_id) + __field(unsigned int, pri) + __field(unsigned int, pg_id) + __field(unsigned int, load_cycles) + __field(unsigned int, init_cycles) + __field(unsigned int, processing_cycles) + ), + TP_fast_assign(__entry->func = func; + __entry->id = id; + __entry->issue_id = issue_id; + __entry->pri = pri; + __entry->pg_id = pg_id; + __entry->load_cycles = load_cycles; + __entry->init_cycles = init_cycles; + __entry->processing_cycles = processing_cycles;), + TP_printk + ("pg-kcmd: func=%s,id=%u,issue_id=0x%llx,pri=%u,pg_id=%d,load_cycles=%u,init_cycles=%u,processing_cycles=%u", + __entry->func, __entry->id, __entry->issue_id, __entry->pri, + __entry->pg_id, __entry->load_cycles, __entry->init_cycles, + __entry->processing_cycles) + ); + +#endif +#endif + +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE ipu-trace-event +/* This part must be outside protection */ +#include diff --git a/drivers/media/pci/intel/ipu-trace.c b/drivers/media/pci/intel/ipu-trace.c new file mode 100644 index 0000000000000..d9e95d8fb144e --- /dev/null +++ b/drivers/media/pci/intel/ipu-trace.c @@ -0,0 +1,915 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2014 - 2018 Intel Corporation + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipu.h" +#include "ipu-platform-regs.h" +#include "ipu-trace.h" + +/* Input data processing states */ +enum config_file_parse_states { + STATE_FILL = 0, + STATE_COMMENT, + STATE_COMPLETE, +}; + +struct trace_register_range { + u32 start; + u32 end; +}; + +static u16 trace_unit_template[] = TRACE_REG_CREATE_TUN_REGISTER_LIST; +static u16 trace_monitor_template[] = TRACE_REG_CREATE_TM_REGISTER_LIST; +static u16 trace_gpc_template[] = TRACE_REG_CREATE_GPC_REGISTER_LIST; + +static struct trace_register_range trace_csi2_range_template[] = { + { + .start = TRACE_REG_CSI2_TM_RESET_REG_IDX, + .end = TRACE_REG_CSI2_TM_IRQ_ENABLE_REG_IDn(7) + }, + { + .start = TRACE_REG_END_MARK, + .end = TRACE_REG_END_MARK + } +}; + +static struct trace_register_range trace_csi2_3ph_range_template[] = { + { + .start = TRACE_REG_CSI2_3PH_TM_RESET_REG_IDX, + .end = TRACE_REG_CSI2_3PH_TM_IRQ_ENABLE_REG_IDn(7) + }, + { + .start = TRACE_REG_END_MARK, + .end = TRACE_REG_END_MARK + } +}; + +static struct trace_register_range trace_sig2cio_range_template[] = { + { + .start = TRACE_REG_SIG2CIO_ADDRESS, + .end = (TRACE_REG_SIG2CIO_STATUS + 8 * TRACE_REG_SIG2CIO_SIZE_OF) + }, + { + .start = TRACE_REG_END_MARK, + .end = TRACE_REG_END_MARK + } +}; + +#define LINE_MAX_LEN 128 +#define MEMORY_RING_BUFFER_SIZE (SZ_1M * 10) +#define TRACE_MESSAGE_SIZE 16 +/* + * It looks that the trace unit sometimes writes outside the given buffer. + * To avoid memory corruption one extra page is reserved at the end + * of the buffer. Read also the extra area since it may contain valid data. + */ +#define MEMORY_RING_BUFFER_GUARD PAGE_SIZE +#define MEMORY_RING_BUFFER_OVERREAD MEMORY_RING_BUFFER_GUARD +#define MAX_TRACE_REGISTERS 200 +#define TRACE_CONF_DUMP_BUFFER_SIZE (MAX_TRACE_REGISTERS * 2 * 32) + +#define IPU_TRACE_TIME_RETRY 5 + +struct config_value { + u32 reg; + u32 value; +}; + +struct ipu_trace_buffer { + dma_addr_t dma_handle; + void *memory_buffer; +}; + +struct ipu_subsystem_trace_config { + u32 offset; + void __iomem *base; + struct ipu_trace_buffer memory; /* ring buffer */ + struct device *dev; + struct ipu_trace_block *blocks; + unsigned int fill_level; /* Nbr of regs in config table below */ + bool running; + /* Cached register values */ + struct config_value config[MAX_TRACE_REGISTERS]; +}; + +/* + * State of the input data processing is kept in this structure. + * Only one user is supported at time. + */ +struct buf_state { + char line_buffer[LINE_MAX_LEN]; + enum config_file_parse_states state; + int offset; /* Offset to line_buffer */ +}; + +struct ipu_trace { + struct mutex lock; + bool open; + char *conf_dump_buffer; + int size_conf_dump; + struct buf_state buffer_state; + + struct ipu_subsystem_trace_config isys; + struct ipu_subsystem_trace_config psys; +}; + +int ipu_trace_get_timer(struct device *dev, u64 *timer) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_subsystem_trace_config *sys = adev->trace_cfg; + struct ipu_trace_block *blocks; + void __iomem *addr = NULL; + uint32_t time_hi1, time_hi2, time_lo, retry; + + if (!sys) + return -ENODEV; + /* Find trace unit base address */ + blocks = sys->blocks; + while (blocks->type != IPU_TRACE_BLOCK_END) { + if (blocks->type == IPU_TRACE_BLOCK_TUN) { + addr = sys->base + blocks->offset; + break; + } + blocks++; + } + if (!addr) + return -ENODEV; + + for (retry = 0; retry < IPU_TRACE_TIME_RETRY; retry++) { + time_hi1 = readl(addr + TRACE_REG_TUN_LOCAL_TIMER1); + time_lo = readl(addr + TRACE_REG_TUN_LOCAL_TIMER0); + time_hi2 = readl(addr + TRACE_REG_TUN_LOCAL_TIMER1); + *timer = (((u64) time_hi1) << 32) | time_lo; + if (time_hi1 == time_hi2) + return 0; + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(ipu_trace_get_timer); + +static void __ipu_trace_restore(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_device *isp = adev->isp; + struct ipu_trace *trace = isp->trace; + struct config_value *config; + struct ipu_subsystem_trace_config *sys = adev->trace_cfg; + struct ipu_trace_block *blocks; + uint32_t mapped_trace_buffer; + void __iomem *addr = NULL; + int i; + + if (trace->open) { + dev_info(dev, "Trace control file open. Skipping update\n"); + return; + } + + if (!sys) + return; + + /* leave if no trace configuration for this subsystem */ + if (sys->fill_level == 0) + return; + + /* Find trace unit base address */ + blocks = sys->blocks; + while (blocks->type != IPU_TRACE_BLOCK_END) { + if (blocks->type == IPU_TRACE_BLOCK_TUN) { + addr = sys->base + blocks->offset; + break; + } + blocks++; + } + if (!addr) + return; + + if (!sys->memory.memory_buffer) { + sys->memory.memory_buffer = + dma_alloc_coherent(dev, MEMORY_RING_BUFFER_SIZE + + MEMORY_RING_BUFFER_GUARD, + &sys->memory.dma_handle, + GFP_KERNEL); + } + + if (!sys->memory.memory_buffer) { + dev_err(dev, "No memory for tracing. Trace unit disabled\n"); + return; + } + + config = sys->config; + mapped_trace_buffer = sys->memory.dma_handle; + + /* ring buffer base */ + writel(mapped_trace_buffer, addr + TRACE_REG_TUN_DRAM_BASE_ADDR); + + /* ring buffer end */ + writel(mapped_trace_buffer + MEMORY_RING_BUFFER_SIZE - + TRACE_MESSAGE_SIZE, addr + TRACE_REG_TUN_DRAM_END_ADDR); + + /* Infobits for ddr trace */ + writel(IPU_INFO_REQUEST_DESTINATION_PRIMARY, + addr + TRACE_REG_TUN_DDR_INFO_VAL); + + /* Find trace timer reset address */ + addr = NULL; + blocks = sys->blocks; + while (blocks->type != IPU_TRACE_BLOCK_END) { + if (blocks->type == IPU_TRACE_TIMER_RST) { + addr = sys->base + blocks->offset; + break; + } + blocks++; + } + if (!addr) { + dev_err(dev, "No trace reset addr\n"); + return; + } + + /* Remove reset from trace timers */ + writel(TRACE_REG_GPREG_TRACE_TIMER_RST_OFF, addr); + + /* Register config received from userspace */ + for (i = 0; i < sys->fill_level; i++) { + dev_dbg(dev, + "Trace restore: reg 0x%08x, value 0x%08x\n", + config[i].reg, config[i].value); + writel(config[i].value, isp->base + config[i].reg); + } + + sys->running = true; +} + +void ipu_trace_restore(struct device *dev) +{ + struct ipu_trace *trace = to_ipu_bus_device(dev)->isp->trace; + + if (!trace) + return; + + mutex_lock(&trace->lock); + __ipu_trace_restore(dev); + mutex_unlock(&trace->lock); +} +EXPORT_SYMBOL_GPL(ipu_trace_restore); + +static void __ipu_trace_stop(struct device *dev) +{ + struct ipu_subsystem_trace_config *sys = + to_ipu_bus_device(dev)->trace_cfg; + struct ipu_trace_block *blocks; + + if (!sys) + return; + + if (!sys->running) + return; + sys->running = false; + + /* Turn off all the gpc blocks */ + blocks = sys->blocks; + while (blocks->type != IPU_TRACE_BLOCK_END) { + if (blocks->type == IPU_TRACE_BLOCK_GPC) { + writel(0, sys->base + blocks->offset + + TRACE_REG_GPC_OVERALL_ENABLE); + } + blocks++; + } + + /* Turn off all the trace monitors */ + blocks = sys->blocks; + while (blocks->type != IPU_TRACE_BLOCK_END) { + if (blocks->type == IPU_TRACE_BLOCK_TM) { + writel(0, sys->base + blocks->offset + + TRACE_REG_TM_TRACE_ENABLE_NPK); + + writel(0, sys->base + blocks->offset + + TRACE_REG_TM_TRACE_ENABLE_DDR); + } + blocks++; + } + + /* Turn off trace units */ + blocks = sys->blocks; + while (blocks->type != IPU_TRACE_BLOCK_END) { + if (blocks->type == IPU_TRACE_BLOCK_TUN) { + writel(0, sys->base + blocks->offset + + TRACE_REG_TUN_DDR_ENABLE); + writel(0, sys->base + blocks->offset + + TRACE_REG_TUN_NPK_ENABLE); + } + blocks++; + } +} + +void ipu_trace_stop(struct device *dev) +{ + struct ipu_trace *trace = to_ipu_bus_device(dev)->isp->trace; + + if (!trace) + return; + + mutex_lock(&trace->lock); + __ipu_trace_stop(dev); + mutex_unlock(&trace->lock); +} +EXPORT_SYMBOL_GPL(ipu_trace_stop); + +static int validate_register(u32 base, u32 reg, u16 *template) +{ + int i = 0; + + while (template[i] != TRACE_REG_END_MARK) { + if (template[i] + base != reg) { + i++; + continue; + } + /* This is a valid register */ + return 0; + } + return -EINVAL; +} + +static int validate_register_range(u32 base, u32 reg, + struct trace_register_range *template) +{ + unsigned int i = 0; + + if (!IS_ALIGNED(reg, sizeof(u32))) + return -EINVAL; + + while (template[i].start != TRACE_REG_END_MARK) { + if ((reg < template[i].start + base) || + (reg > template[i].end + base)) { + i++; + continue; + } + /* This is a valid register */ + return 0; + } + return -EINVAL; +} + +static int update_register_cache(struct ipu_device *isp, u32 reg, u32 value) +{ + struct ipu_trace *dctrl = isp->trace; + const struct ipu_trace_block *blocks; + struct ipu_subsystem_trace_config *sys; + struct device *dev; + u32 base = 0; + u16 *template = NULL; + struct trace_register_range *template_range = NULL; + int i, range; + int rval = -EINVAL; + + if (dctrl->isys.offset == dctrl->psys.offset) { + /* For the IPU with uniform address space */ + if (reg >= IPU_ISYS_OFFSET && + reg < IPU_ISYS_OFFSET + TRACE_REG_MAX_ISYS_OFFSET) + sys = &dctrl->isys; + else if (reg >= IPU_PSYS_OFFSET && + reg < IPU_PSYS_OFFSET + TRACE_REG_MAX_PSYS_OFFSET) + sys = &dctrl->psys; + else + goto error; + } else { + if (dctrl->isys.offset && + reg >= dctrl->isys.offset && + reg < dctrl->isys.offset + TRACE_REG_MAX_ISYS_OFFSET) + sys = &dctrl->isys; + else if (dctrl->psys.offset && + reg >= dctrl->psys.offset && + reg < dctrl->psys.offset + TRACE_REG_MAX_PSYS_OFFSET) + sys = &dctrl->psys; + else + goto error; + } + + blocks = sys->blocks; + dev = sys->dev; + + /* Check registers block by block */ + i = 0; + while (blocks[i].type != IPU_TRACE_BLOCK_END) { + base = blocks[i].offset + sys->offset; + if ((reg >= base && reg < base + TRACE_REG_MAX_BLOCK_SIZE)) + break; + i++; + } + + range = 0; + switch (blocks[i].type) { + case IPU_TRACE_BLOCK_TUN: + template = trace_unit_template; + break; + case IPU_TRACE_BLOCK_TM: + template = trace_monitor_template; + break; + case IPU_TRACE_BLOCK_GPC: + template = trace_gpc_template; + break; + case IPU_TRACE_CSI2: + range = 1; + template_range = trace_csi2_range_template; + break; + case IPU_TRACE_CSI2_3PH: + range = 1; + template_range = trace_csi2_3ph_range_template; + break; + case IPU_TRACE_SIG2CIOS: + range = 1; + template_range = trace_sig2cio_range_template; + break; + default: + goto error; + } + + if (range) + rval = validate_register_range(base, reg, template_range); + else + rval = validate_register(base, reg, template); + + if (rval) + goto error; + + if (sys->fill_level < MAX_TRACE_REGISTERS) { + dev_dbg(dev, + "Trace reg addr 0x%08x value 0x%08x\n", reg, value); + sys->config[sys->fill_level].reg = reg; + sys->config[sys->fill_level].value = value; + sys->fill_level++; + } else { + rval = -ENOMEM; + goto error; + } + return 0; +error: + dev_info(&isp->pdev->dev, + "Trace register address 0x%08x ignored as invalid register\n", + reg); + return rval; +} + +/* + * We don't know how much data is received this time. Process given data + * character by character. + * Fill the line buffer until either + * 1) new line is got -> go to decode + * or + * 2) line_buffer is full -> ignore rest of line and then try to decode + * or + * 3) Comment mark is found -> ignore rest of the line and then try to decode + * the data which was received before the comment mark + * + * Decode phase tries to find "reg = value" pairs and validates those + */ +static int process_buffer(struct ipu_device *isp, + char *buffer, int size, struct buf_state *state) +{ + int i, ret; + int curr_state = state->state; + u32 reg, value; + + for (i = 0; i < size; i++) { + /* + * Comment mark in any position turns on comment mode + * until end of line + */ + if (curr_state != STATE_COMMENT && buffer[i] == '#') { + state->line_buffer[state->offset] = '\0'; + curr_state = STATE_COMMENT; + continue; + } + + switch (curr_state) { + case STATE_COMMENT: + /* Only new line can break this mode */ + if (buffer[i] == '\n') + curr_state = STATE_COMPLETE; + break; + case STATE_FILL: + state->line_buffer[state->offset] = buffer[i]; + state->offset++; + + if (state->offset >= sizeof(state->line_buffer) - 1) { + /* Line buffer full - ignore rest */ + state->line_buffer[state->offset] = '\0'; + curr_state = STATE_COMMENT; + break; + } + + if (buffer[i] == '\n') { + state->line_buffer[state->offset] = '\0'; + curr_state = STATE_COMPLETE; + } + break; + default: + state->offset = 0; + state->line_buffer[state->offset] = '\0'; + curr_state = STATE_COMMENT; + } + + if (curr_state == STATE_COMPLETE) { + ret = sscanf(state->line_buffer, "%x = %x", + ®, &value); + if (ret == 2) + update_register_cache(isp, reg, value); + + state->offset = 0; + curr_state = STATE_FILL; + } + } + state->state = curr_state; + return 0; +} + +static void traceconf_dump(struct ipu_device *isp) +{ + struct ipu_subsystem_trace_config *sys[2] = { + &isp->trace->isys, + &isp->trace->psys + }; + int i, j, rem_size; + char *out; + + isp->trace->size_conf_dump = 0; + out = isp->trace->conf_dump_buffer; + rem_size = TRACE_CONF_DUMP_BUFFER_SIZE; + + for (j = 0; j < ARRAY_SIZE(sys); j++) { + for (i = 0; i < sys[j]->fill_level && rem_size > 0; i++) { + int bytes_print; + int n = snprintf(out, rem_size, "0x%08x = 0x%08x\n", + sys[j]->config[i].reg, + sys[j]->config[i].value); + + bytes_print = min(n, rem_size - 1); + rem_size -= bytes_print; + out += bytes_print; + } + } + isp->trace->size_conf_dump = out - isp->trace->conf_dump_buffer; +} + +static void clear_trace_buffer(struct ipu_subsystem_trace_config *sys) +{ + if (!sys->memory.memory_buffer) + return; + + memset(sys->memory.memory_buffer, 0, MEMORY_RING_BUFFER_SIZE + + MEMORY_RING_BUFFER_OVERREAD); + + dma_sync_single_for_device(sys->dev, + sys->memory.dma_handle, + MEMORY_RING_BUFFER_SIZE + + MEMORY_RING_BUFFER_GUARD, DMA_FROM_DEVICE); +} + +static int traceconf_open(struct inode *inode, struct file *file) +{ + int ret; + struct ipu_device *isp; + + if (!inode->i_private) + return -EACCES; + + isp = inode->i_private; + + ret = mutex_trylock(&isp->trace->lock); + if (!ret) + return -EBUSY; + + if (isp->trace->open) { + mutex_unlock(&isp->trace->lock); + return -EBUSY; + } + + file->private_data = isp; + isp->trace->open = 1; + if (file->f_mode & FMODE_WRITE) { + /* TBD: Allocate temp buffer for processing. + * Push validated buffer to active config + */ + + /* Forget old config if opened for write */ + isp->trace->isys.fill_level = 0; + isp->trace->psys.fill_level = 0; + } + + if (file->f_mode & FMODE_READ) { + isp->trace->conf_dump_buffer = + vzalloc(TRACE_CONF_DUMP_BUFFER_SIZE); + if (!isp->trace->conf_dump_buffer) { + isp->trace->open = 0; + mutex_unlock(&isp->trace->lock); + return -ENOMEM; + } + traceconf_dump(isp); + } + mutex_unlock(&isp->trace->lock); + return 0; +} + +static ssize_t traceconf_read(struct file *file, char __user *buf, + size_t len, loff_t *ppos) +{ + struct ipu_device *isp = file->private_data; + + return simple_read_from_buffer(buf, len, ppos, + isp->trace->conf_dump_buffer, + isp->trace->size_conf_dump); +} + +static ssize_t traceconf_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos) +{ + struct ipu_device *isp = file->private_data; + char buffer[64]; + ssize_t bytes, count; + loff_t pos = *ppos; + + if (*ppos < 0) + return -EINVAL; + + count = min(len, sizeof(buffer)); + bytes = copy_from_user(buffer, buf, count); + if (bytes == count) + return -EFAULT; + + count -= bytes; + mutex_lock(&isp->trace->lock); + process_buffer(isp, buffer, count, &isp->trace->buffer_state); + mutex_unlock(&isp->trace->lock); + *ppos = pos + count; + + return count; +} + +static int traceconf_release(struct inode *inode, struct file *file) +{ + struct ipu_device *isp = file->private_data; + struct device *psys_dev = isp->psys ? &isp->psys->dev : NULL; + struct device *isys_dev = isp->isys ? &isp->isys->dev : NULL; + int pm_rval = -EINVAL; + + /* + * Turn devices on outside trace->lock mutex. PM transition may + * cause call to function which tries to take the same lock. + * Also do this before trace->open is set back to 0 to avoid + * double restore (one here and one in pm transition). We can't + * rely purely on the restore done by pm call backs since trace + * configuration can occur in any phase compared to other activity. + */ + + if (file->f_mode & FMODE_WRITE) { + if (isys_dev) + pm_rval = pm_runtime_get_sync(isys_dev); + + if (pm_rval >= 0) { + /* ISYS ok or missing */ + if (psys_dev) + pm_rval = pm_runtime_get_sync(psys_dev); + + if (pm_rval < 0) { + pm_runtime_put_noidle(psys_dev); + if (isys_dev) + pm_runtime_put(isys_dev); + } + } else { + pm_runtime_put_noidle(&isp->isys->dev); + } + } + + mutex_lock(&isp->trace->lock); + isp->trace->open = 0; + vfree(isp->trace->conf_dump_buffer); + isp->trace->conf_dump_buffer = NULL; + + if (pm_rval >= 0) { + /* Update new cfg to HW */ + if (isys_dev) { + __ipu_trace_stop(isys_dev); + clear_trace_buffer(isp->isys->trace_cfg); + __ipu_trace_restore(isys_dev); + } + + if (psys_dev) { + __ipu_trace_stop(psys_dev); + clear_trace_buffer(isp->psys->trace_cfg); + __ipu_trace_restore(psys_dev); + } + } + + mutex_unlock(&isp->trace->lock); + + if (pm_rval >= 0) { + /* Again - this must be done with trace->lock not taken */ + if (psys_dev) + pm_runtime_put(psys_dev); + if (isys_dev) + pm_runtime_put(isys_dev); + } + return 0; +} + +static const struct file_operations ipu_traceconf_fops = { + .owner = THIS_MODULE, + .open = traceconf_open, + .release = traceconf_release, + .read = traceconf_read, + .write = traceconf_write, + .llseek = noop_llseek, +}; + +static int gettrace_open(struct inode *inode, struct file *file) +{ + struct ipu_subsystem_trace_config *sys = inode->i_private; + + if (!sys) + return -EACCES; + + if (!sys->memory.memory_buffer) + return -EACCES; + + dma_sync_single_for_cpu(sys->dev, + sys->memory.dma_handle, + MEMORY_RING_BUFFER_SIZE + + MEMORY_RING_BUFFER_GUARD, DMA_FROM_DEVICE); + + file->private_data = sys; + return 0; +}; + +static ssize_t gettrace_read(struct file *file, char __user *buf, + size_t len, loff_t *ppos) +{ + struct ipu_subsystem_trace_config *sys = file->private_data; + + return simple_read_from_buffer(buf, len, ppos, + sys->memory.memory_buffer, + MEMORY_RING_BUFFER_SIZE + + MEMORY_RING_BUFFER_OVERREAD); +} + +static ssize_t gettrace_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos) +{ + struct ipu_subsystem_trace_config *sys = file->private_data; + static const char str[] = "clear"; + char buffer[sizeof(str)] = { 0 }; + ssize_t ret; + + ret = simple_write_to_buffer(buffer, sizeof(buffer), ppos, buf, len); + if (ret < 0) + return ret; + + if (ret < sizeof(str) - 1) + return -EINVAL; + + if (!strncmp(str, buffer, sizeof(str) - 1)) { + clear_trace_buffer(sys); + return len; + } + + return -EINVAL; +} + +static int gettrace_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations ipu_gettrace_fops = { + .owner = THIS_MODULE, + .open = gettrace_open, + .release = gettrace_release, + .read = gettrace_read, + .write = gettrace_write, + .llseek = noop_llseek, +}; + +int ipu_trace_init(struct ipu_device *isp, void __iomem *base, + struct device *dev, struct ipu_trace_block *blocks) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_trace *trace = isp->trace; + struct ipu_subsystem_trace_config *sys; + int ret = 0; + + if (!isp->trace) + return 0; + + mutex_lock(&isp->trace->lock); + + if (dev == &isp->isys->dev) { + sys = &trace->isys; + } else if (dev == &isp->psys->dev) { + sys = &trace->psys; + } else { + ret = -EINVAL; + goto leave; + } + + adev->trace_cfg = sys; + sys->dev = dev; + sys->offset = base - isp->base; /* sub system offset */ + sys->base = base; + sys->blocks = blocks; + +leave: + mutex_unlock(&isp->trace->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(ipu_trace_init); + +void ipu_trace_uninit(struct device *dev) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(dev); + struct ipu_device *isp = adev->isp; + struct ipu_trace *trace = isp->trace; + struct ipu_subsystem_trace_config *sys = adev->trace_cfg; + + if (!trace || !sys) + return; + + mutex_lock(&trace->lock); + + if (sys->memory.memory_buffer) + dma_free_attrs(sys->dev, + MEMORY_RING_BUFFER_SIZE + + MEMORY_RING_BUFFER_GUARD, + sys->memory.memory_buffer, + sys->memory.dma_handle, 0); + + sys->dev = NULL; + sys->memory.memory_buffer = NULL; + + mutex_unlock(&trace->lock); +} +EXPORT_SYMBOL_GPL(ipu_trace_uninit); + +int ipu_trace_debugfs_add(struct ipu_device *isp, struct dentry *dir) +{ + struct dentry *files[3]; + int i = 0; + + files[i] = debugfs_create_file("traceconf", 0644, + dir, isp, &ipu_traceconf_fops); + if (!files[i]) + return -ENOMEM; + i++; + + files[i] = debugfs_create_file("getisystrace", 0444, + dir, + &isp->trace->isys, &ipu_gettrace_fops); + + if (!files[i]) + goto error; + i++; + + files[i] = debugfs_create_file("getpsystrace", 0444, + dir, + &isp->trace->psys, &ipu_gettrace_fops); + if (!files[i]) + goto error; + + return 0; + +error: + for (; i > 0; i--) + debugfs_remove(files[i - 1]); + return -ENOMEM; +} + +int ipu_trace_add(struct ipu_device *isp) +{ + isp->trace = devm_kzalloc(&isp->pdev->dev, + sizeof(struct ipu_trace), GFP_KERNEL); + if (!isp->trace) + return -ENOMEM; + + mutex_init(&isp->trace->lock); + + return 0; +} + +void ipu_trace_release(struct ipu_device *isp) +{ + if (!isp->trace) + return; + mutex_destroy(&isp->trace->lock); +} + +MODULE_AUTHOR("Samu Onkalo "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu trace support"); diff --git a/drivers/media/pci/intel/ipu-trace.h b/drivers/media/pci/intel/ipu-trace.h new file mode 100644 index 0000000000000..9167c0400273f --- /dev/null +++ b/drivers/media/pci/intel/ipu-trace.h @@ -0,0 +1,312 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2014 - 2018 Intel Corporation */ + +#ifndef IPU_TRACE_H +#define IPU_TRACE_H +#include + +#define TRACE_REG_MAX_BLOCK_SIZE 0x0fff + +#define TRACE_REG_END_MARK 0xffff + +#define TRACE_REG_CMD_TYPE_D64 0x0 +#define TRACE_REG_CMD_TYPE_D64M 0x1 +#define TRACE_REG_CMD_TYPE_D64TS 0x2 +#define TRACE_REG_CMD_TYPE_D64MTS 0x3 + +/* Trace unit register offsets */ +#define TRACE_REG_TUN_DDR_ENABLE 0x000 +#define TRACE_REG_TUN_NPK_ENABLE 0x004 +#define TRACE_REG_TUN_DDR_INFO_VAL 0x008 +#define TRACE_REG_TUN_NPK_ADDR 0x00C +#define TRACE_REG_TUN_DRAM_BASE_ADDR 0x010 +#define TRACE_REG_TUN_DRAM_END_ADDR 0x014 +#define TRACE_REG_TUN_LOCAL_TIMER0 0x018 +#define TRACE_REG_TUN_LOCAL_TIMER1 0x01C +#define TRACE_REG_TUN_WR_PTR 0x020 +#define TRACE_REG_TUN_RD_PTR 0x024 + +#define TRACE_REG_CREATE_TUN_REGISTER_LIST { \ + TRACE_REG_TUN_DDR_ENABLE, \ + TRACE_REG_TUN_NPK_ENABLE, \ + TRACE_REG_TUN_DDR_INFO_VAL, \ + TRACE_REG_TUN_NPK_ADDR, \ + TRACE_REG_END_MARK \ +} +/* + * Following registers are left out on purpose: + * TUN_LOCAL_TIMER0, TUN_LOCAL_TIMER1, TUN_DRAM_BASE_ADDR + * TUN_DRAM_END_ADDR, TUN_WR_PTR, TUN_RD_PTR + */ + +/* Trace monitor register offsets */ +#define TRACE_REG_TM_TRACE_ADDR_A 0x0900 +#define TRACE_REG_TM_TRACE_ADDR_B 0x0904 +#define TRACE_REG_TM_TRACE_ADDR_C 0x0908 +#define TRACE_REG_TM_TRACE_ADDR_D 0x090c +#define TRACE_REG_TM_TRACE_ENABLE_NPK 0x0910 +#define TRACE_REG_TM_TRACE_ENABLE_DDR 0x0914 +#define TRACE_REG_TM_TRACE_PER_PC 0x0918 +#define TRACE_REG_TM_TRACE_PER_BRANCH 0x091c +#define TRACE_REG_TM_TRACE_HEADER 0x0920 +#define TRACE_REG_TM_TRACE_CFG 0x0924 +#define TRACE_REG_TM_TRACE_LOST_PACKETS 0x0928 +#define TRACE_REG_TM_TRACE_LP_CLEAR 0x092c +#define TRACE_REG_TM_TRACE_LMRUN_MASK 0x0930 +#define TRACE_REG_TM_TRACE_LMRUN_PC_LOW 0x0934 +#define TRACE_REG_TM_TRACE_LMRUN_PC_HIGH 0x0938 +#define TRACE_REG_TM_TRACE_MMIO_SEL 0x093c +#define TRACE_REG_TM_TRACE_MMIO_WP0_LOW 0x0940 +#define TRACE_REG_TM_TRACE_MMIO_WP1_LOW 0x0944 +#define TRACE_REG_TM_TRACE_MMIO_WP2_LOW 0x0948 +#define TRACE_REG_TM_TRACE_MMIO_WP3_LOW 0x094c +#define TRACE_REG_TM_TRACE_MMIO_WP0_HIGH 0x0950 +#define TRACE_REG_TM_TRACE_MMIO_WP1_HIGH 0x0954 +#define TRACE_REG_TM_TRACE_MMIO_WP2_HIGH 0x0958 +#define TRACE_REG_TM_TRACE_MMIO_WP3_HIGH 0x095c +#define TRACE_REG_TM_FWTRACE_FIRST 0x0A00 +#define TRACE_REG_TM_FWTRACE_MIDDLE 0x0A04 +#define TRACE_REG_TM_FWTRACE_LAST 0x0A08 + +#define TRACE_REG_CREATE_TM_REGISTER_LIST { \ + TRACE_REG_TM_TRACE_ADDR_A, \ + TRACE_REG_TM_TRACE_ADDR_B, \ + TRACE_REG_TM_TRACE_ADDR_C, \ + TRACE_REG_TM_TRACE_ADDR_D, \ + TRACE_REG_TM_TRACE_ENABLE_NPK, \ + TRACE_REG_TM_TRACE_ENABLE_DDR, \ + TRACE_REG_TM_TRACE_PER_PC, \ + TRACE_REG_TM_TRACE_PER_BRANCH, \ + TRACE_REG_TM_TRACE_HEADER, \ + TRACE_REG_TM_TRACE_CFG, \ + TRACE_REG_TM_TRACE_LOST_PACKETS, \ + TRACE_REG_TM_TRACE_LP_CLEAR, \ + TRACE_REG_TM_TRACE_LMRUN_MASK, \ + TRACE_REG_TM_TRACE_LMRUN_PC_LOW, \ + TRACE_REG_TM_TRACE_LMRUN_PC_HIGH, \ + TRACE_REG_TM_TRACE_MMIO_SEL, \ + TRACE_REG_TM_TRACE_MMIO_WP0_LOW, \ + TRACE_REG_TM_TRACE_MMIO_WP1_LOW, \ + TRACE_REG_TM_TRACE_MMIO_WP2_LOW, \ + TRACE_REG_TM_TRACE_MMIO_WP3_LOW, \ + TRACE_REG_TM_TRACE_MMIO_WP0_HIGH, \ + TRACE_REG_TM_TRACE_MMIO_WP1_HIGH, \ + TRACE_REG_TM_TRACE_MMIO_WP2_HIGH, \ + TRACE_REG_TM_TRACE_MMIO_WP3_HIGH, \ + TRACE_REG_END_MARK \ +} + +/* + * Following exists only in (I)SP address space: + * TM_FWTRACE_FIRST, TM_FWTRACE_MIDDLE, TM_FWTRACE_LAST + */ + +#define TRACE_REG_GPC_RESET 0x000 +#define TRACE_REG_GPC_OVERALL_ENABLE 0x004 +#define TRACE_REG_GPC_TRACE_HEADER 0x008 +#define TRACE_REG_GPC_TRACE_ADDRESS 0x00C +#define TRACE_REG_GPC_TRACE_NPK_EN 0x010 +#define TRACE_REG_GPC_TRACE_DDR_EN 0x014 +#define TRACE_REG_GPC_TRACE_LPKT_CLEAR 0x018 +#define TRACE_REG_GPC_TRACE_LPKT 0x01C + +#define TRACE_REG_GPC_ENABLE_ID0 0x020 +#define TRACE_REG_GPC_ENABLE_ID1 0x024 +#define TRACE_REG_GPC_ENABLE_ID2 0x028 +#define TRACE_REG_GPC_ENABLE_ID3 0x02c + +#define TRACE_REG_GPC_VALUE_ID0 0x030 +#define TRACE_REG_GPC_VALUE_ID1 0x034 +#define TRACE_REG_GPC_VALUE_ID2 0x038 +#define TRACE_REG_GPC_VALUE_ID3 0x03c + +#define TRACE_REG_GPC_CNT_INPUT_SELECT_ID0 0x040 +#define TRACE_REG_GPC_CNT_INPUT_SELECT_ID1 0x044 +#define TRACE_REG_GPC_CNT_INPUT_SELECT_ID2 0x048 +#define TRACE_REG_GPC_CNT_INPUT_SELECT_ID3 0x04c + +#define TRACE_REG_GPC_CNT_START_SELECT_ID0 0x050 +#define TRACE_REG_GPC_CNT_START_SELECT_ID1 0x054 +#define TRACE_REG_GPC_CNT_START_SELECT_ID2 0x058 +#define TRACE_REG_GPC_CNT_START_SELECT_ID3 0x05c + +#define TRACE_REG_GPC_CNT_STOP_SELECT_ID0 0x060 +#define TRACE_REG_GPC_CNT_STOP_SELECT_ID1 0x064 +#define TRACE_REG_GPC_CNT_STOP_SELECT_ID2 0x068 +#define TRACE_REG_GPC_CNT_STOP_SELECT_ID3 0x06c + +#define TRACE_REG_GPC_CNT_MSG_SELECT_ID0 0x070 +#define TRACE_REG_GPC_CNT_MSG_SELECT_ID1 0x074 +#define TRACE_REG_GPC_CNT_MSG_SELECT_ID2 0x078 +#define TRACE_REG_GPC_CNT_MSG_SELECT_ID3 0x07c + +#define TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID0 0x080 +#define TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID1 0x084 +#define TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID2 0x088 +#define TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID3 0x08c + +#define TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID0 0x090 +#define TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID1 0x094 +#define TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID2 0x098 +#define TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID3 0x09c + +#define TRACE_REG_GPC_IRQ_TIMER_SELECT_ID0 0x0a0 +#define TRACE_REG_GPC_IRQ_TIMER_SELECT_ID1 0x0a4 +#define TRACE_REG_GPC_IRQ_TIMER_SELECT_ID2 0x0a8 +#define TRACE_REG_GPC_IRQ_TIMER_SELECT_ID3 0x0ac + +#define TRACE_REG_GPC_IRQ_ENABLE_ID0 0x0b0 +#define TRACE_REG_GPC_IRQ_ENABLE_ID1 0x0b4 +#define TRACE_REG_GPC_IRQ_ENABLE_ID2 0x0b8 +#define TRACE_REG_GPC_IRQ_ENABLE_ID3 0x0bc + +#define TRACE_REG_CREATE_GPC_REGISTER_LIST { \ + TRACE_REG_GPC_RESET, \ + TRACE_REG_GPC_OVERALL_ENABLE, \ + TRACE_REG_GPC_TRACE_HEADER, \ + TRACE_REG_GPC_TRACE_ADDRESS, \ + TRACE_REG_GPC_TRACE_NPK_EN, \ + TRACE_REG_GPC_TRACE_DDR_EN, \ + TRACE_REG_GPC_TRACE_LPKT_CLEAR, \ + TRACE_REG_GPC_TRACE_LPKT, \ + TRACE_REG_GPC_ENABLE_ID0, \ + TRACE_REG_GPC_ENABLE_ID1, \ + TRACE_REG_GPC_ENABLE_ID2, \ + TRACE_REG_GPC_ENABLE_ID3, \ + TRACE_REG_GPC_VALUE_ID0, \ + TRACE_REG_GPC_VALUE_ID1, \ + TRACE_REG_GPC_VALUE_ID2, \ + TRACE_REG_GPC_VALUE_ID3, \ + TRACE_REG_GPC_CNT_INPUT_SELECT_ID0, \ + TRACE_REG_GPC_CNT_INPUT_SELECT_ID1, \ + TRACE_REG_GPC_CNT_INPUT_SELECT_ID2, \ + TRACE_REG_GPC_CNT_INPUT_SELECT_ID3, \ + TRACE_REG_GPC_CNT_START_SELECT_ID0, \ + TRACE_REG_GPC_CNT_START_SELECT_ID1, \ + TRACE_REG_GPC_CNT_START_SELECT_ID2, \ + TRACE_REG_GPC_CNT_START_SELECT_ID3, \ + TRACE_REG_GPC_CNT_STOP_SELECT_ID0, \ + TRACE_REG_GPC_CNT_STOP_SELECT_ID1, \ + TRACE_REG_GPC_CNT_STOP_SELECT_ID2, \ + TRACE_REG_GPC_CNT_STOP_SELECT_ID3, \ + TRACE_REG_GPC_CNT_MSG_SELECT_ID0, \ + TRACE_REG_GPC_CNT_MSG_SELECT_ID1, \ + TRACE_REG_GPC_CNT_MSG_SELECT_ID2, \ + TRACE_REG_GPC_CNT_MSG_SELECT_ID3, \ + TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID0, \ + TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID1, \ + TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID2, \ + TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID3, \ + TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID0, \ + TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID1, \ + TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID2, \ + TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID3, \ + TRACE_REG_GPC_IRQ_TIMER_SELECT_ID0, \ + TRACE_REG_GPC_IRQ_TIMER_SELECT_ID1, \ + TRACE_REG_GPC_IRQ_TIMER_SELECT_ID2, \ + TRACE_REG_GPC_IRQ_TIMER_SELECT_ID3, \ + TRACE_REG_GPC_IRQ_ENABLE_ID0, \ + TRACE_REG_GPC_IRQ_ENABLE_ID1, \ + TRACE_REG_GPC_IRQ_ENABLE_ID2, \ + TRACE_REG_GPC_IRQ_ENABLE_ID3, \ + TRACE_REG_END_MARK \ +} + +/* CSI2 legacy receiver trace registers */ +#define TRACE_REG_CSI2_TM_RESET_REG_IDX 0x0000 +#define TRACE_REG_CSI2_TM_OVERALL_ENABLE_REG_IDX 0x0004 +#define TRACE_REG_CSI2_TM_TRACE_HEADER_REG_IDX 0x0008 +#define TRACE_REG_CSI2_TM_TRACE_ADDRESS_REG_IDX 0x000c +#define TRACE_REG_CSI2_TM_TRACE_HEADER_VAL 0xf +#define TRACE_REG_CSI2_TM_TRACE_ADDRESS_VAL 0x100218 +#define TRACE_REG_CSI2_TM_MONITOR_ID 0x8 + +/* 0 <= n <= 3 */ +#define TRACE_REG_CSI2_TM_TRACE_NPK_EN_REG_IDX_P(n) (0x0010 + (n) * 4) +#define TRACE_REG_CSI2_TM_TRACE_DDR_EN_REG_IDX_P(n) (0x0020 + (n) * 4) +#define TRACE_CSI2_TM_EVENT_FE(vc) (BIT(0) << (vc * 6)) +#define TRACE_CSI2_TM_EVENT_FS(vc) (BIT(1) << (vc * 6)) +#define TRACE_CSI2_TM_EVENT_PE(vc) (BIT(2) << (vc * 6)) +#define TRACE_CSI2_TM_EVENT_PS(vc) (BIT(3) << (vc * 6)) +#define TRACE_CSI2_TM_EVENT_LE(vc) (BIT(4) << (vc * 6)) +#define TRACE_CSI2_TM_EVENT_LS(vc) (BIT(5) << (vc * 6)) + +#define TRACE_REG_CSI2_TM_TRACE_LPKT_CLEAR_REG_IDX 0x0030 +#define TRACE_REG_CSI2_TM_TRACE_LPKT_REG_IDX 0x0034 + +/* 0 <= n <= 7 */ +#define TRACE_REG_CSI2_TM_ENABLE_REG_IDn(n) (0x0038 + (n) * 4) +#define TRACE_REG_CSI2_TM_VALUE_REG_IDn(n) (0x0058 + (n) * 4) +#define TRACE_REG_CSI2_TM_CNT_INPUT_SELECT_REG_IDn(n) (0x0078 + (n) * 4) +#define TRACE_REG_CSI2_TM_CNT_START_SELECT_REG_IDn(n) (0x0098 + (n) * 4) +#define TRACE_REG_CSI2_TM_CNT_STOP_SELECT_REG_IDn(n) (0x00b8 + (n) * 4) +#define TRACE_REG_CSI2_TM_IRQ_TRIGGER_VALUE_REG_IDn(n) (0x00d8 + (n) * 4) +#define TRACE_REG_CSI2_TM_IRQ_TIMER_SELECT_REG_IDn(n) (0x00f8 + (n) * 4) +#define TRACE_REG_CSI2_TM_IRQ_ENABLE_REG_IDn(n) (0x0118 + (n) * 4) + +/* CSI2_3PH combo receiver trace registers */ +#define TRACE_REG_CSI2_3PH_TM_RESET_REG_IDX 0x0000 +#define TRACE_REG_CSI2_3PH_TM_OVERALL_ENABLE_REG_IDX 0x0004 +#define TRACE_REG_CSI2_3PH_TM_TRACE_HEADER_REG_IDX 0x0008 +#define TRACE_REG_CSI2_3PH_TM_TRACE_ADDRESS_REG_IDX 0x000c +#define TRACE_REG_CSI2_3PH_TM_TRACE_ADDRESS_VAL 0x100258 +#define TRACE_REG_CSI2_3PH_TM_MONITOR_ID 0x9 + +/* 0 <= n <= 5 */ +#define TRACE_REG_CSI2_3PH_TM_TRACE_NPK_EN_REG_IDX_P(n) (0x0010 + (n) * 4) +#define TRACE_REG_CSI2_3PH_TM_TRACE_DDR_EN_REG_IDX_P(n) (0x0028 + (n) * 4) + +#define TRACE_REG_CSI2_3PH_TM_TRACE_LPKT_CLEAR_REG_IDX 0x0040 +#define TRACE_REG_CSI2_3PH_TM_TRACE_LPKT_REG_IDX 0x0044 + +/* 0 <= n <= 7 */ +#define TRACE_REG_CSI2_3PH_TM_ENABLE_REG_IDn(n) (0x0048 + (n) * 4) +#define TRACE_REG_CSI2_3PH_TM_VALUE_REG_IDn(n) (0x0068 + (n) * 4) +#define TRACE_REG_CSI2_3PH_TM_CNT_INPUT_SELECT_REG_IDn(n) (0x0088 + (n) * 4) +#define TRACE_REG_CSI2_3PH_TM_CNT_START_SELECT_REG_IDn(n) (0x00a8 + (n) * 4) +#define TRACE_REG_CSI2_3PH_TM_CNT_STOP_SELECT_REG_IDn(n) (0x00c8 + (n) * 4) +#define TRACE_REG_CSI2_3PH_TM_IRQ_TRIGGER_VALUE_REG_IDn(n) (0x00e8 + (n) * 4) +#define TRACE_REG_CSI2_3PH_TM_IRQ_TIMER_SELECT_REG_IDn(n) (0x0108 + (n) * 4) +#define TRACE_REG_CSI2_3PH_TM_IRQ_ENABLE_REG_IDn(n) (0x0128 + (n) * 4) + +/* SIG2CIO trace monitors */ +#define TRACE_REG_SIG2CIO_ADDRESS 0x0000 +#define TRACE_REG_SIG2CIO_WDATA 0x0004 +#define TRACE_REG_SIG2CIO_MASK 0x0008 +#define TRACE_REG_SIG2CIO_GROUP_CFG 0x000c +#define TRACE_REG_SIG2CIO_STICKY 0x0010 +#define TRACE_REG_SIG2CIO_RST_STICKY 0x0014 +#define TRACE_REG_SIG2CIO_MANUAL_RST_STICKY 0x0018 +#define TRACE_REG_SIG2CIO_STATUS 0x001c +/* Size of on SIG2CIO block */ +#define TRACE_REG_SIG2CIO_SIZE_OF 0x0020 + +struct ipu_trace; +struct ipu_subsystem_trace_config; + +enum ipu_trace_block_type { + IPU_TRACE_BLOCK_TUN = 0, /* Trace unit */ + IPU_TRACE_BLOCK_TM, /* Trace monitor */ + IPU_TRACE_BLOCK_GPC, /* General purpose control */ + IPU_TRACE_CSI2, /* CSI2 legacy receiver */ + IPU_TRACE_CSI2_3PH, /* CSI2 combo receiver */ + IPU_TRACE_SIG2CIOS, + IPU_TRACE_TIMER_RST, /* Trace reset control timer */ + IPU_TRACE_BLOCK_END /* End of list */ +}; + +struct ipu_trace_block { + u32 offset; /* Offset to block inside subsystem */ + enum ipu_trace_block_type type; +}; + +int ipu_trace_add(struct ipu_device *isp); +int ipu_trace_debugfs_add(struct ipu_device *isp, struct dentry *dir); +void ipu_trace_release(struct ipu_device *isp); +int ipu_trace_init(struct ipu_device *isp, void __iomem *base, + struct device *dev, struct ipu_trace_block *blocks); +void ipu_trace_restore(struct device *dev); +void ipu_trace_uninit(struct device *dev); +void ipu_trace_stop(struct device *dev); +int ipu_trace_get_timer(struct device *dev, u64 *timer); +#endif diff --git a/drivers/media/pci/intel/ipu-wrapper.c b/drivers/media/pci/intel/ipu-wrapper.c new file mode 100644 index 0000000000000..92515234daff1 --- /dev/null +++ b/drivers/media/pci/intel/ipu-wrapper.c @@ -0,0 +1,532 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include + +#include +#include +#include +#include +#include + +#include "ipu-bus.h" +#include "ipu-dma.h" +#include "ipu-mmu.h" +#include "ipu-wrapper.h" +#include "vied_subsystem_access.h" +#include "vied_subsystem_access_initialization.h" +#include "shared_memory_map.h" +#include "shared_memory_access.h" + +struct wrapper_base { + void __iomem *sys_base; + const struct dma_map_ops *ops; + /* Protect shared memory buffers */ + spinlock_t lock; + struct list_head buffers; + u32 css_map_done; + struct device *dev; +}; + +static struct wrapper_base isys; +static struct wrapper_base psys; + +struct my_css_memory_buffer_item { + struct list_head list; + dma_addr_t iova; + unsigned long *addr; + size_t bytes; + unsigned long attrs; +}; + +static struct wrapper_base *get_mem_sub_system(int mmid) +{ + if (mmid == ISYS_MMID) + return &isys; + + if (mmid == PSYS_MMID) + return &psys; + WARN(1, "Invalid mem subsystem"); + return NULL; +} + +static struct wrapper_base *get_sub_system(int ssid) +{ + if (ssid == ISYS_SSID) + return &isys; + + if (ssid == PSYS_SSID) + return &psys; + WARN(1, "Invalid subsystem"); + return NULL; +} + +/* + * Subsystem access functions to access IUNIT MMIO space + */ +static void *host_addr(int ssid, u32 addr) +{ + if (ssid == ISYS_SSID) + return isys.sys_base + addr; + else if (ssid == PSYS_SSID) + return psys.sys_base + addr; + /* + * Calling WARN_ON is a bit brutal but better to capture wrong register + * accesses immediately. We have no way to return an error here. + */ + WARN_ON(1); + + return NULL; +} + +void vied_subsystem_store_32(unsigned int ssid, u32 addr, u32 data) +{ + writel(data, host_addr(ssid, addr)); +} + +void vied_subsystem_store_16(unsigned int ssid, u32 addr, u16 data) +{ + writew(data, host_addr(ssid, addr)); +} + +void vied_subsystem_store_8(unsigned int ssid, u32 addr, u8 data) +{ + writeb(data, host_addr(ssid, addr)); +} + +void vied_subsystem_store(unsigned int ssid, + u32 addr, const void *data, unsigned int size) +{ + void *dst = host_addr(ssid, addr); + + dev_dbg(get_sub_system(ssid)->dev, "access: %s 0x%x size: %d\n", + __func__, addr, size); + + for (; size >= sizeof(u32); size -= sizeof(u32), + dst += sizeof(u32), data += sizeof(u32)) { + writel(*(u32 *) data, dst); + } + if (size >= sizeof(u16)) { + writew(*(u16 *) data, dst); + size -= sizeof(u16), dst += sizeof(u16), data += sizeof(u16); + } + if (size) + writeb(*(u8 *) data, dst); +} + +u32 vied_subsystem_load_32(unsigned int ssid, u32 addr) +{ + return readl(host_addr(ssid, addr)); +} + +u16 vied_subsystem_load_16(unsigned int ssid, u32 addr) +{ + return readw(host_addr(ssid, addr)); +} + +u8 vied_subsystem_load_8(unsigned int ssid, u32 addr) +{ + return readb(host_addr(ssid, addr)); +} + +void vied_subsystem_load(unsigned int ssid, u32 addr, + void *data, unsigned int size) +{ + void *src = host_addr(ssid, addr); + + dev_dbg(get_sub_system(ssid)->dev, "access: %s 0x%x size: %d\n", + __func__, addr, size); + + for (; size >= sizeof(u32); size -= sizeof(u32), + src += sizeof(u32), data += sizeof(u32)) + *(u32 *) data = readl(src); + if (size >= sizeof(u16)) { + *(u16 *) data = readw(src); + size -= sizeof(u16), src += sizeof(u16), data += sizeof(u16); + } + if (size) + *(u8 *) data = readb(src); +} + +/* + * Initialize base address for subsystem + */ +void vied_subsystem_access_initialize(unsigned int system) +{ +} + +/* + * Shared memory access codes written by Dash Biswait, + * copied from FPGA environment + */ + +/** + * \brief Initialize the shared memory interface administration on the host. + * \param mmid: id of ddr memory + * \param host_ddr_addr: physical address of memory as seen from host + * \param memory_size: size of ddr memory in bytes + * \param ps: size of page in bytes (for instance 4096) + */ +int shared_memory_allocation_initialize(unsigned int mmid, u64 host_ddr_addr, + size_t memory_size, size_t ps) +{ + return 0; +} + +/** + * \brief De-initialize the shared memory interface administration on the host. + * + */ +void shared_memory_allocation_uninitialize(unsigned int mmid) +{ +} + +/** + * \brief Initialize the shared memory interface administration on the host. + * \param ssid: id of subsystem + * \param mmid: id of ddr memory + * \param mmu_ps: size of page in bits + * \param mmu_pnrs: page numbers + * \param ddr_addr: base address + * \param inv_tlb: invalidate tbl + * \param sbt: set l1 base address + */ +int shared_memory_map_initialize(unsigned int ssid, unsigned int mmid, + size_t mmu_ps, size_t mmu_pnrs, u64 ddr_addr, + shared_memory_invalidate_mmu_tlb inv_tlb, + shared_memory_set_page_table_base_address sbt) +{ + return 0; +} + +/** + * \brief De-initialize the shared memory interface administration on the host. + */ +void shared_memory_map_uninitialize(unsigned int ssid, unsigned int mmid) +{ +} + +static u8 alloc_cookie; + +/** + * \brief Allocate (DDR) shared memory space and return a host virtual address. + * \Returns NULL when insufficient memory available + */ +u64 shared_memory_alloc(unsigned int mmid, size_t bytes) +{ + struct wrapper_base *mine = get_mem_sub_system(mmid); + struct my_css_memory_buffer_item *buf; + unsigned long flags; + + if (!mine) { + pr_err("Invalid mem subsystem, return. mmid=%d", mmid); + return 0; + } + + dev_dbg(mine->dev, "%s: in, size: %zu\n", __func__, bytes); + + if (!bytes) + return (unsigned long)&alloc_cookie; + + might_sleep(); + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return 0; + + /*alloc using ipu dma driver */ + buf->bytes = PAGE_ALIGN(bytes); + + buf->addr = dma_alloc_coherent(mine->dev, buf->bytes, &buf->iova, + GFP_KERNEL); + if (!buf->addr) { + kfree(buf); + return 0; + } + + spin_lock_irqsave(&mine->lock, flags); + list_add(&buf->list, &mine->buffers); + spin_unlock_irqrestore(&mine->lock, flags); + + return (unsigned long)buf->addr; +} + +/** + * \brief Free (DDR) shared memory space. + */ +void shared_memory_free(unsigned int mmid, u64 addr) +{ + struct wrapper_base *mine = get_mem_sub_system(mmid); + struct my_css_memory_buffer_item *buf = NULL; + unsigned long flags; + + if (!mine) { + pr_err("Invalid mem subsystem, return. mmid=%d", mmid); + return; + } + + if ((void *)(unsigned long)addr == &alloc_cookie) + return; + + might_sleep(); + + dev_dbg(mine->dev, "looking for iova %8.8llx\n", addr); + + spin_lock_irqsave(&mine->lock, flags); + list_for_each_entry(buf, &mine->buffers, list) { + dev_dbg(mine->dev, "buffer addr %8.8lx\n", (long)buf->addr); + if ((long)buf->addr != addr) + continue; + + dev_dbg(mine->dev, "found it!\n"); + list_del(&buf->list); + spin_unlock_irqrestore(&mine->lock, flags); + dma_free_attrs(mine->dev, buf->bytes, buf->addr, buf->iova, + buf->attrs + ); + kfree(buf); + return; + } + dev_warn(mine->dev, "Can't find mem object %8.8llx\n", addr); + spin_unlock_irqrestore(&mine->lock, flags); +} + +/** + * \brief Convert a host virtual address to a CSS virtual address and + * \update the MMU. + */ +u32 shared_memory_map(unsigned int ssid, unsigned int mmid, u64 addr) +{ + struct wrapper_base *mine = get_mem_sub_system(mmid); + struct my_css_memory_buffer_item *buf = NULL; + unsigned long flags; + + if (!mine) { + pr_err("Invalid mem subsystem, return NULL. mmid=%d", mmid); + return 0; + } + + if ((void *)(unsigned long)addr == &alloc_cookie) + return 0; + + spin_lock_irqsave(&mine->lock, flags); + list_for_each_entry(buf, &mine->buffers, list) { + dev_dbg(mine->dev, "%s %8.8lx\n", __func__, (long)buf->addr); + if ((long)buf->addr != addr) + continue; + + dev_dbg(mine->dev, "mapped!!\n"); + spin_unlock_irqrestore(&mine->lock, flags); + return buf->iova; + } + dev_err(mine->dev, "Can't find mapped object %8.8llx\n", addr); + spin_unlock_irqrestore(&mine->lock, flags); + return 0; +} + +/** + * \brief Free a CSS virtual address and update the MMU. + */ +void shared_memory_unmap(unsigned int ssid, unsigned int mmid, u32 addr) +{ +} + +/** + * \brief Store a byte into (DDR) shared memory space using a host + * \virtual address + */ +void shared_memory_store_8(unsigned int mmid, u64 addr, u8 data) +{ + if (get_mem_sub_system(mmid)) + dev_dbg(get_mem_sub_system(mmid)->dev, + "access: %s: Enter addr = 0x%llx data = 0x%x\n", + __func__, addr, data); + + *((u8 *)(unsigned long) addr) = data; + /*Invalidate the cache lines to flush the content to ddr. */ + clflush_cache_range((void *)(unsigned long)addr, sizeof(u8)); +} + +/** + * \brief Store a 16-bit word into (DDR) shared memory space using a host + * \virtual address + */ +void shared_memory_store_16(unsigned int mmid, u64 addr, u16 data) +{ + if (get_mem_sub_system(mmid)) + dev_dbg(get_mem_sub_system(mmid)->dev, + "access: %s: Enter addr = 0x%llx data = 0x%x\n", + __func__, addr, data); + + *((u16 *)(unsigned long) addr) = data; + /*Invalidate the cache lines to flush the content to ddr. */ + clflush_cache_range((void *)(unsigned long) addr, sizeof(u16)); +} + +/** + * \brief Store a 32-bit word into (DDR) shared memory space using a host + * \virtual address + */ +void shared_memory_store_32(unsigned int mmid, u64 addr, u32 data) +{ + if (get_mem_sub_system(mmid)) + dev_dbg(get_mem_sub_system(mmid)->dev, + "access: %s: Enter addr = 0x%llx data = 0x%x\n", + __func__, addr, data); + + *((u32 *)(unsigned long) addr) = data; + /* Invalidate the cache lines to flush the content to ddr. */ + clflush_cache_range((void *)(unsigned long) addr, sizeof(u32)); +} + +/** + * \brief Store a number of bytes into (DDR) shared memory space using a host + * \virtual address + */ +void shared_memory_store(unsigned int mmid, u64 addr, const void *data, + size_t bytes) +{ + dev_dbg(get_mem_sub_system(mmid)->dev, + "access: %s: Enter addr = 0x%lx bytes = 0x%zx\n", __func__, + (unsigned long)addr, bytes); + + if (!data) { + if (get_mem_sub_system(mmid)) + dev_err(get_mem_sub_system(mmid)->dev, + "%s: data ptr is null\n", __func__); + else + pr_err("data ptr is null. mmid=%d\n", mmid); + + return; + } else { + const u8 *pdata = data; + u8 *paddr = (u8 *)(unsigned long)addr; + size_t i = 0; + + for (; i < bytes; ++i) + *paddr++ = *pdata++; + + /* Invalidate the cache lines to flush the content to ddr. */ + clflush_cache_range((void *)(unsigned long) addr, bytes); + } +} + +/** + * \brief Set a number of bytes of (DDR) shared memory space to 0 using a host + * \virtual address + */ +void shared_memory_zero(unsigned int mmid, u64 addr, size_t bytes) +{ + if (get_mem_sub_system(mmid)) + dev_dbg(get_mem_sub_system(mmid)->dev, + "access: %s: Enter addr = 0x%llx data = 0x%zx\n", + __func__, (unsigned long long)addr, bytes); + + memset((void *)(unsigned long)addr, 0, bytes); + clflush_cache_range((void *)(unsigned long)addr, bytes); +} + +/** + * \brief Load a byte from (DDR) shared memory space using a host + * \virtual address + */ +u8 shared_memory_load_8(unsigned int mmid, u64 addr) +{ + u8 data = 0; + + if (get_mem_sub_system(mmid)) + dev_dbg(get_mem_sub_system(mmid)->dev, + "access: %s: Enter addr = 0x%llx\n", __func__, addr); + + /* Invalidate the cache lines to flush the content to ddr. */ + clflush_cache_range((void *)(unsigned long)addr, sizeof(u8)); + data = *(u8 *)(unsigned long) addr; + return data; +} + +/** + * \brief Load a 16-bit word from (DDR) shared memory space using a host + * \virtual address + */ +u16 shared_memory_load_16(unsigned int mmid, u64 addr) +{ + u16 data = 0; + + if (get_mem_sub_system(mmid)) + dev_dbg(get_mem_sub_system(mmid)->dev, + "access: %s: Enter addr = 0x%llx\n", __func__, addr); + + /* Invalidate the cache lines to flush the content to ddr. */ + clflush_cache_range((void *)(unsigned long)addr, sizeof(u16)); + data = *(u16 *)(unsigned long)addr; + return data; +} + +/** + * \brief Load a 32-bit word from (DDR) shared memory space using a host + * \virtual address + */ +u32 shared_memory_load_32(unsigned int mmid, u64 addr) +{ + u32 data = 0; + + if (get_mem_sub_system(mmid)) + dev_dbg(get_mem_sub_system(mmid)->dev, + "access: %s: Enter addr = 0x%llx\n", __func__, addr); + + /* Invalidate the cache lines to flush the content to ddr. */ + clflush_cache_range((void *)(unsigned long)addr, sizeof(u32)); + data = *(u32 *)(unsigned long)addr; + return data; +} + +/** + * \brief Load a number of bytes from (DDR) shared memory space using a host + * \virtual address + */ +void shared_memory_load(unsigned int mmid, u64 addr, void *data, size_t bytes) +{ + if (get_mem_sub_system(mmid)) + dev_dbg(get_mem_sub_system(mmid)->dev, + "access: %s: Enter addr = 0x%lx bytes = 0x%zx\n", __func__, + (unsigned long)addr, bytes); + + if (!data && get_mem_sub_system(mmid)) { + dev_err(get_mem_sub_system(mmid)->dev, + "%s: data ptr is null\n", __func__); + + } else { + u8 *pdata = data; + u8 *paddr = (u8 *)(unsigned long)addr; + size_t i = 0; + + /* Invalidate the cache lines to flush the content to ddr. */ + clflush_cache_range((void *)(unsigned long)addr, bytes); + for (; i < bytes; ++i) + *pdata++ = *paddr++; + } +} + +static int init_wrapper(struct wrapper_base *sys) +{ + INIT_LIST_HEAD(&sys->buffers); + spin_lock_init(&sys->lock); + return 0; +} + +/* + * Wrapper driver set base address for library use + */ +void ipu_wrapper_init(int mmid, struct device *dev, void __iomem *base) +{ + struct wrapper_base *sys = get_mem_sub_system(mmid); + + if (!sys) { + pr_err("Invalid mem subsystem, return. mmid=%d", mmid); + return; + } + init_wrapper(sys); + sys->dev = dev; + sys->sys_base = base; +} diff --git a/drivers/media/pci/intel/ipu-wrapper.h b/drivers/media/pci/intel/ipu-wrapper.h new file mode 100644 index 0000000000000..52ca2d1593cd2 --- /dev/null +++ b/drivers/media/pci/intel/ipu-wrapper.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_WRAPPER_H +#define IPU_WRAPPER_H + +#define ISYS_SSID 1 +#define PSYS_SSID 0 + +#define ISYS_MMID 1 +#define PSYS_MMID 0 +struct device; + +void ipu_wrapper_init(int mmid, struct device *dev, void __iomem *base); + +#endif /* IPU_WRAPPER_H */ diff --git a/drivers/media/pci/intel/ipu.c b/drivers/media/pci/intel/ipu.c new file mode 100644 index 0000000000000..aa165bdbb5760 --- /dev/null +++ b/drivers/media/pci/intel/ipu.c @@ -0,0 +1,756 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ipu.h" +#include "ipu-buttress.h" +#include "ipu-platform.h" +#include "ipu-platform-buttress-regs.h" +#include "ipu-cpd.h" +#include "ipu-pdata.h" +#include "ipu-bus.h" +#include "ipu-mmu.h" +#include "ipu-platform-regs.h" +#include "ipu-platform-isys-csi2-reg.h" +#include "ipu-trace.h" + +#define IPU_PCI_BAR 0 + +static struct ipu_bus_device *ipu_mmu_init(struct pci_dev *pdev, + struct device *parent, + struct ipu_buttress_ctrl *ctrl, + void __iomem *base, + const struct ipu_hw_variants *hw, + unsigned int nr, int mmid) +{ + struct device *dev = &pdev->dev; + + int ret; + ret = ipu_bridge_init(dev, ipu_bridge_parse_ssdb); + if (ret) { + dev_err_probe(dev, ret, "IPU6 bridge init failed\n"); + return ERR_PTR(ret); + } + + struct ipu_mmu_pdata *pdata = + devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + unsigned int i; + + if (!pdata) + return ERR_PTR(-ENOMEM); + + if (hw->nr_mmus > IPU_MMU_MAX_DEVICES) + return ERR_PTR(-EINVAL); + + for (i = 0; i < hw->nr_mmus; i++) { + struct ipu_mmu_hw *pdata_mmu = &pdata->mmu_hw[i]; + const struct ipu_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->nr_mmus = hw->nr_mmus; + pdata->mmid = mmid; + + return ipu_bus_add_device(pdev, parent, pdata, NULL, ctrl, + IPU_MMU_NAME, nr); +} + +static struct ipu_bus_device *ipu_isys_init(struct pci_dev *pdev, + struct device *parent, + struct device *iommu, + void __iomem *base, + const struct ipu_isys_internal_pdata + *ipdata, + struct ipu_isys_subdev_pdata + *spdata, unsigned int nr) +{ + struct ipu_isys_pdata *pdata = + devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + + if (!pdata) + return ERR_PTR(-ENOMEM); + + pdata->base = base; + pdata->ipdata = ipdata; + pdata->spdata = spdata; + + return ipu_bus_add_device(pdev, parent, pdata, iommu, NULL, + IPU_ISYS_NAME, nr); +} + +static struct ipu_bus_device *ipu_psys_init(struct pci_dev *pdev, + struct device *parent, + struct device *iommu, + void __iomem *base, + const struct ipu_psys_internal_pdata + *ipdata, unsigned int nr) +{ + struct ipu_psys_pdata *pdata = + devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + + if (!pdata) + return ERR_PTR(-ENOMEM); + + pdata->base = base; + pdata->ipdata = ipdata; + return ipu_bus_add_device(pdev, parent, pdata, iommu, NULL, + IPU_PSYS_NAME, nr); +} + +int ipu_fw_authenticate(void *data, u64 val) +{ + struct ipu_device *isp = data; + int ret; + + if (!isp->secure_mode) + return -EINVAL; + + ret = ipu_buttress_reset_authentication(isp); + if (ret) { + dev_err(&isp->pdev->dev, "Failed to reset authentication!\n"); + return ret; + } + + return ipu_buttress_authenticate(isp); +} +EXPORT_SYMBOL(ipu_fw_authenticate); +DEFINE_SIMPLE_ATTRIBUTE(authenticate_fops, NULL, ipu_fw_authenticate, "%llu\n"); + +#ifdef CONFIG_DEBUG_FS +static int resume_ipu_bus_device(struct ipu_bus_device *adev) +{ + struct device *dev = &adev->dev; + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (!pm || !pm->resume) + return -EIO; + + return pm->resume(dev); +} + +static int suspend_ipu_bus_device(struct ipu_bus_device *adev) +{ + struct device *dev = &adev->dev; + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (!pm || !pm->suspend) + return -EIO; + + return pm->suspend(dev); +} + +static int force_suspend_get(void *data, u64 *val) +{ + struct ipu_device *isp = data; + struct ipu_buttress *b = &isp->buttress; + + *val = b->force_suspend; + return 0; +} + +static int force_suspend_set(void *data, u64 val) +{ + struct ipu_device *isp = data; + struct ipu_buttress *b = &isp->buttress; + int ret = 0; + + if (val == b->force_suspend) + return 0; + + if (val) { + b->force_suspend = 1; + ret = suspend_ipu_bus_device(isp->psys_iommu); + if (ret) { + dev_err(&isp->pdev->dev, "Failed to suspend psys\n"); + return ret; + } + ret = suspend_ipu_bus_device(isp->isys_iommu); + if (ret) { + dev_err(&isp->pdev->dev, "Failed to suspend isys\n"); + return ret; + } + ret = pci_set_power_state(isp->pdev, PCI_D3hot); + if (ret) { + dev_err(&isp->pdev->dev, + "Failed to suspend IUnit PCI device\n"); + return ret; + } + } else { + ret = pci_set_power_state(isp->pdev, PCI_D0); + if (ret) { + dev_err(&isp->pdev->dev, + "Failed to suspend IUnit PCI device\n"); + return ret; + } + ret = resume_ipu_bus_device(isp->isys_iommu); + if (ret) { + dev_err(&isp->pdev->dev, "Failed to resume isys\n"); + return ret; + } + ret = resume_ipu_bus_device(isp->psys_iommu); + if (ret) { + dev_err(&isp->pdev->dev, "Failed to resume psys\n"); + return ret; + } + b->force_suspend = 0; + } + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(force_suspend_fops, force_suspend_get, + force_suspend_set, "%llu\n"); +/* + * The sysfs interface for reloading cpd fw is there only for debug purpose, + * and it must not be used when either isys or psys is in use. + */ +static int cpd_fw_reload(void *data, u64 val) +{ + struct ipu_device *isp = data; + int rval = -EINVAL; + + if (isp->cpd_fw_reload) + rval = isp->cpd_fw_reload(isp); + if (!rval && isp->isys_fw_reload) + rval = isp->isys_fw_reload(isp); + + return rval; +} + +DEFINE_SIMPLE_ATTRIBUTE(cpd_fw_fops, NULL, cpd_fw_reload, "%llu\n"); + +#endif /* CONFIG_DEBUG_FS */ + +static int ipu_init_debugfs(struct ipu_device *isp) +{ +#ifdef CONFIG_DEBUG_FS + struct dentry *file; + struct dentry *dir; + + dir = debugfs_create_dir(pci_name(isp->pdev), NULL); + if (!dir) + return -ENOMEM; + + file = debugfs_create_file("force_suspend", 0700, dir, isp, + &force_suspend_fops); + if (!file) + goto err; + file = debugfs_create_file("authenticate", 0700, dir, isp, + &authenticate_fops); + if (!file) + goto err; + + file = debugfs_create_file("cpd_fw_reload", 0700, dir, isp, + &cpd_fw_fops); + if (!file) + goto err; + + if (ipu_trace_debugfs_add(isp, dir)) + goto err; + + isp->ipu_dir = dir; + + if (ipu_buttress_debugfs_init(isp)) + goto err; + + return 0; +err: + debugfs_remove_recursive(dir); + return -ENOMEM; +#else + return 0; +#endif /* CONFIG_DEBUG_FS */ +} + +static void ipu_remove_debugfs(struct ipu_device *isp) +{ + /* + * Since isys and psys debugfs dir will be created under ipu root dir, + * mark its dentry to NULL to avoid duplicate removal. + */ + debugfs_remove_recursive(isp->ipu_dir); + isp->ipu_dir = NULL; +} + +static int ipu_pci_config_setup(struct pci_dev *dev) +{ + u16 pci_command; + int rval = pci_enable_msi(dev); + + if (rval) { + dev_err(&dev->dev, "Failed to enable msi (%d)\n", rval); + return rval; + } + + pci_read_config_word(dev, PCI_COMMAND, &pci_command); + pci_command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_INTX_DISABLE; + pci_write_config_word(dev, PCI_COMMAND, pci_command); + + return 0; +} + +static void ipu_configure_vc_mechanism(struct ipu_device *isp) +{ + u32 val = readl(isp->base + BUTTRESS_REG_BTRS_CTRL); + + if (IPU_BTRS_ARB_STALL_MODE_VC0 == IPU_BTRS_ARB_MODE_TYPE_STALL) + val |= BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC0; + else + val &= ~BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC0; + + if (IPU_BTRS_ARB_STALL_MODE_VC1 == IPU_BTRS_ARB_MODE_TYPE_STALL) + val |= BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC1; + else + val &= ~BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC1; + + writel(val, isp->base + BUTTRESS_REG_BTRS_CTRL); +} + +int request_cpd_fw(const struct firmware **firmware_p, const char *name, + struct device *device) +{ + const struct firmware *fw; + struct firmware *tmp; + int ret; + + ret = request_firmware(&fw, name, device); + if (ret) + return ret; + + if (is_vmalloc_addr(fw->data)) { + *firmware_p = fw; + } else { + tmp = (struct firmware *)kzalloc(sizeof(struct firmware), GFP_KERNEL); + if (!tmp) { + release_firmware(fw); + return -ENOMEM; + } + tmp->size = fw->size; + tmp->data = vmalloc(fw->size); + if (!tmp->data) { + kfree(tmp); + release_firmware(fw); + return -ENOMEM; + } + memcpy((void *)tmp->data, fw->data, fw->size); + *firmware_p = tmp; + release_firmware(fw); + } + + return 0; +} +EXPORT_SYMBOL(request_cpd_fw); + +static int ipu_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct ipu_device *isp; + phys_addr_t phys; + void __iomem *const *iomap; + void __iomem *isys_base = NULL; + void __iomem *psys_base = NULL; + struct ipu_buttress_ctrl *isys_ctrl, *psys_ctrl; + unsigned int dma_mask = IPU_DMA_MASK; + int rval; + + trace_printk("B|%d|TMWK\n", current->pid); + + isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL); + if (!isp) + return -ENOMEM; + + dev_set_name(&pdev->dev, "intel-ipu"); + isp->pdev = pdev; + INIT_LIST_HEAD(&isp->devices); + + rval = pcim_enable_device(pdev); + if (rval) { + dev_err(&pdev->dev, "Failed to enable CI ISP device (%d)\n", + rval); + trace_printk("E|TMWK\n"); + return rval; + } + + dev_info(&pdev->dev, "Device 0x%x (rev: 0x%x)\n", + pdev->device, pdev->revision); + + phys = pci_resource_start(pdev, IPU_PCI_BAR); + + rval = pcim_iomap_regions(pdev, + 1 << IPU_PCI_BAR, + pci_name(pdev)); + if (rval) { + dev_err(&pdev->dev, "Failed to I/O memory remapping (%d)\n", + rval); + trace_printk("E|TMWK\n"); + return rval; + } + dev_info(&pdev->dev, "physical base address 0x%llx\n", phys); + + iomap = pcim_iomap_table(pdev); + if (!iomap) { + dev_err(&pdev->dev, "Failed to iomap table (%d)\n", rval); + trace_printk("E|TMWK\n"); + return -ENODEV; + } + + isp->base = iomap[IPU_PCI_BAR]; + dev_info(&pdev->dev, "mapped as: 0x%p\n", isp->base); + + pci_set_drvdata(pdev, isp); + pci_set_master(pdev); + + isp->cpd_fw_name = IPU_CPD_FIRMWARE_NAME; + + isys_base = isp->base + isys_ipdata.hw_variant.offset; + psys_base = isp->base + psys_ipdata.hw_variant.offset; + + rval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(dma_mask)); + if (rval) { + dev_err(&pdev->dev, "Failed to set DMA mask (%d)\n", rval); + trace_printk("E|TMWK\n"); + return rval; + } + + rval = ipu_pci_config_setup(pdev); + if (rval) { + trace_printk("E|TMWK\n"); + return rval; + } + + rval = devm_request_threaded_irq(&pdev->dev, pdev->irq, + ipu_buttress_isr, + ipu_buttress_isr_threaded, + IRQF_SHARED, IPU_NAME, isp); + if (rval) { + dev_err(&pdev->dev, "Requesting irq failed(%d)\n", rval); + trace_printk("E|TMWK\n"); + return rval; + } + + rval = ipu_buttress_init(isp); + if (rval) { + trace_printk("E|TMWK\n"); + return rval; + } + + dev_info(&pdev->dev, "cpd file name: %s\n", isp->cpd_fw_name); + + rval = request_cpd_fw(&isp->cpd_fw, isp->cpd_fw_name, &pdev->dev); + if (rval) { + dev_err(&isp->pdev->dev, "Requesting signed firmware failed\n"); + trace_printk("E|TMWK\n"); + return rval; + } + + rval = ipu_cpd_validate_cpd_file(isp, isp->cpd_fw->data, + isp->cpd_fw->size); + if (rval) { + dev_err(&isp->pdev->dev, "Failed to validate cpd\n"); + goto out_ipu_bus_del_devices; + } + + rval = ipu_trace_add(isp); + if (rval) + dev_err(&pdev->dev, "Trace support not available\n"); + + /* + * NOTE Device hierarchy below is important to ensure proper + * runtime suspend and resume order. + * Also registration order is important to ensure proper + * suspend and resume order during system + * suspend. Registration order is as follows: + * isys_iommu->isys->psys_iommu->psys + */ + isys_ctrl = devm_kzalloc(&pdev->dev, sizeof(*isys_ctrl), GFP_KERNEL); + if (!isys_ctrl) { + rval = -ENOMEM; + goto out_ipu_bus_del_devices; + } + + /* Init butress control with default values based on the HW */ + memcpy(isys_ctrl, &isys_buttress_ctrl, sizeof(*isys_ctrl)); + + isp->isys_iommu = ipu_mmu_init(pdev, &pdev->dev, isys_ctrl, + isys_base, + &isys_ipdata.hw_variant, 0, ISYS_MMID); + rval = PTR_ERR(isp->isys_iommu); + if (IS_ERR(isp->isys_iommu)) { + dev_err(&pdev->dev, "can't create isys iommu device\n"); + rval = -ENOMEM; + goto out_ipu_bus_del_devices; + } + + isp->isys = ipu_isys_init(pdev, &isp->isys_iommu->dev, + &isp->isys_iommu->dev, isys_base, + &isys_ipdata, pdev->dev.platform_data, 0); + rval = PTR_ERR(isp->isys); + if (IS_ERR(isp->isys)) + goto out_ipu_bus_del_devices; + + psys_ctrl = devm_kzalloc(&pdev->dev, sizeof(*psys_ctrl), GFP_KERNEL); + if (!psys_ctrl) { + rval = -ENOMEM; + goto out_ipu_bus_del_devices; + } + + /* Init butress control with default values based on the HW */ + memcpy(psys_ctrl, &psys_buttress_ctrl, sizeof(*psys_ctrl)); + + isp->psys_iommu = ipu_mmu_init(pdev, + isp->isys_iommu ? + &isp->isys_iommu->dev : + &pdev->dev, psys_ctrl, psys_base, + &psys_ipdata.hw_variant, 1, PSYS_MMID); + rval = PTR_ERR(isp->psys_iommu); + if (IS_ERR(isp->psys_iommu)) { + dev_err(&pdev->dev, "can't create psys iommu device\n"); + goto out_ipu_bus_del_devices; + } + + isp->psys = ipu_psys_init(pdev, &isp->psys_iommu->dev, + &isp->psys_iommu->dev, psys_base, + &psys_ipdata, 0); + rval = PTR_ERR(isp->psys); + if (IS_ERR(isp->psys)) + goto out_ipu_bus_del_devices; + + rval = ipu_init_debugfs(isp); + if (rval) { + dev_err(&pdev->dev, "Failed to initialize debugfs"); + goto out_ipu_bus_del_devices; + } + + /* Configure the arbitration mechanisms for VC requests */ + ipu_configure_vc_mechanism(isp); + + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_allow(&pdev->dev); + + dev_info(&pdev->dev, "IPU driver verion %d.%d\n", IPU_MAJOR_VERSION, + IPU_MINOR_VERSION); + + trace_printk("E|TMWK\n"); + return 0; + +out_ipu_bus_del_devices: + ipu_bus_del_devices(pdev); + ipu_buttress_exit(isp); + release_firmware(isp->cpd_fw); + + trace_printk("E|TMWK\n"); + return rval; +} + +static void ipu_pci_remove(struct pci_dev *pdev) +{ + struct ipu_device *isp = pci_get_drvdata(pdev); + + ipu_remove_debugfs(isp); + ipu_trace_release(isp); + + ipu_bus_del_devices(pdev); + + pm_runtime_forbid(&pdev->dev); + pm_runtime_get_noresume(&pdev->dev); + + pci_release_regions(pdev); + pci_disable_device(pdev); + + ipu_buttress_exit(isp); + + release_firmware(isp->cpd_fw); +} + +static void ipu_pci_reset_prepare(struct pci_dev *pdev) +{ + struct ipu_device *isp = pci_get_drvdata(pdev); + + dev_warn(&pdev->dev, "FLR prepare\n"); + pm_runtime_forbid(&isp->pdev->dev); + isp->flr_done = true; +} + +static void ipu_pci_reset_done(struct pci_dev *pdev) +{ + struct ipu_device *isp = pci_get_drvdata(pdev); + + ipu_buttress_restore(isp); + if (isp->secure_mode) + ipu_buttress_reset_authentication(isp); + + ipu_bus_flr_recovery(); + isp->ipc_reinit = true; + pm_runtime_allow(&isp->pdev->dev); + + dev_warn(&pdev->dev, "FLR completed\n"); +} + +#ifdef CONFIG_PM + +/* + * PCI base driver code requires driver to provide these to enable + * PCI device level PM state transitions (D0<->D3) + */ +static int ipu_suspend(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct ipu_device *isp = pci_get_drvdata(pdev); + + isp->flr_done = false; + + return 0; +} + +static int ipu_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct ipu_device *isp = pci_get_drvdata(pdev); + struct ipu_buttress *b = &isp->buttress; + int rval; + + /* Configure the arbitration mechanisms for VC requests */ + ipu_configure_vc_mechanism(isp); + + ipu_buttress_set_secure_mode(isp); + isp->secure_mode = ipu_buttress_get_secure_mode(isp); + dev_info(dev, "IPU in %s mode\n", + isp->secure_mode ? "secure" : "non-secure"); + + ipu_buttress_restore(isp); + + rval = ipu_buttress_ipc_reset(isp, &b->cse); + if (rval) + dev_err(&isp->pdev->dev, "IPC reset protocol failed!\n"); + + return 0; +} + +static int ipu_runtime_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct ipu_device *isp = pci_get_drvdata(pdev); + int rval; + + ipu_configure_vc_mechanism(isp); + ipu_buttress_restore(isp); + + if (isp->ipc_reinit) { + struct ipu_buttress *b = &isp->buttress; + + isp->ipc_reinit = false; + rval = ipu_buttress_ipc_reset(isp, &b->cse); + if (rval) + dev_err(&isp->pdev->dev, + "IPC reset protocol failed!\n"); + } + + return 0; +} + +static const struct dev_pm_ops ipu_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(&ipu_suspend, &ipu_resume) + SET_RUNTIME_PM_OPS(&ipu_suspend, /* Same as in suspend flow */ + &ipu_runtime_resume, + NULL) +}; + +#define IPU_PM (&ipu_pm_ops) +#else +#define IPU_PM NULL +#endif + +static const struct pci_device_id ipu_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU_PCI_ID)}, + {0,} +}; +MODULE_DEVICE_TABLE(pci, ipu_pci_tbl); + +static const struct pci_error_handlers pci_err_handlers = { + .reset_prepare = ipu_pci_reset_prepare, + .reset_done = ipu_pci_reset_done, +}; + +static struct pci_driver ipu_pci_driver = { + .name = IPU_NAME, + .id_table = ipu_pci_tbl, + .probe = ipu_pci_probe, + .remove = ipu_pci_remove, + .driver = { + .pm = IPU_PM, + }, + .err_handler = &pci_err_handlers, +}; + +static int __init ipu_init(void) +{ + int rval = ipu_bus_register(); + + if (rval) { + pr_warn("can't register ipu bus (%d)\n", rval); + return rval; + } + + rval = pci_register_driver(&ipu_pci_driver); + if (rval) { + pr_warn("can't register pci driver (%d)\n", rval); + goto out_pci_register_driver; + } + + ipu_bus_register_driver(&ipu_mmu_driver); + + return 0; + +out_pci_register_driver: + ipu_bus_unregister(); + + return rval; +} + +static void __exit ipu_exit(void) +{ + ipu_bus_unregister_driver(&ipu_mmu_driver); + pci_unregister_driver(&ipu_pci_driver); + ipu_bus_unregister(); +} + +module_init(ipu_init); +module_exit(ipu_exit); + +MODULE_IMPORT_NS("INTEL_IPU_BRIDGE"); +MODULE_AUTHOR("Sakari Ailus "); +MODULE_AUTHOR("Jouni Högander "); +MODULE_AUTHOR("Antti Laakso "); +MODULE_AUTHOR("Samu Onkalo "); +MODULE_AUTHOR("Jianxu Zheng "); +MODULE_AUTHOR("Tianshu Qiu "); +MODULE_AUTHOR("Renwei Wu "); +MODULE_AUTHOR("Bingbu Cao "); +MODULE_AUTHOR("Yunliang Ding "); +MODULE_AUTHOR("Zaikuo Wang "); +MODULE_AUTHOR("Leifu Zhao "); +MODULE_AUTHOR("Xia Wu "); +MODULE_AUTHOR("Kun Jiang "); +MODULE_AUTHOR("Intel"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu pci driver"); diff --git a/drivers/media/pci/intel/ipu.h b/drivers/media/pci/intel/ipu.h new file mode 100644 index 0000000000000..96e9a2144133b --- /dev/null +++ b/drivers/media/pci/intel/ipu.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_H +#define IPU_H + +#include +#include +#include +#include + +#include "ipu-pdata.h" +#include "ipu-bus.h" +#include "ipu-buttress.h" +#include "ipu-trace.h" + +#if defined(CONFIG_VIDEO_INTEL_IPU4) +#define IPU_PCI_ID 0x5a88 +#elif defined(CONFIG_VIDEO_INTEL_IPU4P) +#define IPU_PCI_ID 0x8a19 +#endif + +/* + * IPU version definitions to reflect the IPU driver changes. + * Both ISYS and PSYS share the same version. + */ +#define IPU_MAJOR_VERSION 1 +#define IPU_MINOR_VERSION 0 +#define IPU_DRIVER_VERSION (IPU_MAJOR_VERSION << 16 | IPU_MINOR_VERSION) + +/* processing system frequency: 25Mhz x ratio, Legal values [8,32] */ +#define PS_FREQ_CTL_DEFAULT_RATIO 0x12 + +/* input system frequency: 1600Mhz / divisor. Legal values [2,8] */ +#define IS_FREQ_SOURCE 1600000000 +#define IS_FREQ_CTL_DIVISOR 0x4 + +/* + * 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 + +/* + * Physical pages in GDA 128 * 1K pages. + */ +#define IPU_DEVICE_GDA_NR_PAGES 128 + +/* + * Virtualization factor to calculate the available virtual pages. + */ +#if defined(CONFIG_VIDEO_INTEL_IPU4) +#define IPU_DEVICE_GDA_VIRT_FACTOR 8 +#elif defined(CONFIG_VIDEO_INTEL_IPU4P) +#define IPU_DEVICE_GDA_VIRT_FACTOR 32 +#else +#define IPU_DEVICE_GDA_VIRT_FACTOR 8 +#endif + +struct pci_dev; +struct list_head; +struct firmware; + +#define NR_OF_MMU_RESOURCES 2 + +struct ipu_device { + struct pci_dev *pdev; + struct list_head devices; + struct ipu_bus_device *isys_iommu, *isys; + struct ipu_bus_device *psys_iommu, *psys; + struct ipu_buttress buttress; + + const struct firmware *cpd_fw; + const char *cpd_fw_name; + u64 *pkg_dir; + dma_addr_t pkg_dir_dma_addr; + unsigned int pkg_dir_size; + + void __iomem *base; + void __iomem *base2; + struct dentry *ipu_dir; + struct ipu_trace *trace; + bool flr_done; + bool ipc_reinit; + bool secure_mode; + + int (*isys_fw_reload)(struct ipu_device *isp); + int (*cpd_fw_reload)(struct ipu_device *isp); +}; + +#define IPU_DMA_MASK 39 +#define IPU_LIB_CALL_TIMEOUT_MS 2000 +#define IPU_PSYS_CMD_TIMEOUT_MS 2000 +#define IPU_PSYS_OPEN_TIMEOUT_US 50 +#define IPU_PSYS_OPEN_RETRY (10000 / IPU_PSYS_OPEN_TIMEOUT_US) + +int ipu_fw_authenticate(void *data, u64 val); +void ipu_configure_spc(struct ipu_device *isp, + const struct ipu_hw_variants *hw_variant, + int pkg_dir_idx, void __iomem *base, u64 *pkg_dir, + dma_addr_t pkg_dir_dma_addr); +int request_cpd_fw(const struct firmware **firmware_p, const char *name, + struct device *device); +#endif /* IPU_H */ diff --git a/drivers/media/pci/intel/ipu4/Makefile b/drivers/media/pci/intel/ipu4/Makefile new file mode 100644 index 0000000000000..47fb8a2cd7785 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/Makefile @@ -0,0 +1,134 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2010 - 2018, Intel Corporation. + +ifneq ($(EXTERNAL_BUILD), 1) +srcpath := $(srctree) +endif + +ifdef CONFIG_VIDEO_INTEL_IPU4 +ccflags-y += -DHAS_DUAL_CMD_CTX_SUPPORT=0 -DIPU_VC_SUPPORT -DIPU_HAS_ISA -DIPU_PSYS_LEGACY +ccflags-y += -DIPU_META_DATA_SUPPORT -DI2C_WA + +intel-ipu4-objs += ../ipu.o \ + ../ipu-bus.o \ + ../ipu-dma.o \ + ../ipu-mmu.o \ + ../ipu-buttress.o \ + ../ipu-trace.o \ + ../ipu-cpd.o \ + ../ipu-fw-com.o \ + ipu4.o + +obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu4.o + +intel-ipu4-isys-objs += ../ipu-isys.o \ + ../ipu-isys-csi2.o \ + ipu4-isys.o \ + ipu4-isys-csi2.o \ + ../ipu-isys-csi2-be-soc.o \ + ../ipu-isys-csi2-be.o \ + ../ipu-fw-isys.o \ + ipu4-isys-isa.o \ + ../ipu-isys-video.o \ + ../ipu-isys-queue.o \ + ../ipu-isys-subdev.o \ + ../ipu-isys-tpg.o + +obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu4-isys.o + +intel-ipu4-psys-objs += ../ipu-psys.o \ + ipu4-psys.o \ + ipu4-resources.o \ + +ifndef CONFIG_VIDEO_INTEL_IPU_FW_LIB +intel-ipu4-psys-objs += ipu4-fw-resources.o \ + ../ipu-fw-psys.o +endif + +ifeq ($(CONFIG_COMPAT),y) +intel-ipu4-psys-objs += ../ipu-psys-compat32.o +endif + +obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu4-psys.o + +ifdef CONFIG_VIDEO_INTEL_IPU_FW_LIB +include $(srcpath)/$(src)/ipu4-css/Makefile.isyslib +include $(srcpath)/$(src)/ipu4-css/Makefile.psyslib +endif + +ccflags-y += -I$(srcpath)/$(src)/../../../../../include/ +ccflags-y += -I$(srcpath)/$(src)/../ +ccflags-y += -I$(srcpath)/$(src)/ +ifdef CONFIG_VIDEO_INTEL_IPU_FW_LIB +ccflags-y += -I$(srcpath)/$(src)/ipu4-css +endif + +ccflags-y += -DPARAMETER_INTERFACE_V2 +endif + +ifdef CONFIG_VIDEO_INTEL_IPU4P +ccflags-y += -DHAS_DUAL_CMD_CTX_SUPPORT=0 -DIPU_VC_SUPPORT -DIPU_PSYS_LEGACY -DIPU_HAS_ISA +ccflags-y += -DIPU_META_DATA_SUPPORT + +intel-ipu4p-objs += ../ipu.o \ + ../ipu-bus.o \ + ../ipu-dma.o \ + ../ipu-mmu.o \ + ../ipu-buttress.o \ + ../ipu-trace.o \ + ../ipu-cpd.o \ + ../ipu-fw-com.o \ + ipu4.o + +obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu4p.o + +intel-ipu4p-isys-objs += ../ipu-isys.o \ + ../ipu-isys-csi2.o \ + ipu4-isys.o \ + ipu4p-isys-csi2.o \ + ../ipu-isys-csi2-be-soc.o \ + ../ipu-isys-csi2-be.o \ + ../ipu-fw-isys.o \ + ipu4-isys-isa.o \ + ../ipu-isys-video.o \ + ../ipu-isys-queue.o \ + ../ipu-isys-subdev.o \ + ../ipu-isys-tpg.o +obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu4p-isys.o + +intel-ipu4p-psys-objs += ../ipu-psys.o \ + ipu4-psys.o \ + ipu4-resources.o \ + +ifndef CONFIG_VIDEO_INTEL_IPU_FW_LIB +intel-ipu4p-psys-objs += ipu4-fw-resources.o \ + ../ipu-fw-psys.o +endif + +ifeq ($(CONFIG_COMPAT),y) +intel-ipu4p-psys-objs += ../ipu-psys-compat32.o +endif + +obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu4p-psys.o + +ifdef CONFIG_VIDEO_INTEL_IPU_FW_LIB +include $(srcpath)/$(src)/ipu4p-css/Makefile.isyslib +include $(srcpath)/$(src)/ipu4p-css/Makefile.psyslib +endif + +ccflags-y += -I$(srcpath)/$(src)/../../../../../include/ +ccflags-y += -I$(srcpath)/$(src)/../ +ccflags-y += -I$(srcpath)/$(src)/ +ifdef CONFIG_VIDEO_INTEL_IPU_FW_LIB +ccflags-y += -I$(srcpath)/$(src)/ipu4p-css +endif + +ccflags-y += -DPARAMETER_INTERFACE_V2 +endif + +# ignore IPU FW Lib marco redefined warning if using clang +ifeq ($(CONFIG_CC_IS_CLANG),y) +ifdef CONFIG_VIDEO_INTEL_IPU_FW_LIB +ccflags-y += -Wno-error=macro-redefined +endif +endif diff --git a/drivers/media/pci/intel/ipu4/ipu-platform-buttress-regs.h b/drivers/media/pci/intel/ipu4/ipu-platform-buttress-regs.h new file mode 100644 index 0000000000000..34f2f7855089c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu-platform-buttress-regs.h @@ -0,0 +1,287 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2014 - 2018 Intel Corporation */ + +#ifndef IPU_PLATFORM_BUTTRESS_REGS_H +#define IPU_PLATFORM_BUTTRESS_REGS_H + +#ifdef CONFIG_VIDEO_INTEL_IPU4P +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_SHIFT 20 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_MASK (0x1f << 20) +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_IDLE 0x0 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_IS_RDY 0xc + +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_SHIFT 25 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_MASK (0x1f << 25) +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_IDLE 0x0 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_PS_PWR_UP 0x10 + +#define BUTTRESS_REG_CSI_BSCAN_EXCLUDE 0x100d8 +#define CPHY0_DLL_OVRD_OFFSET 0x10100 +#define CPHY0_RX_CONTROL1_OFFSET 0x10110 +#define DPHY0_DLL_OVRD_OFFSET 0x1014c +#define DPHY0_RX_CNTRL_OFFSET 0x10158 +#define BB0_AFE_CONFIG_OFFSET 0x10174 + +#define BUTTRESS_REG_IS_FREQ_CTL_RATIO_SHIFT 1 +#define BUTTRESS_REG_PS_FREQ_CTL_OVRD_SHIFT 7 +#define BUTTRESS_REG_PS_FREQ_CTL_RATIO_SHIFT 8 + +#define BUTTRESS_REG_CPHYX_DLL_OVRD(x) \ + (CPHY0_DLL_OVRD_OFFSET + (x >> 1) * 0x100) +#define BUTTRESS_REG_CPHYX_RX_CONTROL1(x) \ + (CPHY0_RX_CONTROL1_OFFSET + (x >> 1) * 0x100) +#define BUTTRESS_REG_DPHYX_DLL_OVRD(x) \ + (DPHY0_DLL_OVRD_OFFSET + (x >> 1) * 0x100) +#define BUTTRESS_REG_DPHYX_RX_CNTRL(x) \ + (DPHY0_RX_CNTRL_OFFSET + (x >> 1) * 0x100) +#define BUTTRESS_REG_BBX_AFE_CONFIG(x) \ + (BB0_AFE_CONFIG_OFFSET + (x >> 1) * 0x100) +#endif /* CONFIG_VIDEO_INTEL_IPU4P */ + +#ifdef CONFIG_VIDEO_INTEL_IPU4 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_SHIFT 20 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_MASK (0xf << 20) +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_IDLE 0x0 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_IS_RDY 0xa + +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_SHIFT 24 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_MASK (0x1f << 24) +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_IDLE 0x0 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_PS_PWR_UP 0xf +#endif /* CONFIG_VIDEO_INTEL_IPU4 */ + +#define BUTTRESS_REG_WDT 0x8 +#define BUTTRESS_REG_BTRS_CTRL 0xc +#define BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC0 BIT(0) +#define BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC1 BIT(1) + +#define BUTTRESS_REG_FW_RESET_CTL 0x30 +#define BUTTRESS_FW_RESET_CTL_START_SHIFT 0 +#define BUTTRESS_FW_RESET_CTL_DONE_SHIFT 1 + +#define BUTTRESS_REG_IS_FREQ_CTL 0x34 +#define BUTTRESS_IS_FREQ_CTL_DIVISOR_MASK 0xf + +#define BUTTRESS_REG_PS_FREQ_CTL 0x38 +#define BUTTRESS_PS_FREQ_CTL_RATIO_MASK 0xff + +#define BUTTRESS_FREQ_CTL_START_SHIFT 31 +#define BUTTRESS_FREQ_CTL_QOS_FLOOR_SHIFT 8 +#define BUTTRESS_FREQ_CTL_QOS_FLOOR_MASK (0xff << 8) + +#define BUTTRESS_REG_PWR_STATE 0x5c +#define BUTTRESS_PWR_STATE_IS_PWR_SHIFT 4 +#define BUTTRESS_PWR_STATE_IS_PWR_MASK (0x7 << 4) + +#define BUTTRESS_PWR_STATE_PS_PWR_SHIFT 8 +#define BUTTRESS_PWR_STATE_PS_PWR_MASK (0x7 << 8) + +#define BUTTRESS_PWR_STATE_RESET 0x0 +#define BUTTRESS_PWR_STATE_PWR_ON_DONE 0x1 +#define BUTTRESS_PWR_STATE_PWR_RDY 0x3 +#define BUTTRESS_PWR_STATE_PWR_IDLE 0x4 + +#define BUTTRESS_PWR_STATE_HH_STATUS_SHIFT 12 +#define BUTTRESS_PWR_STATE_HH_STATUS_MASK (0x3 << 12) + +enum { + BUTTRESS_PWR_STATE_HH_STATE_IDLE, + BUTTRESS_PWR_STATE_HH_STATE_IN_PRGS, + BUTTRESS_PWR_STATE_HH_STATE_DONE, + BUTTRESS_PWR_STATE_HH_STATE_ERR, +}; + +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_PLL_CMP 0x1 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_CLKACK 0x2 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_PG_ACK 0x3 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_RST_ASSRT_CYCLES 0x4 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_STOP_CLK_CYCLES1 0x5 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_STOP_CLK_CYCLES2 0x6 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_RST_DEASSRT_CYCLES 0x7 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_FUSE_WR_CMP 0x8 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_BRK_POINT 0x9 +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_HALT_HALTED 0xb +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_RST_DURATION_CNT3 0xc +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_CLKACK_PD 0xd +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_PD_BRK_POINT 0xe +#define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_PD_PG_ACK0 0xf +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PU_PLL_IP_RDY 0x1 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_RO_PRE_CNT_EXH 0x2 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PU_VGI_PWRGOOD 0x3 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_RO_POST_CNT_EXH 0x4 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WR_PLL_RATIO 0x5 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PU_PLL_CMP 0x6 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PU_CLKACK 0x7 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_RST_ASSRT_CYCLES 0x8 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_STOP_CLK_CYCLES1 0x9 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_STOP_CLK_CYCLES2 0xa +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_RST_DEASSRT_CYCLES 0xb +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_PU_BRK_PNT 0xc +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_FUSE_ACCPT 0xd +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_4_HALTED 0x10 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_RESET_CNT3 0x11 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PD_CLKACK 0x12 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PD_OFF_IND 0x13 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_DVFS_PH4 0x14 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_DVFS_PLL_CMP 0x15 +#define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_DVFS_CLKACK 0x16 + +#define BUTTRESS_REG_SECURITY_CTL 0x300 + +#define BUTTRESS_SECURITY_CTL_FW_SECURE_MODE_SHIFT 16 +#define BUTTRESS_SECURITY_CTL_FW_SETUP_SHIFT 0 +#define BUTTRESS_SECURITY_CTL_FW_SETUP_MASK 0x1f + +#define BUTTRESS_SECURITY_CTL_FW_SETUP_DONE 0x1 +#define BUTTRESS_SECURITY_CTL_AUTH_DONE 0x2 +#define BUTTRESS_SECURITY_CTL_AUTH_FAILED 0x8 + +#define BUTTRESS_REG_SENSOR_FREQ_CTL 0x16c + +#define BUTTRESS_SENSOR_FREQ_CTL_OSC_OUT_FREQ_DEFAULT(i) \ + (0x1b << ((i) * 10)) +#define BUTTRESS_SENSOR_FREQ_CTL_OSC_OUT_FREQ_SHIFT(i) ((i) * 10) +#define BUTTRESS_SENSOR_FREQ_CTL_OSC_OUT_FREQ_MASK(i) \ + (0x1ff << ((i) * 10)) + +#define BUTTRESS_SENSOR_CLK_FREQ_6P75MHZ 0x176 +#define BUTTRESS_SENSOR_CLK_FREQ_8MHZ 0x164 +#define BUTTRESS_SENSOR_CLK_FREQ_9P6MHZ 0x2 +#define BUTTRESS_SENSOR_CLK_FREQ_12MHZ 0x1b2 +#define BUTTRESS_SENSOR_CLK_FREQ_13P6MHZ 0x1ac +#define BUTTRESS_SENSOR_CLK_FREQ_14P4MHZ 0x1cc +#define BUTTRESS_SENSOR_CLK_FREQ_15P8MHZ 0x1a6 +#define BUTTRESS_SENSOR_CLK_FREQ_16P2MHZ 0xca +#define BUTTRESS_SENSOR_CLK_FREQ_17P3MHZ 0x12e +#define BUTTRESS_SENSOR_CLK_FREQ_18P6MHZ 0x1c0 +#define BUTTRESS_SENSOR_CLK_FREQ_19P2MHZ 0x0 +#define BUTTRESS_SENSOR_CLK_FREQ_24MHZ 0xb2 +#define BUTTRESS_SENSOR_CLK_FREQ_26MHZ 0xae +#define BUTTRESS_SENSOR_CLK_FREQ_27MHZ 0x196 + +#define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_FB_RATIO_MASK 0xff +#define BUTTRESS_SENSOR_FREQ_CTL_SEL_MIPICLK_A_SHIFT 8 +#define BUTTRESS_SENSOR_FREQ_CTL_SEL_MIPICLK_A_MASK (0x2 << 8) +#define BUTTRESS_SENSOR_FREQ_CTL_SEL_MIPICLK_C_SHIFT 10 +#define BUTTRESS_SENSOR_FREQ_CTL_SEL_MIPICLK_C_MASK (0x2 << 10) +#define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_FORCE_OFF_SHIFT 12 +#define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_REF_RATIO_SHIFT 14 +#define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_REF_RATIO_MASK (0x2 << 14) +#define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_PVD_RATIO_SHIFT 16 +#define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_PVD_RATIO_MASK (0x2 << 16) +#define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_OUTPUT_RATIO_SHIFT 18 +#define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_OUTPUT_RATIO_MASK (0x2 << 18) +#define BUTTRESS_SENSOR_FREQ_CTL_START_SHIFT 31 + +#define BUTTRESS_REG_SENSOR_CLK_CTL 0x170 + +/* 0 <= i <= 2 */ +#define BUTTRESS_SENSOR_CLK_CTL_OSC_CLK_OUT_EN_SHIFT(i) ((i) * 2) +#define BUTTRESS_SENSOR_CLK_CTL_OSC_CLK_OUT_SEL_SHIFT(i) ((i) * 2 + 1) + +#define BUTTRESS_REG_FW_SOURCE_BASE_LO 0x78 +#define BUTTRESS_REG_FW_SOURCE_BASE_HI 0x7C +#define BUTTRESS_REG_FW_SOURCE_SIZE 0x80 + +#define BUTTRESS_REG_ISR_STATUS 0x90 +#define BUTTRESS_REG_ISR_ENABLED_STATUS 0x94 +#define BUTTRESS_REG_ISR_ENABLE 0x98 +#define BUTTRESS_REG_ISR_CLEAR 0x9C + +#define BUTTRESS_ISR_IS_IRQ BIT(0) +#define BUTTRESS_ISR_PS_IRQ BIT(1) +#define BUTTRESS_ISR_IPC_EXEC_DONE_BY_CSE BIT(2) +#define BUTTRESS_ISR_IPC_EXEC_DONE_BY_ISH BIT(3) +#define BUTTRESS_ISR_IPC_FROM_CSE_IS_WAITING BIT(4) +#define BUTTRESS_ISR_IPC_FROM_ISH_IS_WAITING BIT(5) +#define BUTTRESS_ISR_CSE_CSR_SET BIT(6) +#define BUTTRESS_ISR_ISH_CSR_SET BIT(7) +#define BUTTRESS_ISR_SPURIOUS_CMP BIT(8) +#define BUTTRESS_ISR_WATCHDOG_EXPIRED BIT(9) +#define BUTTRESS_ISR_PUNIT_2_IUNIT_IRQ BIT(10) +#define BUTTRESS_ISR_SAI_VIOLATION BIT(11) +#define BUTTRESS_ISR_HW_ASSERTION BIT(12) + +#define BUTTRESS_REG_IU2CSEDB0 0x100 + +#define BUTTRESS_IU2CSEDB0_BUSY_SHIFT 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_REG_IU2CSEDATA0 0x104 + +#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 1 +#define BUTTRESS_CSE2IUDATA0_IPC_AUTH_RUN_DONE 2 +#define BUTTRESS_CSE2IUDATA0_IPC_AUTH_REPLACE_DONE 4 +#define BUTTRESS_CSE2IUDATA0_IPC_UPDATE_SECURE_TOUCH_DONE 16 + +#define BUTTRESS_REG_IU2CSECSR 0x108 + +#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) + +#define BUTTRESS_REG_CSE2IUDB0 0x304 +#define BUTTRESS_REG_CSE2IUCSR 0x30C +#define BUTTRESS_REG_CSE2IUDATA0 0x308 + +/* 0x20 == NACK, 0xf == unknown command */ +#define BUTTRESS_CSE2IUDATA0_IPC_NACK 0xf20 +#define BUTTRESS_CSE2IUDATA0_IPC_NACK_MASK 0xffff + +#define BUTTRESS_REG_ISH2IUCSR 0x50 +#define BUTTRESS_REG_ISH2IUDB0 0x54 +#define BUTTRESS_REG_ISH2IUDATA0 0x58 + +#define BUTTRESS_REG_IU2ISHDB0 0x10C +#define BUTTRESS_REG_IU2ISHDATA0 0x110 +#define BUTTRESS_REG_IU2ISHDATA1 0x114 +#define BUTTRESS_REG_IU2ISHCSR 0x118 + +#define BUTTRESS_REG_ISH_START_DETECT 0x198 +#define BUTTRESS_REG_ISH_START_DETECT_MASK 0x19C + +#define BUTTRESS_REG_FABRIC_CMD 0x88 + +#define BUTTRESS_FABRIC_CMD_START_TSC_SYNC BIT(0) +#define BUTTRESS_FABRIC_CMD_IS_DRAIN BIT(4) + +#define BUTTRESS_REG_TSW_CTL 0x120 +#define BUTTRESS_TSW_CTL_SOFT_RESET BIT(8) + +#define BUTTRESS_REG_TSC_LO 0x164 +#define BUTTRESS_REG_TSC_HI 0x168 + +#define BUTTRESS_REG_CSI2_PORT_CONFIG_AB 0x200 +#define BUTTRESS_CSI2_PORT_CONFIG_AB_MUX_MASK 0x1f +#define BUTTRESS_CSI2_PORT_CONFIG_AB_COMBO_SHIFT_B0 16 + +#define BUTTRESS_REG_PS_FREQ_CAPABILITIES 0xf7498 + +#define BUTTRESS_PS_FREQ_CAPABILITIES_LAST_RESOLVED_RATIO_SHIFT 24 +#define BUTTRESS_PS_FREQ_CAPABILITIES_LAST_RESOLVED_RATIO_MASK (0xff << 24) +#define BUTTRESS_PS_FREQ_CAPABILITIES_MAX_RATIO_SHIFT 16 +#define BUTTRESS_PS_FREQ_CAPABILITIES_MAX_RATIO_MASK (0xff << 16) +#define BUTTRESS_PS_FREQ_CAPABILITIES_EFFICIENT_RATIO_SHIFT 8 +#define BUTTRESS_PS_FREQ_CAPABILITIES_EFFICIENT_RATIO_MASK (0xff << 8) +#define BUTTRESS_PS_FREQ_CAPABILITIES_MIN_RATIO_SHIFT 0 +#define BUTTRESS_PS_FREQ_CAPABILITIES_MIN_RATIO_MASK (0xff) + +#define BUTTRESS_IRQS (BUTTRESS_ISR_SAI_VIOLATION | \ + BUTTRESS_ISR_IPC_FROM_CSE_IS_WAITING | \ + BUTTRESS_ISR_IPC_FROM_ISH_IS_WAITING | \ + BUTTRESS_ISR_IPC_EXEC_DONE_BY_CSE | \ + BUTTRESS_ISR_IPC_EXEC_DONE_BY_ISH | \ + BUTTRESS_ISR_IS_IRQ | \ + BUTTRESS_ISR_PS_IRQ) + +#endif /* IPU_BUTTRESS_REGS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu-platform-isys-csi2-reg.h b/drivers/media/pci/intel/ipu4/ipu-platform-isys-csi2-reg.h new file mode 100644 index 0000000000000..efdf287e38f61 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu-platform-isys-csi2-reg.h @@ -0,0 +1,222 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_PLATFORM_ISYS_CSI2_REG_H +#define IPU_PLATFORM_ISYS_CSI2_REG_H + +#ifdef CONFIG_VIDEO_INTEL_IPU4P +/* CSI RX CPHY regs */ +#define CSI2_REG_CSI_RX_CPHY_NOF_ENABLED_LANES 0x04 +#define CSI2_REG_CSI_RX_CPHY_HBP_TESTMODE 0x08 +#define CSI2_REG_CSI_RX_CPHY_PH_CRC_CFG 0x0C +#define CSI2_REG_CSI_RX_CPHY_ERR_HANDLING 0x10 +#define CSI2_REG_CSI_RX_CPHY_PORTCFG_CTL 0x14 +#define CSI2_REG_CSI_RX_CPHY_PORTCFG_TIMEOUT_CNTR 0x18 +#define CSI2_REG_CSI_RX_CPHY_SYNC_CNTR_SEL 0x1C +#define CSI2_REG_CSI_RX_CPHY_STATS 0x20 + +#define CSI2_REG_CSI2PART_IRQ_EDGE 0xB00 +#define CSI2_REG_CSI2PART_IRQ_MASK 0xB04 +#define CSI2_REG_CSI2PART_IRQ_STATUS 0xB08 +#define CSI2_REG_CSI2PART_IRQ_CLEAR 0xB0c +#define CSI2_REG_CSI2PART_IRQ_ENABLE 0xB10 +#define CSI2_REG_CSI2PART_IRQ_LEVEL_NOT_PULSE 0xB14 +#define CSI2_CSI2PART_IRQ_CSIRX 0x10000 +#define CSI2_CSI2PART_IRQ_CSI2S2M 0x20000 + +#define CSI2_REG_CSIRX_IRQ_EDGE 0xC00 +#define CSI2_REG_CSIRX_IRQ_MASK 0xC04 +#define CSI2_REG_CSIRX_IRQ_STATUS 0xC08 +#define CSI2_REG_CSIRX_IRQ_CLEAR 0xC0c +#define CSI2_REG_CSIRX_IRQ_ENABLE 0xC10 +#define CSI2_REG_CSIRX_IRQ_LEVEL_NOT_PULSE 0xC14 +#define CSI2_CSIRX_HEADER_SINGLE_ERROR_CORRECTED BIT(0) +#define CSI2_CSIRX_HEADER_MULTIPLE_ERRORS_CORRECTED BIT(1) +#define CSI2_CSIRX_PAYLOAD_CRC_ERROR BIT(2) +#define CSI2_CSIRX_FIFO_OVERFLOW BIT(3) +#define CSI2_CSIRX_RESERVED_SHORT_PACKET_DATA_TYPE BIT(4) +#define CSI2_CSIRX_RESERVED_LONG_PACKET_DATA_TYPE BIT(5) +#define CSI2_CSIRX_INCOMPLETE_LONG_PACKET BIT(6) +#define CSI2_CSIRX_FRAME_SYNC_ERROR BIT(7) +#define CSI2_CSIRX_LINE_SYNC_ERROR BIT(8) +#define CSI2_CSIRX_DPHY_RECOVERABLE_SYNC_ERROR BIT(9) +#define CSI2_CSIRX_DPHY_NONRECOVERABLE_SYNC_ERROR BIT(10) +#define CSI2_CSIRX_ESCAPE_MODE_ERROR BIT(11) +#define CSI2_CSIRX_ESCAPE_MODE_TRIGGER_EVENT BIT(12) +#define CSI2_CSIRX_ESCAPE_MODE_ULTRALOW_POWER_DATA BIT(13) +#define CSI2_CSIRX_ESCAPE_MODE_ULTRALOW_POWER_EXIT_CLK BIT(14) +#define CSI2_CSIRX_INTER_FRAME_SHORT_PACKET_DISCARDED BIT(15) +#define CSI2_CSIRX_INTER_FRAME_LONG_PACKET_DISCARDED BIT(16) +#define CSI2_CSIRX_NUM_ERRORS 17 + +#define CSI2_REG_CSI2S2M_IRQ_EDGE 0xD00 +#define CSI2_REG_CSI2S2M_IRQ_MASK 0xD04 +#define CSI2_REG_CSI2S2M_IRQ_STATUS 0xD08 +#define CSI2_REG_CSI2S2M_IRQ_CLEAR 0xD0c +#define CSI2_REG_CSI2S2M_IRQ_ENABLE 0xD10 +#define CSI2_REG_CSI2S2M_IRQ_LEVEL_NOT_PULSE 0xD14 + +#ifdef IPU_VC_SUPPORT +#define CSI2_IRQ_FS_VC(chn) (0x10000 << ((chn) * 4)) +#define CSI2_IRQ_FE_VC(chn) (0x20000 << ((chn) * 4)) +#define CSI2_IRQ_LS_VC(chn) (0x40000 << ((chn) * 4)) +#define CSI2_IRQ_LE_VC(chn) (0x80000 << ((chn) * 4)) +#else +#define CSI2_IRQ_FS_VC 0x10000 +#define CSI2_IRQ_FE_VC 0x20000 +#define CSI2_IRQ_LS_VC 0x40000 +#define CSI2_IRQ_LE_VC 0x80000 +#endif /* IPU_VC_SUPPORT */ +#define CSI2_REG_CL0_IBUFCTL_EN_FLUSH_FOR_IDRAIN 0x6002c +#define CSI2_REG_CL1_IBUFCTL_EN_FLUSH_FOR_IDRAIN 0x6802c +#define IPU_REG_ISYS_IBUFCTL_EN_FLUSH_FOR_IDRAIN 0xb602c +#endif /* CONFIG_VIDEO_INTEL_IPU4P */ + +#ifdef CONFIG_VIDEO_INTEL_IPU4 +/* IRQ-related registers specific to each of the four CSI receivers */ +#define CSI2_REG_CSI2PART_IRQ_EDGE 0x400 +#define CSI2_REG_CSI2PART_IRQ_MASK 0x404 +#define CSI2_REG_CSI2PART_IRQ_STATUS 0x408 +#define CSI2_REG_CSI2PART_IRQ_CLEAR 0x40c +#define CSI2_REG_CSI2PART_IRQ_ENABLE 0x410 +#define CSI2_REG_CSI2PART_IRQ_LEVEL_NOT_PULSE 0x414 +#define CSI2_CSI2PART_IRQ_CSIRX 0x10000 +#define CSI2_CSI2PART_IRQ_CSI2S2M 0x20000 + +#define CSI2_REG_CSIRX_IRQ_EDGE 0x500 +#define CSI2_REG_CSIRX_IRQ_MASK 0x504 +#define CSI2_REG_CSIRX_IRQ_STATUS 0x508 +#define CSI2_REG_CSIRX_IRQ_CLEAR 0x50c +#define CSI2_REG_CSIRX_IRQ_ENABLE 0x510 +#define CSI2_REG_CSIRX_IRQ_LEVEL_NOT_PULSE 0x514 +#define CSI2_CSIRX_HEADER_SINGLE_ERROR_CORRECTED BIT(0) +#define CSI2_CSIRX_HEADER_MULTIPLE_ERRORS_CORRECTED BIT(1) +#define CSI2_CSIRX_PAYLOAD_CRC_ERROR BIT(2) +#define CSI2_CSIRX_FIFO_OVERFLOW BIT(3) +#define CSI2_CSIRX_RESERVED_SHORT_PACKET_DATA_TYPE BIT(4) +#define CSI2_CSIRX_RESERVED_LONG_PACKET_DATA_TYPE BIT(5) +#define CSI2_CSIRX_INCOMPLETE_LONG_PACKET BIT(6) +#define CSI2_CSIRX_FRAME_SYNC_ERROR BIT(7) +#define CSI2_CSIRX_LINE_SYNC_ERROR BIT(8) +#define CSI2_CSIRX_DPHY_RECOVERABLE_SYNC_ERROR BIT(9) +#define CSI2_CSIRX_DPHY_NONRECOVERABLE_SYNC_ERROR BIT(10) +#define CSI2_CSIRX_ESCAPE_MODE_ERROR BIT(11) +#define CSI2_CSIRX_ESCAPE_MODE_TRIGGER_EVENT BIT(12) +#define CSI2_CSIRX_ESCAPE_MODE_ULTRALOW_POWER_DATA BIT(13) +#define CSI2_CSIRX_ESCAPE_MODE_ULTRALOW_POWER_EXIT_CLK BIT(14) +#define CSI2_CSIRX_INTER_FRAME_SHORT_PACKET_DISCARDED BIT(15) +#define CSI2_CSIRX_INTER_FRAME_LONG_PACKET_DISCARDED BIT(16) +#define CSI2_CSIRX_NUM_ERRORS 17 + +#define CSI2_REG_CSI2S2M_IRQ_EDGE 0x600 +#define CSI2_REG_CSI2S2M_IRQ_MASK 0x604 +#define CSI2_REG_CSI2S2M_IRQ_STATUS 0x608 +#define CSI2_REG_CSI2S2M_IRQ_CLEAR 0x60c +#define CSI2_REG_CSI2S2M_IRQ_ENABLE 0x610 +#define CSI2_REG_CSI2S2M_IRQ_LEVEL_NOT_PULSE 0x614 + +#ifdef IPU_VC_SUPPORT +#define CSI2_IRQ_FS_VC(chn) (1 << ((chn) * 4)) +#define CSI2_IRQ_FE_VC(chn) (2 << ((chn) * 4)) +#define CSI2_IRQ_LS_VC(chn) (4 << ((chn) * 4)) +#define CSI2_IRQ_LE_VC(chn) (8 << ((chn) * 4)) +#else +#define CSI2_IRQ_FS_VC 1 +#define CSI2_IRQ_FE_VC 2 +#define CSI2_IRQ_LS_VC 4 +#define CSI2_IRQ_LE_VC 8 +#endif /* IPU_VC_SUPPORT */ +#endif /* CONFIG_VIDEO_INTEL_IPU4 */ + +#define CSI2_REG_CSI_RX_ENABLE 0x00 +#define CSI2_CSI_RX_ENABLE_ENABLE 0x01 +/* Enabled lanes - 1 */ +#define CSI2_REG_CSI_RX_NOF_ENABLED_LANES 0x04 +#define CSI2_REG_CSI_RX_CONFIG 0x08 +#define CSI2_CSI_RX_CONFIG_RELEASE_LP11 0x1 +#define CSI2_CSI_RX_CONFIG_DISABLE_BYTE_CLK_GATING 0x2 +#define CSI2_CSI_RX_CONFIG_SKEWCAL_ENABLE 0x4 +#define CSI2_REG_CSI_RX_HBP_TESTMODE_ENABLE 0x0c +#define CSI2_REG_CSI_RX_ERROR_HANDLING 0x10 +#define CSI2_REG_CSI_RX_SYNC_COUNTER_SEL 0x14 +#define CSI2_RX_SYNC_COUNTER_INTERNAL 0 +#define CSI2_RX_SYNC_COUNTER_EXTERNAL 3 +#define CSI2_REG_CSI_RX_SP_IF_CONFIG 0x18 +#define CSI2_REG_CSI_RX_LP_IF_CONFIG 0x1C +#define CSI2_REG_CSI_RX_STATUS 0x20 +#define CSI2_CSI_RX_STATUS_BUSY 0x01 +#define CSI2_REG_CSI_RX_STATUS_DLANE_HS 0x24 +#define CSI2_REG_CSI_RX_STATUS_DLANE_LP 0x28 +#define CSI2_REG_CSI_RX_DLY_CNT_TERMEN_CLANE 0x2c +#define CSI2_REG_CSI_RX_DLY_CNT_SETTLE_CLANE 0x30 +/* 0..3 */ +#define CSI2_REG_CSI_RX_DLY_CNT_TERMEN_DLANE(n) (0x34 + (n) * 8) +#define CSI2_REG_CSI_RX_DLY_CNT_SETTLE_DLANE(n) (0x38 + (n) * 8) + +/*General purposer registers, offset to gpreg base*/ +#define CSI2_REG_CSI_GPREG_SOFT_RESET 0 +#define CSI2_REG_CSI_GPREG_SOFT_RESET_SLV 0x4 +#define CSI2_REG_CSI_GPREG_HPLL_FREQ 0x8 +#define CSI2_REG_CSI_GPREG_ISCLK_RATIO 0xc +#define CSI2_REG_CSI_GPREG_HPLL_FREQ_ISCLK_RATIO_OVERRIDE 0x10 +#define CSI2_REG_CSI_GPREG_CR_PORT_CONFIG 0x14 +#define CSI2_REG_CSI_GPREG_RCOMP_TIMER_DISABLE 0x18 +#define CSI2_REG_CSI_GPREG_RCOMP_TIMER_VALUE 0x1c + +/* + * Following is the list of relevant registers and + * their offset within the legacy PHY endpoint. Accessible only via + * sideband bus. + * Register naming is a bit misleading. DPHY / CPHY / LANE0 / LANE1 + * all are required for DPHY configurations. + * Registers are accessible only via sideband bus. + */ + +/* Legacy receiver block */ +#define CSI2_SB_CSI_RCOMP_CONTROL_LEGACY 0xb8 +#define CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_ENABLE_PORT4_SHIFT 9 +#define CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_ENABLE_PORT3_SHIFT 8 +#define CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_ENABLE_PORT2_SHIFT 7 +#define CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_ENABLE_PORT1_SHIFT 6 +#define CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_CODE_SHIFT 1 +#define CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_ENABLE_SHIFT 0 + +/* Combo receiver block */ +#define CSI2_SB_CSI_RCOMP_CONTROL_COMBO 0x08 +#define CSI2_SB_CSI_RCOMP_UPDATE_MODE_SHIFT 15 +#define CSI2_SB_CSI_RCOMP_OVR_ENABLE_SHIFT 6 +#define CSI2_SB_CSI_RCOMP_OVR_CODE_SHIFT 1 + +#define CSI2_SB_CPHY0_DLL_OVRD 0x18 +#define CSI2_SB_CPHY0_DLL_OVRD_CRCDC_FSM_DLANE0_SHIFT 1 +#define CSI2_SB_CPHY0_DLL_OVRD_LDEN_CRCDC_FSM_DLANE0 BIT(0) +#define CSI2_SB_CPHY2_DLL_OVRD 0x60 +#define CSI2_SB_CPHY2_DLL_OVRD_CRCDC_FSM_DLANE1_SHIFT 1 +#define CSI2_SB_CPHY2_DLL_OVRD_LDEN_CRCDC_FSM_DLANE1 BIT(0) + +#define CSI2_SB_CPHY0_RX_CONTROL1 0x28 +#define CSI2_SB_CPHY0_RX_CONTROL1_EQ_LANE0_SHIFT 27 +#define CSI2_SB_CPHY2_RX_CONTROL1 0x68 +#define CSI2_SB_CPHY2_RX_CONTROL1_EQ_LANE1_SHIFT 27 + +#define CSI2_SB_DPHY0_DLL_OVRD 0xA4 +#define CSI2_SB_DPHY0_DLL_OVRD_LDEN_DRC_FSM_SHIFT 0 +#define CSI2_SB_DPHY0_DLL_OVRD_DRC_FSM_OVRD_SHIFT 1 +#define CSI2_SB_DPHY1_DLL_OVRD 0xD0 +#define CSI2_SB_DPHY1_DLL_OVRD_LDEN_DRC_FSM_SHIFT 0 +#define CSI2_SB_DPHY1_DLL_OVRD_DRC_FSM_OVRD_SHIFT 1 + +#define CSI2_SB_DPHY0_RX_CNTRL 0xB0 +#define CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE3_SHIFT 28 +#define CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE2_SHIFT 26 +#define CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE1_SHIFT 24 +#define CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE0_SHIFT 22 +#define CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE23_MASK \ + ((1 << CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE3_SHIFT) | \ + (1 << CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE2_SHIFT)) + +#define CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE01_MASK \ + ((1 << CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE1_SHIFT) | \ + (1 << CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE0_SHIFT)) + +#endif /* IPU_ISYS_CSI2_REG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu-platform-isys.h b/drivers/media/pci/intel/ipu4/ipu-platform-isys.h new file mode 100644 index 0000000000000..e5df4fabf65e8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu-platform-isys.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2018 Intel Corporation */ + +#ifndef IPU_PLATFORM_ISYS_H +#define IPU_PLATFORM_ISYS_H + +#include "ipu4-isys-isa.h" + +#define IPU_ISYS_ENTITY_PREFIX "Intel IPU4" + +#define IPU_ISYS_CSI2_ENTITY_PREFIX "Intel IPU4 CSI-2" + +/* + * FW support max 8 streams + */ +#define IPU_ISYS_MAX_STREAMS 8 +#ifdef IPU_VC_SUPPORT + +#define NR_OF_CSI2_BE_SOC_STREAMS 8 +#define NR_OF_CSI2_VC 4 +#endif + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu-platform-psys.h b/drivers/media/pci/intel/ipu4/ipu-platform-psys.h new file mode 100644 index 0000000000000..7826727f377aa --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu-platform-psys.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2018 Intel Corporation */ + +#ifndef IPU_PLATFORM_PSYS_H +#define IPU_PLATFORM_PSYS_H + +#include + +struct ipu_psys_fh; +struct ipu_psys_kcmd; + +struct ipu_psys_scheduler { + struct list_head kcmds[IPU_PSYS_CMD_PRIORITY_NUM]; + struct ipu_psys_kcmd + *new_kcmd_tail[IPU_PSYS_CMD_PRIORITY_NUM]; +}; + +enum ipu_psys_cmd_state { + KCMD_STATE_NEW, + KCMD_STATE_START_PREPARED, + KCMD_STATE_STARTED, + KCMD_STATE_RUN_PREPARED, + KCMD_STATE_RUNNING, + KCMD_STATE_COMPLETE +}; + +int ipu_psys_fh_init(struct ipu_psys_fh *fh); +int ipu_psys_fh_deinit(struct ipu_psys_fh *fh); + +#endif /* IPU_PLATFORM_PSYS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu-platform-regs.h b/drivers/media/pci/intel/ipu4/ipu-platform-regs.h new file mode 100644 index 0000000000000..89fd679948848 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu-platform-regs.h @@ -0,0 +1,266 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2014 - 2018 Intel Corporation */ + +#ifndef IPU_PLATFORM_REGS_H +#define IPU_PLATFORM_REGS_H + +#ifdef CONFIG_VIDEO_INTEL_IPU4P +#define IPU_ISYS_IOMMU0_OFFSET 0x000e0000 +#define IPU_ISYS_IOMMU1_OFFSET 0x000e0100 + +#define IPU_ISYS_OFFSET 0x00100000 +#define IPU_PSYS_OFFSET 0x00400000 + +#define IPU_PSYS_IOMMU0_OFFSET 0x000b0000 +#define IPU_PSYS_IOMMU1_OFFSET 0x000b0100 +#define IPU_PSYS_IOMMU1R_OFFSET 0x000b0600 + +/* the offset from IOMMU base register */ +#define IPU_MMU_L1_STREAM_ID_REG_OFFSET 0x0c +#define IPU_MMU_L2_STREAM_ID_REG_OFFSET 0x4c + +#define IPU_TPG0_ADDR_OFFSET 0x66c00 +#define IPU_TPG1_ADDR_OFFSET 0x6ec00 +#define IPU_CSI2BE_ADDR_OFFSET 0xba000 + +#define IPU_PSYS_MMU0_CTRL_OFFSET 0x08 + +#define IPU_GPOFFSET 0x66800 +#define IPU_COMBO_GPOFFSET 0x6e800 + +#define IPU_GPREG_MIPI_PKT_GEN0_SEL 0x1c +#define IPU_GPREG_MIPI_PKT_GEN1_SEL 0x1c + +#define IPU_REG_ISYS_ISA_ACC_IRQ_CTRL_BASE 0xb0c00 +#define IPU_REG_ISYS_A_IRQ_CTRL_BASE 0xbe200 +#define IPU_REG_ISYS_SIP0_IRQ_CTRL_BASE 0x66d00 +#define IPU_REG_ISYS_SIP1_IRQ_CTRL_BASE 0x6ed00 +#define IPU_REG_ISYS_SIP0_IRQ_CTRL_STATUS 0x66d08 +#define IPU_REG_ISYS_SIP1_IRQ_CTRL_STATUS 0x6ed08 +#define IPU_REG_ISYS_SIP0_IRQ_CTRL_CLEAR 0x66d0c +#define IPU_REG_ISYS_SIP1_IRQ_CTRL_CLEAR 0x6ed0c +#define IPU_REG_ISYS_CSI_IRQ_CTRL_BASE(p) \ + ({ typeof(p) __p = (p); \ + __p > 0 ? (0x6cb00 + 0x800 * (__p - 1)) : (0x66300); }) +#define IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(p) \ + ({ typeof(p) __p = (p); \ + __p > 0 ? (0x6cc00 + 0x800 * (__p - 1)) : (0x66400); }) +#define IPU_ISYS_CSI2_A_IRQ_MASK GENMASK(0, 0) +#define IPU_ISYS_CSI2_B_IRQ_MASK GENMASK(1, 1) +#define IPU_ISYS_CSI2_C_IRQ_MASK GENMASK(2, 2) +#define IPU_ISYS_CSI2_D_IRQ_MASK GENMASK(3, 3) +#define IPU_ISYS_CSI2_E_IRQ_MASK GENMASK(4, 4) +#define IPU_ISYS_CSI2_F_IRQ_MASK GENMASK(5, 5) +#define IPU_ISYS_CSI2_G_IRQ_MASK GENMASK(6, 6) + +/* IRQ-related registers relative to ISYS_OFFSET */ +#define IPU_REG_ISYS_UNISPART_IRQ_EDGE 0x7c000 +#define IPU_REG_ISYS_UNISPART_IRQ_MASK 0x7c004 +#define IPU_REG_ISYS_UNISPART_IRQ_STATUS 0x7c008 +#define IPU_REG_ISYS_UNISPART_IRQ_CLEAR 0x7c00c +#define IPU_REG_ISYS_UNISPART_IRQ_ENABLE 0x7c010 +#define IPU_REG_ISYS_UNISPART_IRQ_LEVEL_NOT_PULSE 0x7c014 +#define IPU_REG_ISYS_UNISPART_SW_IRQ_REG 0x7c414 +#define IPU_REG_ISYS_UNISPART_SW_IRQ_MUX_REG 0x7c418 +#define IPU_ISYS_UNISPART_IRQ_SW BIT(22) +#endif + +#ifdef CONFIG_VIDEO_INTEL_IPU4 +#define IPU_ISYS_IOMMU0_OFFSET 0x000e0000 +#define IPU_ISYS_IOMMU1_OFFSET 0x000e0100 + +#define IPU_ISYS_OFFSET 0x00100000 +#define IPU_PSYS_OFFSET 0x00400000 + +#define IPU_PSYS_IOMMU0_OFFSET 0x000b0000 +#define IPU_PSYS_IOMMU1_OFFSET 0x000b0100 +#define IPU_PSYS_IOMMU1R_OFFSET 0x000b0600 + +/* the offset from IOMMU base register */ +#define IPU_MMU_L1_STREAM_ID_REG_OFFSET 0x0c +#define IPU_MMU_L2_STREAM_ID_REG_OFFSET 0x4c + +#define IPU_TPG0_ADDR_OFFSET 0x64800 +#define IPU_TPG1_ADDR_OFFSET 0x6f400 +#define IPU_CSI2BE_ADDR_OFFSET 0xba000 + +#define IPU_PSYS_MMU0_CTRL_OFFSET 0x08 + +#define IPU_GPOFFSET 0x67800 +#define IPU_COMBO_GPOFFSET 0x6f000 + +#define IPU_GPREG_MIPI_PKT_GEN0_SEL 0x24 +#define IPU_GPREG_MIPI_PKT_GEN1_SEL 0x1c + +/* IRQ-related registers relative to ISYS_OFFSET */ +#define IPU_REG_ISYS_UNISPART_IRQ_EDGE 0x7c000 +#define IPU_REG_ISYS_UNISPART_IRQ_MASK 0x7c004 +#define IPU_REG_ISYS_UNISPART_IRQ_STATUS 0x7c008 +#define IPU_REG_ISYS_UNISPART_IRQ_CLEAR 0x7c00c +#define IPU_REG_ISYS_UNISPART_IRQ_ENABLE 0x7c010 +#define IPU_REG_ISYS_UNISPART_IRQ_LEVEL_NOT_PULSE 0x7c014 +#define IPU_REG_ISYS_UNISPART_SW_IRQ_REG 0x7c414 +#define IPU_REG_ISYS_UNISPART_SW_IRQ_MUX_REG 0x7c418 +#define IPU_ISYS_UNISPART_IRQ_SW BIT(30) +#endif /* CONFIG_VIDEO_INTEL_IPU4 */ + +#define IPU_ISYS_SPC_OFFSET 0x000000 +#define IPU_PSYS_SPC_OFFSET 0x000000 +#define IPU_ISYS_DMEM_OFFSET 0x008000 +#define IPU_PSYS_DMEM_OFFSET 0x008000 + +/* PKG DIR OFFSET in IMR in secure mode */ +#define IPU_PKG_DIR_IMR_OFFSET 0x40 + +/* PCI config registers */ +#define IPU_REG_PCI_PCIECAPHDR_PCIECAP 0x70 +#define IPU_REG_PCI_DEVICECAP 0x74 +#define IPU_REG_PCI_DEVICECTL_DEVICESTS 0x78 +#define IPU_REG_PCI_MSI_CAPID 0xac +#define IPU_REG_PCI_MSI_ADDRESS_LO 0xb0 +#define IPU_REG_PCI_MSI_ADDRESS_HI 0xb4 +#define IPU_REG_PCI_MSI_DATA 0xb8 +#define IPU_REG_PCI_PMCAP 0xd0 +#define IPU_REG_PCI_PMCS 0xd4 +#define IPU_REG_PCI_MANUFACTURING_ID 0xf8 +#define IPU_REG_PCI_IUNIT_ACCESS_CTRL_VIOL 0xfc + +/* ISYS registers */ +/* Isys DMA CIO info register */ +#define IPU_REG_ISYS_INFO_CIO_DMA0(a) (0x81810 + (a) * 0x40) +#define IPU_REG_ISYS_INFO_CIO_DMA1(a) (0x93010 + (a) * 0x40) +#define IPU_REG_ISYS_INFO_CIO_DMA_IS(a) (0xb0610 + (a) * 0x40) +#define IPU_ISYS_NUM_OF_DMA0_CHANNELS 16 +#define IPU_ISYS_NUM_OF_DMA1_CHANNELS 32 +#define IPU_ISYS_NUM_OF_IS_CHANNELS 4 +/*Isys Info register offsets*/ +#define IPU_REG_ISYS_INFO_SEG_0_CONFIG_ICACHE_MASTER 0x14 +#define IPU_REG_ISYS_INFO_SEG_CMEM_MASTER(a) (0x2C + (a * 12)) +#define IPU_REG_ISYS_INFO_SEG_XMEM_MASTER(a) (0x5C + (a * 12)) + +/* CDC Burst collector thresholds for isys - 3 FIFOs i = 0..2 */ +#define IPU_REG_ISYS_CDC_THRESHOLD(i) (0x7c400 + ((i) * 4)) + +/*Iunit Info bits*/ +#define IPU_REG_PSYS_INFO_SEG_CMEM_MASTER(a) (0x2C + ((a) * 12)) +#define IPU_REG_PSYS_INFO_SEG_XMEM_MASTER(a) (0x5C + ((a) * 12)) +#define IPU_REG_PSYS_INFO_SEG_DATA_MASTER(a) (0x8C + ((a) * 12)) + +#define IPU_ISYS_REG_SPC_STATUS_CTRL 0x0 + +#define IPU_ISYS_SPC_STATUS_START BIT(1) +#define IPU_ISYS_SPC_STATUS_RUN BIT(3) +#define IPU_ISYS_SPC_STATUS_READY BIT(5) +#define IPU_ISYS_SPC_STATUS_CTRL_ICACHE_INVALIDATE BIT(12) +#define IPU_ISYS_SPC_STATUS_ICACHE_PREFETCH BIT(13) + +#define IPU_PSYS_REG_SPC_STATUS_CTRL 0x0 + +#define IPU_PSYS_SPC_STATUS_START BIT(1) +#define IPU_PSYS_SPC_STATUS_RUN BIT(3) +#define IPU_PSYS_SPC_STATUS_READY BIT(5) +#define IPU_PSYS_SPC_STATUS_CTRL_ICACHE_INVALIDATE BIT(12) +#define IPU_PSYS_SPC_STATUS_ICACHE_PREFETCH BIT(13) + +#define IPU_PSYS_REG_SPC_START_PC 0x4 +#define IPU_PSYS_REG_SPC_ICACHE_BASE 0x10 +#define IPU_PSYS_REG_SPP0_STATUS_CTRL 0x20000 +#define IPU_PSYS_REG_SPP1_STATUS_CTRL 0x30000 +#define IPU_PSYS_REG_SPF_STATUS_CTRL 0x40000 +#define IPU_PSYS_REG_ISP0_STATUS_CTRL 0x1C0000 +#define IPU_PSYS_REG_ISP1_STATUS_CTRL 0x240000 +#define IPU_PSYS_REG_ISP2_STATUS_CTRL 0x2C0000 +#define IPU_PSYS_REG_ISP3_STATUS_CTRL 0x340000 +#define IPU_REG_PSYS_INFO_SEG_0_CONFIG_ICACHE_MASTER 0x14 + +/* VC0 */ +#define IPU_INFO_ENABLE_SNOOP BIT(0) +#define IPU_INFO_IMR_DESTINED BIT(1) +#define IPU_INFO_REQUEST_DESTINATION_BUT_REGS 0 +#define IPU_INFO_REQUEST_DESTINATION_PRIMARY BIT(4) +#define IPU_INFO_REQUEST_DESTINATION_P2P (BIT(4) | BIT(5)) +/* VC1 */ +#define IPU_INFO_DEADLINE_PTR BIT(1) +#define IPU_INFO_ZLW BIT(2) +#define IPU_INFO_STREAM_ID_SET(a) ((a & 0xF) << 4) +#define IPU_INFO_ADDRESS_SWIZZ BIT(8) + +/* Trace unit related register definitions */ +#define TRACE_REG_MAX_ISYS_OFFSET 0x0fffff +#define TRACE_REG_MAX_PSYS_OFFSET 0xffffff +/* ISYS trace registers - offsets to isys base address */ +/* Trace unit base offset */ +#define TRACE_REG_IS_TRACE_UNIT_BASE 0x07d000 +/* Trace monitors */ +#define TRACE_REG_IS_SP_EVQ_BASE 0x001000 +/* GPC blocks */ +#define TRACE_REG_IS_SP_GPC_BASE 0x000800 +#define TRACE_REG_IS_ISL_GPC_BASE 0x0bd400 +#define TRACE_REG_IS_MMU_GPC_BASE 0x0e0B00 +/* CSI2 receivers */ +#define TRACE_REG_CSI2_TM_BASE 0x067a00 +#define TRACE_REG_CSI2_3PH_TM_BASE 0x06f200 +/* Trace timers */ +#define TRACE_REG_PS_GPREG_TRACE_TIMER_RST_N 0x060614 +#define TRACE_REG_IS_GPREG_TRACE_TIMER_RST_N 0x07c410 +#define TRACE_REG_GPREG_TRACE_TIMER_RST_OFF BIT(0) +/* SIG2CIO */ +/* 0 < n <= 8 */ +#define TRACE_REG_CSI2_SIG2SIO_GR_BASE(n) (0x067c00 + (n) * 0x20) +#define TRACE_REG_CSI2_SIG2SIO_GR_NUM 9 +/* 0 < n <= 8 */ +#define TRACE_REG_CSI2_PH3_SIG2SIO_GR_BASE(n) (0x06f600 + (n) * 0x20) +#define TRACE_REG_CSI2_PH3_SIG2SIO_GR_NUM 9 +/* PSYS trace registers - offsets to isys base address */ +/* Trace unit base offset */ +#define TRACE_REG_PS_TRACE_UNIT_BASE 0x3e0000 +/* Trace monitors */ +#define TRACE_REG_PS_SPC_EVQ_BASE 0x001000 +#define TRACE_REG_PS_SPP0_EVQ_BASE 0x021000 +#define TRACE_REG_PS_SPP1_EVQ_BASE 0x031000 +#define TRACE_REG_PS_SPF_EVQ_BASE 0x041000 +#define TRACE_REG_PS_ISP0_EVQ_BASE 0x1c1000 +#define TRACE_REG_PS_ISP1_EVQ_BASE 0x241000 +#define TRACE_REG_PS_ISP2_EVQ_BASE 0x2c1000 +#define TRACE_REG_PS_ISP3_EVQ_BASE 0x341000 +/* GPC blocks */ +#define TRACE_REG_PS_SPC_GPC_BASE 0x000800 +#define TRACE_REG_PS_SPP0_GPC_BASE 0x020800 +#define TRACE_REG_PS_SPP1_GPC_BASE 0x030800 +#define TRACE_REG_PS_SPF_GPC_BASE 0x040800 +#define TRACE_REG_PS_MMU_GPC_BASE 0x0b0b00 +#define TRACE_REG_PS_ISL_GPC_BASE 0x0fe800 +#define TRACE_REG_PS_ISP0_GPC_BASE 0x1c0800 +#define TRACE_REG_PS_ISP1_GPC_BASE 0x240800 +#define TRACE_REG_PS_ISP2_GPC_BASE 0x2c0800 +#define TRACE_REG_PS_ISP3_GPC_BASE 0x340800 + +/* common macros on each platform */ +#ifdef CONFIG_VIDEO_INTEL_IPU4 +#define IPU_ISYS_UNISPART_IRQ_CSI2(port) \ + ({ typeof(port) __port = (port); \ + __port < IPU_ISYS_MAX_CSI2_LEGACY_PORTS ? \ + ((0x8) << __port) : \ + (0x800 << (__port - IPU_ISYS_MAX_CSI2_LEGACY_PORTS)); }) +#define IPU_PSYS_GPDEV_IRQ_FWIRQ(n) (BIT(17) << (n)) +#endif +#ifdef CONFIG_VIDEO_INTEL_IPU4P +#define IPU_ISYS_UNISPART_IRQ_CSI2(port) \ + ((port) > 0 ? 0x10 : 0x8) +/* bit 20 for fw irqreg0 */ +#define IPU_PSYS_GPDEV_IRQ_FWIRQ(n) (BIT(20) << (n)) +#endif +/* IRQ-related registers in PSYS, relative to IPU_xx_PSYS_OFFSET */ +#define IPU_REG_PSYS_GPDEV_IRQ_EDGE 0x60200 +#define IPU_REG_PSYS_GPDEV_IRQ_MASK 0x60204 +#define IPU_REG_PSYS_GPDEV_IRQ_STATUS 0x60208 +#define IPU_REG_PSYS_GPDEV_IRQ_CLEAR 0x6020c +#define IPU_REG_PSYS_GPDEV_IRQ_ENABLE 0x60210 +#define IPU_REG_PSYS_GPDEV_IRQ_LEVEL_NOT_PULSE 0x60214 +/* There are 8 FW interrupts, n = 0..7 */ +#define IPU_PSYS_GPDEV_FWIRQ0 0 +#define IPU_REG_PSYS_GPDEV_FWIRQ(n) (4 * (n) + 0x60100) +/* CDC Burst collector thresholds for psys - 4 FIFOs i= 0..3 */ +#define IPU_REG_PSYS_CDC_THRESHOLD(i) (0x60600 + ((i) * 4)) + +#endif /* IPU_REGS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu-platform-resources.h b/drivers/media/pci/intel/ipu4/ipu-platform-resources.h new file mode 100644 index 0000000000000..5ebd0586c96db --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu-platform-resources.h @@ -0,0 +1,225 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2016 - 2018 Intel Corporation */ + +#ifndef IPU_PLATFORM_RESOURCES_H +#define IPU_PLATFORM_RESOURCES_H + +#include +#include + +/* ia_css_psys_program_group_private.h */ +/* ia_css_psys_process_group_cmd_impl.h */ +#ifdef CONFIG_VIDEO_INTEL_IPU4P +#define IPU_FW_PSYS_N_PADDING_UINT8_IN_PROCESS_STRUCT 2 +#define IPU_FW_PSYS_N_PADDING_UINT8_IN_PROGRAM_MANIFEST 0 +#else +#define IPU_FW_PSYS_N_PADDING_UINT8_IN_PROCESS_STRUCT 4 +#define IPU_FW_PSYS_N_PADDING_UINT8_IN_PROGRAM_MANIFEST 4 +#endif +#define IPU_FW_PSYS_N_PADDING_UINT8_IN_PROCESS_GROUP_STRUCT 4 + +/* ia_css_terminal_base_types.h */ +#define IPU_FW_PSYS_N_PADDING_UINT8_IN_TERMINAL_STRUCT 5 + +/* ia_css_terminal_types.h */ +#define IPU_FW_PSYS_N_PADDING_UINT8_IN_PARAM_TERMINAL_STRUCT 6 + +/* ia_css_psys_terminal.c */ +#define IPU_FW_PSYS_N_PADDING_UINT8_IN_DATA_TERMINAL_STRUCT 4 + +/* ia_css_program_group_data.h */ +#define IPU_FW_PSYS_N_PADDING_UINT8_IN_FRAME_DESC_STRUCT 3 +#define IPU_FW_PSYS_N_FRAME_PLANES 6 +#define IPU_FW_PSYS_N_PADDING_UINT8_IN_FRAME_STRUCT 4 + +/* ia_css_psys_buffer_set.h */ +#define IPU_FW_PSYS_N_PADDING_UINT8_IN_BUFFER_SET_STRUCT 5 + +enum { + IPU_FW_PSYS_CMD_QUEUE_COMMAND_ID, + IPU_FW_PSYS_CMD_QUEUE_DEVICE_ID, + IPU_FW_PSYS_CMD_QUEUE_PPG0_COMMAND_ID, + IPU_FW_PSYS_CMD_QUEUE_PPG1_COMMAND_ID, + IPU_FW_PSYS_N_PSYS_CMD_QUEUE_ID +}; + +enum { + IPU_FW_PSYS_GMEM_TYPE_ID = 0, + IPU_FW_PSYS_DMEM_TYPE_ID, + IPU_FW_PSYS_VMEM_TYPE_ID, + IPU_FW_PSYS_BAMEM_TYPE_ID, + IPU_FW_PSYS_PMEM_TYPE_ID, + IPU_FW_PSYS_N_MEM_TYPE_ID +}; + +enum ipu_mem_id { + IPU_FW_PSYS_VMEM0_ID = 0, + IPU_FW_PSYS_VMEM1_ID, + IPU_FW_PSYS_VMEM2_ID, + IPU_FW_PSYS_VMEM3_ID, + IPU_FW_PSYS_VMEM4_ID, + IPU_FW_PSYS_BAMEM0_ID, + IPU_FW_PSYS_BAMEM1_ID, + IPU_FW_PSYS_BAMEM2_ID, + IPU_FW_PSYS_BAMEM3_ID, + IPU_FW_PSYS_DMEM0_ID, + IPU_FW_PSYS_DMEM1_ID, + IPU_FW_PSYS_DMEM2_ID, + IPU_FW_PSYS_DMEM3_ID, + IPU_FW_PSYS_DMEM4_ID, + IPU_FW_PSYS_DMEM5_ID, + IPU_FW_PSYS_DMEM6_ID, + IPU_FW_PSYS_DMEM7_ID, + IPU_FW_PSYS_PMEM0_ID, + IPU_FW_PSYS_PMEM1_ID, + IPU_FW_PSYS_PMEM2_ID, + IPU_FW_PSYS_PMEM3_ID, + IPU_FW_PSYS_N_MEM_ID +}; + +enum { + IPU_FW_PSYS_DEV_CHN_DMA_EXT0_ID = 0, + IPU_FW_PSYS_DEV_CHN_GDC_ID, + IPU_FW_PSYS_DEV_CHN_DMA_EXT1_READ_ID, + IPU_FW_PSYS_DEV_CHN_DMA_EXT1_WRITE_ID, + IPU_FW_PSYS_DEV_CHN_DMA_INTERNAL_ID, + IPU_FW_PSYS_DEV_CHN_DMA_IPFD_ID, + IPU_FW_PSYS_DEV_CHN_DMA_ISA_ID, + IPU_FW_PSYS_DEV_CHN_DMA_FW_ID, +#ifdef CONFIG_VIDEO_INTEL_IPU4P + IPU_FW_PSYS_DEV_CHN_DMA_CMPRS_ID, +#endif + IPU_FW_PSYS_N_DEV_CHN_ID +}; + +enum { + IPU_FW_PSYS_SP_CTRL_TYPE_ID = 0, + IPU_FW_PSYS_SP_SERVER_TYPE_ID, + IPU_FW_PSYS_VP_TYPE_ID, + IPU_FW_PSYS_ACC_PSA_TYPE_ID, + IPU_FW_PSYS_ACC_ISA_TYPE_ID, + IPU_FW_PSYS_ACC_OSA_TYPE_ID, + IPU_FW_PSYS_GDC_TYPE_ID, + IPU_FW_PSYS_N_CELL_TYPE_ID +}; + +enum { + IPU_FW_PSYS_SP0_ID = 0, + IPU_FW_PSYS_SP1_ID, + IPU_FW_PSYS_SP2_ID, + IPU_FW_PSYS_VP0_ID, + IPU_FW_PSYS_VP1_ID, + IPU_FW_PSYS_VP2_ID, + IPU_FW_PSYS_VP3_ID, + IPU_FW_PSYS_ACC0_ID, + IPU_FW_PSYS_ACC1_ID, + IPU_FW_PSYS_ACC2_ID, + IPU_FW_PSYS_ACC3_ID, + IPU_FW_PSYS_ACC4_ID, + IPU_FW_PSYS_ACC5_ID, + IPU_FW_PSYS_ACC6_ID, + IPU_FW_PSYS_ACC7_ID, + IPU_FW_PSYS_GDC0_ID, + IPU_FW_PSYS_GDC1_ID, + IPU_FW_PSYS_N_CELL_ID +}; + +#define IPU_FW_PSYS_N_DEV_DFM_ID 0 +#define IPU_FW_PSYS_N_DATA_MEM_TYPE_ID (IPU_FW_PSYS_N_MEM_TYPE_ID - 1) +#define IPU_FW_PSYS_PROCESS_MAX_CELLS 1 +#define IPU_FW_PSYS_KERNEL_BITMAP_NOF_ELEMS 2 +#define IPU_FW_PSYS_RBM_NOF_ELEMS 2 + +#define IPU_FW_PSYS_DEV_CHN_DMA_EXT0_MAX_SIZE 30 +#define IPU_FW_PSYS_DEV_CHN_GDC_MAX_SIZE 4 +#define IPU_FW_PSYS_DEV_CHN_DMA_EXT1_READ_MAX_SIZE 30 +#define IPU_FW_PSYS_DEV_CHN_DMA_EXT1_WRITE_MAX_SIZE 20 +#define IPU_FW_PSYS_DEV_CHN_DMA_INTERNAL_MAX_SIZE 2 +#define IPU_FW_PSYS_DEV_CHN_DMA_IPFD_MAX_SIZE 5 +#define IPU_FW_PSYS_DEV_CHN_DMA_ISA_MAX_SIZE 2 +#define IPU_FW_PSYS_DEV_CHN_DMA_FW_MAX_SIZE 1 +#define IPU_FW_PSYS_DEV_CHN_DMA_CMPRS_MAX_SIZE 6 + +#define IPU_FW_PSYS_VMEM0_MAX_SIZE 0x0800 +#define IPU_FW_PSYS_VMEM1_MAX_SIZE 0x0800 +#define IPU_FW_PSYS_VMEM2_MAX_SIZE 0x0800 +#define IPU_FW_PSYS_VMEM3_MAX_SIZE 0x0800 +#define IPU_FW_PSYS_VMEM4_MAX_SIZE 0x0800 +#define IPU_FW_PSYS_BAMEM0_MAX_SIZE 0x0400 +#define IPU_FW_PSYS_BAMEM1_MAX_SIZE 0x0400 +#define IPU_FW_PSYS_BAMEM2_MAX_SIZE 0x0400 +#define IPU_FW_PSYS_BAMEM3_MAX_SIZE 0x0400 +#define IPU_FW_PSYS_DMEM0_MAX_SIZE 0x4000 +#define IPU_FW_PSYS_DMEM1_MAX_SIZE 0x1000 +#define IPU_FW_PSYS_DMEM2_MAX_SIZE 0x1000 +#define IPU_FW_PSYS_DMEM3_MAX_SIZE 0x1000 +#define IPU_FW_PSYS_DMEM4_MAX_SIZE 0x1000 +#define IPU_FW_PSYS_DMEM5_MAX_SIZE 0x1000 +#define IPU_FW_PSYS_DMEM6_MAX_SIZE 0x1000 +#define IPU_FW_PSYS_DMEM7_MAX_SIZE 0x1000 +#define IPU_FW_PSYS_PMEM0_MAX_SIZE 0x0500 +#define IPU_FW_PSYS_PMEM1_MAX_SIZE 0x0500 +#define IPU_FW_PSYS_PMEM2_MAX_SIZE 0x0500 +#define IPU_FW_PSYS_PMEM3_MAX_SIZE 0x0500 + +struct ipu_fw_psys_program_manifest { + u32 kernel_bitmap[IPU_FW_PSYS_KERNEL_BITMAP_NOF_ELEMS]; + u32 ID; + u32 program_type; + s32 parent_offset; + u32 program_dependency_offset; + u32 terminal_dependency_offset; + u16 size; + u16 int_mem_size[IPU_FW_PSYS_N_MEM_TYPE_ID]; + u16 ext_mem_size[IPU_FW_PSYS_N_DATA_MEM_TYPE_ID]; + u16 ext_mem_offset[IPU_FW_PSYS_N_DATA_MEM_TYPE_ID]; + u16 dev_chn_size[IPU_FW_PSYS_N_DEV_CHN_ID]; + u16 dev_chn_offset[IPU_FW_PSYS_N_DEV_CHN_ID]; + u8 cell_id; + u8 cell_type_id; + u8 program_dependency_count; + u8 terminal_dependency_count; +#ifndef CONFIG_VIDEO_INTEL_IPU4P + u8 reserved[IPU_FW_PSYS_N_PADDING_UINT8_IN_PROGRAM_MANIFEST]; +#endif +}; + +struct ipu_fw_psys_process { + u32 kernel_bitmap[IPU_FW_PSYS_KERNEL_BITMAP_NOF_ELEMS]; + u32 size; + u32 ID; + u32 program_idx; + u32 state; + s16 parent_offset; + u16 cell_dependencies_offset; + u16 terminal_dependencies_offset; + u16 int_mem_offset[IPU_FW_PSYS_N_MEM_TYPE_ID]; + u16 ext_mem_offset[IPU_FW_PSYS_N_DATA_MEM_TYPE_ID]; + u16 dev_chn_offset[IPU_FW_PSYS_N_DEV_CHN_ID]; + u8 cell_id; + u8 int_mem_id[IPU_FW_PSYS_N_MEM_TYPE_ID]; + u8 ext_mem_id[IPU_FW_PSYS_N_DATA_MEM_TYPE_ID]; + u8 cell_dependency_count; + u8 terminal_dependency_count; + u8 padding[IPU_FW_PSYS_N_PADDING_UINT8_IN_PROCESS_STRUCT]; +}; + +struct ipu_psys_resource_alloc; +struct ipu_fw_psys_process_group; +struct ipu_psys_resource_pool; +int ipu_psys_allocate_resources(const struct device *dev, + struct ipu_fw_psys_process_group *pg, + void *pg_manifest, + struct ipu_psys_resource_alloc *alloc, + struct ipu_psys_resource_pool *pool); +int ipu_psys_move_resources(const struct device *dev, + struct ipu_psys_resource_alloc *alloc, + struct ipu_psys_resource_pool *source_pool, + struct ipu_psys_resource_pool *target_pool); + +void ipu_psys_free_resources(struct ipu_psys_resource_alloc *alloc, + struct ipu_psys_resource_pool *pool); + +extern const struct ipu_fw_resource_definitions *res_defs; + +#endif /* IPU_PLATFORM_RESOURCES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu-platform.h b/drivers/media/pci/intel/ipu4/ipu-platform.h new file mode 100644 index 0000000000000..32956125d5e7d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu-platform.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef IPU_PLATFORM_H +#define IPU_PLATFORM_H + +#define IPU_NAME "intel-ipu4" +#define IPU_ISYS_NUM_STREAMS 8 /* Max 8 */ + +#ifdef CONFIG_VIDEO_INTEL_IPU4 +#define IPU_CPD_FIRMWARE_NAME "ipu4_cpd_b0.bin" +#else +#define IPU_CPD_FIRMWARE_NAME "ipu4p_cpd.bin" +#endif + +/* + * The following definitions are encoded to the media_device's model field so + * that the software components which uses IPU driver can get the hw stepping + * information. + */ +#ifdef CONFIG_VIDEO_INTEL_IPU4 +#define IPU_MEDIA_DEV_MODEL_NAME "ipu4/Broxton B" +#else +#define IPU_MEDIA_DEV_MODEL_NAME "ipu4p" +#endif + +#ifdef CONFIG_VIDEO_INTEL_IPU4 + +#define IPU_HW_BXT_P_B1_REV 0xa +#define IPU_HW_BXT_P_D0_REV 0xb +#define IPU_HW_BXT_P_E0_REV 0xc + +/* BXTP E0 has icache bug fixed */ +#define is_ipu_hw_bxtp_e0(isp) \ + ({ typeof(isp) __isp = (isp); \ + (__isp->pdev->device == IPU_PCI_ID && \ + __isp->pdev->revision == IPU_HW_BXT_P_E0_REV); }) +#endif + +/* declearations, definitions in ipu4.c */ +extern const struct ipu_isys_internal_pdata isys_ipdata; +extern const struct ipu_psys_internal_pdata psys_ipdata; +extern const struct ipu_buttress_ctrl isys_buttress_ctrl; +extern const struct ipu_buttress_ctrl psys_buttress_ctrl; + +/* definitions in ipu4-isys.c */ +extern struct ipu_trace_block isys_trace_blocks[]; +/* definitions in ipu4-psys.c */ +extern struct ipu_trace_block psys_trace_blocks[]; + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4isys_inc b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4isys_inc new file mode 100644 index 0000000000000..48a4edea420fc --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4isys_inc @@ -0,0 +1,26 @@ +IPU_ISYSLIB_INC = \ + -I$(IPU_ISYSLIB_ROOT)/buffer/interface \ + -I$(IPU_ISYSLIB_ROOT)/cell/interface \ + -I$(IPU_ISYSLIB_ROOT)/cell/src \ + -I$(IPU_ISYSLIB_ROOT)/device_access/interface \ + -I$(IPU_ISYSLIB_ROOT)/device_access/src \ + -I$(IPU_ISYSLIB_ROOT)/devices \ + -I$(IPU_ISYSLIB_ROOT)/devices/interface \ + -I$(IPU_ISYSLIB_ROOT)/devices/isys/bxtB0 \ + -I$(IPU_ISYSLIB_ROOT)/devices/src \ + -I$(IPU_ISYSLIB_ROOT)/fw_abi_common_types \ + -I$(IPU_ISYSLIB_ROOT)/fw_abi_common_types/cpu \ + -I$(IPU_ISYSLIB_ROOT)/isysapi/interface \ + -I$(IPU_ISYSLIB_ROOT)/pkg_dir/interface \ + -I$(IPU_ISYSLIB_ROOT)/pkg_dir/src \ + -I$(IPU_ISYSLIB_ROOT)/port/interface \ + -I$(IPU_ISYSLIB_ROOT)/reg_dump/src/isys/bxtB0_gen_reg_dump \ + -I$(IPU_ISYSLIB_ROOT)/regmem/interface \ + -I$(IPU_ISYSLIB_ROOT)/regmem/src \ + -I$(IPU_ISYSLIB_ROOT)/support \ + -I$(IPU_ISYSLIB_ROOT)/syscom/interface \ + -I$(IPU_ISYSLIB_ROOT)/syscom/src \ + -I$(IPU_ISYSLIB_ROOT)/trace/interface \ + -I$(IPU_ISYSLIB_ROOT)/utils/system_defs/ \ + -I$(IPU_ISYSLIB_ROOT)/vied \ + -I$(IPU_ISYSLIB_ROOT)/vied/vied/ \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4isys_src b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4isys_src new file mode 100644 index 0000000000000..c20760bdb5f1d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4isys_src @@ -0,0 +1,19 @@ +IPU_ISYSLIB_SRC = \ + $(IPU_ISYSLIB_ROOT_REL)/isysapi/src/ia_css_isys_private.o \ + $(IPU_ISYSLIB_ROOT_REL)/isysapi/src/ia_css_isys_public.o \ + $(IPU_ISYSLIB_ROOT_REL)/isysapi/src/ia_css_isys_public_trace.o + +ifeq ($(CONFIG_VIDEO_INTEL_IPU), m) +IPU_ISYSLIB_SRC += \ + $(IPU_ISYSLIB_ROOT_REL)/buffer/src/cpu/buffer_access.o \ + $(IPU_ISYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_buffer.o \ + $(IPU_ISYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_input_buffer.o \ + $(IPU_ISYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_output_buffer.o \ + $(IPU_ISYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_shared_buffer.o \ + $(IPU_ISYSLIB_ROOT_REL)/pkg_dir/src/ia_css_pkg_dir.o \ + $(IPU_ISYSLIB_ROOT_REL)/port/src/queue.o \ + $(IPU_ISYSLIB_ROOT_REL)/port/src/recv_port.o \ + $(IPU_ISYSLIB_ROOT_REL)/port/src/send_port.o \ + $(IPU_ISYSLIB_ROOT_REL)/reg_dump/src/reg_dump_generic_bridge.o \ + $(IPU_ISYSLIB_ROOT_REL)/syscom/src/ia_css_syscom.o +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4psys_inc b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4psys_inc new file mode 100644 index 0000000000000..abc61475e9887 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4psys_inc @@ -0,0 +1,52 @@ +IPU_PSYSLIB_INC = \ + -I$(IPU_PSYSLIB_ROOT)/buffer/interface \ + -I$(IPU_PSYSLIB_ROOT)/cell/interface \ + -I$(IPU_PSYSLIB_ROOT)/cell/src \ + -I$(IPU_PSYSLIB_ROOT)/client_pkg/interface \ + -I$(IPU_PSYSLIB_ROOT)/client_pkg/src \ + -I$(IPU_PSYSLIB_ROOT)/cpd/ \ + -I$(IPU_PSYSLIB_ROOT)/cpd/cpd_component/interface \ + -I$(IPU_PSYSLIB_ROOT)/cpd/cpd_metadata/interface \ + -I$(IPU_PSYSLIB_ROOT)/device_access/interface \ + -I$(IPU_PSYSLIB_ROOT)/device_access/src \ + -I$(IPU_PSYSLIB_ROOT)/devices \ + -I$(IPU_PSYSLIB_ROOT)/devices/interface \ + -I$(IPU_PSYSLIB_ROOT)/devices/psys/bxtB0 \ + -I$(IPU_PSYSLIB_ROOT)/devices/src \ + -I$(IPU_PSYSLIB_ROOT)/fw_abi_common_types \ + -I$(IPU_PSYSLIB_ROOT)/fw_abi_common_types/cpu \ + -I$(IPU_PSYSLIB_ROOT)/pkg_dir/interface \ + -I$(IPU_PSYSLIB_ROOT)/pkg_dir/src \ + -I$(IPU_PSYSLIB_ROOT)/port/interface \ + -I$(IPU_PSYSLIB_ROOT)/psys_private_pg/interface \ + -I$(IPU_PSYSLIB_ROOT)/psys_server/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/data/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/data/src \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/device/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/device/interface/bxtB0 \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/dynamic/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/dynamic/src \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/kernel/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/param/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/param/src \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/psys_server_manifest/bxtB0 \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/resource_model/bxtB0 \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/sim/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/sim/src \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/static/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/static/src \ + -I$(IPU_PSYSLIB_ROOT)/reg_dump/src/psys/bxtB0_gen_reg_dump \ + -I$(IPU_PSYSLIB_ROOT)/regmem/interface \ + -I$(IPU_PSYSLIB_ROOT)/regmem/src \ + -I$(IPU_PSYSLIB_ROOT)/routing_bitmap/interface \ + -I$(IPU_PSYSLIB_ROOT)/routing_bitmap/src \ + -I$(IPU_PSYSLIB_ROOT)/support \ + -I$(IPU_PSYSLIB_ROOT)/syscom/interface \ + -I$(IPU_PSYSLIB_ROOT)/syscom/src \ + -I$(IPU_PSYSLIB_ROOT)/trace/interface \ + -I$(IPU_PSYSLIB_ROOT)/vied \ + -I$(IPU_PSYSLIB_ROOT)/vied/vied/ \ + -I$(IPU_PSYSLIB_ROOT)/vied_nci_acb/interface \ + -I$(IPU_PSYSLIB_ROOT)/vied_parameters/interface \ + -I$(IPU_PSYSLIB_ROOT)/vied_parameters/src \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4psys_src b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4psys_src new file mode 100644 index 0000000000000..8344bf569e13e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.ipu4psys_src @@ -0,0 +1,32 @@ +IPU_PSYSLIB_SRC = \ + $(IPU_PSYSLIB_ROOT_REL)/buffer/src/cpu/buffer_access.o \ + $(IPU_PSYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_buffer.o \ + $(IPU_PSYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_input_buffer.o \ + $(IPU_PSYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_output_buffer.o \ + $(IPU_PSYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_shared_buffer.o \ + $(IPU_PSYSLIB_ROOT_REL)/client_pkg/src/ia_css_client_pkg.o \ + $(IPU_PSYSLIB_ROOT_REL)/pkg_dir/src/ia_css_pkg_dir.o \ + $(IPU_PSYSLIB_ROOT_REL)/port/src/queue.o \ + $(IPU_PSYSLIB_ROOT_REL)/port/src/recv_port.o \ + $(IPU_PSYSLIB_ROOT_REL)/port/src/send_port.o \ + $(IPU_PSYSLIB_ROOT_REL)/psys_server/src/bxt_spctrl_process_group_cmd_impl.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/data/src/ia_css_program_group_data.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/device/src/ia_css_psys_device.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/dynamic/src/ia_css_psys_buffer_set.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/dynamic/src/ia_css_psys_process.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/dynamic/src/ia_css_psys_process_group.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/dynamic/src/ia_css_psys_terminal.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/kernel/src/ia_css_kernel_bitmap.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/param/src/ia_css_program_group_param.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/psys_server_manifest/bxtB0/ia_css_psys_server_manifest.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/resource_model/bxtB0/vied_nci_psys_resource_model.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/sim/src/vied_nci_psys_system.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/static/src/ia_css_psys_program_group_manifest.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/static/src/ia_css_psys_program_manifest.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/static/src/ia_css_psys_terminal_manifest.o \ + $(IPU_PSYSLIB_ROOT_REL)/reg_dump/src/reg_dump_generic_bridge.o \ + $(IPU_PSYSLIB_ROOT_REL)/routing_bitmap/src/ia_css_rbm.o \ + $(IPU_PSYSLIB_ROOT_REL)/routing_bitmap/src/ia_css_rbm_manifest.o \ + $(IPU_PSYSLIB_ROOT_REL)/syscom/src/ia_css_syscom.o \ + $(IPU_PSYSLIB_ROOT_REL)/vied_parameters/src/ia_css_terminal.o \ + $(IPU_PSYSLIB_ROOT_REL)/vied_parameters/src/ia_css_terminal_manifest.o \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.isyslib b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.isyslib new file mode 100644 index 0000000000000..33a3df8969194 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.isyslib @@ -0,0 +1,42 @@ +ifneq ($(EXTERNAL_BUILD), 1) +srcpath := $(srctree) +endif + +PROGRAMS = isys_fw +SYSTEM = input_system_system +IPU_ISYSLIB_ROOT_REL = ipu4-css/lib2600 +IPU_ISYSLIB_ROOT = $(srcpath)/$(src)/$(IPU_ISYSLIB_ROOT_REL) + +include $(srcpath)/$(src)/ipu4-css/Makefile.ipu4isys_inc +include $(srcpath)/$(src)/ipu4-css/Makefile.ipu4isys_src + +intel-ipu4-isys-csslib-objs := \ + ipu4-css/libintel-ipu4.o \ + $(IPU_ISYSLIB_SRC) + +ifeq ($(CONFIG_VIDEO_INTEL_IPU), m) +intel-ipu4-isys-csslib-objs += ipu4-css/ipu-wrapper.o +endif +obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu4-isys-csslib.o + +INCLUDES := -I$(srcpath)/$(src)/$(IPU_ISYSLIB_ROOT_REL) \ + -I$(srcpath)/$(src) \ + $(IPU_ISYSLIB_INC) + +DEFINES:= -D__HOST__ -D__KERNEL__ -DISYS_FPGA -DPSYS_FPGA + +DEFINES += -DSSID=1 +DEFINES += -DMMID=1 +DEFINES += -DPROGNAME=isys_fw +DEFINES += -DPROGMAP=\"isys_fw.map.h\" +DEFINES += -DSUBSYSTEM_INCLUDE=\ +DEFINES += -DCELL=input_system_unis_logic_sp_control_tile_sp +DEFINES += -DSPMAIN=isys_fw +DEFINES += -DRUN_INTEGRATION +DEFINES += -DDEBUG_SP_NCI +DEFINES += -DCFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL=1 +DEFINES += -DHRT_ON_VIED_SUBSYSTEM_ACCESS=0 +DEFINES += -DHRT_USE_VIR_ADDRS +DEFINES += -DHRT_HW + +ccflags-y += $(INCLUDES) $(DEFINES) -fno-common diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.psyslib b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.psyslib new file mode 100644 index 0000000000000..c93852bd09a1d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/Makefile.psyslib @@ -0,0 +1,14 @@ +ifneq ($(EXTERNAL_BUILD), 1) +srcpath := $(srctree) +endif + +# note: this file only defines INCLUDES paths for psyslib +include $(srcpath)/$(src)/ipu4-css/Makefile.ipu4psys_inc + +IPU_PSYSLIB_ROOT = $(srcpath)/$(src)/ipu4-css/lib2600psys/lib +HOST_DEFINES += -DPSYS_SERVER_ON_SPC +HOST_DEFINES += -DCFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL=1 + +ccflags-y += $(IPU_PSYSLIB_INC) $(HOST_DEFINES) + +obj-$(CONFIG_VIDEO_INTEL_IPU) += ipu4-css/lib2600psys/ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/ia_css_fw_pkg_release.h b/drivers/media/pci/intel/ipu4/ipu4-css/ia_css_fw_pkg_release.h new file mode 100644 index 0000000000000..408726c817146 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/ia_css_fw_pkg_release.h @@ -0,0 +1,14 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#define IA_CSS_FW_PKG_RELEASE 0x20181222 diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/ipu-wrapper.c b/drivers/media/pci/intel/ipu4/ipu4-css/ipu-wrapper.c new file mode 120000 index 0000000000000..3167dda06f067 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/ipu-wrapper.c @@ -0,0 +1 @@ +../../ipu-wrapper.c \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/buffer.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/buffer.mk new file mode 100644 index 0000000000000..c00a1133b440f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/buffer.mk @@ -0,0 +1,43 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is BUFFER + +ifdef _H_BUFFER_MK +$(error ERROR: buffer.mk included multiple times, please check makefile) +else +_H_BUFFER_MK=1 +endif + +BUFFER_DIR=$${MODULES_DIR}/buffer + +BUFFER_INTERFACE=$(BUFFER_DIR)/interface +BUFFER_SOURCES_CPU=$(BUFFER_DIR)/src/cpu +BUFFER_SOURCES_CSS=$(BUFFER_DIR)/src/css + +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_output_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_input_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_shared_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/buffer_access.c +BUFFER_HOST_CPPFLAGS += -I$(BUFFER_INTERFACE) +BUFFER_HOST_CPPFLAGS += -I$${MODULES_DIR}/support + +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_input_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_output_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_shared_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/buffer_access.c + +BUFFER_FW_CPPFLAGS += -I$(BUFFER_INTERFACE) +BUFFER_FW_CPPFLAGS += -I$${MODULES_DIR}/support diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/buffer_access.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/buffer_access.h new file mode 100644 index 0000000000000..e5fe647742c9f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/buffer_access.h @@ -0,0 +1,36 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __BUFFER_ACCESS_H +#define __BUFFER_ACCESS_H + +#include "buffer_type.h" +/* #def to keep consistent the buffer load interfaces for host and css */ +#define IDM 0 + +void +buffer_load( + buffer_address address, + void *data, + unsigned int size, + unsigned int mm_id); + +void +buffer_store( + buffer_address address, + const void *data, + unsigned int size, + unsigned int mm_id); + +#endif /* __BUFFER_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/buffer_type.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/buffer_type.h new file mode 100644 index 0000000000000..de51f23941582 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/buffer_type.h @@ -0,0 +1,29 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __BUFFER_TYPE_H +#define __BUFFER_TYPE_H + +/* portable access to buffers in DDR */ + +#ifdef __VIED_CELL +typedef unsigned int buffer_address; +#else +/* workaround needed because shared_memory_access.h uses size_t */ +#include "type_support.h" +#include "vied/shared_memory_access.h" +typedef host_virtual_address_t buffer_address; +#endif + +#endif /* __BUFFER_TYPE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_buffer_address.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_buffer_address.h new file mode 100644 index 0000000000000..137bfb1fda166 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_buffer_address.h @@ -0,0 +1,24 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BUFFER_ADDRESS_H +#define __IA_CSS_BUFFER_ADDRESS_H + +#include "type_support.h" + +typedef uint32_t ia_css_buffer_address; /* CSS virtual address */ + +#define ia_css_buffer_address_null ((ia_css_buffer_address)0) + +#endif /* __IA_CSS_BUFFER_ADDRESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_input_buffer.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_input_buffer.h new file mode 100644 index 0000000000000..4e92e35b61843 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_input_buffer.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_INPUT_BUFFER_H +#define __IA_CSS_INPUT_BUFFER_H + + +/* Input Buffers */ + +/* A CSS input buffer is a buffer in DDR that can be written by the CPU, + * and that can be read by CSS hardware, after the buffer has been handed over. + * Examples: command buffer, input frame buffer, parameter buffer + * An input buffer must be mapped into the CPU address space before it can be + * written by the CPU. + * After mapping, writing, and unmapping, the buffer can be handed over to the + * firmware. An input buffer is handed over to the CSS by mapping it to the + * CSS address space (by the CPU), and by passing the resulting CSS (virtial) + * address of the input buffer to the DA CSS hardware. + * The firmware can read from an input buffer as soon as it has been received + * CSS virtual address. + * The firmware should not write into an input buffer. + * The firmware hands over the input buffer (back to the CPU) by sending the + * buffer handle via a response. The host should unmap the buffer, + * before reusing it. + * The firmware should not read from the input buffer after returning the + * buffer handle to the CPU. + * + * A buffer may be pre-mapped to the CPU and/or to the CSS upon allocation, + * depending on the allocator's preference. In case of pre-mapped buffers, + * the map and unmap functions will only manage read and write access. + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_input_buffer; /* input buffer handle */ +typedef void *ia_css_input_buffer_cpu_address; /* CPU virtual address */ +/* CSS virtual address */ +typedef ia_css_buffer_address ia_css_input_buffer_css_address; + +#endif /* __IA_CSS_INPUT_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_input_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_input_buffer_cpu.h new file mode 100644 index 0000000000000..d3d01353ce431 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_input_buffer_cpu.h @@ -0,0 +1,49 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_INPUT_BUFFER_CPU_H +#define __IA_CSS_INPUT_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_input_buffer.h" + +ia_css_input_buffer +ia_css_input_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_input_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_input_buffer b); + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_map(ia_css_input_buffer b); + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_unmap(ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map(vied_memory_t mid, ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map_no_invalidate(vied_memory_t mid, ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_unmap(ia_css_input_buffer b); + + +#endif /* __IA_CSS_INPUT_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_output_buffer.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_output_buffer.h new file mode 100644 index 0000000000000..2c310ea92c6af --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_output_buffer.h @@ -0,0 +1,30 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_OUTPUT_BUFFER_H +#define __IA_CSS_OUTPUT_BUFFER_H + +/* Output Buffers */ +/* A CSS output buffer a buffer in DDR that can be written by CSS hardware + * and that can be read by the host, after the buffer has been handed over + * Examples: output frame buffer + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_output_buffer; +typedef void *ia_css_output_buffer_cpu_address; +typedef ia_css_buffer_address ia_css_output_buffer_css_address; + +#endif /* __IA_CSS_OUTPUT_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_output_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_output_buffer_cpu.h new file mode 100644 index 0000000000000..0299fc3b7eb66 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_output_buffer_cpu.h @@ -0,0 +1,48 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_OUTPUT_BUFFER_CPU_H +#define __IA_CSS_OUTPUT_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_output_buffer.h" + +ia_css_output_buffer +ia_css_output_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_output_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_output_buffer b); + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_map(ia_css_output_buffer b); + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_unmap(ia_css_output_buffer b); + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map(vied_memory_t mid, ia_css_output_buffer b); +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map_no_invalidate(vied_memory_t mid, ia_css_output_buffer b); + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_unmap(ia_css_output_buffer b); + + +#endif /* __IA_CSS_OUTPUT_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_return_token.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_return_token.h new file mode 100644 index 0000000000000..440161d2f32b3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_return_token.h @@ -0,0 +1,54 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RETURN_TOKEN_H +#define __IA_CSS_RETURN_TOKEN_H + +#include "storage_class.h" +#include "assert_support.h" /* For CT_ASSERT */ + +/* ia_css_return_token: data item of exacly 8 bytes (64 bits) + * which can be used to pass a return token back to the host +*/ +typedef unsigned long long ia_css_return_token; + +STORAGE_CLASS_INLINE void +ia_css_return_token_copy(ia_css_return_token *to, + const ia_css_return_token *from) +{ + /* copy a return token on VIED processor */ + int *dst = (int *)to; + int *src = (int *)from; + + dst[0] = src[0]; + dst[1] = src[1]; +} + +STORAGE_CLASS_INLINE void +ia_css_return_token_zero(ia_css_return_token *to) +{ + /* zero return token on VIED processor */ + int *dst = (int *)to; + + dst[0] = 0; + dst[1] = 0; +} + +STORAGE_CLASS_INLINE void _check_return_token_size(void) +{ + CT_ASSERT(sizeof(int) == 4); + CT_ASSERT(sizeof(ia_css_return_token) == 8); +} + +#endif /* __IA_CSS_RETURN_TOKEN_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_shared_buffer.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_shared_buffer.h new file mode 100644 index 0000000000000..558ec679f98a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_shared_buffer.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SHARED_BUFFER_H +#define __IA_CSS_SHARED_BUFFER_H + +/* Shared Buffers */ +/* A CSS shared buffer is a buffer in DDR that can be read and written by the + * CPU and CSS. + * Both the CPU and CSS can have the buffer mapped simultaneously. + * Access rights are not managed by this interface, this could be done by means + * the read and write pointer of a queue, for example. + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_shared_buffer; +typedef void *ia_css_shared_buffer_cpu_address; +typedef ia_css_buffer_address ia_css_shared_buffer_css_address; + +#endif /* __IA_CSS_SHARED_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_shared_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_shared_buffer_cpu.h new file mode 100644 index 0000000000000..ff62914f99dc3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/interface/ia_css_shared_buffer_cpu.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SHARED_BUFFER_CPU_H +#define __IA_CSS_SHARED_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_shared_buffer.h" + +ia_css_shared_buffer +ia_css_shared_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_shared_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_shared_buffer b); + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_map(ia_css_shared_buffer b); + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_unmap(ia_css_shared_buffer b); + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_map(ia_css_shared_buffer b); + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_unmap(ia_css_shared_buffer b); + +ia_css_shared_buffer +ia_css_shared_buffer_css_update(vied_memory_t mid, ia_css_shared_buffer b); + +ia_css_shared_buffer +ia_css_shared_buffer_cpu_update(vied_memory_t mid, ia_css_shared_buffer b); + +#endif /* __IA_CSS_SHARED_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/buffer_access.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/buffer_access.c new file mode 100644 index 0000000000000..f0c617fe501a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/buffer_access.c @@ -0,0 +1,39 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/* implementation of buffer access from the CPU */ +/* using shared_memory interface */ + +#include "buffer_access.h" +#include "vied/shared_memory_access.h" + +void +buffer_load( + buffer_address address, + void *data, + unsigned int bytes, + unsigned int mm_id) +{ + shared_memory_load(mm_id, address, data, bytes); +} + +void +buffer_store( + buffer_address address, + const void *data, + unsigned int bytes, + unsigned int mm_id) +{ + shared_memory_store(mm_id, address, data, bytes); +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_buffer.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_buffer.c new file mode 100644 index 0000000000000..146d4109de440 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_buffer.c @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/* provided interface */ +#include "ia_css_buffer.h" + +/* used interfaces */ +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + +ia_css_buffer_t +ia_css_buffer_alloc(vied_subsystem_t sid, vied_memory_t mid, unsigned int size) +{ + ia_css_buffer_t b; + + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + + b->css_address = shared_memory_map(sid, mid, b->mem); + b->size = size; + return b; +} + + +void +ia_css_buffer_free(vied_subsystem_t sid, vied_memory_t mid, ia_css_buffer_t b) +{ + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_buffer.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_buffer.h new file mode 100644 index 0000000000000..a8959fdcd04ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_buffer.h @@ -0,0 +1,58 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BUFFER_H +#define __IA_CSS_BUFFER_H + +/* workaround: needed because uses size_t */ +#include "type_support.h" +#include "vied/shared_memory_map.h" + +typedef enum { + buffer_unmapped, /* buffer is not accessible by cpu, nor css */ + buffer_write, /* output buffer: css has write access */ + /* input buffer: cpu has write access */ + buffer_read, /* input buffer: css has read access */ + /* output buffer: cpu has read access */ + buffer_cpu, /* shared buffer: cpu has read/write access */ + buffer_css /* shared buffer: css has read/write access */ +} buffer_state; + +struct ia_css_buffer_s { + /* number of bytes allocated */ + unsigned int size; + /* allocated virtual memory object */ + host_virtual_address_t mem; + /* virtual address to be used on css/firmware */ + vied_virtual_address_t css_address; + /* virtual address to be used on cpu/host */ + void *cpu_address; + buffer_state state; +}; + +typedef struct ia_css_buffer_s *ia_css_buffer_t; + +ia_css_buffer_t +ia_css_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_buffer_t b); + +#endif /* __IA_CSS_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_input_buffer.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_input_buffer.c new file mode 100644 index 0000000000000..2a128795d03e2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_input_buffer.c @@ -0,0 +1,184 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_input_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_input_buffer +ia_css_input_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_input_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_input_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_input_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_map(ia_css_input_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map input buffer to CPU address space, acquire write access */ + b->state = buffer_write; + + /* return pre-mapped buffer */ + return b->cpu_address; +} + + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_unmap(ia_css_input_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_write) + return NULL; + + /* unmap input buffer from CPU address space, release write access */ + b->state = buffer_unmapped; + + /* return pre-mapped buffer */ + return b->cpu_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map(vied_memory_t mid, ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map input buffer to CSS address space, acquire read access */ + b->state = buffer_read; + + /* now flush the cache */ + ia_css_cpu_mem_cache_flush(b->cpu_address, b->size); +#ifndef HRT_HW + /* only copy in case of simulation, otherwise it should just work */ + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return (ia_css_input_buffer_css_address)b->css_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map_no_invalidate(vied_memory_t mid, ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map input buffer to CSS address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only copy in case of simulation, otherwise it should just work */ + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return (ia_css_input_buffer_css_address)b->css_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_unmap(ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_read) + return 0; + + /* unmap input buffer from CSS address space, release read access */ + b->state = buffer_unmapped; + + /* input buffer only, no need to invalidate cache */ + + return (ia_css_input_buffer_css_address)b->css_address; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_output_buffer.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_output_buffer.c new file mode 100644 index 0000000000000..30bc8d52a5a9e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_output_buffer.c @@ -0,0 +1,181 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_output_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_output_buffer +ia_css_output_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_output_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_output_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_output_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_map(ia_css_output_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map output buffer to CSS address space, acquire write access */ + b->state = buffer_write; + + return (ia_css_output_buffer_css_address)b->css_address; +} + + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_unmap(ia_css_output_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_write) + return 0; + + /* unmap output buffer from CSS address space, release write access */ + b->state = buffer_unmapped; + + return (ia_css_output_buffer_css_address)b->css_address; +} + + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map(vied_memory_t mid, ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map output buffer to CPU address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only in simulation */ + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + /* now invalidate the cache */ + ia_css_cpu_mem_cache_invalidate(b->cpu_address, b->size); + + return b->cpu_address; +} + + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map_no_invalidate(vied_memory_t mid, ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map output buffer to CPU address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only in simulation */ + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return b->cpu_address; +} + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_unmap(ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_read) + return NULL; + + /* unmap output buffer from CPU address space, release read access */ + b->state = buffer_unmapped; + + /* output only, no need to flush cache */ + + return b->cpu_address; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_shared_buffer.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_shared_buffer.c new file mode 100644 index 0000000000000..92b7110644fe3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/buffer/src/cpu/ia_css_shared_buffer.c @@ -0,0 +1,187 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_shared_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_shared_buffer +ia_css_shared_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_shared_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_shared_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_shared_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_map(ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map shared buffer to CPU address space */ + b->state = buffer_cpu; + + return b->cpu_address; +} + + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_unmap(ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_cpu) + return NULL; + + /* unmap shared buffer from CPU address space */ + b->state = buffer_unmapped; + + return b->cpu_address; +} + + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_map(ia_css_shared_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map shared buffer to CSS address space */ + b->state = buffer_css; + + return (ia_css_shared_buffer_css_address)b->css_address; +} + + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_unmap(ia_css_shared_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_css) + return 0; + + /* unmap shared buffer from CSS address space */ + b->state = buffer_unmapped; + + return (ia_css_shared_buffer_css_address)b->css_address; +} + + +ia_css_shared_buffer +ia_css_shared_buffer_css_update(vied_memory_t mid, ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + + /* flush the buffer to CSS after it was modified by the CPU */ + /* flush cache to ddr */ + ia_css_cpu_mem_cache_flush(b->cpu_address, b->size); +#ifndef HRT_HW + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return b; +} + + +ia_css_shared_buffer +ia_css_shared_buffer_cpu_update(vied_memory_t mid, ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + + /* flush the buffer to the CPU after it has been modified by CSS */ +#ifndef HRT_HW + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + /* flush cache to ddr */ + ia_css_cpu_mem_cache_invalidate(b->cpu_address, b->size); + + return b; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/cell/cell.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/cell/cell.mk new file mode 100644 index 0000000000000..fa5e650226017 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/cell/cell.mk @@ -0,0 +1,43 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +ifndef _CELL_MK_ +_CELL_MK_ = 1 + + +CELL_DIR=$${MODULES_DIR}/cell +CELL_INTERFACE=$(CELL_DIR)/interface +CELL_SOURCES=$(CELL_DIR)/src + +CELL_HOST_FILES = +CELL_FW_FILES = + +CELL_HOST_CPPFLAGS = \ + -I$(CELL_INTERFACE) \ + -I$(CELL_SOURCES) + +CELL_FW_CPPFLAGS = \ + -I$(CELL_INTERFACE) \ + -I$(CELL_SOURCES) + +ifdef 0 +# Disabled until it is decided to go this way or not +include $(MODULES_DIR)/device_access/device_access.mk +CELL_HOST_FILES += $(DEVICE_ACCESS_HOST_FILES) +CELL_FW_FILES += $(DEVICE_ACCESS_FW_FILES) +CELL_HOST_CPPFLAGS += $(DEVICE_ACCESS_HOST_CPPFLAGS) +CELL_FW_CPPFLAGS += $(DEVICE_ACCESS_FW_CPPFLAGS) +endif + +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/cell/interface/ia_css_cell.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/cell/interface/ia_css_cell.h new file mode 100644 index 0000000000000..3fac3c791b6e6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/cell/interface/ia_css_cell.h @@ -0,0 +1,112 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_H +#define __IA_CSS_CELL_H + +#include "storage_class.h" +#include "type_support.h" + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stat_ctrl(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_stat_ctrl(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_pc(unsigned int ssid, unsigned int cell_id, + unsigned int pc); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +#if 0 /* To be implemented after completing cell device properties */ +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_info_bits(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_debug_pc(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stall_bits(unsigned int ssid, unsigned int cell_id); +#endif + +/* configure master ports */ + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_base_address(unsigned int ssid, + unsigned int cell_id, + unsigned int master, unsigned int segment, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_bits(unsigned int ssid, unsigned int cell_id, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_bits(unsigned int ssid, + unsigned int cell_id, + unsigned int master, unsigned int segment, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_override_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_override_bits(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value); + +/* Access memories */ + +STORAGE_CLASS_INLINE void +ia_css_cell_mem_store_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr, unsigned int value); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_mem_load_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr); + +/***********************************************************************/ + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_is_ready(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_bit(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_run_bit(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_start(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_start_prefetch(unsigned int ssid, unsigned int cell_id, + bool prefetch); + +STORAGE_CLASS_INLINE void +ia_css_cell_wait(unsigned int ssid, unsigned int cell_id); + +/* include inline implementation */ +#include "ia_css_cell_impl.h" + +#endif /* __IA_CSS_CELL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/cell/src/ia_css_cell_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/cell/src/ia_css_cell_impl.h new file mode 100644 index 0000000000000..60b2e234da1a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/cell/src/ia_css_cell_impl.h @@ -0,0 +1,272 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_IMPL_H +#define __IA_CSS_CELL_IMPL_H + +#include "ia_css_cell.h" + +#include "ia_css_cmem.h" +#include "ipu_device_cell_properties.h" +#include "storage_class.h" +#include "assert_support.h" +#include "platform_support.h" +#include "misc_support.h" + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_regs_addr(unsigned int cell_id) +{ + /* mem_id 0 is for registers */ + return ipu_device_cell_memory_address(cell_id, 0); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_dmem_addr(unsigned int cell_id) +{ + /* mem_id 1 is for DMEM */ + return ipu_device_cell_memory_address(cell_id, 1); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_mem_store_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr, unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ipu_device_cell_memory_address( + cell_id, mem_id) + addr, value); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_mem_load_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr) +{ + return ia_css_cmem_load_32( + ssid, ipu_device_cell_memory_address(cell_id, mem_id) + addr); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stat_ctrl(unsigned int ssid, unsigned int cell_id) +{ + return ia_css_cmem_load_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_stat_ctrl(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS, value); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_is_ready(unsigned int ssid, unsigned int cell_id) +{ + unsigned int reg; + + reg = ia_css_cell_get_stat_ctrl(ssid, cell_id); + /* READY must be 1, START must be 0 */ + return (reg & (1 << IPU_DEVICE_CELL_STAT_CTRL_READY_BIT)) && + ((~reg) & (1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT)); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_pc(unsigned int ssid, unsigned int cell_id, + unsigned int pc) +{ + /* set start PC */ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_START_PC_REG_ADDRESS, pc); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_bit(unsigned int ssid, unsigned int cell_id) +{ + unsigned int reg; + + reg = 1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT; + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_run_bit(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + unsigned int reg; + + reg = value << IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT; + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_start(unsigned int ssid, unsigned int cell_id) +{ + ia_css_cell_start_prefetch(ssid, cell_id, 0); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_start_prefetch(unsigned int ssid, unsigned int cell_id, + bool prefetch) +{ + unsigned int reg = 0; + + /* Set run bit and start bit */ + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT); + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT); + /* Invalidate the icache */ + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_INVALIDATE_ICACHE_BIT); + /* Optionally enable prefetching */ + reg |= ((prefetch == 1) ? + (1 << IPU_DEVICE_CELL_STAT_CTRL_ICACHE_ENABLE_PREFETCH_BIT) : + 0); + + /* store into register */ + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_wait(unsigned int ssid, unsigned int cell_id) +{ + do { + ia_css_sleep(); + } while (!ia_css_cell_is_ready(ssid, cell_id)); +}; + +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_ICACHE_BASE_REG_ADDRESS, value); +} + +/* master port configuration */ + + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_override_bits(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_override_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_base_address(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) + +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_base_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_override_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_override_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_base_address(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments, segment_size; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_base_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + segment_size = ipu_device_cell_master_segment_size(cell, master); + + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + value += segment_size; + } +} + +#endif /* __IA_CSS_CELL_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/config/isys/subsystem_bxtB0.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/config/isys/subsystem_bxtB0.mk new file mode 100644 index 0000000000000..da142032349f1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/config/isys/subsystem_bxtB0.mk @@ -0,0 +1,60 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +############################################################################ +# This file is used to specify versions and properties of ISYS firmware +# components. Please note that these are subsystem specific. System specific +# properties should go to system_$IPU_SYSVER.mk. Also the device versions +# should be defined under "devices" or should be taken from the SDK. +############################################################################ + +############################################################################ +# FIRMWARE RELATED VARIABLES +############################################################################ + +# Activate loading params and storing stats DDR<->REGs with DMA +ISYS_USE_ISA_DMA = 1 +# Used in ISA module +ISYS_ISL_DPC_DPC_V2 = 0 + +# Specification for Isys server's fixed globals' locations +REGMEM_OFFSET = 0 # Starting from 0 +REGMEM_SIZE = 34 +REGMEM_WORD_BYTES = 4 +FW_LOAD_NO_OF_REQUEST_OFFSET = 136 # Taken from REGMEM_OFFSET + REGMEM_SIZE_BYTES +FW_LOAD_NO_OF_REQUEST_SIZE_BYTES = 4 + +# Workarounds: + +# This WA is not to pipeline store frame commands for SID processors that control a Str2Vec (ISA output) +WA_HSD1304553438 = 1 + +# Larger than specified frames that complete mid-line +WA_HSD1209062354 = 1 + +# WA to disable clock gating for the devices in the CSI receivers needed for using the mipi_pkt_gen device +WA_HSD1805168877 = 0 + +# Support IBUF soft-reset at stream start +SOFT_RESET_IBUF_STREAM_START_SUPPORT = 1 + +############################################################################ +# TESTING RELATED VARIABLES +############################################################################ + +# TODO: This define should be entirely removed. +# Used in mipi_capture +ISYS_DISABLE_VERIFY_RECEIVED_SOF_EOF = 0 + +ISYS_ACCESS_BLOCKER_VERSION = v1 diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/config/system_bxtB0.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/config/system_bxtB0.mk new file mode 100644 index 0000000000000..24d079b405167 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/config/system_bxtB0.mk @@ -0,0 +1,88 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +LOGICAL_FW_INPUT_SYSTEM = input_system_system +LOGICAL_FW_PROCESSING_SYSTEM = processing_system_system +LOGICAL_FW_IPU_SYSTEM = css_broxton_system +LOGICAL_FW_ISP_SYSTEM = isp2601_default_system +SP_CONTROL_CELL = sp2601_control +SP_PROXY_CELL = sp2601_proxy +SP_FP_CELL = sp2601_fp +ISP_CELL = isp2601 +# The non-capital define isp2601 is used in the sdk, in order to distinguish +# between different isp versions the ISP_CELL_IDENTIFIER define is added. +ISP_CELL_IDENTIFIER = ISP2601 +HAS_IPFD = 1 +HAS_S2M_IN_ISYS_ISL_NONSOC_PATH = 0 +HAS_S2V_IN_ISYS_ISL_NONSOC_PATH = 1 +# ISL-IS non-SoC path has ISA without PAF and DPC-Pext support for IPU4-B0 +HAS_ISA_IN_ISYS_ISL = 1 +HAS_PAF_IN_ISYS_ISL = 0 +HAS_DPC_PEXT_IN_ISYS_ISL = 0 +HAS_PMA_IF = 0 + +HAS_MIPIBE_IN_PSYS_ISL = 1 + +HAS_VPLESS_SUPPORT = 0 + +DLI_SYSTEM = hive_isp_css_2600_system +RESOURCE_MANAGER_VERSION = v1 +MEM_RESOURCE_VALIDATION_ERROR = 0 +OFS_SCALER_1_4K_TILEY_422_SUPPORT= 1 +PROGDESC_ACC_SYMBOLS_VERSION = v1 +DEVPROXY_INTERFACE_VERSION = v1 +FW_ABI_IPU_TYPES_VERSION = v1 + +HAS_ONLINE_MODE_SUPPORT_IN_ISYS_PSYS = 0 + +MMU_INTERFACE_VERSION = v1 +DEVICE_ACCESS_VERSION = v2 +PSYS_SERVER_VERSION = v2 +PSYS_SERVER_LOADER_VERSION = v1 +PSYS_HW_VERSION = BXT_B0_HW + +# Enable FW_DMA for loading firmware +PSYS_SERVER_ENABLE_FW_LOAD_DMA = 1 + +NCI_SPA_VERSION = v1 +MANIFEST_TOOL_VERSION = v2 +PSYS_CON_MGR_TOOL_VERSION = v1 +# TODO: Should be removed after performance issues OTF are solved +PSYS_PROC_MGR_VERSION = v1 +IPU_RESOURCES_VERSION = v1 + +HAS_ACC_CLUSTER_PAF_PAL = 0 +HAS_ACC_CLUSTER_PEXT_PAL = 0 +HAS_ACC_CLUSTER_GBL_PAL = 1 + +# TODO use version naming scheme "v#" to decouple +# IPU_SYSVER from version. +PARAMBINTOOL_ISA_INIT_VERSION = bxtB0 + +# Select EQC2EQ version +# Version 1: uniform address space, equal EQ addresses regardless of EQC device +# Version 2: multiple addresses per EQ, depending on location of EQC device +EQC2EQ_VERSION = v1 + +# Select DMA instance for fw_load +FW_LOAD_DMA_INSTANCE = NCI_DMA_FW + +HAS_DMA_FW = 1 + +HAS_SIS = 0 +HAS_IDS = 1 + +PSYS_SERVER_ENABLE_TPROXY = 1 +PSYS_SERVER_ENABLE_DEVPROXY = 1 +NCI_OFS_VERSION = v1 diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/device_access.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/device_access.mk new file mode 100644 index 0000000000000..1629d9af803b6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/device_access.mk @@ -0,0 +1,40 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# + +ifndef _DEVICE_ACCESS_MK_ +_DEVICE_ACCESS_MK_ = 1 + +# DEVICE_ACCESS_VERSION= +include $(MODULES_DIR)/config/system_$(IPU_SYSVER).mk + +DEVICE_ACCESS_DIR=$${MODULES_DIR}/device_access +DEVICE_ACCESS_INTERFACE=$(DEVICE_ACCESS_DIR)/interface +DEVICE_ACCESS_SOURCES=$(DEVICE_ACCESS_DIR)/src + +DEVICE_ACCESS_HOST_FILES = + +DEVICE_ACCESS_FW_FILES = + +DEVICE_ACCESS_HOST_CPPFLAGS = \ + -I$(DEVICE_ACCESS_INTERFACE) \ + -I$(DEVICE_ACCESS_SOURCES) + +DEVICE_ACCESS_FW_CPPFLAGS = \ + -I$(DEVICE_ACCESS_INTERFACE) \ + -I$(DEVICE_ACCESS_SOURCES) + +DEVICE_ACCESS_FW_CPPFLAGS += \ + -I$(DEVICE_ACCESS_SOURCES)/$(DEVICE_ACCESS_VERSION) +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/interface/ia_css_cmem.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/interface/ia_css_cmem.h new file mode 100644 index 0000000000000..3dc47c29fcab7 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/interface/ia_css_cmem.h @@ -0,0 +1,58 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CMEM_H +#define __IA_CSS_CMEM_H + +#include "type_support.h" +#include "storage_class.h" + +#ifdef __VIED_CELL +typedef unsigned int ia_css_cmem_address_t; +#else +#include +typedef vied_subsystem_address_t ia_css_cmem_address_t; +#endif + +STORAGE_CLASS_INLINE uint32_t +ia_css_cmem_load_32(unsigned int ssid, ia_css_cmem_address_t address); + +STORAGE_CLASS_INLINE void +ia_css_cmem_store_32(unsigned int ssid, ia_css_cmem_address_t address, + uint32_t value); + +STORAGE_CLASS_INLINE void +ia_css_cmem_load(unsigned int ssid, ia_css_cmem_address_t address, void *data, + unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_cmem_store(unsigned int ssid, ia_css_cmem_address_t address, + const void *data, unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_cmem_zero(unsigned int ssid, ia_css_cmem_address_t address, + unsigned int size); + +STORAGE_CLASS_INLINE ia_css_cmem_address_t +ia_css_cmem_get_cmem_addr_from_dmem(unsigned int base_addr, void *p); + +/* Include inline implementation */ + +#ifdef __VIED_CELL +#include "ia_css_cmem_cell.h" +#else +#include "ia_css_cmem_host.h" +#endif + +#endif /* __IA_CSS_CMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/interface/ia_css_xmem.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/interface/ia_css_xmem.h new file mode 100644 index 0000000000000..de2b94d8af541 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/interface/ia_css_xmem.h @@ -0,0 +1,65 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_H +#define __IA_CSS_XMEM_H + +#include "type_support.h" +#include "storage_class.h" + +#ifdef __VIED_CELL +typedef unsigned int ia_css_xmem_address_t; +#else +#include +typedef host_virtual_address_t ia_css_xmem_address_t; +#endif + +STORAGE_CLASS_INLINE uint8_t +ia_css_xmem_load_8(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE uint16_t +ia_css_xmem_load_16(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE uint32_t +ia_css_xmem_load_32(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE void +ia_css_xmem_load(unsigned int mmid, ia_css_xmem_address_t address, void *data, + unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_8(unsigned int mmid, ia_css_xmem_address_t address, + uint8_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_16(unsigned int mmid, ia_css_xmem_address_t address, + uint16_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_32(unsigned int mmid, ia_css_xmem_address_t address, + uint32_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store(unsigned int mmid, ia_css_xmem_address_t address, + const void *data, unsigned int bytes); + +/* Include inline implementation */ + +#ifdef __VIED_CELL +#include "ia_css_xmem_cell.h" +#else +#include "ia_css_xmem_host.h" +#endif + +#endif /* __IA_CSS_XMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/interface/ia_css_xmem_cmem.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/interface/ia_css_xmem_cmem.h new file mode 100644 index 0000000000000..57aab3323c739 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/interface/ia_css_xmem_cmem.h @@ -0,0 +1,35 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_CMEM_H +#define __IA_CSS_XMEM_CMEM_H + +#include "ia_css_cmem.h" +#include "ia_css_xmem.h" + +/* Copy data from xmem to cmem, e.g., from a program in DDR to a cell's DMEM */ +/* This may also be implemented using DMA */ + +STORAGE_CLASS_INLINE void +ia_css_xmem_to_cmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size); + +/* include inline implementation */ +#include "ia_css_xmem_cmem_impl.h" + +#endif /* __IA_CSS_XMEM_CMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/src/ia_css_cmem_host.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/src/ia_css_cmem_host.h new file mode 100644 index 0000000000000..22799e67214c1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/src/ia_css_cmem_host.h @@ -0,0 +1,121 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CMEM_HOST_H +#define __IA_CSS_CMEM_HOST_H + +/* This file is an inline implementation for the interface ia_css_cmem.h + * and should only be included there. */ + +#include "assert_support.h" +#include "misc_support.h" + +STORAGE_CLASS_INLINE uint32_t +ia_css_cmem_load_32(unsigned int ssid, ia_css_cmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + return vied_subsystem_load_32(ssid, address); +} + +STORAGE_CLASS_INLINE uint32_t +ia_css_cond_cmem_load_32(bool cond, unsigned int ssid, + ia_css_cmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + if (cond) + return vied_subsystem_load_32(ssid, address); + else + return 0; +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_store_32(unsigned int ssid, ia_css_cmem_address_t address, + uint32_t data) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + vied_subsystem_store_32(ssid, address, data); +} + +STORAGE_CLASS_INLINE void +ia_css_cond_cmem_store_32(bool cond, unsigned int ssid, + ia_css_cmem_address_t address, uint32_t data) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + if (cond) + vied_subsystem_store_32(ssid, address, data); +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_load(unsigned int ssid, ia_css_cmem_address_t address, void *data, + unsigned int size) +{ + uint32_t *data32 = (uint32_t *)data; + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + assert((long)data % 4 == 0); + + while (address != end) { + *data32 = ia_css_cmem_load_32(ssid, address); + address += 4; + data32 += 1; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_store(unsigned int ssid, ia_css_cmem_address_t address, + const void *data, unsigned int size) +{ + uint32_t *data32 = (uint32_t *)data; + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + assert((long)data % 4 == 0); + + while (address != end) { + ia_css_cmem_store_32(ssid, address, *data32); + address += 4; + data32 += 1; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_zero(unsigned int ssid, ia_css_cmem_address_t address, + unsigned int size) +{ + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + + while (address != end) { + ia_css_cmem_store_32(ssid, address, 0); + address += 4; + } +} + +STORAGE_CLASS_INLINE ia_css_cmem_address_t +ia_css_cmem_get_cmem_addr_from_dmem(unsigned int base_addr, void *p) +{ + NOT_USED(base_addr); + return (ia_css_cmem_address_t)(uintptr_t)p; +} + +#endif /* __IA_CSS_CMEM_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/src/ia_css_xmem_cmem_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/src/ia_css_xmem_cmem_impl.h new file mode 100644 index 0000000000000..adc178b75059a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/src/ia_css_xmem_cmem_impl.h @@ -0,0 +1,79 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_CMEM_IMPL_H +#define __IA_CSS_XMEM_CMEM_IMPL_H + +#include "ia_css_xmem_cmem.h" + +#include "ia_css_cmem.h" +#include "ia_css_xmem.h" + +/* Copy data from xmem to cmem, e.g., from a program in DDR to a cell's DMEM */ +/* This may also be implemented using DMA */ + +STORAGE_CLASS_INLINE void +ia_css_xmem_to_cmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size) +{ + /* copy from ddr to subsystem, e.g., cell dmem */ + ia_css_cmem_address_t end = dst + size; + + assert(size % 4 == 0); + assert((uintptr_t) dst % 4 == 0); + assert((uintptr_t) src % 4 == 0); + + while (dst != end) { + uint32_t data; + + data = ia_css_xmem_load_32(mmid, src); + ia_css_cmem_store_32(ssid, dst, data); + dst += 4; + src += 4; + } +} + +/* Copy data from cmem to xmem */ + +STORAGE_CLASS_INLINE void +ia_css_cmem_to_xmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_cmem_address_t src, + ia_css_xmem_address_t dst, + unsigned int size) +{ + /* copy from ddr to subsystem, e.g., cell dmem */ + ia_css_xmem_address_t end = dst + size; + + assert(size % 4 == 0); + assert((uintptr_t) dst % 4 == 0); + assert((uintptr_t) src % 4 == 0); + + while (dst != end) { + uint32_t data; + + data = ia_css_cmem_load_32(mmid, src); + ia_css_xmem_store_32(ssid, dst, data); + dst += 4; + src += 4; + } +} + + +#endif /* __IA_CSS_XMEM_CMEM_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/src/ia_css_xmem_host.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/src/ia_css_xmem_host.h new file mode 100644 index 0000000000000..d94991fc11143 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/device_access/src/ia_css_xmem_host.h @@ -0,0 +1,84 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_HOST_H +#define __IA_CSS_XMEM_HOST_H + +#include "ia_css_xmem.h" +#include +#include "assert_support.h" +#include + +STORAGE_CLASS_INLINE uint8_t +ia_css_xmem_load_8(unsigned int mmid, ia_css_xmem_address_t address) +{ + return shared_memory_load_8(mmid, address); +} + +STORAGE_CLASS_INLINE uint16_t +ia_css_xmem_load_16(unsigned int mmid, ia_css_xmem_address_t address) +{ + /* Address has to be half-word aligned */ + assert(0 == (uintptr_t) address % 2); + return shared_memory_load_16(mmid, address); +} + +STORAGE_CLASS_INLINE uint32_t +ia_css_xmem_load_32(unsigned int mmid, ia_css_xmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == (uintptr_t) address % 4); + return shared_memory_load_32(mmid, address); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_load(unsigned int mmid, ia_css_xmem_address_t address, void *data, + unsigned int size) +{ + shared_memory_load(mmid, address, data, size); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_8(unsigned int mmid, ia_css_xmem_address_t address, + uint8_t value) +{ + shared_memory_store_8(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_16(unsigned int mmid, ia_css_xmem_address_t address, + uint16_t value) +{ + /* Address has to be half-word aligned */ + assert(0 == (uintptr_t) address % 2); + shared_memory_store_16(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_32(unsigned int mmid, ia_css_xmem_address_t address, + uint32_t value) +{ + /* Address has to be word aligned */ + assert(0 == (uintptr_t) address % 4); + shared_memory_store_32(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store(unsigned int mmid, ia_css_xmem_address_t address, + const void *data, unsigned int bytes) +{ + shared_memory_store(mmid, address, data, bytes); +} + +#endif /* __IA_CSS_XMEM_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/bxtB0/ipu_device_buttress_properties_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/bxtB0/ipu_device_buttress_properties_struct.h new file mode 100644 index 0000000000000..5102f6e44d2f6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/bxtB0/ipu_device_buttress_properties_struct.h @@ -0,0 +1,68 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H +#define __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H + +/* Destination values for master port 0 and bitfield "request_dest" */ +enum cio_M0_btrs_dest { + DEST_IS_BUT_REGS = 0, + DEST_IS_DDR, + RESERVED, + DEST_IS_SUBSYSTEM, + N_BTRS_DEST +}; + +/* Bit-field positions for M0 info bits */ +enum ia_css_info_bits_m0_pos { + IA_CSS_INFO_BITS_M0_SNOOPABLE_POS = 0, + IA_CSS_INFO_BITS_M0_IMR_DESTINED_POS = 1, + IA_CSS_INFO_BITS_M0_REQUEST_DEST_POS = 4 +}; + +#define IA_CSS_INFO_BITS_M0_DDR \ + (DEST_IS_DDR << IA_CSS_INFO_BITS_M0_REQUEST_DEST_POS) +#define IA_CSS_INFO_BITS_M0_SNOOPABLE (1 << IA_CSS_INFO_BITS_M0_SNOOPABLE_POS) + +/* Info bits as expected by the buttress */ +/* Deprecated because bit fields are not portable */ + +/* For master port 0*/ +union cio_M0_t { + struct { + unsigned int snoopable : 1; + unsigned int imr_destined : 1; + unsigned int spare0 : 2; + unsigned int request_dest : 2; + unsigned int spare1 : 26; + } as_bitfield; + unsigned int as_word; +}; + +/* For master port 1*/ +union cio_M1_t { + struct { + unsigned int spare0 : 1; + unsigned int deadline_pointer : 1; + unsigned int reserved : 1; + unsigned int zlw : 1; + unsigned int stream_id : 4; + unsigned int address_swizzling : 1; + unsigned int spare1 : 23; + } as_bitfield; + unsigned int as_word; +}; + + +#endif /* __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_properties.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_properties.h new file mode 100644 index 0000000000000..e6e1e9dcbe80c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_properties.h @@ -0,0 +1,76 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_H +#define __IPU_DEVICE_CELL_PROPERTIES_H + +#include "storage_class.h" +#include "ipu_device_cell_type_properties.h" + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_devices(void); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_memories(const unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_size(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_address(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_databus_memory_address(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_masters(const unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_bits(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_num_segments(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_size(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_stride(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_base_reg(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_reg(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_icache_align(unsigned int cell_id); + +#ifdef C_RUN +STORAGE_CLASS_INLINE int +ipu_device_cell_id_crun(int cell_id); +#endif + +#include "ipu_device_cell_properties_func.h" + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_properties_func.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_properties_func.h new file mode 100644 index 0000000000000..481b0504a2378 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_properties_func.h @@ -0,0 +1,164 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_FUNC_H +#define __IPU_DEVICE_CELL_PROPERTIES_FUNC_H + +/* define properties for all cells uses in ISYS */ + +#include "ipu_device_cell_properties_impl.h" +#include "ipu_device_cell_devices.h" +#include "assert_support.h" +#include "storage_class.h" + +enum {IA_CSS_CELL_MASTER_ADDRESS_WIDTH = 32}; + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_devices(void) +{ + return NUM_CELLS; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_memories(const unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + num_memories; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_size(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + return ipu_device_cell_properties[cell_id].type_properties-> + mem_size[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_address(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + return ipu_device_cell_properties[cell_id].mem_address[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_databus_memory_address(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + assert(mem_id != 0); + return ipu_device_cell_properties[cell_id].mem_databus_address[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_masters(const unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + num_master_ports; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_bits(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].segment_bits; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_num_segments(const unsigned int cell_id, + const unsigned int master_id) +{ + return 1u << ipu_device_cell_master_segment_bits(cell_id, master_id); +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_size(const unsigned int cell_id, + const unsigned int master_id) +{ + return 1u << (IA_CSS_CELL_MASTER_ADDRESS_WIDTH - + ipu_device_cell_master_segment_bits(cell_id, master_id)); +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_stride(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].stride; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_base_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].base_address_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].info_bits_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_override_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].info_override_bits_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_icache_align(unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + icache_align; +} + +#ifdef C_RUN +STORAGE_CLASS_INLINE int +ipu_device_cell_id_crun(int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_map_cell_id_to_crun_proc_id[cell_id]; +} +#endif + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_FUNC_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_properties_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_properties_struct.h new file mode 100644 index 0000000000000..63397dc0b7fe6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_properties_struct.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H +#define __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H + +/* definitions for all cell types */ + +struct ipu_device_cell_count_s { + unsigned int num_memories; + unsigned int num_master_ports; + unsigned int num_stall_bits; + unsigned int icache_align; +}; + +struct ipu_device_cell_master_properties_s { + unsigned int segment_bits; + unsigned int stride; /* offset to register of next segment */ + unsigned int base_address_register; /* address of first base address + register */ + unsigned int info_bits_register; + unsigned int info_override_bits_register; +}; + +struct ipu_device_cell_type_properties_s { + const struct ipu_device_cell_count_s *count; + const struct ipu_device_cell_master_properties_s *master; + const unsigned int *reg_offset; /* offsets of registers, some depend + on cell type */ + const unsigned int *mem_size; +}; + +struct ipu_device_cell_properties_s { + const struct ipu_device_cell_type_properties_s *type_properties; + const unsigned int *mem_address; + const unsigned int *mem_databus_address; + /* const cell_master_port_properties_s* master_port_properties; */ +}; + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_type_properties.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_type_properties.h new file mode 100644 index 0000000000000..72caed3eef0c9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/interface/ipu_device_cell_type_properties.h @@ -0,0 +1,69 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_TYPE_PROPERTIES_H +#define __IPU_DEVICE_CELL_TYPE_PROPERTIES_H + +#define IPU_DEVICE_INVALID_MEM_ADDRESS 0xFFFFFFFF + +enum ipu_device_cell_stat_ctrl_bit { + IPU_DEVICE_CELL_STAT_CTRL_RESET_BIT = 0, + IPU_DEVICE_CELL_STAT_CTRL_START_BIT = 1, + IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT = 3, + IPU_DEVICE_CELL_STAT_CTRL_READY_BIT = 5, + IPU_DEVICE_CELL_STAT_CTRL_SLEEP_BIT = 6, + IPU_DEVICE_CELL_STAT_CTRL_STALL_BIT = 7, + IPU_DEVICE_CELL_STAT_CTRL_CLEAR_IRQ_MASK_FLAG_BIT = 8, + IPU_DEVICE_CELL_STAT_CTRL_BROKEN_IRQ_MASK_FLAG_BIT = 9, + IPU_DEVICE_CELL_STAT_CTRL_READY_IRQ_MASK_FLAG_BIT = 10, + IPU_DEVICE_CELL_STAT_CTRL_SLEEP_IRQ_MASK_FLAG_BIT = 11, + IPU_DEVICE_CELL_STAT_CTRL_INVALIDATE_ICACHE_BIT = 12, + IPU_DEVICE_CELL_STAT_CTRL_ICACHE_ENABLE_PREFETCH_BIT = 13 +}; + +enum ipu_device_cell_reg_addr { + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS = 0x0, + IPU_DEVICE_CELL_START_PC_REG_ADDRESS = 0x4, + IPU_DEVICE_CELL_ICACHE_BASE_REG_ADDRESS = 0x10, + IPU_DEVICE_CELL_ICACHE_INFO_BITS_REG_ADDRESS = 0x14 +}; + +enum ipu_device_cell_reg { + IPU_DEVICE_CELL_STAT_CTRL_REG, + IPU_DEVICE_CELL_START_PC_REG, + IPU_DEVICE_CELL_ICACHE_BASE_REG, + IPU_DEVICE_CELL_DEBUG_PC_REG, + IPU_DEVICE_CELL_STALL_REG, + IPU_DEVICE_CELL_NUM_REGS +}; + +enum ipu_device_cell_mem { + IPU_DEVICE_CELL_REGS, /* memory id of registers */ + IPU_DEVICE_CELL_PMEM, /* memory id of pmem */ + IPU_DEVICE_CELL_DMEM, /* memory id of dmem */ + IPU_DEVICE_CELL_BAMEM, /* memory id of bamem */ + IPU_DEVICE_CELL_VMEM /* memory id of vmem */ +}; +#define IPU_DEVICE_CELL_NUM_MEMORIES (IPU_DEVICE_CELL_VMEM + 1) + +enum ipu_device_cell_master { + IPU_DEVICE_CELL_MASTER_ICACHE, /* master port id of icache */ + IPU_DEVICE_CELL_MASTER_QMEM, + IPU_DEVICE_CELL_MASTER_CMEM, + IPU_DEVICE_CELL_MASTER_XMEM, + IPU_DEVICE_CELL_MASTER_XVMEM +}; +#define IPU_DEVICE_CELL_MASTER_NUM_MASTERS (IPU_DEVICE_CELL_MASTER_XVMEM + 1) + +#endif /* __IPU_DEVICE_CELL_TYPE_PROPERTIES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/isys/bxtB0/ipu_device_cell_devices.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/isys/bxtB0/ipu_device_cell_devices.h new file mode 100644 index 0000000000000..bd672104db3bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/isys/bxtB0/ipu_device_cell_devices.h @@ -0,0 +1,27 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_DEVICES_H +#define __IPU_DEVICE_CELL_DEVICES_H + +/* define cell instances in ISYS */ + +#define SPC0_CELL input_system_unis_logic_sp_control_tile_sp + +enum ipu_device_isys_cell_id { + SPC0, + NUM_CELLS +}; + +#endif /* __IPU_DEVICE_CELL_DEVICES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/isys/bxtB0/ipu_device_cell_properties_defs.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/isys/bxtB0/ipu_device_cell_properties_defs.h new file mode 100644 index 0000000000000..1b4df534a665a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/isys/bxtB0/ipu_device_cell_properties_defs.h @@ -0,0 +1,22 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +/* Generated file - please do not edit. */ + +#ifndef _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ +#define _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ +#define SPC0_REGS_CBUS_ADDRESS 0x0 +#define SPC0_DMEM_CBUS_ADDRESS 0x8000 +#define SPC0_DMEM_DBUS_ADDRESS 0x8000 +#define SPC0_DMEM_DMA_M0_ADDRESS 0x210000 +#endif /* _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/isys/bxtB0/ipu_device_cell_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/isys/bxtB0/ipu_device_cell_properties_impl.h new file mode 100644 index 0000000000000..5f8ab1ac928f3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/isys/bxtB0/ipu_device_cell_properties_impl.h @@ -0,0 +1,57 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_IMPL_H +#define __IPU_DEVICE_CELL_PROPERTIES_IMPL_H + +/* define properties for all cells uses in ISYS */ + +#include "ipu_device_sp2600_control_properties_impl.h" +#include "ipu_device_cell_properties_defs.h" +#include "ipu_device_cell_devices.h" +#include "ipu_device_cell_type_properties.h"/* IPU_DEVICE_INVALID_MEM_ADDRESS */ + +static const unsigned int +ipu_device_spc0_mem_address[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + SPC0_REGS_CBUS_ADDRESS, + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPC0_DMEM_CBUS_ADDRESS +}; + +static const unsigned int +ipu_device_spc0_databus_mem_address[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* regs not accessible from DBUS */ + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPC0_DMEM_DBUS_ADDRESS +}; + +static const struct +ipu_device_cell_properties_s ipu_device_cell_properties[NUM_CELLS] = { + { + &ipu_device_sp2600_control_properties, + ipu_device_spc0_mem_address, + ipu_device_spc0_databus_mem_address + } +}; + +#ifdef C_RUN + +/* Mapping between hrt_hive_processors enum and cell_id's used in FW */ +static const int ipu_device_map_cell_id_to_crun_proc_id[NUM_CELLS] = { + 0 /* SPC0 */ +}; + +#endif + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/src/ipu_device_sp2600_control_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/src/ipu_device_sp2600_control_properties_impl.h new file mode 100644 index 0000000000000..430295cd9d949 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/devices/src/ipu_device_sp2600_control_properties_impl.h @@ -0,0 +1,136 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H +#define __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H + +/* sp2600_control definition */ + +#include "ipu_device_cell_properties_struct.h" + +enum ipu_device_sp2600_control_registers { + /* control registers */ + IPU_DEVICE_SP2600_CONTROL_STAT_CTRL = 0x0, + IPU_DEVICE_SP2600_CONTROL_START_PC = 0x4, + + /* master port registers */ + IPU_DEVICE_SP2600_CONTROL_ICACHE_BASE = 0x10, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO = 0x14, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO_OVERRIDE = 0x18, + + IPU_DEVICE_SP2600_CONTROL_QMEM_BASE = 0x1C, + + IPU_DEVICE_SP2600_CONTROL_CMEM_BASE = 0x28, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO = 0x2C, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO_OVERRIDE = 0x30, + + IPU_DEVICE_SP2600_CONTROL_XMEM_BASE = 0x58, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO = 0x5C, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO_OVERRIDE = 0x60, + + /* debug registers */ + IPU_DEVICE_SP2600_CONTROL_DEBUG_PC = 0x9C, + IPU_DEVICE_SP2600_CONTROL_STALL = 0xA0 +}; + +enum ipu_device_sp2600_control_mems { + IPU_DEVICE_SP2600_CONTROL_REGS, + IPU_DEVICE_SP2600_CONTROL_PMEM, + IPU_DEVICE_SP2600_CONTROL_DMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES +}; + +static const unsigned int +ipu_device_sp2600_control_mem_size[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + 0x000AC, + 0x00000, + 0x10000 +}; + +enum ipu_device_sp2600_control_masters { + IPU_DEVICE_SP2600_CONTROL_ICACHE, + IPU_DEVICE_SP2600_CONTROL_QMEM, + IPU_DEVICE_SP2600_CONTROL_CMEM, + IPU_DEVICE_SP2600_CONTROL_XMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS +}; + +static const struct ipu_device_cell_master_properties_s +ipu_device_sp2600_control_masters[IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS] = { + { + 0, + 0xC, + IPU_DEVICE_SP2600_CONTROL_ICACHE_BASE, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO_OVERRIDE + }, + { + 0, + 0xC, + IPU_DEVICE_SP2600_CONTROL_QMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_CONTROL_CMEM_BASE, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO_OVERRIDE + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_CONTROL_XMEM_BASE, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO_OVERRIDE + } +}; + +enum ipu_device_sp2600_control_stall_bits { + IPU_DEVICE_SP2600_CONTROL_STALL_ICACHE, + IPU_DEVICE_SP2600_CONTROL_STALL_DMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_QMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_CMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_XMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_STALL_BITS +}; + +/* 32 bits per instruction */ +#define IPU_DEVICE_SP2600_CONTROL_ICACHE_WORD_SIZE 4 +/* 32 instructions per burst */ +#define IPU_DEVICE_SP2600_CONTROL_ICACHE_BURST_SIZE 32 + +static const struct ipu_device_cell_count_s ipu_device_sp2600_control_count = { + IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES, + IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS, + IPU_DEVICE_SP2600_CONTROL_NUM_STALL_BITS, + IPU_DEVICE_SP2600_CONTROL_ICACHE_WORD_SIZE * + IPU_DEVICE_SP2600_CONTROL_ICACHE_BURST_SIZE +}; + +static const unsigned int +ipu_device_sp2600_control_reg_offset[/* CELL_NUM_REGS */] = { + 0x0, 0x4, 0x10, 0x9C, 0xA0 +}; + +static const struct ipu_device_cell_type_properties_s +ipu_device_sp2600_control_properties = { + &ipu_device_sp2600_control_count, + ipu_device_sp2600_control_masters, + ipu_device_sp2600_control_reg_offset, + ipu_device_sp2600_control_mem_size +}; + +#endif /* __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/cpu/fw_abi_cpu_types.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/cpu/fw_abi_cpu_types.mk new file mode 100644 index 0000000000000..b1ffbf7ea21ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/cpu/fw_abi_cpu_types.mk @@ -0,0 +1,24 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +# MODULE is FW ABI COMMON TYPES + +FW_ABI_COMMON_TYPES_DIRS = -I$${MODULES_DIR}/fw_abi_common_types +FW_ABI_COMMON_TYPES_DIRS += -I$${MODULES_DIR}/fw_abi_common_types/cpu + +FW_ABI_COMMON_TYPES_HOST_FILES = +FW_ABI_COMMON_TYPES_HOST_CPPFLAGS = $(FW_ABI_COMMON_TYPES_DIRS) + +FW_ABI_COMMON_TYPES_FW_FILES = +FW_ABI_COMMON_TYPES_FW_CPPFLAGS = $(FW_ABI_COMMON_TYPES_DIRS) diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_base_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_base_types.h new file mode 100644 index 0000000000000..21cc3f43f485e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_base_types.h @@ -0,0 +1,42 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_BASE_TYPES_H +#define __IA_CSS_TERMINAL_BASE_TYPES_H + + +#include "type_support.h" +#include "ia_css_terminal_defs.h" + +#define N_UINT16_IN_TERMINAL_STRUCT 3 +#define N_PADDING_UINT8_IN_TERMINAL_STRUCT 5 + +#define SIZE_OF_TERMINAL_STRUCT_BITS \ + (IA_CSS_TERMINAL_TYPE_BITS \ + + IA_CSS_TERMINAL_ID_BITS \ + + N_UINT16_IN_TERMINAL_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_IN_TERMINAL_STRUCT * IA_CSS_UINT8_T_BITS) + +/* ==================== Base Terminal - START ==================== */ +struct ia_css_terminal_s { /**< Base terminal */ + ia_css_terminal_type_t terminal_type; /**< Type ia_css_terminal_type_t */ + int16_t parent_offset; /**< Offset to the process group */ + uint16_t size; /**< Size of this whole terminal layout-structure */ + uint16_t tm_index; /**< Index of the terminal manifest object */ + ia_css_terminal_ID_t ID; /**< Absolute referal ID for this terminal, valid ID's != 0 */ + uint8_t padding[N_PADDING_UINT8_IN_TERMINAL_STRUCT]; +}; +/* ==================== Base Terminal - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h new file mode 100644 index 0000000000000..056e1b6d5d4bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h @@ -0,0 +1,42 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H +#define __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H + +#include "ia_css_terminal_defs.h" + +#define N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT 5 +#define SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + (IA_CSS_UINT16_T_BITS \ + + IA_CSS_TERMINAL_ID_BITS \ + + IA_CSS_TERMINAL_TYPE_BITS \ + + IA_CSS_UINT32_T_BITS \ + + (N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT*IA_CSS_UINT8_T_BITS)) + +/* ==================== Base Terminal Manifest - START ==================== */ +struct ia_css_terminal_manifest_s { + ia_css_terminal_type_t terminal_type; /**< Type ia_css_terminal_type_t */ + int16_t parent_offset; /**< Offset to the program group manifest */ + uint16_t size; /**< Size of this whole terminal-manifest layout-structure */ + ia_css_terminal_ID_t ID; + uint8_t padding[N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT]; +}; + +typedef struct ia_css_terminal_manifest_s + ia_css_terminal_manifest_t; + +/* ==================== Base Terminal Manifest - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/ia_css_base_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/ia_css_base_types.h new file mode 100644 index 0000000000000..3b80a17a6ad38 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/ia_css_base_types.h @@ -0,0 +1,38 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BASE_TYPES_H +#define __IA_CSS_BASE_TYPES_H + +#include "type_support.h" + +#define VIED_VADDRESS_BITS 32 +typedef uint32_t vied_vaddress_t; + +#define DEVICE_DESCRIPTOR_ID_BITS 32 +typedef struct { + uint8_t device_id; + uint8_t instance_id; + uint8_t channel_id; + uint8_t section_id; +} device_descriptor_fields_t; + +typedef union { + device_descriptor_fields_t fields; + uint32_t data; +} device_descriptor_id_t; + +typedef uint16_t ia_css_process_id_t; + +#endif /* __IA_CSS_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/ia_css_terminal_defs.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/ia_css_terminal_defs.h new file mode 100644 index 0000000000000..dbf1cf93756ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/fw_abi_common_types/ia_css_terminal_defs.h @@ -0,0 +1,105 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_DEFS_H +#define __IA_CSS_TERMINAL_DEFS_H + + +#include "type_support.h" + +#define IA_CSS_TERMINAL_ID_BITS 8 +typedef uint8_t ia_css_terminal_ID_t; +#define IA_CSS_TERMINAL_INVALID_ID ((ia_css_terminal_ID_t)(-1)) + +/* + * Terminal Base Type + */ +typedef enum ia_css_terminal_type { + /**< Data input */ + IA_CSS_TERMINAL_TYPE_DATA_IN = 0, + /**< Data output */ + IA_CSS_TERMINAL_TYPE_DATA_OUT, + /**< Type 6 parameter input */ + IA_CSS_TERMINAL_TYPE_PARAM_STREAM, + /**< Type 1-5 parameter input */ + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN, + /**< Type 1-5 parameter output */ + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT, + /**< Represent the new type of terminal for the + * "spatial dependent parameters", when params go in + */ + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN, + /**< Represent the new type of terminal for the + * "spatial dependent parameters", when params go out + */ + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT, + /**< Represent the new type of terminal for the + * explicit slicing, when params go in + */ + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN, + /**< Represent the new type of terminal for the + * explicit slicing, when params go out + */ + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT, + /**< State (private data) input */ + IA_CSS_TERMINAL_TYPE_STATE_IN, + /**< State (private data) output */ + IA_CSS_TERMINAL_TYPE_STATE_OUT, + IA_CSS_TERMINAL_TYPE_PROGRAM, + IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT, + IA_CSS_N_TERMINAL_TYPES +} ia_css_terminal_type_t; + +#define IA_CSS_TERMINAL_TYPE_BITS 32 + +/* Temporary redirection needed to facilicate merging with the drivers + in a backwards compatible manner */ +#define IA_CSS_TERMINAL_TYPE_PARAM_CACHED IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN + +/* + * Dimensions of the data objects. Note that a C-style + * data order is assumed. Data stored by row. + */ +typedef enum ia_css_dimension { + /**< The number of columns, i.e. the size of the row */ + IA_CSS_COL_DIMENSION = 0, + /**< The number of rows, i.e. the size of the column */ + IA_CSS_ROW_DIMENSION = 1, + IA_CSS_N_DATA_DIMENSION = 2 +} ia_css_dimension_t; + +#define IA_CSS_N_COMMAND_COUNT (4) + +#ifndef PIPE_GENERATION +/* Don't include these complex enum structures in Genpipe, it can't handle and it does not need them */ +/* + * enum ia_css_isys_link_id. Lists the link IDs used by the FW for On The Fly feature + */ +typedef enum ia_css_isys_link_id { + IA_CSS_ISYS_LINK_OFFLINE = 0, + IA_CSS_ISYS_LINK_MAIN_OUTPUT = 1, + IA_CSS_ISYS_LINK_PDAF_OUTPUT = 2 +} ia_css_isys_link_id_t; +#define N_IA_CSS_ISYS_LINK_ID (IA_CSS_ISYS_LINK_PDAF_OUTPUT + 1) + +/* + * enum ia_css_data_barrier_link_id. Lists the link IDs used by the FW for data barrier feature + */ +typedef enum ia_css_data_barrier_link_id { + IA_CSS_DATA_BARRIER_LINK_MEMORY = N_IA_CSS_ISYS_LINK_ID, + N_IA_CSS_DATA_BARRIER_LINK_ID +} ia_css_data_barrier_link_id_t; + +#endif /* #ifndef PIPE_GENERATION */ +#endif /* __IA_CSS_TERMINAL_DEFS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isys_fw_bridged_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isys_fw_bridged_types.h new file mode 100644 index 0000000000000..3af5c22cccbab --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isys_fw_bridged_types.h @@ -0,0 +1,404 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYS_FW_BRIDGED_TYPES_H +#define __IA_CSS_ISYS_FW_BRIDGED_TYPES_H + +#include "platform_support.h" + +#include "ia_css_isysapi_fw_types.h" + +/** + * struct ia_css_isys_buffer_partition_comm - buffer partition information + * @num_gda_pages: Number of virtual gda pages available for each + * virtual stream + */ +struct ia_css_isys_buffer_partition_comm { + aligned_uint32(unsigned int, num_gda_pages[STREAM_ID_MAX]); +}; + +/** + * struct ia_css_isys_fw_config - contains the parts from + * ia_css_isys_device_cfg_data + * we need to transfer to the cell + * @num_send_queues: Number of send queues per queue + * type(N_IA_CSS_ISYS_QUEUE_TYPE) + * @num_recv_queues: Number of receive queues per queue + * type(N_IA_CSS_ISYS_QUEUE_TYPE) + */ +struct ia_css_isys_fw_config { + aligned_struct(struct ia_css_isys_buffer_partition_comm, + buffer_partition); + aligned_uint32(unsigned int, + num_send_queues[N_IA_CSS_ISYS_QUEUE_TYPE]); + aligned_uint32(unsigned int, + num_recv_queues[N_IA_CSS_ISYS_QUEUE_TYPE]); +}; + +/** + * struct ia_css_isys_resolution_comm: Generic resolution structure. + * @Width + * @Height + */ +struct ia_css_isys_resolution_comm { + aligned_uint32(unsigned int, width); + aligned_uint32(unsigned int, height); +}; + +/** + * struct ia_css_isys_output_pin_payload_comm + * @out_buf_id: Points to output pin buffer - buffer identifier + * @addr: Points to output pin buffer - CSS Virtual Address + * @compress: Request frame compression (1), or not (0) + * This must be the same as ia_css_isys_output_pin_info_comm::reserve_compression + */ +struct ia_css_isys_output_pin_payload_comm { + aligned_uint64(ia_css_return_token, out_buf_id); + aligned_uint32(ia_css_output_buffer_css_address, addr); + aligned_uint32(unsigned int, compress); +}; + +/** + * struct ia_css_isys_output_pin_info_comm + * @input_pin_id: input pin id/index which is source of + * the data for this output pin + * @output_res: output pin resolution + * @stride: output stride in Bytes (not valid for statistics) + * @watermark_in_lines: pin watermark level in lines + * @payload_buf_size: Size in Bytes of all buffers that will be supplied for capture + * on this pin (i.e. addressed by ia_css_isys_output_pin_payload::addr) + * @send_irq: assert if pin event should trigger irq + * @pt: pin type + * @ft: frame format type + * @link_id: identifies PPG to connect to, link_id = 0 implies offline + * while link_id > 0 implies buffer_chasing or online mode + * can be entered. + * @reserve_compression: Reserve compression resources for pin. + */ +struct ia_css_isys_output_pin_info_comm { + aligned_struct(struct ia_css_isys_resolution_comm, output_res); + aligned_uint32(unsigned int, stride); + aligned_uint32(unsigned int, watermark_in_lines); + aligned_uint32(unsigned int, payload_buf_size); + aligned_uint8(unsigned int, send_irq); + aligned_uint8(unsigned int, input_pin_id); + aligned_uint8(enum ia_css_isys_pin_type, pt); + aligned_uint8(enum ia_css_isys_frame_format_type, ft); + aligned_uint8(enum ia_css_isys_link_id, link_id); + aligned_uint8(unsigned int, reserve_compression); +}; + +/** + * struct ia_css_isys_param_pin_comm + * @param_buf_id: Points to param port buffer - buffer identifier + * @addr: Points to param pin buffer - CSS Virtual Address + */ +struct ia_css_isys_param_pin_comm { + aligned_uint64(ia_css_return_token, param_buf_id); + aligned_uint32(ia_css_input_buffer_css_address, addr); +}; + +/** + * struct ia_css_isys_input_pin_info_comm + * @input_res: input resolution + * @dt: mipi data type + * @mipi_store_mode: defines if legacy long packet header will be stored or + * hdiscarded if discarded, output pin pin type for this + * input pin can only be MIPI + * @bits_per_pix: native bits per pixel + * @dt_rename: mapped_dt + */ +struct ia_css_isys_input_pin_info_comm { + aligned_struct(struct ia_css_isys_resolution_comm, input_res); + aligned_uint8(enum ia_css_isys_mipi_data_type, dt); + aligned_uint8(enum ia_css_isys_mipi_store_mode, mipi_store_mode); + aligned_uint8(unsigned int, bits_per_pix); + aligned_uint8(unsigned int, mapped_dt); +}; + +/** + * ISA configuration fields, definition and macros + */ +#define ISA_CFG_FIELD_BLC_EN_LEN 1 +#define ISA_CFG_FIELD_BLC_EN_SHIFT 0 + +#define ISA_CFG_FIELD_LSC_EN_LEN 1 +#define ISA_CFG_FIELD_LSC_EN_SHIFT 1 + +#define ISA_CFG_FIELD_DPC_EN_LEN 1 +#define ISA_CFG_FIELD_DPC_EN_SHIFT 2 + +#define ISA_CFG_FIELD_DOWNSCALER_EN_LEN 1 +#define ISA_CFG_FIELD_DOWNSCALER_EN_SHIFT 3 + +#define ISA_CFG_FIELD_AWB_EN_LEN 1 +#define ISA_CFG_FIELD_AWB_EN_SHIFT 4 + +#define ISA_CFG_FIELD_AF_EN_LEN 1 +#define ISA_CFG_FIELD_AF_EN_SHIFT 5 + +#define ISA_CFG_FIELD_AE_EN_LEN 1 +#define ISA_CFG_FIELD_AE_EN_SHIFT 6 + +#define ISA_CFG_FIELD_PAF_TYPE_LEN 8 +#define ISA_CFG_FIELD_PAF_TYPE_SHIFT 7 + +#define ISA_CFG_FIELD_SEND_IRQ_STATS_READY_LEN 1 +#define ISA_CFG_FIELD_SEND_IRQ_STATS_READY_SHIFT 15 + +#define ISA_CFG_FIELD_SEND_RESP_STATS_READY_LEN 1 +#define ISA_CFG_FIELD_SEND_RESP_STATS_READY_SHIFT 16 + +/* Helper macros */ +#define ISA_CFG_GET_MASK_FROM_LEN(len) ((1 << (len)) - 1) +#define ISA_CFG_GET_MASK_FROM_TAG(tag) \ + (ISA_CFG_GET_MASK_FROM_LEN(ISA_CFG_FIELD_##tag##_LEN)) +#define ISA_CFG_GET_SHIFT_FROM_TAG(tag) \ + (ISA_CFG_FIELD_##tag##_SHIFT) +/* Get/Set macros */ +#define ISA_CFG_FIELD_GET(tag, word) \ + ( \ + ((word) >> (ISA_CFG_GET_SHIFT_FROM_TAG(tag))) &\ + ISA_CFG_GET_MASK_FROM_TAG(tag) \ + ) +#define ISA_CFG_FIELD_SET(tag, word, value) \ + ( \ + word |= ( \ + ((value) & ISA_CFG_GET_MASK_FROM_TAG(tag)) << \ + ISA_CFG_GET_SHIFT_FROM_TAG(tag) \ + ) \ + ) + +/** + * struct ia_css_isys_isa_cfg_comm. Describes the ISA cfg + */ +struct ia_css_isys_isa_cfg_comm { + aligned_struct(struct ia_css_isys_resolution_comm, + isa_res[N_IA_CSS_ISYS_RESOLUTION_INFO]); + aligned_uint32(/* multi-field packing */, cfg_fields); +}; + + /** + * struct ia_css_isys_cropping_comm - cropping coordinates + */ +struct ia_css_isys_cropping_comm { + aligned_int32(int, top_offset); + aligned_int32(int, left_offset); + aligned_int32(int, bottom_offset); + aligned_int32(int, right_offset); +}; + + /** + * struct ia_css_isys_stream_cfg_data_comm + * ISYS stream configuration data structure + * @isa_cfg: details about what ACCs are active if ISA is used + * @crop: defines cropping resolution for the + * maximum number of input pins which can be cropped, + * it is directly mapped to the HW devices + * @input_pins: input pin descriptors + * @output_pins: output pin descriptors + * @compfmt: de-compression setting for User Defined Data + * @nof_input_pins: number of input pins + * @nof_output_pins: number of output pins + * @send_irq_sof_discarded: send irq on discarded frame sof response + * - if '1' it will override the send_resp_sof_discarded and send + * the response + * - if '0' the send_resp_sof_discarded will determine whether to + * send the response + * @send_irq_eof_discarded: send irq on discarded frame eof response + * - if '1' it will override the send_resp_eof_discarded and send + * the response + * - if '0' the send_resp_eof_discarded will determine whether to + * send the response + * @send_resp_sof_discarded: send response for discarded frame sof detected, + * used only when send_irq_sof_discarded is '0' + * @send_resp_eof_discarded: send response for discarded frame eof detected, + * used only when send_irq_eof_discarded is '0' + * @src: Stream source index e.g. MIPI_generator_0, CSI2-rx_1 + * @vc: MIPI Virtual Channel (up to 4 virtual per physical channel) + * @isl_use: indicates whether stream requires ISL and how + */ +struct ia_css_isys_stream_cfg_data_comm { + aligned_struct(struct ia_css_isys_isa_cfg_comm, isa_cfg); + aligned_struct(struct ia_css_isys_cropping_comm, + crop[N_IA_CSS_ISYS_CROPPING_LOCATION]); + aligned_struct(struct ia_css_isys_input_pin_info_comm, + input_pins[MAX_IPINS]); + aligned_struct(struct ia_css_isys_output_pin_info_comm, + output_pins[MAX_OPINS]); + aligned_uint32(unsigned int, compfmt); + aligned_uint8(unsigned int, nof_input_pins); + aligned_uint8(unsigned int, nof_output_pins); + aligned_uint8(unsigned int, send_irq_sof_discarded); + aligned_uint8(unsigned int, send_irq_eof_discarded); + aligned_uint8(unsigned int, send_resp_sof_discarded); + aligned_uint8(unsigned int, send_resp_eof_discarded); + aligned_uint8(enum ia_css_isys_stream_source, src); + aligned_uint8(enum ia_css_isys_mipi_vc, vc); + aligned_uint8(enum ia_css_isys_isl_use, isl_use); +}; + +/** + * struct ia_css_isys_frame_buff_set - frame buffer set + * @output_pins: output pin addresses + * @process_group_light: process_group_light buffer address + * @send_irq_sof: send irq on frame sof response + * - if '1' it will override the send_resp_sof and send the + * response + * - if '0' the send_resp_sof will determine whether to send the + * response + * @send_irq_eof: send irq on frame eof response + * - if '1' it will override the send_resp_eof and send the + * response + * - if '0' the send_resp_eof will determine whether to send the + * response + * @send_resp_sof: send response for frame sof detected, used only when + * send_irq_sof is '0' + * @send_resp_eof: send response for frame eof detected, used only when + * send_irq_eof is '0' + * @frame_counter: frame number associated with this buffer set. + */ +struct ia_css_isys_frame_buff_set_comm { + aligned_struct(struct ia_css_isys_output_pin_payload_comm, + output_pins[MAX_OPINS]); + aligned_struct(struct ia_css_isys_param_pin_comm, process_group_light); + aligned_uint8(unsigned int, send_irq_sof); + aligned_uint8(unsigned int, send_irq_eof); + aligned_uint8(unsigned int, send_irq_capture_ack); + aligned_uint8(unsigned int, send_irq_capture_done); + aligned_uint8(unsigned int, send_resp_sof); + aligned_uint8(unsigned int, send_resp_eof); + aligned_uint8(unsigned int, frame_counter); +}; + +/** + * struct ia_css_isys_error_info_comm + * @error: error code if something went wrong + * @error_details: depending on error code, it may contain additional + * error info + */ +struct ia_css_isys_error_info_comm { + aligned_enum(enum ia_css_isys_error, error); + aligned_uint32(unsigned int, error_details); +}; + +/** + * struct ia_css_isys_resp_info_comm + * @pin: this var is only valid for pin event related responses, + * contains pin addresses + * @process_group_light: this var is valid for stats ready related responses, + * contains process group addresses + * @error_info: error information from the FW + * @timestamp: Time information for event if available + * @stream_handle: stream id the response corresponds to + * @type: response type + * @pin_id: pin id that the pin payload corresponds to + * @acc_id: this var is valid for stats ready related responses, + * contains accelerator id that finished producing + * all related statistics + * @frame_counter: valid for STREAM_START_AND_CAPTURE_DONE, + * STREAM_CAPTURE_DONE and STREAM_CAPTURE_DISCARDED, + * @written_direct: indicates if frame was written direct (online mode) or not. + * + */ + +struct ia_css_isys_resp_info_comm { + aligned_uint64(ia_css_return_token, buf_id); /* Used internally only */ + aligned_struct(struct ia_css_isys_output_pin_payload_comm, pin); + aligned_struct(struct ia_css_isys_param_pin_comm, process_group_light); + aligned_struct(struct ia_css_isys_error_info_comm, error_info); + aligned_uint32(unsigned int, timestamp[2]); + aligned_uint8(unsigned int, stream_handle); + aligned_uint8(enum ia_css_isys_resp_type, type); + aligned_uint8(unsigned int, pin_id); + aligned_uint8(unsigned int, acc_id); + aligned_uint8(unsigned int, frame_counter); + aligned_uint8(unsigned int, written_direct); +}; + +/** + * struct ia_css_isys_proxy_error_info_comm + * @proxy_error: error code if something went wrong + * @proxy_error_details: depending on error code, it may contain additional + * error info + */ +struct ia_css_isys_proxy_error_info_comm { + aligned_enum(enum ia_css_proxy_error, error); + aligned_uint32(unsigned int, error_details); +}; + +/** + * struct ia_css_isys_proxy_resp_info_comm + * @request_id: Unique identifier for the write request + * (in case multiple write requests are issued for same register) + * @error_info: details in struct definition + */ +struct ia_css_isys_proxy_resp_info_comm { + aligned_uint32(uint32_t, request_id); + aligned_struct(struct ia_css_isys_proxy_error_info_comm, error_info); +}; + +/** + * struct ia_css_proxy_write_queue_token + * @request_id: update id for the specific proxy write request + * @region_index: Region id for the proxy write request + * @offset: Offset of the write request according to the base address of the + * region + * @value: Value that is requested to be written with the proxy write request + */ +struct ia_css_proxy_write_queue_token { + aligned_uint32(uint32_t, request_id); + aligned_uint32(uint32_t, region_index); + aligned_uint32(uint32_t, offset); + aligned_uint32(uint32_t, value); +}; + +/* From here on type defines not coming from the ISYSAPI interface */ + +/** + * struct resp_queue_token + */ +struct resp_queue_token { + aligned_struct(struct ia_css_isys_resp_info_comm, resp_info); +}; + +/** + * struct send_queue_token + */ +struct send_queue_token { + aligned_uint64(ia_css_return_token, buf_handle); + aligned_uint32(ia_css_input_buffer_css_address, payload); + aligned_uint16(enum ia_css_isys_send_type, send_type); + aligned_uint16(unsigned int, stream_id); +}; + +/** + * struct proxy_resp_queue_token + */ +struct proxy_resp_queue_token { + aligned_struct(struct ia_css_isys_proxy_resp_info_comm, + proxy_resp_info); +}; + +/** + * struct proxy_send_queue_token + */ +struct proxy_send_queue_token { + aligned_uint32(uint32_t, request_id); + aligned_uint32(uint32_t, region_index); + aligned_uint32(uint32_t, offset); + aligned_uint32(uint32_t, value); +}; + +#endif /* __IA_CSS_ISYS_FW_BRIDGED_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi.h new file mode 100644 index 0000000000000..514cbcda69099 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi.h @@ -0,0 +1,321 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_H +#define __IA_CSS_ISYSAPI_H + + +/* The following is needed for the function arguments */ +#include "ia_css_isysapi_types.h" + +/* To define the HANDLE */ +#include "type_support.h" + + +/** + * ia_css_isys_device_open() - configure ISYS device + * @ context : device handle output parameter + * @config: device configuration data struct ptr as input parameter, + * read only by css fw until function return + * Ownership, ISYS will only access read my_device during fct call + * Prepares and Sends to PG server (SP) the syscom and isys context + * Executes the host level 0 and 1 boot sequence and starts the PG server (SP) + * All streams must be stopped when calling ia_css_isys_device_open() + * + * Return: int type error code (errno.h) + */ +#if HAS_DUAL_CMD_CTX_SUPPORT +extern int ia_css_isys_context_create( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config +); +extern int ia_css_isys_context_store_dmem( + const HANDLE *context, + const struct ia_css_isys_device_cfg_data *config +); +extern bool ia_css_isys_ab_spc_ready( + HANDLE *context +); +extern int ia_css_isys_device_open( + const struct ia_css_isys_device_cfg_data *config +); +#else +extern int ia_css_isys_device_open( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config +); +#endif + +/** + * ia_css_isys_device_open_ready() - Complete ISYS device configuration + * @ context : device handle output parameter + * read only by css fw until function return + * Requires the boot failure to be completed before it can return + * successfully (includes syscom and isys context) + * Initialise Host/ISYS messaging queues + * Must be called multiple times until it succeeds or it is determined by + * the driver that the boot seuqence has failed. + * All streams must be stopped when calling ia_css_isys_device_open() + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_device_open_ready( + HANDLE context +); + + /** + * ia_css_isys_stream_open() - open and configure a virtual stream + * @ stream_handle: stream handle + * @ stream_cfg: stream configuration data struct pointer, which is + * "read only" by ISYS until function return + * ownership, ISYS will only read access stream_cfg during fct call + * Pre-conditions: + * Any Isys/Ssys interface changes must call ia_css_isys_stream_open() + * Post-condition: + * On successful call, ISYS hardware resource (IBFctrl, ISL, DMAs) + * are acquired and ISYS server is able to handle stream specific commands + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_open( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_stream_cfg_data *stream_cfg +); + +/** + * ia_css_isys_stream_close() - close virtual stream + * @ stream_handle: stream identifier + * release ISYS resources by freeing up stream HW resources + * output pin buffers ownership is returned to the driver + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_close( + HANDLE context, + const unsigned int stream_handle +); + +/** + * ia_css_isys_stream_start() - starts handling a mipi virtual stream + * @ stream_handle: stream identifier + * @next_frame: + * if next_frame != NULL: apply next_frame + * settings asynchronously and start stream + * This mode ensures that the first frame is captured + * and thus a minimal start up latency + * (preconditions: sensor streaming must be switched off) + * + * if next_frame == NULL: sensor can be in a streaming state, + * all capture indicates commands will be + * processed synchronously (e.g. on mipi SOF events) + * + * To be called once ia_css_isys_stream_open() successly called + * On success, the stream's HW resources are in active state + * + * Object ownership: During this function call, + * next_frame struct must be read but not modified by the ISYS, + * and in addition the driver is not allowed to modify it + * on function exit next_frame ownership is returned to + * the driver and is no longer accesses by iSYS + * next_frame contains a collection of + * ia_css_isys_output_pin * and ia_css_isys_input_pin * + * which point to the frame's "output/input pin info & data buffers", + * + * Upon the ia_css_isys_stream_start() call, + * ia_css_isys_output_pin* or ia_css_isys_input_pin* + * will now be owned by the ISYS + * these ptr will enable runtime/dynamic ISYS configuration and also + * to store and write captured payload data + * at the address specified in ia_css_isys_output_pin_payload + * These ptrs should no longer be accessed by any other + * code until (ia_css_isys_output_pin) gets handed + * back to the driver via the response mechansim + * ia_css_isys_stream_handle_response() + * the driver is responsible for providing valid + * ia_css_isys_output_pin* or ia_css_isys_output_pin* + * Pointers set to NULL will simply not be used by the ISYS + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_start( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_frame_buff_set *next_frame +); + +/** + * ia_css_isys_stream_stop() - Stops a mipi virtual stream + * @ stream_handle: stream identifier + * stop both accepting new commands and processing + * submitted capture indication commands + * Support for Secure Touch + * Precondition: stream must be started + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_stop( + HANDLE context, + const unsigned int stream_handle +); + +/** + * ia_css_isys_stream_flush() - stops a mipi virtual stream but + * completes processing cmd backlog + * @ stream_handle: stream identifier + * stop accepting commands, but process + * the already submitted capture indicates + * Precondition: stream must be started + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_flush( + HANDLE context, + const unsigned int stream_handle +); + +/** + * ia_css_isys_stream_capture_indication() + * captures "next frame" on stream_handle + * @ stream_handle: stream identifier + * @ next_frame: frame pin payloads are provided atomically + * purpose: stream capture new frame command, Successfull calls will + * result in frame output pins being captured + * + * To be called once ia_css_isys_stream_start() is successly called + * On success, the stream's HW resources are in active state + * + * Object ownership: During this function call, + * next_frame struct must be read but not modified by the ISYS, + * and in addition the driver is not allowed to modify it + * on function exit next_frame ownership is returned to + * the driver and is no longer accesses by iSYS + * next_frame contains a collection of + * ia_css_isys_output_pin * and ia_css_isys_input_pin * + * which point to the frame's "output/input pin info & data buffers", + * + * Upon the ia_css_isys_stream_capture_indication() call, + * ia_css_isys_output_pin* or ia_css_isys_input_pin* + * will now be owned by the ISYS + * these ptr will enable runtime/dynamic ISYS configuration and also + * to store and write captured payload data + * at the address specified in ia_css_isys_output_pin_payload + * These ptrs should no longer be accessed by any other + * code until (ia_css_isys_output_pin) gets handed + * back to the driver via the response mechanism + * ia_css_isys_stream_handle_response() + * the driver is responsible for providing valid + * ia_css_isys_output_pin* or ia_css_isys_output_pin* + * Pointers set to NULL will simply not be used by the ISYS, and this + * refers specifically the following cases: + * - output pins from SOC path if the same datatype is also passed into ISAPF + * path or it has active MIPI output (not NULL) + * - full resolution pin from ISA (but not when bypassing ISA) + * - scaled pin from ISA (bypassing ISA for scaled pin is impossible) + * - output pins from MIPI path but only when the same datatype is also + * either forwarded to the ISAPF path based on the stream configuration + * (it is ok if the second output pin of this datatype is also skipped) + * or it has an active SOC output (not NULL) + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_capture_indication( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_frame_buff_set *next_frame +); + +/** + * ia_css_isys_stream_handle_response() - handle ISYS responses + * @received_response: provides response info from the + * "next response element" from ISYS server + * received_response will be written to during the fct call and + * can be read by the drv once fct is returned + * + * purpose: Allows the client to handle received ISYS responses + * Upon an IRQ event, the driver will call ia_css_isys_stream_handle_response() + * until the queue is emptied + * Responses returning IA_CSS_ISYS_RESP_TYPE_PIN_DATA_READY to the driver will + * hand back ia_css_isys_output_pin ownership to the drv + * ISYS FW will not write/read access ia_css_isys_output_pin + * once it belongs to the driver + * Pre-conditions: ISYS client must have sent a CMDs to ISYS srv + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_handle_response( + HANDLE context, + struct ia_css_isys_resp_info *received_response +); + +/** + * ia_css_isys_device_close() - close ISYS device + * @context : device handle output parameter + * Purpose: Request for the cell to close + * All streams must be stopped when calling ia_css_isys_device_close() + * + * Return: int type error code (errno.h) + */ +#if HAS_DUAL_CMD_CTX_SUPPORT +extern int ia_css_isys_context_destroy( + HANDLE context +); +extern void ia_css_isys_device_close( + void +); +#else +extern int ia_css_isys_device_close( + HANDLE context +); +#endif + +/** + * ia_css_isys_device_release() - release ISYS device + * @context : device handle output parameter + * @force: forces release or verifies the state before releasing + * Purpose: Free context forcibly or not + * Must be called after ia_css_isys_device_close() + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_device_release( + HANDLE context, + unsigned int force +); + +/** + * ia_css_isys_proxy_write_req() - issue a isys proxy write request + * @context : device handle output parameter + * Purpose: Issues a write request for the regions that are exposed + * by proxy interface + * Can be called any time between ia_css_isys_device_open + * ia_css_isys_device_close + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_proxy_write_req( + HANDLE context, + const struct ia_css_proxy_write_req_val *write_req_val +); + +/** + * ia_css_isys_proxy_handle_write_response() + * - Handles isys proxy write request responses + * @context : device handle output parameter + * Purpose: Handling the responses that are created by FW upon the completion + * proxy interface write request + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_proxy_handle_write_response( + HANDLE context, + struct ia_css_proxy_write_req_resp *received_response +); + +#endif /* __IA_CSS_ISYSAPI_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_fw_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_fw_types.h new file mode 100644 index 0000000000000..938f726d1cfb8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_fw_types.h @@ -0,0 +1,512 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_FW_TYPES_H +#define __IA_CSS_ISYSAPI_FW_TYPES_H + + +/* Max number of Input/Output Pins */ +#define MAX_IPINS (4) +/* worst case is ISA use where a single input pin produces: +* Mipi output, NS Pixel Output, and Scaled Pixel Output. +* This is how the 2 is calculated +*/ +#define MAX_OPINS ((MAX_IPINS) + 2) + +/* Max number of supported virtual streams */ +#define STREAM_ID_MAX (8) + +/* Aligned with the approach of having one dedicated per stream */ +#define N_MAX_MSG_SEND_QUEUES (STREAM_ID_MAX) +/* Single return queue for all streams/commands type */ +#define N_MAX_MSG_RECV_QUEUES (1) +/* Single device queue for high priority commands (bypass in-order queue) */ +#define N_MAX_DEV_SEND_QUEUES (1) +/* Single dedicated send queue for proxy interface */ +#define N_MAX_PROXY_SEND_QUEUES (1) +/* Single dedicated recv queue for proxy interface */ +#define N_MAX_PROXY_RECV_QUEUES (1) +/* Send queues layout */ +#define BASE_PROXY_SEND_QUEUES (0) +#define BASE_DEV_SEND_QUEUES (BASE_PROXY_SEND_QUEUES + N_MAX_PROXY_SEND_QUEUES) +#define BASE_MSG_SEND_QUEUES (BASE_DEV_SEND_QUEUES + N_MAX_DEV_SEND_QUEUES) +#define N_MAX_SEND_QUEUES (BASE_MSG_SEND_QUEUES + N_MAX_MSG_SEND_QUEUES) +/* Recv queues layout */ +#define BASE_PROXY_RECV_QUEUES (0) +#define BASE_MSG_RECV_QUEUES (BASE_PROXY_RECV_QUEUES + N_MAX_PROXY_RECV_QUEUES) +#define N_MAX_RECV_QUEUES (BASE_MSG_RECV_QUEUES + N_MAX_MSG_RECV_QUEUES) + +#define MAX_QUEUE_SIZE (256) +#define MIN_QUEUE_SIZE (1) + +/* Consider 1 slot per stream since driver is not expected to pipeline + * device commands for the same stream */ +#define DEV_SEND_QUEUE_SIZE (STREAM_ID_MAX) + +/* Max number of supported SRAM buffer partitions */ +/* It refers to the size of stream partitions */ +/* These partitions are further subpartitioned internally */ +/* by the FW, but by declaring statically the stream */ +/* partitions we solve the buffer fragmentation issue */ +#define NOF_SRAM_BLOCKS_MAX (STREAM_ID_MAX) + +/* Max number of supported input pins routed in ISL */ +#define MAX_IPINS_IN_ISL (2) + +/* Max number of planes for frame formats supported by the FW */ +#define PIN_PLANES_MAX (4) + +/** + * enum ia_css_isys_resp_type + */ +enum ia_css_isys_resp_type { + IA_CSS_ISYS_RESP_TYPE_STREAM_OPEN_DONE = 0, + IA_CSS_ISYS_RESP_TYPE_STREAM_START_ACK, + IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK, + IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK, + IA_CSS_ISYS_RESP_TYPE_STREAM_STOP_ACK, + IA_CSS_ISYS_RESP_TYPE_STREAM_FLUSH_ACK, + IA_CSS_ISYS_RESP_TYPE_STREAM_CLOSE_ACK, + IA_CSS_ISYS_RESP_TYPE_PIN_DATA_READY, + IA_CSS_ISYS_RESP_TYPE_PIN_DATA_WATERMARK, + IA_CSS_ISYS_RESP_TYPE_FRAME_SOF, + IA_CSS_ISYS_RESP_TYPE_FRAME_EOF, + IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE, + IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_DONE, + IA_CSS_ISYS_RESP_TYPE_PIN_DATA_SKIPPED, + IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_SKIPPED, + IA_CSS_ISYS_RESP_TYPE_FRAME_SOF_DISCARDED, + IA_CSS_ISYS_RESP_TYPE_FRAME_EOF_DISCARDED, + IA_CSS_ISYS_RESP_TYPE_STATS_DATA_READY, + N_IA_CSS_ISYS_RESP_TYPE +}; + +/** + * enum ia_css_isys_send_type + */ +enum ia_css_isys_send_type { + IA_CSS_ISYS_SEND_TYPE_STREAM_OPEN = 0, + IA_CSS_ISYS_SEND_TYPE_STREAM_START, + IA_CSS_ISYS_SEND_TYPE_STREAM_START_AND_CAPTURE, + IA_CSS_ISYS_SEND_TYPE_STREAM_CAPTURE, + IA_CSS_ISYS_SEND_TYPE_STREAM_STOP, + IA_CSS_ISYS_SEND_TYPE_STREAM_FLUSH, + IA_CSS_ISYS_SEND_TYPE_STREAM_CLOSE, + N_IA_CSS_ISYS_SEND_TYPE +}; + +/** + * enum ia_css_isys_queue_type + */ +enum ia_css_isys_queue_type { + IA_CSS_ISYS_QUEUE_TYPE_PROXY = 0, + IA_CSS_ISYS_QUEUE_TYPE_DEV, + IA_CSS_ISYS_QUEUE_TYPE_MSG, + N_IA_CSS_ISYS_QUEUE_TYPE +}; + +/** + * enum ia_css_isys_stream_source: Specifies a source for a stream + */ +enum ia_css_isys_stream_source { + IA_CSS_ISYS_STREAM_SRC_PORT_0 = 0, + IA_CSS_ISYS_STREAM_SRC_PORT_1, + IA_CSS_ISYS_STREAM_SRC_PORT_2, + IA_CSS_ISYS_STREAM_SRC_PORT_3, + IA_CSS_ISYS_STREAM_SRC_PORT_4, + IA_CSS_ISYS_STREAM_SRC_PORT_5, + IA_CSS_ISYS_STREAM_SRC_PORT_6, + IA_CSS_ISYS_STREAM_SRC_PORT_7, + IA_CSS_ISYS_STREAM_SRC_PORT_8, + IA_CSS_ISYS_STREAM_SRC_PORT_9, + IA_CSS_ISYS_STREAM_SRC_PORT_10, + IA_CSS_ISYS_STREAM_SRC_PORT_11, + IA_CSS_ISYS_STREAM_SRC_PORT_12, + IA_CSS_ISYS_STREAM_SRC_PORT_13, + IA_CSS_ISYS_STREAM_SRC_PORT_14, + IA_CSS_ISYS_STREAM_SRC_PORT_15, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_0, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_1, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_2, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_3, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_4, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_5, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_6, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_7, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_8, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_9, + N_IA_CSS_ISYS_STREAM_SRC +}; + +#define IA_CSS_ISYS_STREAM_SRC_CSI2_PORT0 IA_CSS_ISYS_STREAM_SRC_PORT_0 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_PORT1 IA_CSS_ISYS_STREAM_SRC_PORT_1 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_PORT2 IA_CSS_ISYS_STREAM_SRC_PORT_2 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_PORT3 IA_CSS_ISYS_STREAM_SRC_PORT_3 + +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_PORTA IA_CSS_ISYS_STREAM_SRC_PORT_4 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_PORTB IA_CSS_ISYS_STREAM_SRC_PORT_5 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT0 IA_CSS_ISYS_STREAM_SRC_PORT_6 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT1 IA_CSS_ISYS_STREAM_SRC_PORT_7 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT2 IA_CSS_ISYS_STREAM_SRC_PORT_8 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT3 IA_CSS_ISYS_STREAM_SRC_PORT_9 + +#define IA_CSS_ISYS_STREAM_SRC_MIPIGEN_PORT0 IA_CSS_ISYS_STREAM_SRC_MIPIGEN_0 +#define IA_CSS_ISYS_STREAM_SRC_MIPIGEN_PORT1 IA_CSS_ISYS_STREAM_SRC_MIPIGEN_1 + +/** + * enum ia_css_isys_mipi_vc: MIPI csi2 spec + * supports upto 4 virtual per physical channel + */ +enum ia_css_isys_mipi_vc { + IA_CSS_ISYS_MIPI_VC_0 = 0, + IA_CSS_ISYS_MIPI_VC_1, + IA_CSS_ISYS_MIPI_VC_2, + IA_CSS_ISYS_MIPI_VC_3, + N_IA_CSS_ISYS_MIPI_VC +}; + +/** + * Supported Pixel Frame formats. Expandable if needed + */ +enum ia_css_isys_frame_format_type { + IA_CSS_ISYS_FRAME_FORMAT_NV11 = 0,/* 12 bit YUV 411, Y, UV plane */ + IA_CSS_ISYS_FRAME_FORMAT_NV12,/* 12 bit YUV 420, Y, UV plane */ + IA_CSS_ISYS_FRAME_FORMAT_NV12_16,/* 16 bit YUV 420, Y, UV plane */ + IA_CSS_ISYS_FRAME_FORMAT_NV12_TILEY,/* 12 bit YUV 420, Intel + proprietary tiled format, + TileY + */ + IA_CSS_ISYS_FRAME_FORMAT_NV16,/* 16 bit YUV 422, Y, UV plane */ + IA_CSS_ISYS_FRAME_FORMAT_NV21,/* 12 bit YUV 420, Y, VU plane */ + IA_CSS_ISYS_FRAME_FORMAT_NV61,/* 16 bit YUV 422, Y, VU plane */ + IA_CSS_ISYS_FRAME_FORMAT_YV12,/* 12 bit YUV 420, Y, V, U plane */ + IA_CSS_ISYS_FRAME_FORMAT_YV16,/* 16 bit YUV 422, Y, V, U plane */ + IA_CSS_ISYS_FRAME_FORMAT_YUV420,/* 12 bit YUV 420, Y, U, V plane */ + IA_CSS_ISYS_FRAME_FORMAT_YUV420_10,/* yuv420, 10 bits per subpixel */ + IA_CSS_ISYS_FRAME_FORMAT_YUV420_12,/* yuv420, 12 bits per subpixel */ + IA_CSS_ISYS_FRAME_FORMAT_YUV420_14,/* yuv420, 14 bits per subpixel */ + IA_CSS_ISYS_FRAME_FORMAT_YUV420_16,/* yuv420, 16 bits per subpixel */ + IA_CSS_ISYS_FRAME_FORMAT_YUV422,/* 16 bit YUV 422, Y, U, V plane */ + IA_CSS_ISYS_FRAME_FORMAT_YUV422_16,/* yuv422, 16 bits per subpixel */ + IA_CSS_ISYS_FRAME_FORMAT_UYVY,/* 16 bit YUV 422, UYVY interleaved */ + IA_CSS_ISYS_FRAME_FORMAT_YUYV,/* 16 bit YUV 422, YUYV interleaved */ + IA_CSS_ISYS_FRAME_FORMAT_YUV444,/* 24 bit YUV 444, Y, U, V plane */ + IA_CSS_ISYS_FRAME_FORMAT_YUV_LINE,/* Internal format, 2 y lines + followed by a uvinterleaved line + */ + IA_CSS_ISYS_FRAME_FORMAT_RAW8, /* RAW8, 1 plane */ + IA_CSS_ISYS_FRAME_FORMAT_RAW10, /* RAW10, 1 plane */ + IA_CSS_ISYS_FRAME_FORMAT_RAW12, /* RAW12, 1 plane */ + IA_CSS_ISYS_FRAME_FORMAT_RAW14, /* RAW14, 1 plane */ + IA_CSS_ISYS_FRAME_FORMAT_RAW16, /* RAW16, 1 plane */ + IA_CSS_ISYS_FRAME_FORMAT_RGB565,/* 16 bit RGB, 1 plane. Each 3 sub + pixels are packed into one 16 bit + value, 5 bits for R, 6 bits for G + and 5 bits for B. + */ + IA_CSS_ISYS_FRAME_FORMAT_PLANAR_RGB888, /* 24 bit RGB, 3 planes */ + IA_CSS_ISYS_FRAME_FORMAT_RGBA888,/* 32 bit RGBA, 1 plane, + A=Alpha (alpha is unused) + */ + IA_CSS_ISYS_FRAME_FORMAT_QPLANE6,/* Internal, for advanced ISP */ + IA_CSS_ISYS_FRAME_FORMAT_BINARY_8,/* byte stream, used for jpeg. */ + N_IA_CSS_ISYS_FRAME_FORMAT +}; +/* Temporary for driver compatibility */ +#define IA_CSS_ISYS_FRAME_FORMAT_RAW (IA_CSS_ISYS_FRAME_FORMAT_RAW16) + + +/** + * Supported MIPI data type. Keep in sync array in ia_css_isys_private.c + */ +enum ia_css_isys_mipi_data_type { + /** SYNCHRONIZATION SHORT PACKET DATA TYPES */ + IA_CSS_ISYS_MIPI_DATA_TYPE_FRAME_START_CODE = 0x00, + IA_CSS_ISYS_MIPI_DATA_TYPE_FRAME_END_CODE = 0x01, + IA_CSS_ISYS_MIPI_DATA_TYPE_LINE_START_CODE = 0x02, /* Optional */ + IA_CSS_ISYS_MIPI_DATA_TYPE_LINE_END_CODE = 0x03, /* Optional */ + /** Reserved 0x04-0x07 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x04 = 0x04, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x05 = 0x05, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x06 = 0x06, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x07 = 0x07, + /** GENERIC SHORT PACKET DATA TYPES */ + /** They are used to keep the timing information for the + * opening/closing of shutters, triggering of flashes and etc. + */ + /* Generic Short Packet Code 1 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT1 = 0x08, + /* Generic Short Packet Code 2 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT2 = 0x09, + /* Generic Short Packet Code 3 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT3 = 0x0A, + /* Generic Short Packet Code 4 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT4 = 0x0B, + /* Generic Short Packet Code 5 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT5 = 0x0C, + /* Generic Short Packet Code 6 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT6 = 0x0D, + /* Generic Short Packet Code 7 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT7 = 0x0E, + /* Generic Short Packet Code 8 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT8 = 0x0F, + /** GENERIC LONG PACKET DATA TYPES */ + IA_CSS_ISYS_MIPI_DATA_TYPE_NULL = 0x10, + IA_CSS_ISYS_MIPI_DATA_TYPE_BLANKING_DATA = 0x11, + /* Embedded 8-bit non Image Data */ + IA_CSS_ISYS_MIPI_DATA_TYPE_EMBEDDED = 0x12, + /** Reserved 0x13-0x17 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x13 = 0x13, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x14 = 0x14, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x15 = 0x15, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x16 = 0x16, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x17 = 0x17, + /** YUV DATA TYPES */ + /* 8 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV420_8 = 0x18, + /* 10 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV420_10 = 0x19, + /* 8 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV420_8_LEGACY = 0x1A, + /** Reserved 0x1B */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x1B = 0x1B, + /* YUV420 8-bit (Chroma Shifted Pixel Sampling) */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV420_8_SHIFT = 0x1C, + /* YUV420 10-bit (Chroma Shifted Pixel Sampling) */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV420_10_SHIFT = 0x1D, + /* UYVY..UVYV, 8 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV422_8 = 0x1E, + /* UYVY..UVYV, 10 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV422_10 = 0x1F, + /** RGB DATA TYPES */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RGB_444 = 0x20, + /* BGR..BGR, 5 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RGB_555 = 0x21, + /* BGR..BGR, 5 bits B and R, 6 bits G */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RGB_565 = 0x22, + /* BGR..BGR, 6 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RGB_666 = 0x23, + /* BGR..BGR, 8 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RGB_888 = 0x24, + /** Reserved 0x25-0x27 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x25 = 0x25, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x26 = 0x26, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x27 = 0x27, + /** RAW DATA TYPES */ + /* RAW data, 6 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_6 = 0x28, + /* RAW data, 7 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_7 = 0x29, + /* RAW data, 8 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_8 = 0x2A, + /* RAW data, 10 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_10 = 0x2B, + /* RAW data, 12 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_12 = 0x2C, + /* RAW data, 14 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_14 = 0x2D, + /** Reserved 0x2E-2F are used with assigned meaning */ + /* RAW data, 16 bits per pixel, not specified in CSI-MIPI standard */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_16 = 0x2E, + /* Binary byte stream, which is target at JPEG, not specified in + * CSI-MIPI standard + */ + IA_CSS_ISYS_MIPI_DATA_TYPE_BINARY_8 = 0x2F, + /** USER DEFINED 8-BIT DATA TYPES */ + /** For example, the data transmitter (e.g. the SoC sensor) can keep + * the JPEG data as the User Defined Data Type 4 and the MPEG data as + * the User Defined Data Type 7. + */ + /* User defined 8-bit data type 1 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF1 = 0x30, + /* User defined 8-bit data type 2 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF2 = 0x31, + /* User defined 8-bit data type 3 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF3 = 0x32, + /* User defined 8-bit data type 4 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF4 = 0x33, + /* User defined 8-bit data type 5 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF5 = 0x34, + /* User defined 8-bit data type 6 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF6 = 0x35, + /* User defined 8-bit data type 7 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF7 = 0x36, + /* User defined 8-bit data type 8 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF8 = 0x37, + /** Reserved 0x38-0x3F */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x38 = 0x38, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x39 = 0x39, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3A = 0x3A, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3B = 0x3B, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3C = 0x3C, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3D = 0x3D, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3E = 0x3E, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3F = 0x3F, + + /* Keep always last and max value */ + N_IA_CSS_ISYS_MIPI_DATA_TYPE = 0x40 +}; + +/** enum ia_css_isys_pin_type: output pin buffer types. + * Buffers can be queued and de-queued to hand them over between IA and ISYS + */ +enum ia_css_isys_pin_type { + /* Captured as MIPI packets */ + IA_CSS_ISYS_PIN_TYPE_MIPI = 0, + /* Captured through the ISApf (with/without ISA) + * and the non-scaled output path + */ + IA_CSS_ISYS_PIN_TYPE_RAW_NS, + /* Captured through the ISApf + ISA and the scaled output path */ + IA_CSS_ISYS_PIN_TYPE_RAW_S, + /* Captured through the SoC path */ + IA_CSS_ISYS_PIN_TYPE_RAW_SOC, + /* Reserved for future use, maybe short packets */ + IA_CSS_ISYS_PIN_TYPE_METADATA_0, + /* Reserved for future use */ + IA_CSS_ISYS_PIN_TYPE_METADATA_1, + /* Legacy (non-PIV2), used for the AWB stats */ + IA_CSS_ISYS_PIN_TYPE_AWB_STATS, + /* Legacy (non-PIV2), used for the AF stats */ + IA_CSS_ISYS_PIN_TYPE_AF_STATS, + /* Legacy (non-PIV2), used for the AE stats */ + IA_CSS_ISYS_PIN_TYPE_HIST_STATS, + /* Used for the PAF FF*/ + IA_CSS_ISYS_PIN_TYPE_PAF_FF, + /* Keep always last and max value */ + N_IA_CSS_ISYS_PIN_TYPE +}; + +/** + * enum ia_css_isys_isl_use. Describes the ISL/ISA use + * (ISAPF path in after BXT A0) + */ +enum ia_css_isys_isl_use { + IA_CSS_ISYS_USE_NO_ISL_NO_ISA = 0, + IA_CSS_ISYS_USE_SINGLE_DUAL_ISL, + IA_CSS_ISYS_USE_SINGLE_ISA, + N_IA_CSS_ISYS_USE +}; + +/** + * enum ia_css_isys_mipi_store_mode. Describes if long MIPI packets reach MIPI + * SRAM with the long packet header or not. + * if not, then only option is to capture it with pin type MIPI. + */ +enum ia_css_isys_mipi_store_mode { + IA_CSS_ISYS_MIPI_STORE_MODE_NORMAL = 0, + IA_CSS_ISYS_MIPI_STORE_MODE_DISCARD_LONG_HEADER, + N_IA_CSS_ISYS_MIPI_STORE_MODE +}; + +/** + * enum ia_css_isys_mipi_dt_rename_mode. Describes if long MIPI packets have + * DT with some other DT format. + */ +enum ia_css_isys_mipi_dt_rename_mode { + IA_CSS_ISYS_MIPI_DT_NO_RENAME = 0, + IA_CSS_ISYS_MIPI_DT_RENAMED_MODE, + N_IA_CSS_ISYS_MIPI_DT_MODE +}; + +/** + * enum ia_css_isys_type_paf. Describes the Type of PAF enabled + * (PAF path in after cnlB0) + */ +enum ia_css_isys_type_paf { + /* PAF data not present */ + IA_CSS_ISYS_TYPE_NO_PAF = 0, + /* Type 2 sensor types, PAF coming separately from Image Frame */ + /* PAF data in interleaved format(RLRL or LRLR)*/ + IA_CSS_ISYS_TYPE_INTERLEAVED_PAF, + /* PAF data in non-interleaved format(LL/RR or RR/LL) */ + IA_CSS_ISYS_TYPE_NON_INTERLEAVED_PAF, + /* Type 3 sensor types , PAF data embedded in Image Frame*/ + /* Frame Embedded PAF in interleaved format(RLRL or LRLR)*/ + IA_CSS_ISYS_TYPE_FRAME_EMB_INTERLEAVED_PAF, + /* Frame Embedded PAF non-interleaved format(LL/RR or RR/LL)*/ + IA_CSS_ISYS_TYPE_FRAME_EMB_NON_INTERLEAVED_PAF, + N_IA_CSS_ISYS_TYPE_PAF +}; + +/** + * enum ia_css_isys_cropping_location. Enumerates the cropping locations + * in ISYS + */ +enum ia_css_isys_cropping_location { + /* Cropping executed in ISAPF (mainly), ISAPF preproc (odd column) and + * MIPI STR2MMIO (odd row) + */ + IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA = 0, + /* BXT A0 legacy mode which will never be implemented */ + IA_CSS_ISYS_CROPPING_LOCATION_RESERVED_1, + /* Cropping executed in StreamPifConv in the ISA output for + * RAW_NS pin + */ + IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED, + /* Cropping executed in StreamScaledPifConv in the ISA output for + * RAW_S pin + */ + IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_SCALED, + N_IA_CSS_ISYS_CROPPING_LOCATION +}; + +/** + * enum ia_css_isys_resolution_info. Describes the resolution, required to + * setup the various ISA GP registers. + */ +enum ia_css_isys_resolution_info { + /* Scaled ISA output resolution before the + * StreamScaledPifConv cropping + */ + IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED = 0, + /* Non-Scaled ISA output resolution before the + * StreamPifConv cropping + */ + IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED, + N_IA_CSS_ISYS_RESOLUTION_INFO +}; + +/** + * enum ia_css_isys_error. Describes the error type detected by the FW + */ +enum ia_css_isys_error { + IA_CSS_ISYS_ERROR_NONE = 0, /* No details */ + IA_CSS_ISYS_ERROR_FW_INTERNAL_CONSISTENCY, /* enum */ + IA_CSS_ISYS_ERROR_HW_CONSISTENCY, /* enum */ + IA_CSS_ISYS_ERROR_DRIVER_INVALID_COMMAND_SEQUENCE, /* enum */ + IA_CSS_ISYS_ERROR_DRIVER_INVALID_DEVICE_CONFIGURATION, /* enum */ + IA_CSS_ISYS_ERROR_DRIVER_INVALID_STREAM_CONFIGURATION, /* enum */ + IA_CSS_ISYS_ERROR_DRIVER_INVALID_FRAME_CONFIGURATION, /* enum */ + IA_CSS_ISYS_ERROR_INSUFFICIENT_RESOURCES, /* enum */ + IA_CSS_ISYS_ERROR_HW_REPORTED_STR2MMIO, /* HW code */ + IA_CSS_ISYS_ERROR_HW_REPORTED_SIG2CIO, /* HW code */ + IA_CSS_ISYS_ERROR_SENSOR_FW_SYNC, /* enum */ + IA_CSS_ISYS_ERROR_STREAM_IN_SUSPENSION, /* FW code */ + IA_CSS_ISYS_ERROR_RESPONSE_QUEUE_FULL, /* FW code */ + N_IA_CSS_ISYS_ERROR +}; + +/** + * enum ia_css_proxy_error. Describes the error type for the proxy detected by + * the FW + */ +enum ia_css_proxy_error { + IA_CSS_PROXY_ERROR_NONE = 0, + IA_CSS_PROXY_ERROR_INVALID_WRITE_REGION, + IA_CSS_PROXY_ERROR_INVALID_WRITE_OFFSET, + N_IA_CSS_PROXY_ERROR +}; + +#endif /* __IA_CSS_ISYSAPI_FW_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_fw_version.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_fw_version.h new file mode 100644 index 0000000000000..bc056157cedb6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_fw_version.h @@ -0,0 +1,21 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_FW_VERSION_H +#define __IA_CSS_ISYSAPI_FW_VERSION_H + +/* ISYSAPI FW VERSION is taken from Makefile for FW tests */ +#define BXT_FW_RELEASE_VERSION ISYS_FIRMWARE_VERSION + +#endif /* __IA_CSS_ISYSAPI_FW_VERSION_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_defs.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_defs.h new file mode 100644 index 0000000000000..27c930f6cd19c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_defs.h @@ -0,0 +1,113 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_PROXY_REGION_DEFS_H +#define __IA_CSS_ISYSAPI_PROXY_REGION_DEFS_H + +#include "ia_css_isysapi_proxy_region_types.h" + +/* + * Definitions for IPU4_B0_PROXY_INT + */ + +#if defined(IPU4_B0_PROXY_INT) + +/** + * enum ipu4_b0_ia_css_proxy_write_region. Provides the list of regions for ipu4B0 that + * can be accessed (for writing purpose) through the proxy interface + */ +enum ipu4_b0_ia_css_proxy_write_region { + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_0_ERROR_FILL_RATE = 0, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_1_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_2_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_3_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_4_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_5_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_6_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_7_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_8_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_9_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IRQ_URGENT_THRESHOLD, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IRQ_CRITICAL_THRESHOLD, + N_IPU4_B0_IA_CSS_PROXY_WRITE_REGION +}; + +struct ia_css_proxy_write_region_description ipu4_b0_reg_write_desc[N_IPU4_B0_IA_CSS_PROXY_WRITE_REGION] = { + /* base_addr, offset */ + {0x64128, /*input_system_csi2_logic_s2m_a_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_0_ERROR_FILL_RATE*/ + {0x65128, /*input_system_csi2_logic_s2m_b_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_1_ERROR_FILL_RATE*/ + {0x66128, /*input_system_csi2_logic_s2m_c_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_2_ERROR_FILL_RATE*/ + {0x67128, /*input_system_csi2_logic_s2m_d_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_3_ERROR_FILL_RATE*/ + {0x6C128, /*input_system_csi2_3ph_logic_s2m_a_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_4_ERROR_FILL_RATE*/ + {0x6C928, /*input_system_csi2_3ph_logic_s2m_b_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_5_ERROR_FILL_RATE*/ + {0x6D128, /*input_system_csi2_3ph_logic_s2m_0_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_6_ERROR_FILL_RATE*/ + {0x6D928, /*input_system_csi2_3ph_logic_s2m_1_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_7_ERROR_FILL_RATE*/ + {0x6E128, /*input_system_csi2_3ph_logic_s2m_2_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_8_ERROR_FILL_RATE*/ + {0x6E928, /*input_system_csi2_3ph_logic_s2m_3_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_9_ERROR_FILL_RATE*/ + {0x7800C, /*input_system_unis_logic_gda_irq_urgent_threshold*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IRQ_URGENT_THRESHOLD*/ + {0x78010, /*input_system_unis_logic_gda_irq_critical_threshold*/ 4} /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IRQ_CRITICAL_THRESHOLD*/ +}; + +#endif /*defined(IPU4_B0_PROXY_INT)*/ + +/* + * Definitions for IPU4P_A0_PROXY_INT + */ + +#if defined(IPU4P_A0_PROXY_INT) + +/** + * enum ipu4p_a0_ia_css_proxy_write_region. Provides the list of regions for ipu4pA0 that + * can be accessed (for writing purpose) through the proxy interface + */ +enum ipu4p_a0_ia_css_proxy_write_region { + N_IPU4P_A0_IA_CSS_PROXY_WRITE_REGION +}; + +#define IPU4P_A0_NO_PROXY_WRITE_REGION_AVAILABLE + +#ifndef IPU4P_A0_NO_PROXY_WRITE_REGION_AVAILABLE +struct ia_css_proxy_write_region_description ipu4p_a0_reg_write_desc[N_IPU4P_A0_IA_CSS_PROXY_WRITE_REGION] = { +} +#endif /*IPU4P_A0_NO_PROXY_WRITE_REGION_AVAILABLE*/ + +#endif /*defined(IPU4P_A0_PROXY_INT)*/ + +/* + * Definitions for IPU4P_B0_PROXY_INT + */ + +#if defined(IPU4P_B0_PROXY_INT) + +/** + * enum ipu4p_b0_ia_css_proxy_write_region. Provides the list of regions for ipu4pB0 that + * can be accessed (for writing purpose) through the proxy interface + */ +enum ipu4p_b0_ia_css_proxy_write_region { + IPU4P_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IWAKE_THRESHOLD = 0, + IPU4P_B0_IA_CSS_PROXY_WRITE_REGION_GDA_ENABLE_IWAKE, + N_IPU4P_B0_IA_CSS_PROXY_WRITE_REGION +}; + +struct ia_css_proxy_write_region_description ipu4p_b0_reg_write_desc[N_IPU4P_B0_IA_CSS_PROXY_WRITE_REGION] = { + /* base_addr, max_offset */ + /*input_system_unis_logic_gda_iwake_threshold*/ + {0x78014, 4}, /*IPU4P_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IWAKE_THRESHOLD*/ + /*input_system_unis_logic_gda_enable_iwake*/ + {0x7801C, 4} /*IPU4P_B0_IA_CSS_PROXY_WRITE_REGION_GDA_ENABLE_IWAKE*/ +}; + +#endif /*defined(IPU4P_B0_PROXY_INT)*/ + +#endif /* __IA_CSS_ISYSAPI_PROXY_REGION_DEFS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_types.h new file mode 100644 index 0000000000000..045f089e5a4c8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_types.h @@ -0,0 +1,24 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_PROXY_REGION_TYPES_H +#define __IA_CSS_ISYSAPI_PROXY_REGION_TYPES_H + + +struct ia_css_proxy_write_region_description { + uint32_t base_addr; + uint32_t offset; +}; + +#endif /* __IA_CSS_ISYSAPI_PROXY_REGION_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_types.h new file mode 100644 index 0000000000000..e8b4ad28fbd4b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/interface/ia_css_isysapi_types.h @@ -0,0 +1,349 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_TYPES_H +#define __IA_CSS_ISYSAPI_TYPES_H + +#include "ia_css_isysapi_fw_types.h" +#include "type_support.h" + +#include "ia_css_return_token.h" +#include "ia_css_output_buffer.h" +#include "ia_css_input_buffer.h" +#include "ia_css_terminal_defs.h" + +/** + * struct ia_css_isys_buffer_partition - buffer partition information + * @num_gda_pages: Number of virtual gda pages available for each virtual stream + */ +struct ia_css_isys_buffer_partition { + unsigned int num_gda_pages[STREAM_ID_MAX]; +}; + +/** + * This should contain the driver specified info for sys + */ +struct ia_css_driver_sys_config { + unsigned int ssid; + unsigned int mmid; + unsigned int num_send_queues; /* # of MSG send queues */ + unsigned int num_recv_queues; /* # of MSG recv queues */ + unsigned int send_queue_size; /* max # tokens per queue */ + unsigned int recv_queue_size; /* max # tokens per queue */ + + unsigned int icache_prefetch; /* enable prefetching for SPC */ +}; + +/** + * This should contain the driver specified info for proxy write queues + */ +struct ia_css_driver_proxy_config { + /* max # tokens per PROXY send/recv queue. + * Proxy queues are used for write access purpose + */ + unsigned int proxy_write_queue_size; +}; + + /** + * struct ia_css_isys_device_cfg_data - ISYS device configuration data + * @driver_sys + * @buffer_partition: Information required for the virtual SRAM + * space partition of the streams. + * @driver_proxy + * @secure: Driver needs to set 'secure' to indicate the intention + * when invoking ia_css_isys_context_create() in + * HAS_DUAL_CMD_CTX_SUPPORT case. If 'true', it's for + * secure case. + */ +struct ia_css_isys_device_cfg_data { + struct ia_css_driver_sys_config driver_sys; + struct ia_css_isys_buffer_partition buffer_partition; + struct ia_css_driver_proxy_config driver_proxy; + bool secure; + unsigned int vtl0_addr_mask; /* only applicable in 'secure' case */ +}; + +/** + * struct ia_css_isys_resolution: Generic resolution structure. + * @Width + * @Height + */ +struct ia_css_isys_resolution { + unsigned int width; + unsigned int height; +}; + +/** + * struct ia_css_isys_output_pin_payload + * @out_buf_id: Points to output pin buffer - buffer identifier + * @addr: Points to output pin buffer - CSS Virtual Address + * @compressed: Request frame compression (1), or not (0) + * This must be the same as ia_css_isys_output_pin_info::reserve_compression + */ +struct ia_css_isys_output_pin_payload { + ia_css_return_token out_buf_id; + ia_css_output_buffer_css_address addr; + unsigned int compress; +}; + +/** + * struct ia_css_isys_output_pin_info + * @input_pin_id: input pin id/index which is source of + * the data for this output pin + * @output_res: output pin resolution + * @stride: output stride in Bytes (not valid for statistics) + * @pt: pin type + * @ft: frame format type + * @watermark_in_lines: pin watermark level in lines + * @send_irq: assert if pin event should trigger irq + * @link_id: identifies PPG to connect to, link_id = 0 implies offline + * while link_id > 0 implies buffer_chasing or online mode + * can be entered. + * @reserve_compression: Reserve compression resources for pin. + * @payload_buf_size: Minimum size in Bytes of all buffers that will be supplied for capture + * on this pin (i.e. addressed by ia_css_isys_output_pin_payload::addr) + */ +struct ia_css_isys_output_pin_info { + unsigned int input_pin_id; + struct ia_css_isys_resolution output_res; + unsigned int stride; + enum ia_css_isys_pin_type pt; + enum ia_css_isys_frame_format_type ft; + unsigned int watermark_in_lines; + unsigned int send_irq; + enum ia_css_isys_link_id link_id; + unsigned int reserve_compression; + unsigned int payload_buf_size; +}; + +/** + * struct ia_css_isys_param_pin + * @param_buf_id: Points to param buffer - buffer identifier + * @addr: Points to param buffer - CSS Virtual Address + */ +struct ia_css_isys_param_pin { + ia_css_return_token param_buf_id; + ia_css_input_buffer_css_address addr; +}; + +/** + * struct ia_css_isys_input_pin_info + * @input_res: input resolution + * @dt: mipi data type + * @mipi_store_mode: defines if legacy long packet header will be stored or + * discarded if discarded, output pin pin type for this + * input pin can only be MIPI + * @dt_rename_mode: defines if MIPI data is encapsulated in some other + * data type + * @mapped_dt: Encapsulating in mipi data type(what sensor sends) + */ +struct ia_css_isys_input_pin_info { + struct ia_css_isys_resolution input_res; + enum ia_css_isys_mipi_data_type dt; + enum ia_css_isys_mipi_store_mode mipi_store_mode; + enum ia_css_isys_mipi_dt_rename_mode dt_rename_mode; + enum ia_css_isys_mipi_data_type mapped_dt; +}; + +/** + * struct ia_css_isys_isa_cfg. Describes the ISA cfg + */ +struct ia_css_isys_isa_cfg { + /* Following sets resolution information neeed by the IS GP registers, + * For index IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED, + * it is needed when there is RAW_NS pin + * For index IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED, + * it is needed when there is RAW_S pin + */ + struct ia_css_isys_resolution isa_res[N_IA_CSS_ISYS_RESOLUTION_INFO]; + /* acc id 0, set if process required */ + unsigned int blc_enabled; + /* acc id 1, set if process required */ + unsigned int lsc_enabled; + /* acc id 2, set if process required */ + unsigned int dpc_enabled; + /* acc id 3, set if process required */ + unsigned int downscaler_enabled; + /* acc id 4, set if process required */ + unsigned int awb_enabled; + /* acc id 5, set if process required */ + unsigned int af_enabled; + /* acc id 6, set if process required */ + unsigned int ae_enabled; + /* acc id 7, disabled, or type of paf enabled*/ + enum ia_css_isys_type_paf paf_type; + /* Send irq for any statistics buffers which got completed */ + unsigned int send_irq_stats_ready; + /* Send response for any statistics buffers which got completed */ + unsigned int send_resp_stats_ready; +}; + +/** + * struct ia_css_isys_cropping - cropping coordinates + * Left/Top offsets are INCLUDED + * Right/Bottom offsets are EXCLUDED + * Horizontal: [left_offset,right_offset) + * Vertical: [top_offset,bottom_offset) + * Padding is supported + */ +struct ia_css_isys_cropping { + int top_offset; + int left_offset; + int bottom_offset; + int right_offset; +}; + + /** + * struct ia_css_isys_stream_cfg_data + * ISYS stream configuration data structure + * @src: Stream source index e.g. MIPI_generator_0, CSI2-rx_1 + * @vc: MIPI Virtual Channel (up to 4 virtual per physical channel) + * @isl_use: indicates whether stream requires ISL and how + * @compfmt: de-compression setting for User Defined Data + * @isa_cfg: details about what ACCs are active if ISA is used + * @crop: defines cropping resolution for the + * maximum number of input pins which can be cropped, + * it is directly mapped to the HW devices + * @send_irq_sof_discarded: send irq on discarded frame sof response + * - if '1' it will override the send_resp_sof_discarded and send + * the response + * - if '0' the send_resp_sof_discarded will determine whether to + * send the response + * @send_irq_eof_discarded: send irq on discarded frame eof response + * - if '1' it will override the send_resp_eof_discarded and send + * the response + * - if '0' the send_resp_eof_discarded will determine whether to + * send the response + * @send_resp_sof_discarded: send response for discarded frame sof detected, + * used only when send_irq_sof_discarded is '0' + * @send_resp_eof_discarded: send response for discarded frame eof detected, + * used only when send_irq_eof_discarded is '0' + * @the rest: input/output pin descriptors + */ +struct ia_css_isys_stream_cfg_data { + enum ia_css_isys_stream_source src; + enum ia_css_isys_mipi_vc vc; + enum ia_css_isys_isl_use isl_use; + unsigned int compfmt; + struct ia_css_isys_isa_cfg isa_cfg; + struct ia_css_isys_cropping crop[N_IA_CSS_ISYS_CROPPING_LOCATION]; + unsigned int send_irq_sof_discarded; + unsigned int send_irq_eof_discarded; + unsigned int send_resp_sof_discarded; + unsigned int send_resp_eof_discarded; + unsigned int nof_input_pins; + unsigned int nof_output_pins; + struct ia_css_isys_input_pin_info input_pins[MAX_IPINS]; + struct ia_css_isys_output_pin_info output_pins[MAX_OPINS]; +}; + +/** + * struct ia_css_isys_frame_buff_set - frame buffer set + * @output_pins: output pin addresses + * @process_group_light: process_group_light buffer address + * @send_irq_sof: send irq on frame sof response + * - if '1' it will override the send_resp_sof and send + * the response + * - if '0' the send_resp_sof will determine whether to send + * the response + * @send_irq_eof: send irq on frame eof response + * - if '1' it will override the send_resp_eof and send + * the response + * - if '0' the send_resp_eof will determine whether to send + * the response + * @send_resp_sof: send response for frame sof detected, + * used only when send_irq_sof is '0' + * @send_resp_eof: send response for frame eof detected, + * used only when send_irq_eof is '0' + * @frame_counter: frame number associated with this buffer set. + */ +struct ia_css_isys_frame_buff_set { + struct ia_css_isys_output_pin_payload output_pins[MAX_OPINS]; + struct ia_css_isys_param_pin process_group_light; + unsigned int send_irq_sof; + unsigned int send_irq_eof; + unsigned int send_irq_capture_ack; + unsigned int send_irq_capture_done; + unsigned int send_resp_sof; + unsigned int send_resp_eof; + uint8_t frame_counter; +}; + +/** + * struct ia_css_isys_resp_info + * @type: response type + * @stream_handle: stream id the response corresponds to + * @timestamp: Time information for event if available + * @error: error code if something went wrong + * @error_details: depending on error code, it may contain additional + * error info + * @pin: this var is valid for pin event related responses, + * contains pin addresses + * @pin_id: this var is valid for pin event related responses, + * contains pin id that the pin payload corresponds to + * @process_group_light: this var is valid for stats ready related responses, + * contains process group addresses + * @acc_id: this var is valid for stats ready related responses, + * contains accelerator id that finished producing + * all related statistics + * @frame_counter: valid for STREAM_START_AND_CAPTURE_DONE, + * STREAM_CAPTURE_DONE and STREAM_CAPTURE_DISCARDED + * @written_direct: indicates if frame was written direct (online mode) or to DDR. + */ +struct ia_css_isys_resp_info { + enum ia_css_isys_resp_type type; + unsigned int stream_handle; + unsigned int timestamp[2]; + enum ia_css_isys_error error; + unsigned int error_details; + struct ia_css_isys_output_pin_payload pin; + unsigned int pin_id; + struct ia_css_isys_param_pin process_group_light; + unsigned int acc_id; + uint8_t frame_counter; + uint8_t written_direct; +}; + +/** + * struct ia_css_proxy_write_req_val + * @request_id: Unique identifier for the write request + * (in case multiple write requests are issued for same register) + * @region_index: region id for the write request + * @offset: Offset to the specific register within the region + * @value: Value to be written to register + */ +struct ia_css_proxy_write_req_val { + uint32_t request_id; + uint32_t region_index; + uint32_t offset; + uint32_t value; +}; + +/** + * struct ia_css_proxy_write_req_resp + * @request_id: Unique identifier for the write request + * (in case multiple write requests are issued for same register) + * @error: error code if something went wrong + * @error_details: error detail includes either offset or region index + * information which caused proxy request to be rejected + * (invalid access request) + */ +struct ia_css_proxy_write_req_resp { + uint32_t request_id; + enum ia_css_proxy_error error; + uint32_t error_details; +}; + + +#endif /* __IA_CSS_ISYSAPI_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/isysapi.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/isysapi.mk new file mode 100644 index 0000000000000..0d06298f9acb0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/isysapi.mk @@ -0,0 +1,77 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is ISYSAPI + +include $(MODULES_DIR)/config/isys/subsystem_$(IPU_SYSVER).mk + +ISYSAPI_DIR=$${MODULES_DIR}/isysapi + +ISYSAPI_INTERFACE=$(ISYSAPI_DIR)/interface +ISYSAPI_SOURCES=$(ISYSAPI_DIR)/src +ISYSAPI_EXTINCLUDE=$${MODULES_DIR}/support +ISYSAPI_EXTINTERFACE=$${MODULES_DIR}/syscom/interface + +ISYSAPI_HOST_FILES += $(ISYSAPI_SOURCES)/ia_css_isys_public.c + +ISYSAPI_HOST_FILES += $(ISYSAPI_SOURCES)/ia_css_isys_private.c + +# ISYSAPI Trace Log Level = ISYSAPI_TRACE_LOG_LEVEL_NORMAL +# Other options are [ISYSAPI_TRACE_LOG_LEVEL_OFF, ISYSAPI_TRACE_LOG_LEVEL_DEBUG] +ifndef ISYSAPI_TRACE_CONFIG_HOST + ISYSAPI_TRACE_CONFIG_HOST=ISYSAPI_TRACE_LOG_LEVEL_NORMAL +endif +ifndef ISYSAPI_TRACE_CONFIG_FW + ISYSAPI_TRACE_CONFIG_FW=ISYSAPI_TRACE_LOG_LEVEL_NORMAL +endif + +ISYSAPI_HOST_CPPFLAGS += -DISYSAPI_TRACE_CONFIG=$(ISYSAPI_TRACE_CONFIG_HOST) +ISYSAPI_FW_CPPFLAGS += -DISYSAPI_TRACE_CONFIG=$(ISYSAPI_TRACE_CONFIG_FW) + +ISYSAPI_HOST_FILES += $(ISYSAPI_SOURCES)/ia_css_isys_public_trace.c + +ISYSAPI_HOST_CPPFLAGS += -I$(ISYSAPI_INTERFACE) +ISYSAPI_HOST_CPPFLAGS += -I$(ISYSAPI_EXTINCLUDE) +ISYSAPI_HOST_CPPFLAGS += -I$(ISYSAPI_EXTINTERFACE) +ISYSAPI_HOST_CPPFLAGS += -I$(HIVESDK)/systems/ipu_system/dai/include +ISYSAPI_HOST_CPPFLAGS += -I$(HIVESDK)/systems/ipu_system/dai/include/default_system +ISYSAPI_HOST_CPPFLAGS += -I$(HIVESDK)/include/ipu/dai +ISYSAPI_HOST_CPPFLAGS += -I$(HIVESDK)/include/ipu + +ISYSAPI_FW_FILES += $(ISYSAPI_SOURCES)/isys_fw.c +ISYSAPI_FW_FILES += $(ISYSAPI_SOURCES)/isys_fw_utils.c + +ISYSAPI_FW_CPPFLAGS += -I$(ISYSAPI_INTERFACE) +ISYSAPI_FW_CPPFLAGS += -I$(ISYSAPI_SOURCES)/$(IPU_SYSVER) +ISYSAPI_FW_CPPFLAGS += -I$(ISYSAPI_EXTINCLUDE) +ISYSAPI_FW_CPPFLAGS += -I$(ISYSAPI_EXTINTERFACE) +ISYSAPI_FW_CPPFLAGS += -I$(HIVESDK)/systems/ipu_system/dai/include +ISYSAPI_FW_CPPFLAGS += -I$(HIVESDK)/systems/ipu_system/dai/include/default_system +ISYSAPI_FW_CPPFLAGS += -I$(HIVESDK)/include/ipu/dai +ISYSAPI_FW_CPPFLAGS += -I$(HIVESDK)/include/ipu + +ISYSAPI_FW_CPPFLAGS += -DWA_HSD1805168877=$(WA_HSD1805168877) + +ISYSAPI_HOST_CPPFLAGS += -DREGMEM_OFFSET=$(REGMEM_OFFSET) + +ifeq ($(ISYS_HAS_DUAL_CMD_CTX_SUPPORT), 1) +ISYSAPI_HOST_CPPFLAGS += -DHAS_DUAL_CMD_CTX_SUPPORT=$(ISYS_HAS_DUAL_CMD_CTX_SUPPORT) +ISYSAPI_FW_CPPFLAGS += -DHAS_DUAL_CMD_CTX_SUPPORT=$(ISYS_HAS_DUAL_CMD_CTX_SUPPORT) +endif + +ifdef AB_CONFIG_ARRAY_SIZE +ISYSAPI_FW_CPPFLAGS += -DAB_CONFIG_ARRAY_SIZE=$(AB_CONFIG_ARRAY_SIZE) +else +ISYSAPI_FW_CPPFLAGS += -DAB_CONFIG_ARRAY_SIZE=1 +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_private.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_private.c new file mode 100644 index 0000000000000..4379e20ba058e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_private.c @@ -0,0 +1,979 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_isys_private.h" +/* The following is needed for the contained data types */ +#include "ia_css_isys_fw_bridged_types.h" +#include "ia_css_isysapi_types.h" +#include "ia_css_syscom_config.h" +/* + * The following header file is needed for the + * stddef.h (NULL), + * limits.h (CHAR_BIT definition). + */ +#include "type_support.h" +#include "error_support.h" +#include "ia_css_isysapi_trace.h" +#include "misc_support.h" +#include "cpu_mem_support.h" +#include "storage_class.h" + +#include "ia_css_shared_buffer_cpu.h" + +/* + * defines how many stream cfg host may sent concurrently + * before receiving the stream ack + */ +#define STREAM_CFG_BUFS_PER_MSG_QUEUE (1) +#define NEXT_FRAME_BUFS_PER_MSG_QUEUE \ + (ctx->send_queue_size[IA_CSS_ISYS_QUEUE_TYPE_MSG] + 4 + 1) +/* + * There is an edge case that host has filled the full queue + * with capture requests (ctx->send_queue_size), + * SP reads and HW-queues all of them (4), + * while in the meantime host continues queueing capture requests + * without checking for responses which SP will have sent with each HW-queue + * capture request (if it does then the 4 is much more improbable to appear, + * but still not impossible). + * After this, host tries to queue an extra capture request + * even though there is no space in the msg queue because msg queue + * is checked at a later point, so +1 is needed + */ + +/* + * A DT is supported assuming when the MIPI packets + * have the same size even when even/odd lines are different, + * and the size is the average per line + */ +#define IA_CSS_UNSUPPORTED_DATA_TYPE (0) +static const uint32_t +ia_css_isys_extracted_bits_per_pixel_per_mipi_data_type[ + N_IA_CSS_ISYS_MIPI_DATA_TYPE] = { + /* + * Remove Prefix "IA_CSS_ISYS_MIPI_DATA_TYPE_" in comments + * to align with Checkpatch 80 characters requirements + * For detailed comments of each field, please refer to + * definition of enum ia_css_isys_mipi_data_type{} in + * isysapi/interface/ia_css_isysapi_fw_types.h + */ + 64, /* [0x00] FRAME_START_CODE */ + 64, /* [0x01] FRAME_END_CODE */ + 64, /* [0x02] LINE_START_CODE Optional */ + 64, /* [0x03] LINE_END_CODE Optional */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x04] RESERVED_0x04 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x05] RESERVED_0x05 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x06] RESERVED_0x06 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x07] RESERVED_0x07 */ + 64, /* [0x08] GENERIC_SHORT1 */ + 64, /* [0x09] GENERIC_SHORT2 */ + 64, /* [0x0A] GENERIC_SHORT3 */ + 64, /* [0x0B] GENERIC_SHORT4 */ + 64, /* [0x0C] GENERIC_SHORT5 */ + 64, /* [0x0D] GENERIC_SHORT6 */ + 64, /* [0x0E] GENERIC_SHORT7 */ + 64, /* [0x0F] GENERIC_SHORT8 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x10] NULL To be ignored */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x11] BLANKING_DATA To be ignored */ + 8, /* [0x12] EMBEDDED non Image Data */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x13] RESERVED_0x13 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x14] RESERVED_0x14 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x15] RESERVED_0x15 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x16] RESERVED_0x16 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x17] RESERVED_0x17 */ + 12, /* [0x18] YUV420_8 */ + 15, /* [0x19] YUV420_10 */ + 12, /* [0x1A] YUV420_8_LEGACY */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x1B] RESERVED_0x1B */ + 12, /* [0x1C] YUV420_8_SHIFT */ + 15, /* [0x1D] YUV420_10_SHIFT */ + 16, /* [0x1E] YUV422_8 */ + 20, /* [0x1F] YUV422_10 */ + 16, /* [0x20] RGB_444 */ + 16, /* [0x21] RGB_555 */ + 16, /* [0x22] RGB_565 */ + 18, /* [0x23] RGB_666 */ + 24, /* [0x24] RGB_888 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x25] RESERVED_0x25 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x26] RESERVED_0x26 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x27] RESERVED_0x27 */ + 6, /* [0x28] RAW_6 */ + 7, /* [0x29] RAW_7 */ + 8, /* [0x2A] RAW_8 */ + 10, /* [0x2B] RAW_10 */ + 12, /* [0x2C] RAW_12 */ + 14, /* [0x2D] RAW_14 */ + 16, /* [0x2E] RAW_16 */ + 8, /* [0x2F] BINARY_8 */ + 8, /* [0x30] USER_DEF1 */ + 8, /* [0x31] USER_DEF2 */ + 8, /* [0x32] USER_DEF3 */ + 8, /* [0x33] USER_DEF4 */ + 8, /* [0x34] USER_DEF5 */ + 8, /* [0x35] USER_DEF6 */ + 8, /* [0x36] USER_DEF7 */ + 8, /* [0x37] USER_DEF8 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x38] RESERVED_0x38 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x39] RESERVED_0x39 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x3A] RESERVED_0x3A */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x3B] RESERVED_0x3B */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x3C] RESERVED_0x3C */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x3D] RESERVED_0x3D */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x3E] RESERVED_0x3E */ + IA_CSS_UNSUPPORTED_DATA_TYPE /* [0x3F] RESERVED_0x3F */ +}; + +STORAGE_CLASS_INLINE int get_stream_cfg_buff_slot( + struct ia_css_isys_context *ctx, + int stream_handle, + int stream_cfg_buff_counter) +{ + NOT_USED(ctx); + return (stream_handle * STREAM_CFG_BUFS_PER_MSG_QUEUE) + + stream_cfg_buff_counter; +} + +STORAGE_CLASS_INLINE int get_next_frame_buff_slot( + struct ia_css_isys_context *ctx, + int stream_handle, + int next_frame_buff_counter) +{ + NOT_USED(ctx); + return (stream_handle * NEXT_FRAME_BUFS_PER_MSG_QUEUE) + + next_frame_buff_counter; +} + +STORAGE_CLASS_INLINE void free_comm_buff_shared_mem( + struct ia_css_isys_context *ctx, + int stream_handle, + int stream_cfg_buff_counter, + int next_frame_buff_counter) +{ + int buff_slot; + + /* Initialiser is the current value of stream_handle */ + for (; stream_handle >= 0; stream_handle--) { + /* + * Initialiser is the current value of stream_cfg_buff_counter + */ + for (; stream_cfg_buff_counter >= 0; + stream_cfg_buff_counter--) { + buff_slot = get_stream_cfg_buff_slot( + ctx, stream_handle, stream_cfg_buff_counter); + ia_css_shared_buffer_free( + ctx->ssid, ctx->mmid, + ctx->isys_comm_buffer_queue. + pstream_cfg_buff_id[buff_slot]); + } + /* Set for the next iteration */ + stream_cfg_buff_counter = STREAM_CFG_BUFS_PER_MSG_QUEUE - 1; + /* + * Initialiser is the current value of next_frame_buff_counter + */ + for (; next_frame_buff_counter >= 0; + next_frame_buff_counter--) { + buff_slot = get_next_frame_buff_slot( + ctx, stream_handle, next_frame_buff_counter); + ia_css_shared_buffer_free( + ctx->ssid, ctx->mmid, + ctx->isys_comm_buffer_queue. + pnext_frame_buff_id[buff_slot]); + } + next_frame_buff_counter = NEXT_FRAME_BUFS_PER_MSG_QUEUE - 1; + } +} + +/* + * ia_css_isys_constr_comm_buff_queue() + */ +int ia_css_isys_constr_comm_buff_queue( + struct ia_css_isys_context *ctx) +{ + int stream_handle; + int stream_cfg_buff_counter; + int next_frame_buff_counter; + int buff_slot; + + verifret(ctx, EFAULT); /* Host Consistency */ + + ctx->isys_comm_buffer_queue.pstream_cfg_buff_id = + (ia_css_shared_buffer *) + ia_css_cpu_mem_alloc(ctx-> + num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] * + STREAM_CFG_BUFS_PER_MSG_QUEUE * + sizeof(ia_css_shared_buffer)); + verifret(ctx->isys_comm_buffer_queue.pstream_cfg_buff_id != NULL, + EFAULT); + + ctx->isys_comm_buffer_queue.pnext_frame_buff_id = + (ia_css_shared_buffer *) + ia_css_cpu_mem_alloc(ctx-> + num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] * + NEXT_FRAME_BUFS_PER_MSG_QUEUE * + sizeof(ia_css_shared_buffer)); + if (ctx->isys_comm_buffer_queue.pnext_frame_buff_id == NULL) { + ia_css_cpu_mem_free( + ctx->isys_comm_buffer_queue.pstream_cfg_buff_id); + verifret(0, EFAULT); /* return EFAULT; equivalent */ + } + + for (stream_handle = 0; stream_handle < + (int)ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + stream_handle++) { + /* Initialisation needs to happen here for both loops */ + stream_cfg_buff_counter = 0; + next_frame_buff_counter = 0; + + for (; stream_cfg_buff_counter < STREAM_CFG_BUFS_PER_MSG_QUEUE; + stream_cfg_buff_counter++) { + buff_slot = get_stream_cfg_buff_slot( + ctx, stream_handle, stream_cfg_buff_counter); + ctx->isys_comm_buffer_queue. + pstream_cfg_buff_id[buff_slot] = + ia_css_shared_buffer_alloc( + ctx->ssid, ctx->mmid, + sizeof(struct + ia_css_isys_stream_cfg_data_comm)); + if (ctx->isys_comm_buffer_queue.pstream_cfg_buff_id[ + buff_slot] == 0) { + goto SHARED_BUFF_ALLOC_FAILURE; + } + } + ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle] = 0; + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle] = 0; + for (; next_frame_buff_counter < + (int)NEXT_FRAME_BUFS_PER_MSG_QUEUE; + next_frame_buff_counter++) { + buff_slot = get_next_frame_buff_slot( + ctx, stream_handle, + next_frame_buff_counter); + ctx->isys_comm_buffer_queue. + pnext_frame_buff_id[buff_slot] = + ia_css_shared_buffer_alloc( + ctx->ssid, ctx->mmid, + sizeof(struct + ia_css_isys_frame_buff_set_comm)); + if (ctx->isys_comm_buffer_queue. + pnext_frame_buff_id[buff_slot] == 0) { + goto SHARED_BUFF_ALLOC_FAILURE; + } + } + ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle] = 0; + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle] = 0; + } + + return 0; + +SHARED_BUFF_ALLOC_FAILURE: + /* stream_handle has correct value for calling the free function */ + /* prepare stream_cfg_buff_counter for calling the free function */ + stream_cfg_buff_counter--; + /* prepare next_frame_buff_counter for calling the free function */ + next_frame_buff_counter--; + free_comm_buff_shared_mem( + ctx, + stream_handle, + stream_cfg_buff_counter, + next_frame_buff_counter); + + verifret(0, EFAULT); /* return EFAULT; equivalent */ +} + +/* + * ia_css_isys_force_unmap_comm_buff_queue() + */ +int ia_css_isys_force_unmap_comm_buff_queue( + struct ia_css_isys_context *ctx) +{ + int stream_handle; + int buff_slot; + + verifret(ctx, EFAULT); /* Host Consistency */ + + IA_CSS_TRACE_0(ISYSAPI, WARNING, + "ia_css_isys_force_unmap_comm_buff_queue() called\n"); + for (stream_handle = 0; stream_handle < + (int)ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + stream_handle++) { + /* Host-FW Consistency */ + verifret((ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle] - + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle]) <= + STREAM_CFG_BUFS_PER_MSG_QUEUE, EPROTO); + for (; ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle] < + ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle]; + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle]++) { + IA_CSS_TRACE_1(ISYSAPI, WARNING, + "CSS forced unmapping stream_cfg %d\n", + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle]); + buff_slot = get_stream_cfg_buff_slot( + ctx, stream_handle, + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle] % + STREAM_CFG_BUFS_PER_MSG_QUEUE); + ia_css_shared_buffer_css_unmap( + ctx->isys_comm_buffer_queue. + pstream_cfg_buff_id[buff_slot]); + } + /* Host-FW Consistency */ + verifret((ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle] - + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle]) <= + NEXT_FRAME_BUFS_PER_MSG_QUEUE, EPROTO); + for (; ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle] < + ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle]; + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle]++) { + IA_CSS_TRACE_1(ISYSAPI, WARNING, + "CSS forced unmapping next_frame %d\n", + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle]); + buff_slot = get_next_frame_buff_slot( + ctx, stream_handle, + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle] % + NEXT_FRAME_BUFS_PER_MSG_QUEUE); + ia_css_shared_buffer_css_unmap( + ctx->isys_comm_buffer_queue. + pnext_frame_buff_id[buff_slot]); + } + } + + return 0; +} + +/* + * ia_css_isys_destr_comm_buff_queue() + */ +int ia_css_isys_destr_comm_buff_queue( + struct ia_css_isys_context *ctx) +{ + verifret(ctx, EFAULT); /* Host Consistency */ + + free_comm_buff_shared_mem( + ctx, + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] - 1, + STREAM_CFG_BUFS_PER_MSG_QUEUE - 1, + NEXT_FRAME_BUFS_PER_MSG_QUEUE - 1); + + ia_css_cpu_mem_free(ctx->isys_comm_buffer_queue.pnext_frame_buff_id); + ia_css_cpu_mem_free(ctx->isys_comm_buffer_queue.pstream_cfg_buff_id); + + return 0; +} + +STORAGE_CLASS_INLINE void resolution_host_to_css( + const struct ia_css_isys_resolution *resolution_host, + struct ia_css_isys_resolution_comm *resolution_css) +{ + resolution_css->width = resolution_host->width; + resolution_css->height = resolution_host->height; +} + +STORAGE_CLASS_INLINE void output_pin_payload_host_to_css( + const struct ia_css_isys_output_pin_payload *output_pin_payload_host, + struct ia_css_isys_output_pin_payload_comm *output_pin_payload_css) +{ + output_pin_payload_css->out_buf_id = + output_pin_payload_host->out_buf_id; + output_pin_payload_css->addr = output_pin_payload_host->addr; +#ifdef ENABLE_DEC400 + output_pin_payload_css->compress = output_pin_payload_host->compress; +#else + output_pin_payload_css->compress = 0; +#endif /* ENABLE_DEC400 */ +} + +STORAGE_CLASS_INLINE void output_pin_info_host_to_css( + const struct ia_css_isys_output_pin_info *output_pin_info_host, + struct ia_css_isys_output_pin_info_comm *output_pin_info_css) +{ + output_pin_info_css->input_pin_id = output_pin_info_host->input_pin_id; + resolution_host_to_css( + &output_pin_info_host->output_res, + &output_pin_info_css->output_res); + output_pin_info_css->stride = output_pin_info_host->stride; + output_pin_info_css->pt = output_pin_info_host->pt; + output_pin_info_css->watermark_in_lines = + output_pin_info_host->watermark_in_lines; + output_pin_info_css->send_irq = output_pin_info_host->send_irq; + output_pin_info_css->ft = output_pin_info_host->ft; + output_pin_info_css->link_id = output_pin_info_host->link_id; +#ifdef ENABLE_DEC400 + output_pin_info_css->reserve_compression = output_pin_info_host->reserve_compression; + output_pin_info_css->payload_buf_size = output_pin_info_host->payload_buf_size; +#else + output_pin_info_css->reserve_compression = 0; + /* Though payload_buf_size was added for compression, set sane value for + * payload_buf_size, just in case... + */ + output_pin_info_css->payload_buf_size = + output_pin_info_host->stride * output_pin_info_host->output_res.height; +#endif /* ENABLE_DEC400 */ +} + +STORAGE_CLASS_INLINE void param_pin_host_to_css( + const struct ia_css_isys_param_pin *param_pin_host, + struct ia_css_isys_param_pin_comm *param_pin_css) +{ + param_pin_css->param_buf_id = param_pin_host->param_buf_id; + param_pin_css->addr = param_pin_host->addr; +} + +STORAGE_CLASS_INLINE void input_pin_info_host_to_css( + const struct ia_css_isys_input_pin_info *input_pin_info_host, + struct ia_css_isys_input_pin_info_comm *input_pin_info_css) +{ + resolution_host_to_css( + &input_pin_info_host->input_res, + &input_pin_info_css->input_res); + if (input_pin_info_host->dt >= N_IA_CSS_ISYS_MIPI_DATA_TYPE) { + IA_CSS_TRACE_0(ISYSAPI, ERROR, + "input_pin_info_host->dt out of range\n"); + return; + } + if (input_pin_info_host->dt_rename_mode >= N_IA_CSS_ISYS_MIPI_DT_MODE) { + IA_CSS_TRACE_0(ISYSAPI, ERROR, + "input_pin_info_host->dt_rename_mode out of range\n"); + return; + } + /* Mapped DT check if data type renaming is being used*/ + if (input_pin_info_host->dt_rename_mode == IA_CSS_ISYS_MIPI_DT_RENAMED_MODE && + input_pin_info_host->mapped_dt >= N_IA_CSS_ISYS_MIPI_DATA_TYPE) { + IA_CSS_TRACE_0(ISYSAPI, ERROR, + "input_pin_info_host->mapped_dt out of range\n"); + return; + } + input_pin_info_css->dt = input_pin_info_host->dt; + input_pin_info_css->mipi_store_mode = + input_pin_info_host->mipi_store_mode; + input_pin_info_css->bits_per_pix = + ia_css_isys_extracted_bits_per_pixel_per_mipi_data_type[ + input_pin_info_host->dt]; + if (input_pin_info_host->dt_rename_mode == IA_CSS_ISYS_MIPI_DT_RENAMED_MODE) { + input_pin_info_css->mapped_dt = input_pin_info_host->mapped_dt; + } else { + input_pin_info_css->mapped_dt = N_IA_CSS_ISYS_MIPI_DATA_TYPE; + } +} + +STORAGE_CLASS_INLINE void isa_cfg_host_to_css( + const struct ia_css_isys_isa_cfg *isa_cfg_host, + struct ia_css_isys_isa_cfg_comm *isa_cfg_css) +{ + unsigned int i; + + for (i = 0; i < N_IA_CSS_ISYS_RESOLUTION_INFO; i++) { + resolution_host_to_css(&isa_cfg_host->isa_res[i], + &isa_cfg_css->isa_res[i]); + } + isa_cfg_css->cfg_fields = 0; + ISA_CFG_FIELD_SET(BLC_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->blc_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(LSC_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->lsc_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(DPC_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->dpc_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(DOWNSCALER_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->downscaler_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(AWB_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->awb_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(AF_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->af_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(AE_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->ae_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(PAF_TYPE, isa_cfg_css->cfg_fields, + isa_cfg_host->paf_type); + ISA_CFG_FIELD_SET(SEND_IRQ_STATS_READY, isa_cfg_css->cfg_fields, + isa_cfg_host->send_irq_stats_ready ? 1 : 0); + ISA_CFG_FIELD_SET(SEND_RESP_STATS_READY, isa_cfg_css->cfg_fields, + (isa_cfg_host->send_irq_stats_ready || + isa_cfg_host->send_resp_stats_ready) ? 1 : 0); +} + +STORAGE_CLASS_INLINE void cropping_host_to_css( + const struct ia_css_isys_cropping *cropping_host, + struct ia_css_isys_cropping_comm *cropping_css) +{ + cropping_css->top_offset = cropping_host->top_offset; + cropping_css->left_offset = cropping_host->left_offset; + cropping_css->bottom_offset = cropping_host->bottom_offset; + cropping_css->right_offset = cropping_host->right_offset; + +} + +STORAGE_CLASS_INLINE int stream_cfg_data_host_to_css( + const struct ia_css_isys_stream_cfg_data *stream_cfg_data_host, + struct ia_css_isys_stream_cfg_data_comm *stream_cfg_data_css) +{ + unsigned int i; + + stream_cfg_data_css->src = stream_cfg_data_host->src; + stream_cfg_data_css->vc = stream_cfg_data_host->vc; + stream_cfg_data_css->isl_use = stream_cfg_data_host->isl_use; + stream_cfg_data_css->compfmt = stream_cfg_data_host->compfmt; + stream_cfg_data_css->isa_cfg.cfg_fields = 0; + + switch (stream_cfg_data_host->isl_use) { + case IA_CSS_ISYS_USE_SINGLE_ISA: + isa_cfg_host_to_css(&stream_cfg_data_host->isa_cfg, + &stream_cfg_data_css->isa_cfg); + /* deliberate fall-through */ + case IA_CSS_ISYS_USE_SINGLE_DUAL_ISL: + for (i = 0; i < N_IA_CSS_ISYS_CROPPING_LOCATION; i++) { + cropping_host_to_css(&stream_cfg_data_host->crop[i], + &stream_cfg_data_css->crop[i]); + } + break; + case IA_CSS_ISYS_USE_NO_ISL_NO_ISA: + break; + default: + break; + } + + stream_cfg_data_css->send_irq_sof_discarded = + stream_cfg_data_host->send_irq_sof_discarded ? 1 : 0; + stream_cfg_data_css->send_irq_eof_discarded = + stream_cfg_data_host->send_irq_eof_discarded ? 1 : 0; + stream_cfg_data_css->send_resp_sof_discarded = + stream_cfg_data_host->send_irq_sof_discarded ? + 1 : stream_cfg_data_host->send_resp_sof_discarded; + stream_cfg_data_css->send_resp_eof_discarded = + stream_cfg_data_host->send_irq_eof_discarded ? + 1 : stream_cfg_data_host->send_resp_eof_discarded; + stream_cfg_data_css->nof_input_pins = + stream_cfg_data_host->nof_input_pins; + stream_cfg_data_css->nof_output_pins = + stream_cfg_data_host->nof_output_pins; + for (i = 0; i < stream_cfg_data_host->nof_input_pins; i++) { + input_pin_info_host_to_css( + &stream_cfg_data_host->input_pins[i], + &stream_cfg_data_css->input_pins[i]); + verifret(stream_cfg_data_css->input_pins[i].bits_per_pix, + EINVAL); + } + for (i = 0; i < stream_cfg_data_host->nof_output_pins; i++) { + output_pin_info_host_to_css( + &stream_cfg_data_host->output_pins[i], + &stream_cfg_data_css->output_pins[i]); + } + return 0; +} + +STORAGE_CLASS_INLINE void frame_buff_set_host_to_css( + const struct ia_css_isys_frame_buff_set *frame_buff_set_host, + struct ia_css_isys_frame_buff_set_comm *frame_buff_set_css) +{ + int i; + + for (i = 0; i < MAX_OPINS; i++) { + output_pin_payload_host_to_css( + &frame_buff_set_host->output_pins[i], + &frame_buff_set_css->output_pins[i]); + } + + param_pin_host_to_css(&frame_buff_set_host->process_group_light, + &frame_buff_set_css->process_group_light); + frame_buff_set_css->send_irq_sof = + frame_buff_set_host->send_irq_sof ? 1 : 0; + frame_buff_set_css->send_irq_eof = + frame_buff_set_host->send_irq_eof ? 1 : 0; + frame_buff_set_css->send_irq_capture_done = + (uint8_t)frame_buff_set_host->send_irq_capture_done; + frame_buff_set_css->send_irq_capture_ack = + frame_buff_set_host->send_irq_capture_ack ? 1 : 0; + frame_buff_set_css->send_resp_sof = + frame_buff_set_host->send_irq_sof ? + 1 : frame_buff_set_host->send_resp_sof; + frame_buff_set_css->send_resp_eof = + frame_buff_set_host->send_irq_eof ? + 1 : frame_buff_set_host->send_resp_eof; + frame_buff_set_css->frame_counter = + frame_buff_set_host->frame_counter; +} + +STORAGE_CLASS_INLINE void buffer_partition_host_to_css( + const struct ia_css_isys_buffer_partition *buffer_partition_host, + struct ia_css_isys_buffer_partition_comm *buffer_partition_css) +{ + int i; + + for (i = 0; i < STREAM_ID_MAX; i++) { + buffer_partition_css->num_gda_pages[i] = + buffer_partition_host->num_gda_pages[i]; + } +} + +STORAGE_CLASS_INLINE void output_pin_payload_css_to_host( + const struct ia_css_isys_output_pin_payload_comm * + output_pin_payload_css, + struct ia_css_isys_output_pin_payload *output_pin_payload_host) +{ + output_pin_payload_host->out_buf_id = + output_pin_payload_css->out_buf_id; + output_pin_payload_host->addr = output_pin_payload_css->addr; +#ifdef ENABLE_DEC400 + output_pin_payload_host->compress = output_pin_payload_css->compress; +#else + output_pin_payload_host->compress = 0; +#endif /* ENABLE_DEC400 */ +} + +STORAGE_CLASS_INLINE void param_pin_css_to_host( + const struct ia_css_isys_param_pin_comm *param_pin_css, + struct ia_css_isys_param_pin *param_pin_host) +{ + param_pin_host->param_buf_id = param_pin_css->param_buf_id; + param_pin_host->addr = param_pin_css->addr; + +} + +STORAGE_CLASS_INLINE void resp_info_css_to_host( + const struct ia_css_isys_resp_info_comm *resp_info_css, + struct ia_css_isys_resp_info *resp_info_host) +{ + resp_info_host->type = resp_info_css->type; + resp_info_host->timestamp[0] = resp_info_css->timestamp[0]; + resp_info_host->timestamp[1] = resp_info_css->timestamp[1]; + resp_info_host->stream_handle = resp_info_css->stream_handle; + resp_info_host->error = resp_info_css->error_info.error; + resp_info_host->error_details = + resp_info_css->error_info.error_details; + output_pin_payload_css_to_host( + &resp_info_css->pin, &resp_info_host->pin); + resp_info_host->pin_id = resp_info_css->pin_id; + param_pin_css_to_host(&resp_info_css->process_group_light, + &resp_info_host->process_group_light); + resp_info_host->acc_id = resp_info_css->acc_id; + resp_info_host->frame_counter = resp_info_css->frame_counter; + resp_info_host->written_direct = resp_info_css->written_direct; +} + +/* + * ia_css_isys_constr_fw_stream_cfg() + */ +int ia_css_isys_constr_fw_stream_cfg( + struct ia_css_isys_context *ctx, + const unsigned int stream_handle, + ia_css_shared_buffer_css_address *pstream_cfg_fw, + ia_css_shared_buffer *pbuf_stream_cfg_id, + const struct ia_css_isys_stream_cfg_data *stream_cfg) +{ + ia_css_shared_buffer_cpu_address stream_cfg_cpu_addr; + ia_css_shared_buffer_css_address stream_cfg_css_addr; + int buff_slot; + int retval = 0; + unsigned int wrap_compensation; + const unsigned int wrap_condition = 0xFFFFFFFF; + + verifret(ctx, EFAULT); /* Host Consistency */ + verifret(pstream_cfg_fw, EFAULT); /* Host Consistency */ + verifret(pbuf_stream_cfg_id, EFAULT); /* Host Consistency */ + verifret(stream_cfg, EFAULT); /* Host Consistency */ + + /* Host-FW Consistency */ + verifret((ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle] - + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle]) < + STREAM_CFG_BUFS_PER_MSG_QUEUE, EPROTO); + buff_slot = get_stream_cfg_buff_slot(ctx, stream_handle, + ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle] % + STREAM_CFG_BUFS_PER_MSG_QUEUE); + *pbuf_stream_cfg_id = + ctx->isys_comm_buffer_queue.pstream_cfg_buff_id[buff_slot]; + /* Host-FW Consistency */ + verifret(*pbuf_stream_cfg_id, EADDRNOTAVAIL); + + stream_cfg_cpu_addr = + ia_css_shared_buffer_cpu_map(*pbuf_stream_cfg_id); + /* Host-FW Consistency */ + verifret(stream_cfg_cpu_addr, EADDRINUSE); + + retval = stream_cfg_data_host_to_css(stream_cfg, stream_cfg_cpu_addr); + if (retval) + return retval; + + stream_cfg_cpu_addr = + ia_css_shared_buffer_cpu_unmap(*pbuf_stream_cfg_id); + /* Host Consistency */ + verifret(stream_cfg_cpu_addr, EADDRINUSE); + + stream_cfg_css_addr = + ia_css_shared_buffer_css_map(*pbuf_stream_cfg_id); + /* Host Consistency */ + verifret(stream_cfg_css_addr, EADDRINUSE); + + ia_css_shared_buffer_css_update(ctx->mmid, *pbuf_stream_cfg_id); + + *pstream_cfg_fw = stream_cfg_css_addr; + + /* + * cover head wrap around extreme case, + * in which case force tail to wrap around too + * while maintaining diff and modulo + */ + if (ctx->isys_comm_buffer_queue.stream_cfg_queue_head[stream_handle] == + wrap_condition) { + /* Value to be added to both head and tail */ + wrap_compensation = + /* + * Distance of wrap_condition to 0, + * will need to be added for wrapping around head to 0 + */ + (0 - wrap_condition) + + /* + * To force tail to also wrap around, + * since it has to happen concurrently + */ + STREAM_CFG_BUFS_PER_MSG_QUEUE + + /* To preserve the same modulo, + * since the previous will result in head modulo 0 + */ + (wrap_condition % STREAM_CFG_BUFS_PER_MSG_QUEUE); + ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle] += + wrap_compensation; + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle] += + wrap_compensation; + } + ctx->isys_comm_buffer_queue.stream_cfg_queue_head[stream_handle]++; + + return 0; +} + +/* + * ia_css_isys_constr_fw_next_frame() + */ +int ia_css_isys_constr_fw_next_frame( + struct ia_css_isys_context *ctx, + const unsigned int stream_handle, + ia_css_shared_buffer_css_address *pnext_frame_fw, + ia_css_shared_buffer *pbuf_next_frame_id, + const struct ia_css_isys_frame_buff_set *next_frame) +{ + ia_css_shared_buffer_cpu_address next_frame_cpu_addr; + ia_css_shared_buffer_css_address next_frame_css_addr; + int buff_slot; + unsigned int wrap_compensation; + const unsigned int wrap_condition = 0xFFFFFFFF; + + verifret(ctx, EFAULT); /* Host Consistency */ + verifret(pnext_frame_fw, EFAULT); /* Host Consistency */ + verifret(next_frame, EFAULT); /* Host Consistency */ + verifret(pbuf_next_frame_id, EFAULT); /* Host Consistency */ + + /* For some reason responses are not dequeued in time */ + verifret((ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle] - + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle]) < + NEXT_FRAME_BUFS_PER_MSG_QUEUE, EPERM); + buff_slot = get_next_frame_buff_slot(ctx, stream_handle, + ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle] % + NEXT_FRAME_BUFS_PER_MSG_QUEUE); + *pbuf_next_frame_id = + ctx->isys_comm_buffer_queue.pnext_frame_buff_id[buff_slot]; + /* Host-FW Consistency */ + verifret(*pbuf_next_frame_id, EADDRNOTAVAIL); + + /* map it in cpu */ + next_frame_cpu_addr = + ia_css_shared_buffer_cpu_map(*pbuf_next_frame_id); + /* Host-FW Consistency */ + verifret(next_frame_cpu_addr, EADDRINUSE); + + frame_buff_set_host_to_css(next_frame, next_frame_cpu_addr); + + /* unmap the buffer from cpu */ + next_frame_cpu_addr = + ia_css_shared_buffer_cpu_unmap(*pbuf_next_frame_id); + /* Host Consistency */ + verifret(next_frame_cpu_addr, EADDRINUSE); + + /* map it to css */ + next_frame_css_addr = + ia_css_shared_buffer_css_map(*pbuf_next_frame_id); + /* Host Consistency */ + verifret(next_frame_css_addr, EADDRINUSE); + + ia_css_shared_buffer_css_update(ctx->mmid, *pbuf_next_frame_id); + + *pnext_frame_fw = next_frame_css_addr; + + /* + * cover head wrap around extreme case, + * in which case force tail to wrap around too + * while maintaining diff and modulo + */ + if (ctx->isys_comm_buffer_queue.next_frame_queue_head[stream_handle] == + wrap_condition) { + /* Value to be added to both head and tail */ + wrap_compensation = + /* + * Distance of wrap_condition to 0, + * will need to be added for wrapping around head to 0 + */ + (0 - wrap_condition) + + /* + * To force tail to also wrap around, + * since it has to happen concurrently + */ + NEXT_FRAME_BUFS_PER_MSG_QUEUE + + /* + * To preserve the same modulo, + * since the previous will result in head modulo 0 + */ + (wrap_condition % NEXT_FRAME_BUFS_PER_MSG_QUEUE); + ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle] += + wrap_compensation; + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle] += + wrap_compensation; + } + ctx->isys_comm_buffer_queue.next_frame_queue_head[stream_handle]++; + + return 0; +} + +/* + * ia_css_isys_extract_fw_response() + */ +int ia_css_isys_extract_fw_response( + struct ia_css_isys_context *ctx, + const struct resp_queue_token *token, + struct ia_css_isys_resp_info *received_response) +{ + int buff_slot; + unsigned int css_address; + + verifret(ctx, EFAULT); /* Host Consistency */ + verifret(token, EFAULT); /* Host Consistency */ + verifret(received_response, EFAULT); /* Host Consistency */ + + resp_info_css_to_host(&(token->resp_info), received_response); + + switch (token->resp_info.type) { + case IA_CSS_ISYS_RESP_TYPE_STREAM_OPEN_DONE: + /* Host-FW Consistency */ + verifret((ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[token->resp_info.stream_handle] - + ctx->isys_comm_buffer_queue.stream_cfg_queue_tail[ + token->resp_info.stream_handle]) > 0, EPROTO); + buff_slot = get_stream_cfg_buff_slot(ctx, + token->resp_info.stream_handle, + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[ + token->resp_info.stream_handle] % + STREAM_CFG_BUFS_PER_MSG_QUEUE); + verifret((ia_css_shared_buffer)HOST_ADDRESS( + token->resp_info.buf_id) == + ctx->isys_comm_buffer_queue. + pstream_cfg_buff_id[buff_slot], EIO); + ctx->isys_comm_buffer_queue.stream_cfg_queue_tail[ + token->resp_info.stream_handle]++; + css_address = ia_css_shared_buffer_css_unmap( + (ia_css_shared_buffer) + HOST_ADDRESS(token->resp_info.buf_id)); + verifret(css_address, EADDRINUSE); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK: + case IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK: + /* Host-FW Consistency */ + verifret((ctx->isys_comm_buffer_queue. + next_frame_queue_head[token->resp_info.stream_handle] - + ctx->isys_comm_buffer_queue.next_frame_queue_tail[ + token->resp_info.stream_handle]) > 0, EPROTO); + buff_slot = get_next_frame_buff_slot(ctx, + token->resp_info.stream_handle, + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[ + token->resp_info.stream_handle] % + NEXT_FRAME_BUFS_PER_MSG_QUEUE); + verifret((ia_css_shared_buffer)HOST_ADDRESS( + token->resp_info.buf_id) == + ctx->isys_comm_buffer_queue. + pnext_frame_buff_id[buff_slot], EIO); + ctx->isys_comm_buffer_queue.next_frame_queue_tail[ + token->resp_info.stream_handle]++; + css_address = ia_css_shared_buffer_css_unmap( + (ia_css_shared_buffer) + HOST_ADDRESS(token->resp_info.buf_id)); + verifret(css_address, EADDRINUSE); + break; + default: + break; + } + + return 0; +} + +/* + * ia_css_isys_extract_proxy_response() + */ +int ia_css_isys_extract_proxy_response( + const struct proxy_resp_queue_token *token, + struct ia_css_proxy_write_req_resp *preceived_response) +{ + verifret(token, EFAULT); /* Host Consistency */ + verifret(preceived_response, EFAULT); /* Host Consistency */ + + preceived_response->request_id = token->proxy_resp_info.request_id; + preceived_response->error = token->proxy_resp_info.error_info.error; + preceived_response->error_details = + token->proxy_resp_info.error_info.error_details; + + return 0; +} + +/* + * ia_css_isys_prepare_param() + */ +int ia_css_isys_prepare_param( + struct ia_css_isys_fw_config *isys_fw_cfg, + const struct ia_css_isys_buffer_partition *buf_partition, + const unsigned int num_send_queues[], + const unsigned int num_recv_queues[]) +{ + unsigned int i; + + verifret(isys_fw_cfg, EFAULT); /* Host Consistency */ + verifret(buf_partition, EFAULT); /* Host Consistency */ + verifret(num_send_queues, EFAULT); /* Host Consistency */ + verifret(num_recv_queues, EFAULT); /* Host Consistency */ + + buffer_partition_host_to_css(buf_partition, + &isys_fw_cfg->buffer_partition); + for (i = 0; i < N_IA_CSS_ISYS_QUEUE_TYPE; i++) { + isys_fw_cfg->num_send_queues[i] = num_send_queues[i]; + isys_fw_cfg->num_recv_queues[i] = num_recv_queues[i]; + } + + return 0; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_private.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_private.h new file mode 100644 index 0000000000000..d53fa53c9a818 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_private.h @@ -0,0 +1,156 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYS_PRIVATE_H +#define __IA_CSS_ISYS_PRIVATE_H + + +#include "type_support.h" +/* Needed for the structure member ia_css_sys_context * sys */ +#include "ia_css_syscom.h" +/* Needed for the definitions of STREAM_ID_MAX */ +#include "ia_css_isysapi.h" +/* The following is needed for the function arguments */ +#include "ia_css_isys_fw_bridged_types.h" + +#include "ia_css_shared_buffer.h" + + +/* Set for the respective error handling */ +#define VERIFY_DEVSTATE 1 + +#if (VERIFY_DEVSTATE != 0) +/** + * enum device_state + */ +enum device_state { + IA_CSS_ISYS_DEVICE_STATE_IDLE = 0, + IA_CSS_ISYS_DEVICE_STATE_CONFIGURED = 1, + IA_CSS_ISYS_DEVICE_STATE_READY = 2 +}; +#endif /* VERIFY_DEVSTATE */ + +/** + * enum stream_state + */ +enum stream_state { + IA_CSS_ISYS_STREAM_STATE_IDLE = 0, + IA_CSS_ISYS_STREAM_STATE_OPENED = 1, + IA_CSS_ISYS_STREAM_STATE_STARTED = 2 +}; + + +/** + * struct ia_css_isys_comm_buffer_queue + */ +struct ia_css_isys_comm_buffer_queue { + ia_css_shared_buffer *pstream_cfg_buff_id; + unsigned int stream_cfg_queue_head[STREAM_ID_MAX]; + unsigned int stream_cfg_queue_tail[STREAM_ID_MAX]; + ia_css_shared_buffer *pnext_frame_buff_id; + unsigned int next_frame_queue_head[STREAM_ID_MAX]; + unsigned int next_frame_queue_tail[STREAM_ID_MAX]; +}; + + +/** + * struct ia_css_isys_context + */ +struct ia_css_isys_context { + struct ia_css_syscom_context *sys; + /* add here any isys specific members that need + to be passed into the isys api functions as input */ + unsigned int ssid; + unsigned int mmid; + unsigned int num_send_queues[N_IA_CSS_ISYS_QUEUE_TYPE]; + unsigned int num_recv_queues[N_IA_CSS_ISYS_QUEUE_TYPE]; + unsigned int send_queue_size[N_IA_CSS_ISYS_QUEUE_TYPE]; + struct ia_css_isys_comm_buffer_queue isys_comm_buffer_queue; + unsigned int stream_nof_output_pins[STREAM_ID_MAX]; +#if (VERIFY_DEVSTATE != 0) + enum device_state dev_state; +#endif /* VERIFY_DEVSTATE */ + enum stream_state stream_state_array[STREAM_ID_MAX]; + /* If true, this context is created based on secure config */ + bool secure; +}; + + +/** + * ia_css_isys_constr_comm_buff_queue() + */ +extern int ia_css_isys_constr_comm_buff_queue( + struct ia_css_isys_context *ctx +); + +/** + * ia_css_isys_force_unmap_comm_buff_queue() + */ +extern int ia_css_isys_force_unmap_comm_buff_queue( + struct ia_css_isys_context *ctx +); + +/** + * ia_css_isys_destr_comm_buff_queue() + */ +extern int ia_css_isys_destr_comm_buff_queue( + struct ia_css_isys_context *ctx +); + +/** + * ia_css_isys_constr_fw_stream_cfg() + */ +extern int ia_css_isys_constr_fw_stream_cfg( + struct ia_css_isys_context *ctx, + const unsigned int stream_handle, + ia_css_shared_buffer_css_address *pstream_cfg_fw, + ia_css_shared_buffer *pbuf_stream_cfg_id, + const struct ia_css_isys_stream_cfg_data *stream_cfg +); + +/** + * ia_css_isys_constr_fw_next_frame() + */ +extern int ia_css_isys_constr_fw_next_frame( + struct ia_css_isys_context *ctx, + const unsigned int stream_handle, + ia_css_shared_buffer_css_address *pnext_frame_fw, + ia_css_shared_buffer *pbuf_next_frame_id, + const struct ia_css_isys_frame_buff_set *next_frame +); + +/** + * ia_css_isys_extract_fw_response() + */ +extern int ia_css_isys_extract_fw_response( + struct ia_css_isys_context *ctx, + const struct resp_queue_token *token, + struct ia_css_isys_resp_info *received_response +); +extern int ia_css_isys_extract_proxy_response( + const struct proxy_resp_queue_token *token, + struct ia_css_proxy_write_req_resp *received_response +); + +/** + * ia_css_isys_prepare_param() + */ +extern int ia_css_isys_prepare_param( + struct ia_css_isys_fw_config *isys_fw_cfg, + const struct ia_css_isys_buffer_partition *buf_partition, + const unsigned int num_send_queues[], + const unsigned int num_recv_queues[] +); + +#endif /* __IA_CSS_ISYS_PRIVATE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_public.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_public.c new file mode 100644 index 0000000000000..0e49af6353e03 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_public.c @@ -0,0 +1,1283 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/* TODO: REMOVE --> START IF EXTERNALLY INCLUDED/DEFINED */ +/* These are temporary, the correct numbers need to be inserted/linked */ +/* Until this happens, the following definitions stay here */ +#define INPUT_MIN_WIDTH 1 +#define INPUT_MAX_WIDTH 16384 +#define INPUT_MIN_HEIGHT 1 +#define INPUT_MAX_HEIGHT 16384 +#define OUTPUT_MIN_WIDTH 1 +#define OUTPUT_MAX_WIDTH 16384 +#define OUTPUT_MIN_HEIGHT 1 +#define OUTPUT_MAX_HEIGHT 16384 +/* REMOVE --> END IF EXTERNALLY INCLUDED/DEFINED */ + + +/* The FW bridged types are included through the following */ +#include "ia_css_isysapi.h" +/* The following provides the isys-sys context */ +#include "ia_css_isys_private.h" +/* The following provides the sys layer functions */ +#include "ia_css_syscom.h" + +#include "ia_css_cell.h" +#include "ipu_device_cell_properties.h" + +/* The following provides the tracing functions */ +#include "ia_css_isysapi_trace.h" +#include "ia_css_isys_public_trace.h" + +#include "ia_css_shared_buffer_cpu.h" +/* The following is needed for the + * stddef.h (NULL), + * limits.h (CHAR_BIT definition). + */ +#include "type_support.h" +#include "error_support.h" +#include "cpu_mem_support.h" +#include "math_support.h" +#include "misc_support.h" +#include "system_const.h" + +static int isys_context_create( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config); +static int isys_start_server( + const struct ia_css_isys_device_cfg_data *config); + +static int isys_context_create( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config) +{ + int retval; + unsigned int stream_handle; + struct ia_css_isys_context *ctx; + struct ia_css_syscom_config sys; + /* Needs to be updated in case new type of queues are introduced */ + struct ia_css_syscom_queue_config input_queue_cfg[N_MAX_SEND_QUEUES]; + /* Needs to be updated in case new type of queues are introduced */ + struct ia_css_syscom_queue_config output_queue_cfg[N_MAX_RECV_QUEUES]; + struct ia_css_isys_fw_config isys_fw_cfg; + unsigned int proxy_write_queue_size; + unsigned int ssid; + unsigned int mmid; + unsigned int i; + + /* Printing "ENTRY isys_context_create" + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY isys_context_create\n"); + + verifret(config != NULL, EFAULT); + + /* Printing configuration information if tracing level = VERBOSE. */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_device_config_data(config); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + + /* Runtime check for # of send and recv MSG queues */ + verifret(config->driver_sys.num_send_queues <= + N_MAX_MSG_SEND_QUEUES/*=STREAM_ID_MAX*/, EINVAL); + verifret(config->driver_sys.num_recv_queues <= + N_MAX_MSG_RECV_QUEUES, EINVAL); + + /* Runtime check for send and recv MSG queue sizes */ + verifret(config->driver_sys.send_queue_size <= MAX_QUEUE_SIZE, EINVAL); + verifret(config->driver_sys.recv_queue_size <= MAX_QUEUE_SIZE, EINVAL); + + /* TODO: return an error in case MAX_QUEUE_SIZE is exceeded + * (Similar to runtime check on MSG queue sizes) + */ + proxy_write_queue_size = uclip( + config->driver_proxy.proxy_write_queue_size, + MIN_QUEUE_SIZE, + MAX_QUEUE_SIZE); + + ctx = (struct ia_css_isys_context *) + ia_css_cpu_mem_alloc(sizeof(struct ia_css_isys_context)); + verifret(ctx != NULL, EFAULT); + *context = (HANDLE)ctx; + + /* Copy to the sys config the driver_sys config, + * and add the internal info (token sizes) + */ + ssid = config->driver_sys.ssid; + mmid = config->driver_sys.mmid; + sys.ssid = ssid; + sys.mmid = mmid; + + ctx->secure = config->secure; + /* Following operations need to be aligned with + * "enum ia_css_isys_queue_type" list (list of queue types) + */ + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] = + N_MAX_PROXY_SEND_QUEUES; + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV] = + N_MAX_DEV_SEND_QUEUES; + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] = + config->driver_sys.num_send_queues; + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] = + N_MAX_PROXY_RECV_QUEUES; + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV] = + 0; /* Common msg/dev return queue */ + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] = + config->driver_sys.num_recv_queues; + + sys.num_input_queues = + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] + + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV] + + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + sys.num_output_queues = + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] + + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV] + + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + + sys.input = input_queue_cfg; + for (i = 0; + i < ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY]; + i++) { + input_queue_cfg[BASE_PROXY_SEND_QUEUES + i].queue_size = + proxy_write_queue_size; + input_queue_cfg[BASE_PROXY_SEND_QUEUES + i].token_size = + sizeof(struct proxy_send_queue_token); + } + for (i = 0; + i < ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV]; + i++) { + input_queue_cfg[BASE_DEV_SEND_QUEUES + i].queue_size = + DEV_SEND_QUEUE_SIZE; + input_queue_cfg[BASE_DEV_SEND_QUEUES + i].token_size = + sizeof(struct send_queue_token); + } + for (i = 0; + i < ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + i++) { + input_queue_cfg[BASE_MSG_SEND_QUEUES + i].queue_size = + config->driver_sys.send_queue_size; + input_queue_cfg[BASE_MSG_SEND_QUEUES + i].token_size = + sizeof(struct send_queue_token); + } + + ctx->send_queue_size[IA_CSS_ISYS_QUEUE_TYPE_PROXY] = + proxy_write_queue_size; + ctx->send_queue_size[IA_CSS_ISYS_QUEUE_TYPE_DEV] = + DEV_SEND_QUEUE_SIZE; + ctx->send_queue_size[IA_CSS_ISYS_QUEUE_TYPE_MSG] = + config->driver_sys.send_queue_size; + + sys.output = output_queue_cfg; + for (i = 0; + i < ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY]; + i++) { + output_queue_cfg[BASE_PROXY_RECV_QUEUES + i].queue_size = + proxy_write_queue_size; + output_queue_cfg[BASE_PROXY_RECV_QUEUES + i].token_size = + sizeof(struct proxy_resp_queue_token); + } + /* There is no recv DEV queue */ + for (i = 0; + i < ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + i++) { + output_queue_cfg[BASE_MSG_RECV_QUEUES + i].queue_size = + config->driver_sys.recv_queue_size; + output_queue_cfg[BASE_MSG_RECV_QUEUES + i].token_size = + sizeof(struct resp_queue_token); + } + + sys.regs_addr = ipu_device_cell_memory_address(SPC0, + IPU_DEVICE_SP2600_CONTROL_REGS); + sys.dmem_addr = ipu_device_cell_memory_address(SPC0, + IPU_DEVICE_SP2600_CONTROL_DMEM); + +#if HAS_DUAL_CMD_CTX_SUPPORT + sys.dmem_addr += config->secure ? REGMEM_SECURE_OFFSET : REGMEM_OFFSET; +#endif + + /* Prepare the param */ + ia_css_isys_prepare_param( + &isys_fw_cfg, + &config->buffer_partition, + ctx->num_send_queues, + ctx->num_recv_queues); + + /* parameter struct to be passed to fw */ + sys.specific_addr = &isys_fw_cfg; + /* parameters size */ + sys.specific_size = sizeof(isys_fw_cfg); + sys.secure = config->secure; + if (config->secure) { + sys.vtl0_addr_mask = config->vtl0_addr_mask; + } + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "isys_context_create || call ia_css_syscom_open()\n"); + /* The allocation of the queues will take place within this call and + * info will be stored in sys_context output + */ + ctx->sys = ia_css_syscom_open(&sys, NULL); + if (!ctx->sys) { + ia_css_cpu_mem_free(ctx); + return -EFAULT; + } + + /* Update the context with the id's */ + ctx->ssid = ssid; + ctx->mmid = mmid; + + for (stream_handle = 0; stream_handle < STREAM_ID_MAX; + stream_handle++) { + ctx->stream_state_array[stream_handle] = + IA_CSS_ISYS_STREAM_STATE_IDLE; + } + + retval = ia_css_isys_constr_comm_buff_queue(ctx); + if (retval) { + ia_css_syscom_close(ctx->sys); + ia_css_syscom_release(ctx->sys, 1); + ia_css_cpu_mem_free(ctx); + return retval; + } + +#if (VERIFY_DEVSTATE != 0) + ctx->dev_state = IA_CSS_ISYS_DEVICE_STATE_CONFIGURED; +#endif /* VERIFY_DEVSTATE */ + + /* Printing device configuration and device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + + /* Printing "LEAVE isys_context_create" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE isys_context_create\n"); + return 0; +} + +static int isys_start_server( + const struct ia_css_isys_device_cfg_data *config) +{ + verifret(config != NULL, EFAULT); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "isys_start_server || start SPC\n"); + /* The firmware is loaded and syscom is ready, start the SPC */ + ia_css_cell_start_prefetch(config->driver_sys.ssid, SPC0, + config->driver_sys.icache_prefetch); + IA_CSS_TRACE_1(ISYSAPI, VERBOSE, "SPC prefetch: %d\n", + config->driver_sys.icache_prefetch); + return 0; +} + +/** + * ia_css_isys_device_open() - open and configure ISYS device + */ +#if HAS_DUAL_CMD_CTX_SUPPORT +int ia_css_isys_context_create( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config) +{ + return isys_context_create(context, config); +} + +/* push context information to DMEM for FW to access */ +int ia_css_isys_context_store_dmem( + const HANDLE *context, + const struct ia_css_isys_device_cfg_data *config) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *) *context; + + return ia_css_syscom_store_dmem(ctx->sys, config->driver_sys.ssid, config->vtl0_addr_mask); +} + +bool ia_css_isys_ab_spc_ready( + HANDLE *context) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *) *context; + + return ia_css_syscom_is_ab_spc_ready(ctx->sys); +} + +int ia_css_isys_device_open( + const struct ia_css_isys_device_cfg_data *config) +{ + return isys_start_server(config); +} +#else +int ia_css_isys_device_open( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config) +{ + int retval; + + retval = isys_context_create(context, config); + if (retval) { + IA_CSS_TRACE_1(ISYSAPI, ERROR, "ia_css_isys_device_open() failed (retval %d)\n", retval); + return retval; + } + + isys_start_server(config); + return 0; +} +#endif + +/** + * ia_css_isys_device_open_ready() - open and configure ISYS device + */ +int ia_css_isys_device_open_ready(HANDLE context) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + unsigned int i; + int retval; + + /* Printing "ENTRY IA_CSS_ISYS_DEVICE_OPEN" + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_DEVICE_OPEN\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_CONFIGURED, EPERM); +#endif /* VERIFY_DEVSTATE */ + + /* Open the ports for all the non-MSG send queues (PROXY + DEV) */ + for (i = 0; + i < ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] + + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV]; + i++) { + retval = ia_css_syscom_send_port_open(ctx->sys, i); + verifret(retval != FW_ERROR_BUSY, EBUSY); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + } + + /* Open the ports for all the recv queues (PROXY + MSG) */ + for (i = 0; + i < (ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] + + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]); + i++) { + retval = ia_css_syscom_recv_port_open(ctx->sys, i); + verifret(retval != FW_ERROR_BUSY, EBUSY); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + } + +#if (VERIFY_DEVSTATE != 0) + ctx->dev_state = IA_CSS_ISYS_DEVICE_STATE_READY; +#endif /* VERIFY_DEVSTATE */ + + /* Printing "LEAVE IA_CSS_ISYS_DEVICE_OPEN_READY" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "LEAVE IA_CSS_ISYS_DEVICE_OPEN_READY\n"); + return 0; +} + + + /** + * ia_css_isys_stream_open() - open and configure a virtual stream + */ +int ia_css_isys_stream_open( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_stream_cfg_data *stream_cfg) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + unsigned int i; + int retval = 0; + int packets; + struct send_queue_token token; + ia_css_shared_buffer_css_address stream_cfg_fw = 0; + ia_css_shared_buffer buf_stream_cfg_id = (ia_css_shared_buffer)NULL; + /* Printing "ENTRY IA_CSS_ISYS_STREAM_OPEN" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_STREAM_OPEN\n"); + + verifret(ctx, EFAULT); + + /* Printing stream configuration and device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); + print_stream_config_data(stream_cfg); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_IDLE, EPERM); + + verifret(stream_cfg != NULL, EFAULT); + verifret(stream_cfg->src < N_IA_CSS_ISYS_STREAM_SRC, EINVAL); + verifret(stream_cfg->vc < N_IA_CSS_ISYS_MIPI_VC, EINVAL); + verifret(stream_cfg->isl_use < N_IA_CSS_ISYS_USE, EINVAL); + if (stream_cfg->isl_use != IA_CSS_ISYS_USE_NO_ISL_NO_ISA) { + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].bottom_offset >= + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].top_offset + + OUTPUT_MIN_HEIGHT, EINVAL); + + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].bottom_offset <= + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].top_offset + + OUTPUT_MAX_HEIGHT, EINVAL); + + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].right_offset >= + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].left_offset + + OUTPUT_MIN_WIDTH, EINVAL); + + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].right_offset <= + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].left_offset + + OUTPUT_MAX_WIDTH, EINVAL); + } + verifret(stream_cfg->nof_input_pins <= MAX_IPINS, EINVAL); + verifret(stream_cfg->nof_output_pins <= MAX_OPINS, EINVAL); + for (i = 0; i < stream_cfg->nof_input_pins; i++) { + /* Verify input pin */ + verifret( + stream_cfg->input_pins[i].input_res.width >= + INPUT_MIN_WIDTH && + stream_cfg->input_pins[i].input_res.width <= + INPUT_MAX_WIDTH && + stream_cfg->input_pins[i].input_res.height >= + INPUT_MIN_HEIGHT && + stream_cfg->input_pins[i].input_res.height <= + INPUT_MAX_HEIGHT, EINVAL); + verifret(stream_cfg->input_pins[i].dt < + N_IA_CSS_ISYS_MIPI_DATA_TYPE, EINVAL); +/* #ifdef To be removed when driver inits the value */ +#ifdef DRIVER_INIT_MIPI_STORE_MODE + verifret(stream_cfg->input_pins[i].mipi_store_mode < + N_IA_CSS_ISYS_MIPI_STORE_MODE, EINVAL); +#endif /* DRIVER_INIT_MIPI_STORE_MODE */ + } + for (i = 0; i < stream_cfg->nof_output_pins; i++) { + /* Verify output pin */ + verifret(stream_cfg->output_pins[i].input_pin_id < + stream_cfg->nof_input_pins, EINVAL); + verifret(stream_cfg->output_pins[i].pt < + N_IA_CSS_ISYS_PIN_TYPE, EINVAL); + verifret(stream_cfg->output_pins[i].ft < + N_IA_CSS_ISYS_FRAME_FORMAT, EINVAL); + /* Verify that the stride is aligned to 64 bytes: HW spec */ + verifret(stream_cfg->output_pins[i].stride%(XMEM_WIDTH/8) == + 0, EINVAL); + verifret((stream_cfg->output_pins[i].output_res.width >= + OUTPUT_MIN_WIDTH) && + (stream_cfg->output_pins[i].output_res.width <= + OUTPUT_MAX_WIDTH) && + (stream_cfg->output_pins[i].output_res.height >= + OUTPUT_MIN_HEIGHT) && + (stream_cfg->output_pins[i].output_res.height <= + OUTPUT_MAX_HEIGHT), EINVAL); + verifret((stream_cfg->output_pins[i].pt == + IA_CSS_ISYS_PIN_TYPE_MIPI) || + (stream_cfg-> + input_pins[stream_cfg->output_pins[i].input_pin_id].mipi_store_mode != + IA_CSS_ISYS_MIPI_STORE_MODE_DISCARD_LONG_HEADER), EINVAL); + if (stream_cfg->isl_use == IA_CSS_ISYS_USE_SINGLE_ISA) { + switch (stream_cfg->output_pins[i].pt) { + case IA_CSS_ISYS_PIN_TYPE_RAW_NS: + /* Ensure the PIFCONV cropped resolution + * matches the RAW_NS output pin resolution + */ + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED].bottom_offset == + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED].top_offset + + (int)stream_cfg->output_pins[i].output_res.height, EINVAL); + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED].right_offset == + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED].left_offset + + (int)stream_cfg->output_pins[i].output_res.width, EINVAL); + /* Ensure the ISAPF cropped resolution matches + * the Non-scaled ISA output resolution before + * the PIFCONV cropping, since nothing can + * modify the resolution in that part of + * the pipe + */ + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].bottom_offset == + stream_cfg->crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].top_offset + + (int)stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED].height, + EINVAL); + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].right_offset == + stream_cfg->crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].left_offset + + (int)stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED].width, + EINVAL); + /* Ensure the Non-scaled ISA output resolution + * before the PIFCONV cropping bounds the + * RAW_NS pin output resolution since padding + * is not supported + */ + verifret(stream_cfg-> +isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED].height >= +stream_cfg->output_pins[i].output_res.height, EINVAL); + verifret(stream_cfg-> +isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED].width >= +stream_cfg->output_pins[i].output_res.width, EINVAL); + break; + case IA_CSS_ISYS_PIN_TYPE_RAW_S: + /* Ensure the ScaledPIFCONV cropped resolution + * matches the RAW_S output pin resolution + */ + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_SCALED].bottom_offset == + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_SCALED].top_offset + + (int)stream_cfg->output_pins[i].output_res.height, EINVAL); + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_SCALED].right_offset == + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_SCALED].left_offset + + (int)stream_cfg->output_pins[i].output_res.width, EINVAL); + /* Ensure the ISAPF cropped resolution bounds + * the Scaled ISA output resolution before the + * ScaledPIFCONV cropping, since only IDS can + * modify the resolution, and this only to + * make it smaller + */ + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].bottom_offset >= + stream_cfg->crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].top_offset + + (int)stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED].height, + EINVAL); + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].right_offset >= + stream_cfg->crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].left_offset + + (int)stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED].width, + EINVAL); + /* Ensure the Scaled ISA output resolution + * before the ScaledPIFCONV cropping bounds + * the RAW_S pin output resolution since + * padding is not supported + */ + verifret(stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED].height >= + stream_cfg->output_pins[i].output_res.height, EINVAL); + verifret(stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED].width >= + stream_cfg->output_pins[i].output_res.width, EINVAL); + break; + default: + break; + } + } + } + + /* open 1 send queue/stream and a single receive queue + * if not existing + */ + retval = ia_css_syscom_send_port_open(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(retval != FW_ERROR_BUSY, EBUSY); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_OPEN; + retval = ia_css_isys_constr_fw_stream_cfg(ctx, stream_handle, + &stream_cfg_fw, &buf_stream_cfg_id, stream_cfg); + verifret(retval == 0, retval); + token.payload = stream_cfg_fw; + token.buf_handle = HOST_ADDRESS(buf_stream_cfg_id); + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + ctx->stream_nof_output_pins[stream_handle] = + stream_cfg->nof_output_pins; + ctx->stream_state_array[stream_handle] = + IA_CSS_ISYS_STREAM_STATE_OPENED; + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_OPEN" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_STREAM_OPEN\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_close() - close virtual stream + */ +int ia_css_isys_stream_close( + HANDLE context, + const unsigned int stream_handle) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct send_queue_token token; + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_CLOSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_STREAM_CLOSE\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_OPENED, EPERM); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_CLOSE; + token.stream_id = stream_handle; + token.payload = 0; + token.buf_handle = 0; + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + /* close 1 send queue/stream and the single receive queue + * if none is using it + */ + retval = ia_css_syscom_send_port_close(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + + ctx->stream_state_array[stream_handle] = IA_CSS_ISYS_STREAM_STATE_IDLE; + /* Printing "LEAVE IA_CSS_ISYS_STREAM_CLOSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_STREAM_CLOSE\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_start() - starts handling a mipi virtual stream + */ +int ia_css_isys_stream_start( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_frame_buff_set *next_frame) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct send_queue_token token; + ia_css_shared_buffer_css_address next_frame_fw = 0; + ia_css_shared_buffer buf_next_frame_id = (ia_css_shared_buffer)NULL; + + /* Printing "ENTRY IA_CSS_ISYS_STREAM_START" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_STREAM_START\n"); + + verifret(ctx, EFAULT); + + /* Printing frame configuration and device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); + print_isys_frame_buff_set(next_frame, + ctx->stream_nof_output_pins[stream_handle]); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_OPENED, EPERM); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + if (next_frame != NULL) { + token.send_type = + IA_CSS_ISYS_SEND_TYPE_STREAM_START_AND_CAPTURE; + retval = ia_css_isys_constr_fw_next_frame(ctx, stream_handle, + &next_frame_fw, &buf_next_frame_id, next_frame); + verifret(retval == 0, retval); + token.payload = next_frame_fw; + token.buf_handle = HOST_ADDRESS(buf_next_frame_id); + } else { + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_START; + token.payload = 0; + token.buf_handle = 0; + } + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + ctx->stream_state_array[stream_handle] = + IA_CSS_ISYS_STREAM_STATE_STARTED; + /* Printing "LEAVE IA_CSS_ISYS_STREAM_START" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_STREAM_START\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_stop() - Stops a mipi virtual stream + */ +int ia_css_isys_stream_stop( + HANDLE context, + const unsigned int stream_handle) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct send_queue_token token; + + /* Printing "ENTRY IA_CSS_ISYS_STREAM_STOP" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_STREAM_STOP\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_STARTED, EPERM); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_DEV_SEND_QUEUES)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_STOP; + token.stream_id = stream_handle; + token.payload = 0; + token.buf_handle = 0; + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_DEV_SEND_QUEUES), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + ctx->stream_state_array[stream_handle] = + IA_CSS_ISYS_STREAM_STATE_OPENED; + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_STOP" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_STREAM_STOP\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_flush() - stops a mipi virtual stream but + * completes processing cmd backlog + */ +int ia_css_isys_stream_flush( + HANDLE context, + const unsigned int stream_handle) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct send_queue_token token; + + /* Printing "ENTRY IA_CSS_ISYS_STREAM_FLUSH" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_STREAM_FLUSH\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_STARTED, EPERM); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_FLUSH; + token.payload = 0; + token.buf_handle = 0; + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + ctx->stream_state_array[stream_handle] = + IA_CSS_ISYS_STREAM_STATE_OPENED; + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_FLUSH" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_STREAM_FLUSH\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_capture_indication() + * - captures "next frame" on stream_handle + */ +int ia_css_isys_stream_capture_indication( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_frame_buff_set *next_frame) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct send_queue_token token; + ia_css_shared_buffer_css_address next_frame_fw = 0; + ia_css_shared_buffer buf_next_frame_id = (ia_css_shared_buffer)NULL; + + /* Printing "ENTRY IA_CSS_ISYS_STREAM_CAPTURE_INDICATION" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "ENTRY IA_CSS_ISYS_STREAM_CAPTURE_INDICATION\n"); + + verifret(ctx, EFAULT); + + /* Printing frame configuration and device handle context information + *if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); + print_isys_frame_buff_set(next_frame, + ctx->stream_nof_output_pins[stream_handle]); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_STARTED, EPERM); + verifret(next_frame != NULL, EFAULT); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + { + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_CAPTURE; + retval = ia_css_isys_constr_fw_next_frame(ctx, stream_handle, + &next_frame_fw, &buf_next_frame_id, next_frame); + verifret(retval == 0, retval); + token.payload = next_frame_fw; + token.buf_handle = HOST_ADDRESS(buf_next_frame_id); + } + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_CAPTURE_INDICATION" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "LEAVE IA_CSS_ISYS_STREAM_CAPTURE_INDICATION\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_handle_response() - handle ISYS responses + */ +int ia_css_isys_stream_handle_response( + HANDLE context, + struct ia_css_isys_resp_info *received_response) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct resp_queue_token token; + + /* Printing "ENTRY IA_CSS_ISYS_STREAM_HANDLE_RESPONSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "ENTRY IA_CSS_ISYS_STREAM_HANDLE_RESPONSE\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(received_response != NULL, EFAULT); + + packets = ia_css_syscom_recv_port_available( + ctx->sys, BASE_MSG_RECV_QUEUES); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + + retval = ia_css_syscom_recv_port_transfer( + ctx->sys, BASE_MSG_RECV_QUEUES, &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + retval = ia_css_isys_extract_fw_response( + ctx, &token, received_response); + verifret(retval == 0, retval); + + /* Printing received response information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_isys_resp_info(received_response); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + + verifret(received_response->type < N_IA_CSS_ISYS_RESP_TYPE, EINVAL); + verifret(received_response->stream_handle < STREAM_ID_MAX, EINVAL); + + if (received_response->type == IA_CSS_ISYS_RESP_TYPE_PIN_DATA_READY || + received_response->type == IA_CSS_ISYS_RESP_TYPE_PIN_DATA_WATERMARK || + received_response->type == IA_CSS_ISYS_RESP_TYPE_PIN_DATA_SKIPPED) { + verifret(received_response->pin.addr != 0, EFAULT); + verifret(received_response->pin.out_buf_id != 0, EFAULT); + verifret(received_response->pin_id < + ctx->stream_nof_output_pins[received_response->stream_handle], + EINVAL); + } + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_HANDLE_RESPONSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "LEAVE IA_CSS_ISYS_STREAM_HANDLE_RESPONSE\n"); + + return 0; +} + + +/** + * ia_css_isys_device_close() - close ISYS device + */ +static int isys_context_destroy(HANDLE context) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + unsigned int stream_handle; + unsigned int queue_id; + unsigned int nof_recv_queues; + int retval = 0; + + /* Printing "ENTRY IA_CSS_ISYS_DEVICE_CLOSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY isys_context_destroy\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + nof_recv_queues = ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] + + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY]; + /* Close the ports for all the recv queues (MSG and PROXY) */ + for (queue_id = 0; queue_id < nof_recv_queues; queue_id++) { + retval = ia_css_syscom_recv_port_close( + ctx->sys, queue_id); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + } + + /* Close the ports for PROXY send queue(s) */ + for (queue_id = 0; + queue_id < ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] + + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV]; + queue_id++) { + retval = ia_css_syscom_send_port_close( + ctx->sys, queue_id); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + } + + for (stream_handle = 0; stream_handle < STREAM_ID_MAX; + stream_handle++) { + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_IDLE, EPERM); + } + + retval = ia_css_syscom_close(ctx->sys); + verifret(retval == 0, EBUSY); + +#if (VERIFY_DEVSTATE != 0) + ctx->dev_state = IA_CSS_ISYS_DEVICE_STATE_CONFIGURED; +#endif /* VERIFY_DEVSTATE */ + + /* Printing "LEAVE IA_CSS_ISYS_DEVICE_CLOSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE isys_context_destroy\n"); + + return 0; +} +/** + * ia_css_isys_device_close() - close ISYS device + */ +#if HAS_DUAL_CMD_CTX_SUPPORT +int ia_css_isys_context_destroy(HANDLE context) +{ + return isys_context_destroy(context); +} + +void ia_css_isys_device_close(void) +{ + /* Created for legacy, nothing to perform here */ +} + +#else +int ia_css_isys_device_close(HANDLE context) +{ + return isys_context_destroy(context); +} +#endif + +/** + * ia_css_isys_device_release() - release ISYS device + */ +int ia_css_isys_device_release(HANDLE context, unsigned int force) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + + /* Printing "ENTRY IA_CSS_ISYS_DEVICE_RELEASE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_DEVICE_RELEASE\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_CONFIGURED, EPERM); +#endif /* VERIFY_DEVSTATE */ + + retval = ia_css_syscom_release(ctx->sys, force); + verifret(retval == 0, EBUSY); + + /* If ia_css_isys_device_release called with force==1, this should + * happen after timeout, so no active transfers + * If ia_css_isys_device_release called with force==0, this should + * happen after SP has gone idle, so no active transfers + */ + ia_css_isys_force_unmap_comm_buff_queue(ctx); + ia_css_isys_destr_comm_buff_queue(ctx); + +#if (VERIFY_DEVSTATE != 0) + ctx->dev_state = IA_CSS_ISYS_DEVICE_STATE_IDLE; +#endif /* VERIFY_DEVSTATE */ + + ia_css_cpu_mem_free(ctx); + + /* Printing "LEAVE IA_CSS_ISYS_DEVICE_RELEASE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_DEVICE_RELEASE\n"); + + return 0; +} + +/** + * ia_css_isys_proxy_write_req() - send ISYS proxy write requests + */ +int ia_css_isys_proxy_write_req( + HANDLE context, + const struct ia_css_proxy_write_req_val *write_req_val) +{ + + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + struct proxy_send_queue_token token; + int packets; + int retval = 0; + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_PROXY_WRITE_REQ\n"); + verifret(ctx, EFAULT); + verifret(write_req_val != NULL, EFAULT); + + packets = ia_css_syscom_send_port_available(ctx->sys, 0); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + + token.request_id = write_req_val->request_id; + token.region_index = write_req_val->region_index; + token.offset = write_req_val->offset; + token.value = write_req_val->value; + + retval = ia_css_syscom_send_port_transfer(ctx->sys, 0, &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_PROXY_WRITE_REQ\n"); + + return 0; +} + +/** + * ia_css_isys_proxy_handle_write_response() - handle ISYS proxy responses + */ +int ia_css_isys_proxy_handle_write_response( + HANDLE context, + struct ia_css_proxy_write_req_resp *received_response) +{ + + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + struct proxy_resp_queue_token token; + int retval = 0; + int packets; + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "ENTRY IA_CSS_ISYS_PROXY_HANDLE_WRITE_RESPONSE\n"); + verifret(ctx, EFAULT); + verifret(received_response != NULL, EFAULT); + + packets = ia_css_syscom_recv_port_available(ctx->sys, 0); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + + retval = ia_css_syscom_recv_port_transfer(ctx->sys, 0, &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + + retval = ia_css_isys_extract_proxy_response(&token, received_response); + verifret(retval == 0, retval); + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "LEAVE IA_CSS_ISYS_PROXY_HANDLE_WRITE_RESPONSE\n"); + + return 0; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_public_trace.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_public_trace.c new file mode 100644 index 0000000000000..660bcc62da3c0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_public_trace.c @@ -0,0 +1,379 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_isysapi_trace.h" +#include "ia_css_isys_public_trace.h" +#include "ia_css_isysapi_types.h" +#include "ia_css_isysapi.h" +#include "ia_css_isys_private.h" +#include "error_support.h" +#include "ia_css_syscom.h" + +/** + * print_handle_context - formatted print function for + * struct ia_css_isys_context *ctx variable + */ +int print_handle_context(struct ia_css_isys_context *ctx) +{ + unsigned int i; + + verifret(ctx != NULL, EFAULT); + /* Print ctx->(ssid, mmid, dev_state) */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "Print ia_css_isys_context *ctx\n" + "-------------------------------------------------------\n"); + IA_CSS_TRACE_3(ISYSAPI, VERBOSE, + "\tia_css_isys_context->ssid = %d\n" + "\t\t\tia_css_isys_context->mmid = %d\n" + "\t\t\tia_css_isys_context->device_state = %d\n" + , ctx->ssid + , ctx->mmid + , ctx->dev_state); + /* Print ctx->(stream_state_array, stream_nof_output_pins) */ + for (i = 0; i < STREAM_ID_MAX; i++) { + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_context->stream_state[i = %d] = %d\n" + "\t\t\tia_css_isys_context->stream_nof_output_pins[i = %d] = %d\n" + , i + , ctx->stream_state_array[i] + , i + , ctx->stream_nof_output_pins[i]); + } + /* Print ctx->ia_css_syscom_context */ + IA_CSS_TRACE_1(ISYSAPI, VERBOSE, + "\tia_css_isys_context->ia_css_syscom_context = %p\n" + , (struct ia_css_syscom_context *)(ctx->sys)); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "-------------------------------------------------------\n"); + return 0; +} + +/** + * print_device_config_data - formatted print function for + * struct ia_css_isys_device_cfg_data *config variable + */ +int print_device_config_data(const struct ia_css_isys_device_cfg_data *config) +{ + verifret(config != NULL, EFAULT); + IA_CSS_TRACE_0(ISYSAPI, + VERBOSE, + "Print ia_css_isys_device_cfg_data *config\n" + "-------------------------------------------------------\n"); + IA_CSS_TRACE_7(ISYSAPI, + VERBOSE, + "\tia_css_isys_device_cfg_data->driver_sys.ssid = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_sys.mmid = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_sys.num_send_queues = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_sys.num_recv_queues = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_sys.send_queue_size = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_sys.recv_queue_size = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_proxy.proxy_write_queue_size = %d\n", + config->driver_sys.ssid, + config->driver_sys.mmid, + config->driver_sys.num_send_queues, + config->driver_sys.num_recv_queues, + config->driver_sys.send_queue_size, + config->driver_sys.recv_queue_size, + config->driver_proxy.proxy_write_queue_size); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "-------------------------------------------------------\n"); + return 0; +} + +/** + * print_stream_config_data - formatted print function for + * ia_css_isys_stream_cfg_data stream_cfg variable + */ +int print_stream_config_data( + const struct ia_css_isys_stream_cfg_data *stream_cfg) +{ + unsigned int i; + + verifret(stream_cfg != NULL, EFAULT); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "Print ia_css_isys_stream_cfg_data stream_cfg\n" + "-------------------------------------------------------\n"); + IA_CSS_TRACE_5(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_isl_use = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_stream_source = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_mipi_vc = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->nof_input_pins = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->nof_output_pins = %d\n" + , stream_cfg->isl_use + , stream_cfg->src + , stream_cfg->vc + , stream_cfg->nof_input_pins + , stream_cfg->nof_output_pins); + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->send_irq_sof_discarded = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->send_irq_eof_discarded = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->send_resp_sof_discarded = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->send_resp_eof_discarded = %d\n" + , stream_cfg->send_irq_sof_discarded + , stream_cfg->send_irq_eof_discarded + , stream_cfg->send_resp_sof_discarded + , stream_cfg->send_resp_eof_discarded); + for (i = 0; i < stream_cfg->nof_input_pins; i++) { + IA_CSS_TRACE_6(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_input_pin_info[i = %d].ia_css_isys_mipi_data_type = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_input_pin_info[i = %d].ia_css_isys_resolution.width = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_input_pin_info[i = %d].ia_css_isys_resolution.height = %d\n" + , i + , stream_cfg->input_pins[i].dt + , i + , stream_cfg->input_pins[i].input_res.width + , i + , stream_cfg->input_pins[i].input_res.height); + IA_CSS_TRACE_2(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_input_pin_info[i = %d].ia_css_isys_mipi_store_mode = %d\n" + , i + , stream_cfg->input_pins[i].mipi_store_mode); + } + for (i = 0; i < N_IA_CSS_ISYS_CROPPING_LOCATION; i++) { + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_cropping[i = %d].top_offset = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_cropping[i = %d].left_offset = %d\n" + , i + , stream_cfg->crop[i].top_offset + , i + , stream_cfg->crop[i].left_offset); + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_cropping[i = %d].bottom_offset = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_cropping[i = %d].right_offset = %d\n" + , i + , stream_cfg->crop[i].bottom_offset + , i + , stream_cfg->crop[i].right_offset); + } + for (i = 0; i < stream_cfg->nof_output_pins; i++) { + IA_CSS_TRACE_6(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].ia_css_isys_pin_type = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].ia_css_isys_frame_format_type = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].input_pin_id = %d\n" + , i + , stream_cfg->output_pins[i].pt + , i + , stream_cfg->output_pins[i].ft + , i + , stream_cfg->output_pins[i].input_pin_id); + IA_CSS_TRACE_6(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].watermark_in_lines = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].send_irq = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].stride = %d\n" + , i + , stream_cfg->output_pins[i].watermark_in_lines + , i + , stream_cfg->output_pins[i].send_irq + , i + , stream_cfg->output_pins[i].stride); + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].ia_css_isys_resolution.width = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].ia_css_isys_resolution.height = %d\n" + , i + , stream_cfg->output_pins[i].output_res.width + , i + , stream_cfg->output_pins[i].output_res.height); + } + for (i = 0; i < N_IA_CSS_ISYS_RESOLUTION_INFO; i++) { + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.ia_css_isys_resolution[i = %d].width = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.ia_css_isys_resolution[i = %d].height = %d\n" + , i + , stream_cfg->isa_cfg.isa_res[i].width + , i + , stream_cfg->isa_cfg.isa_res[i].height); + } + IA_CSS_TRACE_7(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.blc_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.lsc_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.dpc_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.downscaler_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.awb_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.af_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.ae_enabled = %d\n" + , stream_cfg->isa_cfg.blc_enabled + , stream_cfg->isa_cfg.lsc_enabled + , stream_cfg->isa_cfg.dpc_enabled + , stream_cfg->isa_cfg.downscaler_enabled + , stream_cfg->isa_cfg.awb_enabled + , stream_cfg->isa_cfg.af_enabled + , stream_cfg->isa_cfg.ae_enabled); + + IA_CSS_TRACE_1(ISYSAPI, VERBOSE, + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.paf_type = %d\n" + , stream_cfg->isa_cfg.paf_type); + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "-------------------------------------------------------\n"); + return 0; +} + +/** + * print_isys_frame_buff_set - formatted print function for + * struct ia_css_isys_frame_buff_set *next_frame variable + */ +int print_isys_frame_buff_set( + const struct ia_css_isys_frame_buff_set *next_frame, + const unsigned int nof_output_pins) +{ + unsigned int i; + + verifret(next_frame != NULL, EFAULT); + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "Print ia_css_isys_frame_buff_set *next_frame\n" + "-------------------------------------------------------\n"); + for (i = 0; i < nof_output_pins; i++) { + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_frame_buff_set->ia_css_isys_output_pin_payload[i = %d].ia_css_return_token = %016lxu\n" + "\t\t\tia_css_isys_frame_buff_set->ia_css_isys_output_pin_payload[i = %d].ia_css_input_buffer_css_address = %08xu\n" + , i + , (unsigned long) + next_frame->output_pins[i].out_buf_id + , i + , next_frame->output_pins[i].addr); + } + IA_CSS_TRACE_2(ISYSAPI, VERBOSE, + "\tia_css_isys_frame_buff_set->process_group_light.ia_css_return_token = %016lxu\n" + "\t\t\tia_css_isys_frame_buff_set->process_group_light.ia_css_input_buffer_css_address = %08xu\n" + , (unsigned long) + next_frame->process_group_light.param_buf_id + , next_frame->process_group_light.addr); + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_frame_buff_set->send_irq_sof = %d\n" + "\t\t\tia_css_isys_frame_buff_set->send_irq_eof = %d\n" + "\t\t\tia_css_isys_frame_buff_set->send_resp_sof = %d\n" + "\t\t\tia_css_isys_frame_buff_set->send_resp_eof = %d\n" + , (int) next_frame->send_irq_sof + , (int) next_frame->send_irq_eof + , (int) next_frame->send_resp_sof + , (int) next_frame->send_resp_eof); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "-------------------------------------------------------\n"); + return 0; +} + +/** + * print_isys_resp_info - formatted print function for + * struct ia_css_isys_frame_buff_set *next_frame variable + */ +int print_isys_resp_info(struct ia_css_isys_resp_info *received_response) +{ + verifret(received_response != NULL, EFAULT); + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ISYS_RESPONSE_INFO\n" + "-------------------------------------------------------\n"); + switch (received_response->type) { + case IA_CSS_ISYS_RESP_TYPE_STREAM_OPEN_DONE: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_OPEN_DONE\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_START_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_START_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_STOP_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_STOP_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_FLUSH_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_FLUSH_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_CLOSE_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_CLOSE_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_PIN_DATA_READY: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_PIN_DATA_READY\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_PIN_DATA_WATERMARK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_PIN_DATA_WATERMARK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_FRAME_SOF: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_FRAME_SOF\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_FRAME_EOF: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_FRAME_EOF\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_DONE: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_DONE\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_PIN_DATA_SKIPPED: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_PIN_DATA_SKIPPED\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_SKIPPED: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_SKIPPED\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_FRAME_SOF_DISCARDED: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_FRAME_SOF_DISCARDED\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_FRAME_EOF_DISCARDED: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_FRAME_EOF_DISCARDED\n"); + break; + default: + IA_CSS_TRACE_0(ISYSAPI, ERROR, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = INVALID\n"); + break; + } + + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.type = %d\n" + "\t\t\tia_css_isys_resp_info.stream_handle = %d\n" + "\t\t\tia_css_isys_resp_info.time_stamp[0] = %d\n" + "\t\t\tia_css_isys_resp_info.time_stamp[1] = %d\n", + received_response->type, + received_response->stream_handle, + received_response->timestamp[0], + received_response->timestamp[1]); + IA_CSS_TRACE_7(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.error = %d\n" + "\t\t\tia_css_isys_resp_info.error_details = %d\n" + "\t\t\tia_css_isys_resp_info.pin.out_buf_id = %016llxu\n" + "\t\t\tia_css_isys_resp_info.pin.addr = %016llxu\n" + "\t\t\tia_css_isys_resp_info.pin_id = %d\n" + "\t\t\tia_css_isys_resp_info.frame_counter = %d\n," + "\t\t\tia_css_isys_resp_info.written_direct = %d\n", + received_response->error, + received_response->error_details, + (unsigned long long)received_response->pin.out_buf_id, + (unsigned long long)received_response->pin.addr, + received_response->pin_id, + received_response->frame_counter, + received_response->written_direct); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "------------------------------------------------------\n"); + + return 0; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_public_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_public_trace.h new file mode 100644 index 0000000000000..5b6508058fd6e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isys_public_trace.h @@ -0,0 +1,55 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYS_PUBLIC_TRACE_H +#define __IA_CSS_ISYS_PUBLIC_TRACE_H + +#include "ia_css_isysapi_trace.h" + +#include "ia_css_isysapi_types.h" + +#include "ia_css_isysapi.h" + +#include "ia_css_isys_private.h" +/** + * print_handle_context - formatted print function for + * struct ia_css_isys_context *ctx variable + */ +int print_handle_context(struct ia_css_isys_context *ctx); + +/** + * print_device_config_data - formatted print function for + * struct ia_css_isys_device_cfg_data *config variable + */ +int print_device_config_data(const struct ia_css_isys_device_cfg_data *config); +/** + * print_stream_config_data - formatted print function for + * ia_css_isys_stream_cfg_data stream_cfg variable + */ +int print_stream_config_data( + const struct ia_css_isys_stream_cfg_data *stream_cfg); +/** + * print_isys_frame_buff_set - formatted print function for + * struct ia_css_isys_frame_buff_set *next_frame variable + */ +int print_isys_frame_buff_set( + const struct ia_css_isys_frame_buff_set *next_frame, + const unsigned int nof_output_pins); +/** + * print_isys_isys_resp_info - formatted print function for + * struct ia_css_isys_frame_buff_set *next_frame variable + */ +int print_isys_resp_info(struct ia_css_isys_resp_info *received_response); + +#endif /* __IA_CSS_ISYS_PUBLIC_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isysapi_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isysapi_trace.h new file mode 100644 index 0000000000000..c6b944f245b11 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/isysapi/src/ia_css_isysapi_trace.h @@ -0,0 +1,79 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_TRACE_H +#define __IA_CSS_ISYSAPI_TRACE_H + +#include "ia_css_trace.h" + +#define ISYSAPI_TRACE_LOG_LEVEL_OFF 0 +#define ISYSAPI_TRACE_LOG_LEVEL_NORMAL 1 +#define ISYSAPI_TRACE_LOG_LEVEL_DEBUG 2 + +/* ISYSAPI and all the submodules in ISYSAPI will have + * the default tracing level set to this level + */ +#define ISYSAPI_TRACE_CONFIG_DEFAULT ISYSAPI_TRACE_LOG_LEVEL_NORMAL + +/* In case ISYSAPI_TRACE_CONFIG is not defined, set it to default level */ +#if !defined(ISYSAPI_TRACE_CONFIG) + #define ISYSAPI_TRACE_CONFIG ISYSAPI_TRACE_CONFIG_DEFAULT +#endif + +/* ISYSAPI Module tracing backend is mapped to + * TUNIT tracing for target platforms + */ +#ifdef IA_CSS_TRACE_PLATFORM_CELL + #ifndef HRT_CSIM + #define ISYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_TRACE + #else + #define ISYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + #endif +#else + #define ISYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#endif + +#if (defined(ISYSAPI_TRACE_CONFIG)) + /* TRACE_OFF */ + #if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_OFF + #define ISYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED + /* TRACE_NORMAL */ + #elif ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_NORMAL + #define ISYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED + /* TRACE_DEBUG */ + #elif ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + #define ISYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No ISYSAPI_TRACE_CONFIG Tracing level defined" + #endif +#else + #error "ISYSAPI_TRACE_CONFIG not defined" +#endif + +#endif /* __IA_CSS_ISYSAPI_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir.h new file mode 100644 index 0000000000000..a284d74bb4a67 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir.h @@ -0,0 +1,99 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_H +#define __IA_CSS_PKG_DIR_H + +#include "ia_css_pkg_dir_storage_class.h" +#include "ia_css_pkg_dir_types.h" +#include "type_support.h" + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +const ia_css_pkg_dir_entry_t *ia_css_pkg_dir_get_entry( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index +); + +/* User is expected to call the verify function manually, + * other functions do not call it internally + */ +IA_CSS_PKG_DIR_STORAGE_CLASS_H +int ia_css_pkg_dir_verify_header( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_get_num_entries( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_get_size_in_bytes( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +enum ia_css_pkg_dir_version ia_css_pkg_dir_get_version( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint16_t ia_css_pkg_dir_set_version( + ia_css_pkg_dir_entry_t *pkg_dir_header, + enum ia_css_pkg_dir_version version +); + + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_address_lo( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_address_hi( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_size( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint16_t ia_css_pkg_dir_entry_get_version( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint8_t ia_css_pkg_dir_entry_get_type( + const ia_css_pkg_dir_entry_t *entry +); + +/* Get the address of the specified entry in the PKG_DIR + * Note: This function expects the complete PKG_DIR in the same memory space + * and the entries contains offsets and not addresses. + */ +IA_CSS_PKG_DIR_STORAGE_CLASS_H +void *ia_css_pkg_dir_get_entry_address( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index +); + +#ifdef __IA_CSS_PKG_DIR_INLINE__ + +#include "ia_css_pkg_dir_impl.h" + +#endif + +#endif /* __IA_CSS_PKG_DIR_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_iunit.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_iunit.h new file mode 100644 index 0000000000000..ad194b0389eb7 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_iunit.h @@ -0,0 +1,46 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_IUNIT_H +#define __IA_CSS_PKG_DIR_IUNIT_H + +/* In bootflow, pkg_dir only supports upto 16 entries in pkg_dir + * pkg_dir_header + Psys_server pg + Isys_server pg + 13 Client pg + */ + +enum { + IA_CSS_PKG_DIR_SIZE = 16, + IA_CSS_PKG_DIR_ENTRIES = IA_CSS_PKG_DIR_SIZE - 1 +}; + +#define IUNIT_MAX_CLIENT_PKG_ENTRIES 13 + +/* Example assignment of unique identifiers for the FW components + * This should match the identifiers in the manifest + */ +enum ia_css_pkg_dir_entry_type { + IA_CSS_PKG_DIR_HEADER = 0, + IA_CSS_PKG_DIR_PSYS_SERVER_PG, + IA_CSS_PKG_DIR_ISYS_SERVER_PG, + IA_CSS_PKG_DIR_CLIENT_PG +}; + +/* Fixed entries in the package directory */ +enum ia_css_pkg_dir_index { + IA_CSS_PKG_DIR_PSYS_INDEX = 0, + IA_CSS_PKG_DIR_ISYS_INDEX = 1, + IA_CSS_PKG_DIR_CLIENT_0 = 2 +}; + +#endif /* __IA_CSS_PKG_DIR_IUNIT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_storage_class.h new file mode 100644 index 0000000000000..cb64172151f92 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_storage_class.h @@ -0,0 +1,29 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_STORAGE_CLASS_H +#define __IA_CSS_PKG_DIR_STORAGE_CLASS_H + + +#include "storage_class.h" + +#ifndef __IA_CSS_PKG_DIR_INLINE__ +#define IA_CSS_PKG_DIR_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PKG_DIR_STORAGE_CLASS_C +#else +#define IA_CSS_PKG_DIR_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PKG_DIR_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PKG_DIR_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_types.h new file mode 100644 index 0000000000000..b024b3da2f9e6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_types.h @@ -0,0 +1,41 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_TYPES_H +#define __IA_CSS_PKG_DIR_TYPES_H + +#include "type_support.h" + +struct ia_css_pkg_dir_entry { + uint32_t address[2]; + uint32_t size; + uint16_t version; + uint8_t type; + uint8_t unused; +}; + +typedef void ia_css_pkg_dir_t; +typedef struct ia_css_pkg_dir_entry ia_css_pkg_dir_entry_t; + +/* The version field of the pkg_dir header defines + * if entries contain offsets or pointers + */ +/* This is temporary, until all pkg_dirs use pointers */ +enum ia_css_pkg_dir_version { + IA_CSS_PKG_DIR_POINTER, + IA_CSS_PKG_DIR_OFFSET +}; + + +#endif /* __IA_CSS_PKG_DIR_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/pkg_dir.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/pkg_dir.mk new file mode 100644 index 0000000000000..32c8a68f3653c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/pkg_dir.mk @@ -0,0 +1,29 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PKG DIR + +PKG_DIR_DIR = $${MODULES_DIR}/pkg_dir +PKG_DIR_INTERFACE = $(PKG_DIR_DIR)/interface +PKG_DIR_SOURCES = $(PKG_DIR_DIR)/src + +PKG_DIR_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir.c +PKG_DIR_CPPFLAGS = -I$(PKG_DIR_INTERFACE) +PKG_DIR_CPPFLAGS += -I$(PKG_DIR_SOURCES) +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/../isp/kernels/io_ls/common +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/fw_abi_common_types/ipu +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/fw_abi_common_types/ipu/$(FW_ABI_IPU_TYPES_VERSION) + +PKG_DIR_CREATE_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir_create.c +PKG_DIR_UPDATE_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir_update.c diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/src/ia_css_pkg_dir.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/src/ia_css_pkg_dir.c new file mode 100644 index 0000000000000..348b56833e060 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/src/ia_css_pkg_dir.c @@ -0,0 +1,27 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifdef __IA_CSS_PKG_DIR_INLINE__ + +#include "storage_class.h" + +STORAGE_CLASS_INLINE int __ia_css_pkg_dir_avoid_warning_on_empty_file(void) +{ + return 0; +} + +#else +#include "ia_css_pkg_dir_impl.h" + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/src/ia_css_pkg_dir_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/src/ia_css_pkg_dir_impl.h new file mode 100644 index 0000000000000..d5067d21398f9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/src/ia_css_pkg_dir_impl.h @@ -0,0 +1,201 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_IMPL_H +#define __IA_CSS_PKG_DIR_IMPL_H + +#include "ia_css_pkg_dir.h" +#include "ia_css_pkg_dir_int.h" +#include "error_support.h" +#include "type_support.h" +#include "assert_support.h" + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +const ia_css_pkg_dir_entry_t *ia_css_pkg_dir_get_entry( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index) +{ + DECLARE_ERRVAL + struct ia_css_pkg_dir_entry *pkg_dir_header = NULL; + + verifexitval(pkg_dir != NULL, EFAULT); + + pkg_dir_header = (struct ia_css_pkg_dir_entry *)pkg_dir; + + /* First entry of the structure is the header, skip that */ + index++; + verifexitval(index < pkg_dir_header->size, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + return NULL; + } + return &(pkg_dir_header[index]); +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +int ia_css_pkg_dir_verify_header(const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + verifexitval(pkg_dir_header != NULL, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + return -1; + } + return ((pkg_dir_header->address[0] == PKG_DIR_MAGIC_VAL_0) + && (pkg_dir_header->address[1] == PKG_DIR_MAGIC_VAL_1)) ? + 0 : -1; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_get_num_entries( + const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + uint32_t size = 0; + + verifexitval(pkg_dir_header != NULL, EFAULT); + size = pkg_dir_header->size; + verifexitval(size > 0, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return size - 1; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +enum ia_css_pkg_dir_version +ia_css_pkg_dir_get_version(const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + assert(pkg_dir_header != NULL); + return pkg_dir_header->version; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint16_t ia_css_pkg_dir_set_version(ia_css_pkg_dir_entry_t *pkg_dir_header, + enum ia_css_pkg_dir_version version) +{ + DECLARE_ERRVAL + + verifexitval(pkg_dir_header != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 1; + } + pkg_dir_header->version = version; + return 0; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_get_size_in_bytes( + const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + + verifexitval(pkg_dir_header != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return sizeof(struct ia_css_pkg_dir_entry) * pkg_dir_header->size; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_address_lo( + const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->address[0]; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_address_hi( + const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->address[1]; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_size(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->size; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint16_t ia_css_pkg_dir_entry_get_version(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->version; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint8_t ia_css_pkg_dir_entry_get_type(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->type; +} + + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +void *ia_css_pkg_dir_get_entry_address(const ia_css_pkg_dir_t *pkg_dir, + uint32_t index) +{ + void *entry_blob = NULL; + const ia_css_pkg_dir_entry_t *pkg_dir_entry = + ia_css_pkg_dir_get_entry(pkg_dir, index-1); + + if ((pkg_dir_entry != NULL) && + (ia_css_pkg_dir_entry_get_size(pkg_dir_entry) > 0)) { + assert(ia_css_pkg_dir_entry_get_address_hi(pkg_dir_entry) == 0); + entry_blob = (void *)((char *)pkg_dir + + ia_css_pkg_dir_entry_get_address_lo(pkg_dir_entry)); + } + return entry_blob; +} + +#endif /* __IA_CSS_PKG_DIR_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/src/ia_css_pkg_dir_int.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/src/ia_css_pkg_dir_int.h new file mode 100644 index 0000000000000..203505fbee54e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/pkg_dir/src/ia_css_pkg_dir_int.h @@ -0,0 +1,49 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_INT_H +#define __IA_CSS_PKG_DIR_INT_H + +/* + * Package Dir structure as specified in CSE FAS + * + * PKG DIR Header + * Qword 63:56 55 54:48 47:32 31:24 23:0 + * 0 "_IUPKDR_" + * 1 Rsvd Rsvd Type Version Rsvd Size + * + * Version: Version of the Structure + * Size: Size of the entire table (including header) in 16 byte chunks + * Type: Must be 0 for header + * + * Figure 13: PKG DIR Header + * + * + * PKG DIR Entry + * Qword 63:56 55 54:48 47:32 31:24 23:0 + * N Address/Offset + * N+1 Rsvd Rsvd Type Version Rsvd Size + * + * Version: Version # of the Component + * Size: Size of the component in bytes + * Type: Component Identifier + */ + +#define PKG_DIR_SIZE_BITS 24 +#define PKG_DIR_TYPE_BITS 7 + +#define PKG_DIR_MAGIC_VAL_1 (('_' << 24) | ('I' << 16) | ('U' << 8) | 'P') +#define PKG_DIR_MAGIC_VAL_0 (('K' << 24) | ('D' << 16) | ('R' << 8) | '_') + +#endif /* __IA_CSS_PKG_DIR_INT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/port_env_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/port_env_struct.h new file mode 100644 index 0000000000000..4d39a4739a8b0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/port_env_struct.h @@ -0,0 +1,24 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PORT_ENV_STRUCT_H +#define __PORT_ENV_STRUCT_H + +struct port_env { + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; +}; + +#endif /* __PORT_ENV_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/queue.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/queue.h new file mode 100644 index 0000000000000..b233ab3baf014 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/queue.h @@ -0,0 +1,40 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __QUEUE_H +#define __QUEUE_H + +#include "queue_struct.h" +#include "port_env_struct.h" + +/* + * SYS queues are created by the host + * SYS queues cannot be accessed through the queue interface + * To send data into a queue a send_port must be opened. + * To receive data from a queue, a recv_port must be opened. + */ + +/* return required buffer size for queue */ +unsigned int +sys_queue_buf_size(unsigned int size, unsigned int token_size); + +/* + * initialize a queue that can hold at least 'size' tokens of + * 'token_size' bytes. + */ +void +sys_queue_init(struct sys_queue *q, unsigned int size, + unsigned int token_size, struct sys_queue_res *res); + +#endif /* __QUEUE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/queue_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/queue_struct.h new file mode 100644 index 0000000000000..ef48fcfded2b6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/queue_struct.h @@ -0,0 +1,47 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __QUEUE_STRUCT_H +#define __QUEUE_STRUCT_H + +/* queue description, shared between sender and receiver */ + +#include "type_support.h" + +#ifdef __VIED_CELL +typedef struct {uint32_t v[2]; } host_buffer_address_t; +#else +typedef uint64_t host_buffer_address_t; +#endif + +typedef uint32_t vied_buffer_address_t; + + +struct sys_queue { + host_buffer_address_t host_address; + vied_buffer_address_t vied_address; + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* reg no in subsystem's regmem */ + unsigned int rd_reg; + unsigned int _align; +}; + +struct sys_queue_res { + host_buffer_address_t host_address; + vied_buffer_address_t vied_address; + unsigned int reg; +}; + +#endif /* __QUEUE_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/recv_port.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/recv_port.h new file mode 100644 index 0000000000000..cce253b266687 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/recv_port.h @@ -0,0 +1,34 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __RECV_PORT_H +#define __RECV_PORT_H + + +struct recv_port; +struct sys_queue; +struct port_env; + +void +recv_port_open(struct recv_port *p, const struct sys_queue *q, + const struct port_env *env); + +unsigned int +recv_port_available(const struct recv_port *p); + +unsigned int +recv_port_transfer(const struct recv_port *p, void *data); + + +#endif /* __RECV_PORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/recv_port_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/recv_port_struct.h new file mode 100644 index 0000000000000..52ec563b13cf5 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/recv_port_struct.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __RECV_PORT_STRUCT_H +#define __RECV_PORT_STRUCT_H + +#include "buffer_type.h" + +struct recv_port { + buffer_address buffer; /* address of buffer in DDR */ + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* index of write pointer located in regmem */ + unsigned int rd_reg; /* index read pointer located in regmem */ + + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; /* address of memory containing regmem */ +}; + +#endif /* __RECV_PORT_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/send_port.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/send_port.h new file mode 100644 index 0000000000000..04a160f3f0199 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/send_port.h @@ -0,0 +1,52 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __SEND_PORT_H +#define __SEND_PORT_H + + +/* + * A send port can be used to send tokens into a queue. + * The interface can be used on any type of processor (host, SP, ...) + */ + +struct send_port; +struct sys_queue; +struct port_env; + +/* + * Open a send port on a queue. After the port is opened, tokens can be sent + */ +void +send_port_open(struct send_port *p, const struct sys_queue *q, + const struct port_env *env); + +/* + * Determine how many tokens can be sent + */ +unsigned int +send_port_available(const struct send_port *p); + +/* + * Send a token via a send port. The function returns the number of + * tokens that have been sent: + * 1: the token was accepted + * 0: the token was not accepted (full queue) + * The size of a token is determined at initialization. + */ +unsigned int +send_port_transfer(const struct send_port *p, const void *data); + + +#endif /* __SEND_PORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/send_port_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/send_port_struct.h new file mode 100644 index 0000000000000..f834c62bc3db6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/interface/send_port_struct.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __SEND_PORT_STRUCT_H +#define __SEND_PORT_STRUCT_H + +#include "buffer_type.h" + +struct send_port { + buffer_address buffer; + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* index of write pointer in regmem */ + unsigned int rd_reg; /* index of read pointer in regmem */ + + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; +}; + +#endif /* __SEND_PORT_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/port.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/port.mk new file mode 100644 index 0000000000000..b3801247802e9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/port.mk @@ -0,0 +1,31 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PORT + +PORT_DIR=$${MODULES_DIR}/port + +PORT_INTERFACE=$(PORT_DIR)/interface +PORT_SOURCES1=$(PORT_DIR)/src + +PORT_HOST_FILES += $(PORT_SOURCES1)/send_port.c +PORT_HOST_FILES += $(PORT_SOURCES1)/recv_port.c +PORT_HOST_FILES += $(PORT_SOURCES1)/queue.c + +PORT_HOST_CPPFLAGS += -I$(PORT_INTERFACE) + +PORT_FW_FILES += $(PORT_SOURCES1)/send_port.c +PORT_FW_FILES += $(PORT_SOURCES1)/recv_port.c + +PORT_FW_CPPFLAGS += -I$(PORT_INTERFACE) diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/src/queue.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/src/queue.c new file mode 100644 index 0000000000000..eeec99dfe2d0d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/src/queue.c @@ -0,0 +1,47 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "queue.h" + +#include "regmem_access.h" +#include "port_env_struct.h" + +unsigned int sys_queue_buf_size(unsigned int size, unsigned int token_size) +{ + return (size + 1) * token_size; +} + +void +sys_queue_init(struct sys_queue *q, unsigned int size, unsigned int token_size, + struct sys_queue_res *res) +{ + unsigned int buf_size; + + q->size = size + 1; + q->token_size = token_size; + buf_size = sys_queue_buf_size(size, token_size); + + /* acquire the shared buffer space */ + q->host_address = res->host_address; + res->host_address += buf_size; + q->vied_address = res->vied_address; + res->vied_address += buf_size; + + /* acquire the shared read and writer pointers */ + q->wr_reg = res->reg; + res->reg++; + q->rd_reg = res->reg; + res->reg++; + +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/src/recv_port.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/src/recv_port.c new file mode 100644 index 0000000000000..2433ba9659aa4 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/src/recv_port.c @@ -0,0 +1,96 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "recv_port.h" +#include "port_env_struct.h" /* for port_env */ +#include "queue_struct.h" /* for sys_queue */ +#include "recv_port_struct.h" /* for recv_port */ +#include "buffer_access.h" /* for buffer_load, buffer_address */ +#include "regmem_access.h" /* for regmem_load_32, regmem_store_32 */ +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "type_support.h" /* for HOST_ADDRESS */ + +#ifndef __VIED_CELL +#include "cpu_mem_support.h" /* for ia_css_cpu_mem_cache_invalidate */ +#endif + +#include "math_support.h" /* for OP_std_modadd */ + +void +recv_port_open(struct recv_port *p, const struct sys_queue *q, + const struct port_env *env) +{ + p->mmid = env->mmid; + p->ssid = env->ssid; + p->mem_addr = env->mem_addr; + + p->size = q->size; + p->token_size = q->token_size; + p->wr_reg = q->wr_reg; + p->rd_reg = q->rd_reg; + +#ifdef __VIED_CELL + p->buffer = q->vied_address; +#else + p->buffer = q->host_address; +#endif +} + +STORAGE_CLASS_INLINE unsigned int +recv_port_index(const struct recv_port *p, unsigned int i) +{ + unsigned int rd = regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + + return OP_std_modadd(rd, i, p->size); +} + +unsigned int +recv_port_available(const struct recv_port *p) +{ + int wr = (int)regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + int rd = (int)regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + + return OP_std_modadd(wr, -rd, p->size); +} + +STORAGE_CLASS_INLINE void +recv_port_copy(const struct recv_port *p, unsigned int i, void *data) +{ + unsigned int rd = recv_port_index(p, i); + unsigned int token_size = p->token_size; + buffer_address addr = p->buffer + (rd * token_size); +#ifndef __VIED_CELL + ia_css_cpu_mem_cache_invalidate((void *)HOST_ADDRESS(p->buffer), + token_size*p->size); +#endif + buffer_load(addr, data, token_size, p->mmid); +} + +STORAGE_CLASS_INLINE void +recv_port_release(const struct recv_port *p, unsigned int i) +{ + unsigned int rd = recv_port_index(p, i); + + regmem_store_32(p->mem_addr, p->rd_reg, rd, p->ssid); +} + +unsigned int +recv_port_transfer(const struct recv_port *p, void *data) +{ + if (!recv_port_available(p)) + return 0; + recv_port_copy(p, 0, data); + recv_port_release(p, 1); + return 1; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/src/send_port.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/src/send_port.c new file mode 100644 index 0000000000000..b0dfe41cb1046 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/port/src/send_port.c @@ -0,0 +1,95 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "send_port.h" +#include "queue_struct.h" /* for sys_queue */ +#include "send_port_struct.h" /* for send_port */ +#include "port_env_struct.h" /* for port_env */ +#include "regmem_access.h" /* for regmem_load_32, regmem_store_32 */ +#include "buffer_access.h" /* for buffer_store, buffer_address */ +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "type_support.h" /* for HOST_ADDRESS */ + +#ifndef __VIED_CELL +#include "cpu_mem_support.h" /* for ia_css_cpu_mem_cache_flush */ +#endif + +#include "math_support.h" /* for OP_std_modadd */ + +void +send_port_open(struct send_port *p, const struct sys_queue *q, + const struct port_env *env) +{ + p->mmid = env->mmid; + p->ssid = env->ssid; + p->mem_addr = env->mem_addr; + + p->size = q->size; + p->token_size = q->token_size; + p->wr_reg = q->wr_reg; + p->rd_reg = q->rd_reg; +#ifdef __VIED_CELL + p->buffer = q->vied_address; +#else + p->buffer = q->host_address; +#endif +} + +STORAGE_CLASS_INLINE unsigned int +send_port_index(const struct send_port *p, unsigned int i) +{ + unsigned int wr = regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + + return OP_std_modadd(wr, i, p->size); +} + +unsigned int +send_port_available(const struct send_port *p) +{ + int rd = (int)regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + int wr = (int)regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + + return OP_std_modadd(rd, -(wr+1), p->size); +} + +STORAGE_CLASS_INLINE void +send_port_copy(const struct send_port *p, unsigned int i, const void *data) +{ + unsigned int wr = send_port_index(p, i); + unsigned int token_size = p->token_size; + buffer_address addr = p->buffer + (wr * token_size); + + buffer_store(addr, data, token_size, p->mmid); +#ifndef __VIED_CELL + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(addr), token_size); +#endif +} + +STORAGE_CLASS_INLINE void +send_port_release(const struct send_port *p, unsigned int i) +{ + unsigned int wr = send_port_index(p, i); + + regmem_store_32(p->mem_addr, p->wr_reg, wr, p->ssid); +} + +unsigned int +send_port_transfer(const struct send_port *p, const void *data) +{ + if (!send_port_available(p)) + return 0; + send_port_copy(p, 0, data); + send_port_release(p, 1); + return 1; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/reg_dump/src/isys/bxtB0_gen_reg_dump/ia_css_debug_dump.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/reg_dump/src/isys/bxtB0_gen_reg_dump/ia_css_debug_dump.c new file mode 100644 index 0000000000000..c51d65c8cb647 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/reg_dump/src/isys/bxtB0_gen_reg_dump/ia_css_debug_dump.c @@ -0,0 +1,15 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#include "ia_css_debug_dump.h" + void ia_css_debug_dump(void) {} \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/reg_dump/src/isys/bxtB0_gen_reg_dump/ia_css_debug_dump.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/reg_dump/src/isys/bxtB0_gen_reg_dump/ia_css_debug_dump.h new file mode 100644 index 0000000000000..5dd23ddbd180b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/reg_dump/src/isys/bxtB0_gen_reg_dump/ia_css_debug_dump.h @@ -0,0 +1,17 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#ifndef __IA_CSS_DEBUG_DUMP_H_ + #define __IA_CSS_DEBUG_DUMP_H_ + void ia_css_debug_dump(void); + #endif /* __IA_CSS_DEBUG_DUMP_H_ */ \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/reg_dump/src/reg_dump_generic_bridge.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/reg_dump/src/reg_dump_generic_bridge.c new file mode 100644 index 0000000000000..9b9161ae78cf2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/reg_dump/src/reg_dump_generic_bridge.c @@ -0,0 +1,39 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include +#include "ia_css_trace.h" +#ifdef USE_LOGICAL_SSIDS +/* + Logical names can be used to define the SSID + In order to resolve these names the following include file should be provided + and the define above should be enabled +*/ +#include +#endif + +#define REG_DUMP_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#define REG_DUMP_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED + +/* SSID value is defined in test makefiles as either isys0 or psys0 */ +#define REG_DUMP_READ_REGISTER(addr) vied_subsystem_load_32(SSID, addr) + +#define REG_DUMP_PRINT_0(...) \ +EXPAND_VA_ARGS(IA_CSS_TRACE_0(REG_DUMP, VERBOSE, __VA_ARGS__)) +#define REG_DUMP_PRINT_1(...) \ +EXPAND_VA_ARGS(IA_CSS_TRACE_1(REG_DUMP, VERBOSE, __VA_ARGS__)) +#define EXPAND_VA_ARGS(x) x + +/* Including generated source code for reg_dump */ +#include "ia_css_debug_dump.c" diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/interface/regmem_access.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/interface/regmem_access.h new file mode 100644 index 0000000000000..d4576af936f6d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/interface/regmem_access.h @@ -0,0 +1,67 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_ACCESS_H +#define __REGMEM_ACCESS_H + +#include "storage_class.h" + +enum regmem_id { + /* pass pkg_dir address to SPC in non-secure mode */ + PKG_DIR_ADDR_REG = 0, + /* pass syscom configuration to SPC */ + SYSCOM_CONFIG_REG = 1, + /* syscom state - modified by SP */ + SYSCOM_STATE_REG = 2, + /* syscom commands - modified by the host */ + SYSCOM_COMMAND_REG = 3, + /* Store interrupt status - updated by SP */ + SYSCOM_IRQ_REG = 4, + /* Store VTL0_ADDR_MASK in trusted secure regision - provided by host.*/ + SYSCOM_VTL0_ADDR_MASK = 5, +#if HAS_DUAL_CMD_CTX_SUPPORT + /* Initialized if trustlet exists - updated by host */ + TRUSTLET_STATUS = 6, + /* identify if SPC access blocker programming is completed - updated by SP */ + AB_SPC_STATUS = 7, + /* first syscom queue pointer register */ + SYSCOM_QPR_BASE_REG = 8 +#else + /* first syscom queue pointer register */ + SYSCOM_QPR_BASE_REG = 6 +#endif +}; + +#if HAS_DUAL_CMD_CTX_SUPPORT +/* Bit 0: for untrusted non-secure DRV driver on VTL0 + * Bit 1: for trusted secure TEE driver on VTL1 + */ +#define SYSCOM_IRQ_VTL0_MASK 0x1 +#define SYSCOM_IRQ_VTL1_MASK 0x2 +#endif + +STORAGE_CLASS_INLINE unsigned int +regmem_load_32(unsigned int mem_address, unsigned int reg, unsigned int ssid); + +STORAGE_CLASS_INLINE void +regmem_store_32(unsigned int mem_address, unsigned int reg, unsigned int value, + unsigned int ssid); + +#ifdef __VIED_CELL +#include "regmem_access_cell.h" +#else +#include "regmem_access_host.h" +#endif + +#endif /* __REGMEM_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/regmem.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/regmem.mk new file mode 100644 index 0000000000000..24ebc1c325d8e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/regmem.mk @@ -0,0 +1,32 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +ifndef REGMEM_MK +REGMEM_MK=1 + +# MODULE is REGMEM + +REGMEM_DIR=$${MODULES_DIR}/regmem + +REGMEM_INTERFACE=$(REGMEM_DIR)/interface +REGMEM_SOURCES=$(REGMEM_DIR)/src + +REGMEM_HOST_FILES = +REGMEM_FW_FILES = $(REGMEM_SOURCES)/regmem.c + +REGMEM_CPPFLAGS = -I$(REGMEM_INTERFACE) -I$(REGMEM_SOURCES) +REGMEM_HOST_CPPFLAGS = $(REGMEM_CPPFLAGS) +REGMEM_FW_CPPFLAGS = $(REGMEM_CPPFLAGS) + +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/src/regmem_access_host.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/src/regmem_access_host.h new file mode 100644 index 0000000000000..8878d7074fabb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/src/regmem_access_host.h @@ -0,0 +1,41 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_ACCESS_HOST_H +#define __REGMEM_ACCESS_HOST_H + +#include "regmem_access.h" /* implemented interface */ + +#include "storage_class.h" +#include "regmem_const.h" +#include +#include "ia_css_cmem.h" + +STORAGE_CLASS_INLINE unsigned int +regmem_load_32(unsigned int mem_addr, unsigned int reg, unsigned int ssid) +{ + /* No need to add REGMEM_OFFSET, it is already included in mem_addr. */ + return ia_css_cmem_load_32(ssid, mem_addr + (REGMEM_WORD_BYTES*reg)); +} + +STORAGE_CLASS_INLINE void +regmem_store_32(unsigned int mem_addr, unsigned int reg, + unsigned int value, unsigned int ssid) +{ + /* No need to add REGMEM_OFFSET, it is already included in mem_addr. */ + ia_css_cmem_store_32(ssid, mem_addr + (REGMEM_WORD_BYTES*reg), + value); +} + +#endif /* __REGMEM_ACCESS_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/src/regmem_const.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/src/regmem_const.h new file mode 100644 index 0000000000000..ac7e3a98a434f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/regmem/src/regmem_const.h @@ -0,0 +1,28 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_CONST_H +#define __REGMEM_CONST_H + +#ifndef REGMEM_SIZE +#define REGMEM_SIZE (16) +#endif /* REGMEM_SIZE */ +#ifndef REGMEM_OFFSET +#define REGMEM_OFFSET (0) +#endif /* REGMEM_OFFSET */ +#ifndef REGMEM_WORD_BYTES +#define REGMEM_WORD_BYTES (4) +#endif + +#endif /* __REGMEM_CONST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/assert_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/assert_support.h new file mode 100644 index 0000000000000..ec24488bf6b11 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/assert_support.h @@ -0,0 +1,197 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __ASSERT_SUPPORT_H +#define __ASSERT_SUPPORT_H + +/* This file provides support for run-time assertions + * and compile-time assertions. + * + * Run-time asstions are provided via the following syntax: + * assert(condition) + * Run-time assertions are disabled using the NDEBUG flag. + * + * Compile time assertions are provided via the following syntax: + * COMPILATION_ERROR_IF(condition); + * A compile-time assertion will fail to compile if the condition is false. + * The condition must be constant, such that it can be evaluated + * at compile time. + * + * OP___assert is deprecated. + */ + +#define IA_CSS_ASSERT(expr) assert(expr) + +#ifdef __KLOCWORK__ +/* Klocwork does not see that assert will lead to abortion + * as there is no good way to tell this to KW and the code + * should not depend on assert to function (actually the assert + * could be disabled in a release build) it was decided to + * disable the assert for KW scans (by defining NDEBUG) + */ +#define NDEBUG +#endif /* __KLOCWORK__ */ + +/** + * The following macro can help to test the size of a struct at compile + * time rather than at run-time. It does not work for all compilers; see + * below. + * + * Depending on the value of 'condition', the following macro is expanded to: + * - condition==true: + * an expression containing an array declaration with negative size, + * usually resulting in a compilation error + * - condition==false: + * (void) 1; // C statement with no effect + * + * example: + * COMPILATION_ERROR_IF( sizeof(struct host_sp_queues) != + * SIZE_OF_HOST_SP_QUEUES_STRUCT); + * + * verify that the macro indeed triggers a compilation error with your compiler: + * COMPILATION_ERROR_IF( sizeof(struct host_sp_queues) != + * (sizeof(struct host_sp_queues)+1) ); + * + * Not all compilers will trigger an error with this macro; + * use a search engine to search for BUILD_BUG_ON to find other methods. + */ +#define COMPILATION_ERROR_IF(condition) \ +((void)sizeof(char[1 - 2*!!(condition)])) + +/* Compile time assertion */ +#ifndef CT_ASSERT +#define CT_ASSERT(cnd) ((void)sizeof(char[(cnd)?1 : -1])) +#endif /* CT_ASSERT */ + +#ifdef NDEBUG + +#define assert(cnd) ((void)0) + +#else + +#include "storage_class.h" + +#if defined(_MSC_VER) +#ifdef _KERNEL_MODE +/* Windows kernel mode compilation */ +#include +#define assert(cnd) ASSERT(cnd) +#else +/* Windows usermode compilation */ +#include +#endif + +#elif defined(__HIVECC) + +/* + * target: assert disabled + * sched: assert enabled only when SCHED_DEBUG is defined + * unsched: assert enabled + */ +#if defined(HRT_HW) +#define assert(cnd) ((void)0) +#elif defined(HRT_SCHED) && !defined(DEBUG_SCHED) +#define assert(cnd) ((void)0) +#elif defined(PIPE_GENERATION) +#define assert(cnd) ((void)0) +#else +#include +#define assert(cnd) OP___csim_assert(cnd) +#endif + +#elif defined(__KERNEL__) +#include + +#ifndef KERNEL_ASSERT_TO_BUG +#ifndef KERNEL_ASSERT_TO_BUG_ON +#ifndef KERNEL_ASSERT_TO_WARN_ON +#ifndef KERNEL_ASSERT_TO_WARN_ON_INF_LOOP +#ifndef KERNEL_ASSERT_UNDEFINED +/* Default */ +#define KERNEL_ASSERT_TO_BUG +#endif /*KERNEL_ASSERT_UNDEFINED*/ +#endif /*KERNEL_ASSERT_TO_WARN_ON_INF_LOOP*/ +#endif /*KERNEL_ASSERT_TO_WARN_ON*/ +#endif /*KERNEL_ASSERT_TO_BUG_ON*/ +#endif /*KERNEL_ASSERT_TO_BUG*/ + +#ifdef KERNEL_ASSERT_TO_BUG +/* TODO: it would be cleaner to use this: + * #define assert(cnd) BUG_ON(cnd) + * but that causes many compiler warnings (==errors) under Android + * because it seems that the BUG_ON() macro is not seen as a check by + * gcc like the BUG() macro is. */ +#define assert(cnd) \ + do { \ + if (!(cnd)) { \ + BUG(); \ + } \ + } while (0) +#endif /*KERNEL_ASSERT_TO_BUG*/ + +#ifdef KERNEL_ASSERT_TO_BUG_ON +#define assert(cnd) BUG_ON(!(cnd)) +#endif /*KERNEL_ASSERT_TO_BUG_ON*/ + +#ifdef KERNEL_ASSERT_TO_WARN_ON +#define assert(cnd) WARN_ON(!(cnd)) +#endif /*KERNEL_ASSERT_TO_WARN_ON*/ + +#ifdef KERNEL_ASSERT_TO_WARN_ON_INF_LOOP +#define assert(cnd) \ + do { \ + int not_cnd = !(cnd); \ + WARN_ON(not_cnd); \ + if (not_cnd) { \ + for (;;) { \ + } \ + } \ + } while (0) +#endif /*KERNEL_ASSERT_TO_WARN_ON_INF_LOOP*/ + +#ifdef KERNEL_ASSERT_UNDEFINED +#include KERNEL_ASSERT_DEFINITION_FILESTRING +#endif /*KERNEL_ASSERT_UNDEFINED*/ + +#elif defined(__FIST__) || defined(__GNUC__) + +#include "assert.h" + +#else /* default is for unknown environments */ +#define assert(cnd) ((void)0) +#endif + +#endif /* NDEBUG */ + +#ifndef PIPE_GENERATION +/* Deprecated OP___assert, this is still used in ~1000 places + * in the code. This will be removed over time. + * The implementation for the pipe generation tool is in see support.isp.h */ +#define OP___assert(cnd) assert(cnd) + +#ifdef C_RUN +#define compile_time_assert(cond) OP___assert(cond) +#else +#include "storage_class.h" +extern void _compile_time_assert(void); +STORAGE_CLASS_INLINE void compile_time_assert(unsigned int cond) +{ + /* Call undefined function if cond is false */ + if (!cond) + _compile_time_assert(); +} +#endif +#endif /* PIPE_GENERATION */ + +#endif /* __ASSERT_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/cpu_mem_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/cpu_mem_support.h new file mode 100644 index 0000000000000..defea068429ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/cpu_mem_support.h @@ -0,0 +1,233 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __CPU_MEM_SUPPORT_H +#define __CPU_MEM_SUPPORT_H + +#include "storage_class.h" +#include "assert_support.h" +#include "type_support.h" + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_copy(void *dst, const void *src, unsigned int size) +{ + /* memcpy cannot be used in Windows (function is not allowed), + * and the safer function memcpy_s is not available on other platforms. + * Because usage of ia_css_cpu_mem_copy is minimal, we implement it here in an easy, + * but sub-optimal way. + */ + unsigned int i; + + assert(dst != NULL && src != NULL); + + if (!(dst != NULL && src != NULL)) { + return NULL; + } + for (i = 0; i < size; i++) { + ((char *)dst)[i] = ((char *)src)[i]; + } + return dst; +} + +#if defined(__KERNEL__) + +#include +#include +#include +#include + +/* TODO: remove, workaround for issue in hrt file ibuf_ctrl_2600_config.c + * error checking code added to SDK that uses calls to exit function + */ +#define exit(a) return + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return kmalloc(size, GFP_KERNEL); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + return ia_css_cpu_mem_alloc(size); /* todo: align to page size */ +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_protect(void *ptr, unsigned int size, int prot) +{ + /* nothing here yet */ +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); /* available in kernel in linux/string.h */ +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + kfree(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ + /* parameter check here */ + if (ptr == NULL) + return; + + clflush_cache_range(ptr, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ + /* for now same as flush */ + ia_css_cpu_mem_cache_flush(ptr, size); +} + +#elif defined(_MSC_VER) + +#include +#include +#include + +extern void *hrt_malloc(size_t bytes, int zero_mem); +extern void *hrt_free(void *ptr); +extern void hrt_mem_cache_flush(void *ptr, unsigned int size); +extern void hrt_mem_cache_invalidate(void *ptr, unsigned int size); + +#define malloc(a) hrt_malloc(a, 1) +#define free(a) hrt_free(a) + +#define CSS_PAGE_SIZE (1<<12) + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return malloc(size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + unsigned int buffer_size = size; + + /* Currently hrt_malloc calls Windows ExAllocatePoolWithTag() routine + * to request system memory. If the number of bytes is equal or bigger + * than the page size, then the returned address is page aligned, + * but if it's smaller it's not necessarily page-aligned We agreed + * with Windows team that we allocate a full page + * if it's less than page size + */ + if (buffer_size < CSS_PAGE_SIZE) + buffer_size = CSS_PAGE_SIZE; + + return ia_css_cpu_mem_alloc(buffer_size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + free(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ +#ifdef _KERNEL_MODE + hrt_mem_cache_flush(ptr, size); +#else + (void)ptr; + (void)size; +#endif +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ +#ifdef _KERNEL_MODE + hrt_mem_cache_invalidate(ptr, size); +#else + (void)ptr; + (void)size; +#endif +} + +#else + +#include +#include +#include +/* Needed for the MPROTECT */ +#include +#include +#include +#include + + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return malloc(size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + int pagesize; + + pagesize = sysconf(_SC_PAGE_SIZE); + return memalign(pagesize, size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + free(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ + /* not needed in simulation */ + (void)ptr; + (void)size; +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ + /* not needed in simulation */ + (void)ptr; + (void)size; +} + +#endif + +#endif /* __CPU_MEM_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/error_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/error_support.h new file mode 100644 index 0000000000000..9fe1f65125e6c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/error_support.h @@ -0,0 +1,110 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __ERROR_SUPPORT_H +#define __ERROR_SUPPORT_H + +#if defined(__KERNEL__) +#include +#else +#include +#endif +#include + +/* OS-independent definition of IA_CSS errno values */ +/* #define IA_CSS_EINVAL 1 */ +/* #define IA_CSS_EFAULT 2 */ + +#ifdef __HIVECC +#define ERR_EMBEDDED 1 +#else +#define ERR_EMBEDDED 0 +#endif + +#if ERR_EMBEDDED +#define DECLARE_ERRVAL +#else +#define DECLARE_ERRVAL \ + int _errval = 0; +#endif + +/* Use "owl" in while to prevent compiler warnings in Windows */ +#define ALWAYS_FALSE ((void)0, 0) + +#define verifret(cond, error_type) \ +do { \ + if (!(cond)) { \ + return error_type; \ + } \ +} while (ALWAYS_FALSE) + +#define verifjmp(cond, error_tag) \ +do { \ + if (!(cond)) { \ + goto error_tag; \ + } \ +} while (ALWAYS_FALSE) + +#define verifexit(cond) \ +do { \ + if (!(cond)) { \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#if ERR_EMBEDDED +#define verifexitval(cond, error_tag) \ +do { \ + assert(cond); \ +} while (ALWAYS_FALSE) +#else +#define verifexitval(cond, error_tag) \ +do { \ + if (!(cond)) { \ + _errval = (error_tag); \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) +#endif + +#if ERR_EMBEDDED +#define haserror(error_tag) (0) +#else +#define haserror(error_tag) \ + (_errval == (error_tag)) +#endif + +#if ERR_EMBEDDED +#define noerror() (1) +#else +#define noerror() \ + (_errval == 0) +#endif + +#define verifjmpexit(cond) \ +do { \ + if (!(cond)) { \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#define verifjmpexitsetretval(cond, retval) \ +do { \ + if (!(cond)) { \ + retval = -1; \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#endif /* __ERROR_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/math_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/math_support.h new file mode 100644 index 0000000000000..da2ef01dc7f83 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/math_support.h @@ -0,0 +1,313 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __MATH_SUPPORT_H +#define __MATH_SUPPORT_H + +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "type_support.h" +#include "assert_support.h" + +/* in case we have min/max/MIN/MAX macro's undefine them */ +#ifdef min +#undef min +#endif +#ifdef max +#undef max +#endif +#ifdef MIN /* also defined in include/hrt/numeric.h from SDK */ +#undef MIN +#endif +#ifdef MAX +#undef MAX +#endif + +#ifndef UINT16_MAX +#define UINT16_MAX (0xffffUL) +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX (0xffffffffUL) +#endif + +#define IS_ODD(a) ((a) & 0x1) +#define IS_EVEN(a) (!IS_ODD(a)) +#define IS_POWER2(a) (!((a)&((a)-1))) +#define IS_MASK_BITS_SET(a, b) ((a & b) != 0) + +/*To Find next power of 2 number from x */ +#define bit2(x) ((x) | ((x) >> 1)) +#define bit4(x) (bit2(x) | (bit2(x) >> 2)) +#define bit8(x) (bit4(x) | (bit4(x) >> 4)) +#define bit16(x) (bit8(x) | (bit8(x) >> 8)) +#define bit32(x) (bit16(x) | (bit16(x) >> 16)) +#define NEXT_POWER_OF_2(x) (bit32(x-1) + 1) + +/* force a value to a lower even value */ +#define EVEN_FLOOR(x) ((x) & ~1UL) + +/* A => B */ +#define IMPLIES(a, b) (!(a) || (b)) + +/* The ORIG_BITS th bit is the sign bit */ +/* Sign extends a ORIG_BITS bits long signed number to a 64-bit signed number */ +/* By type casting it can relimited to any valid type-size + * (32-bit signed or 16-bit or 8-bit) + */ +/* By masking it can be transformed to any arbitrary bit size */ +#define SIGN_EXTEND(VAL, ORIG_BITS) \ +((~(((VAL)&(1ULL<<((ORIG_BITS)-1)))-1))|(VAL)) + +#define EXTRACT_BIT(a, b) ((a >> b) & 1) + +/* for preprocessor and array sizing use MIN and MAX + otherwise use min and max */ +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define CLIP(a, b, c) MIN((MAX((a), (b))), (c)) +/* Integer round-down division of a with b */ +#define FLOOR_DIV(a, b) ((b) ? ((a) / (b)) : 0) +/* Align a to the lower multiple of b */ +#define FLOOR_MUL(a, b) (FLOOR_DIV(a, b) * (b)) +/* Integer round-up division of a with b */ +#define CEIL_DIV(a, b) ((b) ? (((a) + (b) - 1) / (b)) : 0) +/* Align a to the upper multiple of b */ +#define CEIL_MUL(a, b) (CEIL_DIV(a, b) * (b)) +/* Align a to the upper multiple of b - fast implementation + * for cases when b=pow(2,n) + */ +#define CEIL_MUL2(a, b) (((a) + (b) - 1) & ~((b) - 1)) +/* integer round-up division of a with pow(2,b) */ +#define CEIL_SHIFT(a, b) (((a) + (1UL << (b)) - 1) >> (b)) +/* Align a to the upper multiple of pow(2,b) */ +#define CEIL_SHIFT_MUL(a, b) (CEIL_SHIFT(a, b) << (b)) +/* Absolute difference of a and b */ +#define ABS_DIF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a))) +#define ABS(a) ABS_DIF(a, 0) +/* Square of x */ +#define SQR(x) ((x)*(x)) +/* Integer round-half-down division of a nad b */ +#define ROUND_HALF_DOWN_DIV(a, b) ((b) ? ((a) + (b / 2) - 1) / (b) : 0) +/* Align a to the round-half-down multiple of b */ +#define ROUND_HALF_DOWN_MUL(a, b) (ROUND_HALF_DOWN_DIV(a, b) * (b)) + +#define MAX3(a, b, c) MAX((a), MAX((b), (c))) +#define MIN3(a, b, c) MIN((a), MIN((b), (c))) +#define MAX4(a, b, c, d) MAX((MAX((a), (b))), (MAX((c), (d)))) +#define MIN4(a, b, c, d) MIN((MIN((a), (b))), (MIN((c), (d)))) + +/* min and max should not be macros as they will evaluate their arguments twice. + if you really need a macro (e.g. for CPP or for initializing an array) + use MIN() and MAX(), otherwise use min() and max() */ +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) ((sizeof(a) / sizeof(*(a)))) +#endif + +#ifndef BYTES +#define BYTES(bit) (((bit)+7)/8) +#endif + +#if !defined(PIPE_GENERATION) +STORAGE_CLASS_INLINE unsigned int max_value_bits(unsigned int bits) +{ + return (bits == 0) ? 0 : ((2 * ((1 << ((bits) - 1)) - 1)) + 1); +} +STORAGE_CLASS_INLINE unsigned int max_value_bytes(unsigned int bytes) +{ + return max_value_bits(IA_CSS_UINT8_T_BITS * bytes); +} +STORAGE_CLASS_INLINE int max(int a, int b) +{ + return MAX(a, b); +} + +STORAGE_CLASS_INLINE int min(int a, int b) +{ + return MIN(a, b); +} + +STORAGE_CLASS_INLINE int clip(int a, int b, int c) +{ + return min(max(a, b), c); +} + +STORAGE_CLASS_INLINE unsigned int ipu4_umax(unsigned int a, unsigned int b) +{ + return MAX(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ipu4_umin(unsigned int a, unsigned int b) +{ + return MIN(a, b); +} + +STORAGE_CLASS_INLINE unsigned int uclip(unsigned int a, unsigned int b, + unsigned int c) +{ + return ipu4_umin(ipu4_umax(a, b), c); +} + +STORAGE_CLASS_INLINE unsigned int ceil_div(unsigned int a, unsigned int b) +{ + return CEIL_DIV(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_mul(unsigned int a, unsigned int b) +{ + return CEIL_MUL(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_mul2(unsigned int a, unsigned int b) +{ + return CEIL_MUL2(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_shift(unsigned int a, unsigned int b) +{ + return CEIL_SHIFT(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_shift_mul(unsigned int a, unsigned int b) +{ + return CEIL_SHIFT_MUL(a, b); +} + +STORAGE_CLASS_INLINE int abs_dif(int a, int b) +{ + return ABS_DIF(a, b); +} + +STORAGE_CLASS_INLINE unsigned int uabs_dif(unsigned int a, unsigned int b) +{ + return ABS_DIF(a, b); +} + +STORAGE_CLASS_INLINE unsigned int round_half_down_div(unsigned int a, + unsigned int b) +{ + return ROUND_HALF_DOWN_DIV(a, b); +} + +STORAGE_CLASS_INLINE unsigned int round_half_down_mul(unsigned int a, + unsigned int b) +{ + return ROUND_HALF_DOWN_MUL(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_pow2(uint32_t a) +{ + unsigned int retval = 0; + + if (IS_POWER2(a)) { + retval = (unsigned int)a; + } else { + unsigned int v = a; + + v |= v>>1; + v |= v>>2; + v |= v>>4; + v |= v>>8; + v |= v>>16; + retval = (unsigned int)(v+1); + } + return retval; +} + +STORAGE_CLASS_INLINE unsigned int floor_log2(uint32_t a) +{ + static const uint8_t de_bruijn[] = { + 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 + }; + uint32_t v = a; + + v |= v>>1; + v |= v>>2; + v |= v>>4; + v |= v>>8; + v |= v>>16; + return (unsigned int)de_bruijn[(v*0x07C4ACDDU)>>27]; +} + +/* Divide by small power of two */ +STORAGE_CLASS_INLINE unsigned int +udiv2_small_i(uint32_t a, uint32_t b) +{ + assert(b <= 2); + return a >> (b-1); +} + +/* optimized divide for small results + * a will be divided by b + * outbits is the number of bits needed for the result + * the smaller the cheaper the function will be. + * if the result doesn't fit in the number of output bits + * the result is incorrect and the function will assert + */ +STORAGE_CLASS_INLINE unsigned int +udiv_medium(uint32_t a, uint32_t b, unsigned int outbits) +{ + int bit; + unsigned int res = 0; + unsigned int mask; + +#ifdef VOLCANO +#pragma ipu unroll +#endif + for (bit = outbits-1 ; bit >= 0; bit--) { + mask = 1<= (b<= c ? a+b-c : a+b); +} + +/* + * For SP and ISP, SDK provides the definition of OP_asp_slor. + * We need it only for host + */ +STORAGE_CLASS_INLINE unsigned int OP_asp_slor(int a, int b, int c) +{ + return ((a << c) | b); +} +#else +#include "hive/customops.h" +#endif /* !defined(__VIED_CELL) */ + +#endif /* !defined(PIPE_GENERATION) */ + +#if !defined(__KERNEL__) +#define clamp(a, min_val, max_val) MIN(MAX((a), (min_val)), (max_val)) +#endif /* !defined(__KERNEL__) */ + +#endif /* __MATH_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/misc_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/misc_support.h new file mode 100644 index 0000000000000..a2c2729e946d2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/misc_support.h @@ -0,0 +1,76 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __MISC_SUPPORT_H +#define __MISC_SUPPORT_H + +/* suppress compiler warnings on unused variables */ +#ifndef NOT_USED +#define NOT_USED(a) ((void)(a)) +#endif + +/* Calculate the total bytes for pow(2) byte alignment */ +#define tot_bytes_for_pow2_align(pow2, cur_bytes) \ + ((cur_bytes + (pow2 - 1)) & ~(pow2 - 1)) + +/* Display the macro value given a string */ +#define _STR(x) #x +#define STR(x) _STR(x) + +/* Concatenate */ +#ifndef CAT /* also defined in */ +#define _CAT(a, b) a ## b +#define CAT(a, b) _CAT(a, b) +#endif + +#define _CAT3(a, b, c) a ## b ## c +#define CAT3(a, b, c) _CAT3(a, b, c) + +/* NO_HOIST, NO_CSE, NO_ALIAS attributes must be ignored for host code */ +#ifndef __HIVECC +#ifndef NO_HOIST +#define NO_HOIST +#endif +#ifndef NO_CSE +#define NO_CSE +#endif +#ifndef NO_ALIAS +#define NO_ALIAS +#endif +#endif + +enum hive_method_id { + HIVE_METHOD_ID_CRUN, + HIVE_METHOD_ID_UNSCHED, + HIVE_METHOD_ID_SCHED, + HIVE_METHOD_ID_TARGET +}; + +/* Derive METHOD */ +#if defined(C_RUN) + #define HIVE_METHOD "crun" + #define HIVE_METHOD_ID HIVE_METHOD_ID_CRUN +#elif defined(HRT_UNSCHED) + #define HIVE_METHOD "unsched" + #define HIVE_METHOD_ID HIVE_METHOD_ID_UNSCHED +#elif defined(HRT_SCHED) + #define HIVE_METHOD "sched" + #define HIVE_METHOD_ID HIVE_METHOD_ID_SCHED +#else + #define HIVE_METHOD "target" + #define HIVE_METHOD_ID HIVE_METHOD_ID_TARGET + #define HRT_TARGET 1 +#endif + +#endif /* __MISC_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/platform_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/platform_support.h new file mode 100644 index 0000000000000..d281d841e1c33 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/platform_support.h @@ -0,0 +1,146 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PLATFORM_SUPPORT_H +#define __PLATFORM_SUPPORT_H + +#include "storage_class.h" + +#define MSEC_IN_SEC 1000 +#define NSEC_IN_MSEC 1000000 + +#if defined(_MSC_VER) +#include + +#define IA_CSS_EXTERN +#define SYNC_WITH(x) +#define CSS_ALIGN(d, a) _declspec(align(a)) d + +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + /* Placeholder for driver team*/ +} + +STORAGE_CLASS_INLINE void ia_css_sleep_msec(unsigned long delay_time_ms) +{ + /* Placeholder for driver team*/ + (void)delay_time_ms; +} + +#elif defined(__HIVECC) +#include +#include + +#define IA_CSS_EXTERN extern +#define CSS_ALIGN(d, a) d __aligned(a) +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + OP___schedule(); +} + +#elif defined(__KERNEL__) +#include +#include + +#define IA_CSS_EXTERN +#define CSS_ALIGN(d, a) d __aligned(a) + +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + usleep_range(1, 50); +} + +#elif defined(__GNUC__) +#include + +#define IA_CSS_EXTERN +#define CSS_ALIGN(d, a) d __aligned(a) + +/* Define some __HIVECC specific macros to nothing to allow host code compilation */ +#ifndef NO_ALIAS +#define NO_ALIAS +#endif + +#ifndef SYNC_WITH +#define SYNC_WITH(x) +#endif + +#if defined(HRT_CSIM) +#include "hrt/host.h" /* Using hrt_sleep from hrt/host.h */ +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + /* For the SDK still using hrt_sleep */ + hrt_sleep(); +} +STORAGE_CLASS_INLINE void ia_css_sleep_msec(long unsigned int delay_time_ms) +{ + /* For the SDK still using hrt_sleep */ + long unsigned int i = 0; + for (i = 0; i < delay_time_ms; i++) { + hrt_sleep(); + } +} +#else +#include +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + struct timespec delay_time; + + delay_time.tv_sec = 0; + delay_time.tv_nsec = 10; + nanosleep(&delay_time, NULL); +} +STORAGE_CLASS_INLINE void ia_css_sleep_msec(long unsigned int delay_time_ms) +{ + struct timespec delay_time; + + if (delay_time_ms >= MSEC_IN_SEC) { + delay_time.tv_sec = delay_time_ms / MSEC_IN_SEC; + delay_time.tv_nsec = (delay_time_ms % MSEC_IN_SEC) * NSEC_IN_MSEC; + } else { + delay_time.tv_sec = 0; + delay_time.tv_nsec = delay_time_ms * NSEC_IN_MSEC; + } + nanosleep(&delay_time, NULL); +} +#endif + +#else +#include +#endif + +/*needed for the include in stdint.h for various environments */ +#include "type_support.h" +#include "storage_class.h" + +#define MAX_ALIGNMENT 8 +#define aligned_uint8(type, obj) CSS_ALIGN(uint8_t obj, 1) +#define aligned_int8(type, obj) CSS_ALIGN(int8_t obj, 1) +#define aligned_uint16(type, obj) CSS_ALIGN(uint16_t obj, 2) +#define aligned_int16(type, obj) CSS_ALIGN(int16_t obj, 2) +#define aligned_uint32(type, obj) CSS_ALIGN(uint32_t obj, 4) +#define aligned_int32(type, obj) CSS_ALIGN(int32_t obj, 4) + +/* needed as long as hivecc does not define the type (u)int64_t */ +#if defined(__HIVECC) +#define aligned_uint64(type, obj) CSS_ALIGN(unsigned long long obj, 8) +#define aligned_int64(type, obj) CSS_ALIGN(signed long long obj, 8) +#else +#define aligned_uint64(type, obj) CSS_ALIGN(uint64_t obj, 8) +#define aligned_int64(type, obj) CSS_ALIGN(int64_t obj, 8) +#endif +#define aligned_enum(enum_type, obj) CSS_ALIGN(uint32_t obj, 4) +#define aligned_struct(struct_type, obj) struct_type obj + +#endif /* __PLATFORM_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/print_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/print_support.h new file mode 100644 index 0000000000000..0b614f7ef12d8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/print_support.h @@ -0,0 +1,90 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PRINT_SUPPORT_H +#define __PRINT_SUPPORT_H + +#if defined(_MSC_VER) +#ifdef _KERNEL_MODE + +/* TODO: Windows driver team to provide tracing mechanism for kernel mode + * e.g. DbgPrint and DbgPrintEx + */ +extern void FwTracePrintPWARN(const char *fmt, ...); +extern void FwTracePrintPRINT(const char *fmt, ...); +extern void FwTracePrintPERROR(const char *fmt, ...); +extern void FwTracePrintPDEBUG(const char *fmt, ...); + +#define PWARN(format, ...) FwTracePrintPWARN(format, __VA_ARGS__) +#define PRINT(format, ...) FwTracePrintPRINT(format, __VA_ARGS__) +#define PERROR(format, ...) FwTracePrintPERROR(format, __VA_ARGS__) +#define PDEBUG(format, ...) FwTracePrintPDEBUG(format, __VA_ARGS__) + +#else +/* Windows usermode compilation */ +#include + +/* To change the defines below, communicate with Windows team first + * to ensure they will not get flooded with prints + */ +/* This is temporary workaround to avoid flooding userspace + * Windows driver with prints + */ + +#define PWARN(format, ...) +#define PRINT(format, ...) +#define PERROR(format, ...) printf("error: " format, __VA_ARGS__) +#define PDEBUG(format, ...) + +#endif /* _KERNEL_MODE */ + +#elif defined(__HIVECC) +#include +/* To be revised + +#define PWARN(format) +#define PRINT(format) OP___printstring(format) +#define PERROR(variable) OP___dump(9999, arguments) +#define PDEBUG(variable) OP___dump(__LINE__, arguments) + +*/ + +#define PRINTSTRING(str) OP___printstring(str) + +#elif defined(__KERNEL__) +#include +#include + + +#define PWARN(format, arguments...) pr_debug(format, ##arguments) +#define PRINT(format, arguments...) pr_debug(format, ##arguments) +#define PERROR(format, arguments...) pr_debug(format, ##arguments) +#define PDEBUG(format, arguments...) pr_debug(format, ##arguments) + +#else +#include + +#define PRINT_HELPER(prefix, format, ...) printf(prefix format "%s", __VA_ARGS__) + +/* The trailing "" allows the edge case of printing single string */ +#define PWARN(...) PRINT_HELPER("warning: ", __VA_ARGS__, "") +#define PRINT(...) PRINT_HELPER("", __VA_ARGS__, "") +#define PERROR(...) PRINT_HELPER("error: ", __VA_ARGS__, "") +#define PDEBUG(...) PRINT_HELPER("debug: ", __VA_ARGS__, "") + +#define PRINTSTRING(str) PRINT(str) + +#endif + +#endif /* __PRINT_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/storage_class.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/storage_class.h new file mode 100644 index 0000000000000..58932a6b3ec76 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/storage_class.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __STORAGE_CLASS_H +#define __STORAGE_CLASS_H + +#define STORAGE_CLASS_EXTERN \ +extern + +#if defined(_MSC_VER) +#define STORAGE_CLASS_INLINE \ +static inline +#elif defined(__HIVECC) +#define STORAGE_CLASS_INLINE \ +static inline +#else +#define STORAGE_CLASS_INLINE \ +static inline +#endif + +/* Register struct */ +#ifndef __register +#if defined(__HIVECC) && !defined(PIPE_GENERATION) +#define __register register +#else +#define __register +#endif +#endif + +/* Memory attribute */ +#ifndef MEM +#ifdef PIPE_GENERATION +#elif defined(__HIVECC) +#include +#else +#define MEM(any_mem) +#endif +#endif + +#endif /* __STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/type_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/type_support.h new file mode 100644 index 0000000000000..7d8e00fdd95e1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/support/type_support.h @@ -0,0 +1,80 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __TYPE_SUPPORT_H +#define __TYPE_SUPPORT_H + +/* Per the DLI spec, types are in "type_support.h" and + * "platform_support.h" is for unclassified/to be refactored + * platform specific definitions. + */ +#define IA_CSS_UINT8_T_BITS 8 +#define IA_CSS_UINT16_T_BITS 16 +#define IA_CSS_UINT32_T_BITS 32 +#define IA_CSS_INT32_T_BITS 32 +#define IA_CSS_UINT64_T_BITS 64 + + +#if defined(_MSC_VER) +#include +#include +#include +#include +#if defined(_M_X64) +#define HOST_ADDRESS(x) ((unsigned long long)(x)) +#else +#define HOST_ADDRESS(x) ((unsigned long)(x)) +#endif + +#elif defined(PARAM_GENERATION) +/* Nothing */ +#elif defined(__HIVECC) +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#elif defined(__KERNEL__) +#include +#include + +#define CHAR_BIT (8) +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#elif defined(__GNUC__) +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#else /* default is for the FIST environment */ +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#endif + +#if !defined(PIPE_GENERATION) && !defined(IO_GENERATION) +/* genpipe cannot handle the void* syntax */ +typedef void *HANDLE; +#endif + +#endif /* __TYPE_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/interface/ia_css_syscom.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/interface/ia_css_syscom.h new file mode 100644 index 0000000000000..5426d6d18e0bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/interface/ia_css_syscom.h @@ -0,0 +1,247 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_H +#define __IA_CSS_SYSCOM_H + + +/* + * The CSS Subsystem Communication Interface - Host side + * + * It provides subsystem initialzation, send ports and receive ports + * The PSYS and ISYS interfaces are implemented on top of this interface. + */ + +#include "ia_css_syscom_config.h" + +#define FW_ERROR_INVALID_PARAMETER (-1) +#define FW_ERROR_BAD_ADDRESS (-2) +#define FW_ERROR_BUSY (-3) +#define FW_ERROR_NO_MEMORY (-4) + +struct ia_css_syscom_context; + +/** + * ia_css_syscom_size() - provide syscom external buffer requirements + * @config: pointer to the configuration data (read) + * @size: pointer to the buffer size (write) + * + * Purpose: + * - Provide external buffer requirements + * - To be used for external buffer allocation + * + */ +extern void +ia_css_syscom_size( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size *size +); + +/** + * ia_css_syscom_open() - initialize a subsystem context + * @config: pointer to the configuration data (read) + * @buf: pointer to externally allocated buffers (read) + * @returns: struct ia_css_syscom_context* on success, 0 otherwise. + * + * Purpose: + * - initialize host side data structures + * - boot the subsystem? + * + */ +extern struct ia_css_syscom_context* +ia_css_syscom_open( + struct ia_css_syscom_config *config, + struct ia_css_syscom_buf *buf +); + +/** + * ia_css_syscom_close() - signal close to cell + * @context: pointer to the subsystem context + * @returns: 0 on success, -2 (FW_ERROR_BUSY) if SPC is not ready yet. + * + * Purpose: + * Request from the Cell to terminate + */ +extern int +ia_css_syscom_close( + struct ia_css_syscom_context *context +); + +/** + * ia_css_syscom_release() - free context + * @context: pointer to the subsystem context + * @force: flag which specifies whether cell + * state will be checked before freeing the + * context. + * @returns: 0 on success, -2 (FW_ERROR_BUSY) if cell + * is busy and call was not forced. + * + * Purpose: + * 2 modes, with first (force==true) immediately + * free context, and second (force==false) verifying + * that the cell state is ok and freeing context if so, + * returning error otherwise. + */ +extern int +ia_css_syscom_release( + struct ia_css_syscom_context *context, + unsigned int force +); + +/** + * Open a port for sending tokens to the subsystem + * @context: pointer to the subsystem context + * @port: send port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_open( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Closes a port for sending tokens to the subsystem + * @context: pointer to the subsystem context + * @port: send port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_close( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Get the number of tokens that can be sent to a port without error. + * @context: pointer to the subsystem context + * @port: send port index + * @returns: number of available tokens on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_available( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Send a token to the subsystem port + * The token size is determined during initialization + * @context: pointer to the subsystem context + * @port: send port index + * @token: pointer to the token value that is transferred to the subsystem + * @returns: number of tokens sent on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_transfer( + struct ia_css_syscom_context *context, + unsigned int port, + const void *token +); + +/** + * Open a port for receiving tokens to the subsystem + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_open( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Closes a port for receiving tokens to the subsystem + * Returns 0 on success, otherwise negative value of error code + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_close( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Get the number of tokens that can be received from a port without errors. + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: number of available tokens on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_available( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Receive a token from the subsystem port + * The token size is determined during initialization + * @context: pointer to the subsystem context + * @port: receive port index + * @token (output): pointer to (space for) the token to be received + * @returns: number of tokens received on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_transfer( + struct ia_css_syscom_context *context, + unsigned int port, + void *token +); + +#if HAS_DUAL_CMD_CTX_SUPPORT +/** + * ia_css_syscom_store_dmem() - store subsystem context information in DMEM + * @context: pointer to the subsystem context + * @ssid: subsystem id + * @vtl0_addr_mask: VTL0 address mask; only applicable when the passed in context is secure + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_store_dmem( + struct ia_css_syscom_context *context, + unsigned int ssid, + unsigned int vtl0_addr_mask +); + +/** + * ia_css_syscom_set_trustlet_status() - store truslet configuration setting + * @context: pointer to the subsystem context + * @trustlet_exist: 1 if trustlet exists + */ +extern void +ia_css_syscom_set_trustlet_status( + unsigned int dmem_addr, + unsigned int ssid, + bool trustlet_exist +); + +/** + * ia_css_syscom_is_ab_spc_ready() - check if SPC access blocker programming is completed + * @context: pointer to the subsystem context + * @returns: 1 when status is ready. 0 otherwise + */ +bool +ia_css_syscom_is_ab_spc_ready( + struct ia_css_syscom_context *ctx +); +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +#endif /* __IA_CSS_SYSCOM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/interface/ia_css_syscom_config.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/interface/ia_css_syscom_config.h new file mode 100644 index 0000000000000..2f5eb309df94e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/interface/ia_css_syscom_config.h @@ -0,0 +1,97 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONFIG_H +#define __IA_CSS_SYSCOM_CONFIG_H + +#include +#include + +/* syscom size struct, output of ia_css_syscom_size, + * input for (external) allocation + */ +struct ia_css_syscom_size { + /* Size of host buffer */ + unsigned int cpu; + /* Size of shared config buffer (host to cell) */ + unsigned int shm; + /* Size of shared input queue buffers (host to cell) */ + unsigned int ibuf; + /* Size of shared output queue buffers (cell to host) */ + unsigned int obuf; +}; + +/* syscom buffer struct, output of (external) allocation, + * input for ia_css_syscom_open + */ +struct ia_css_syscom_buf { + char *cpu; /* host buffer */ + + /* shared memory buffer host address */ + host_virtual_address_t shm_host; + /* shared memory buffer cell address */ + vied_virtual_address_t shm_cell; + + /* input queue shared buffer host address */ + host_virtual_address_t ibuf_host; + /* input queue shared buffer cell address */ + vied_virtual_address_t ibuf_cell; + + /* output queue shared buffer host address */ + host_virtual_address_t obuf_host; + /* output queue shared buffer cell address */ + vied_virtual_address_t obuf_cell; +}; + +struct ia_css_syscom_queue_config { + unsigned int queue_size; /* tokens per queue */ + unsigned int token_size; /* bytes per token */ +}; + +/** + * Parameter struct for ia_css_syscom_open + */ +struct ia_css_syscom_config { + /* This member in no longer used in syscom. + It is kept to not break any driver builds, and will be removed when + all assignments have been removed from driver code */ + /* address of firmware in DDR/IMR */ + unsigned long long host_firmware_address; + + /* address of firmware in DDR, seen from SPC */ + unsigned int vied_firmware_address; + + unsigned int ssid; + unsigned int mmid; + + unsigned int num_input_queues; + unsigned int num_output_queues; + struct ia_css_syscom_queue_config *input; + struct ia_css_syscom_queue_config *output; + + unsigned int regs_addr; + unsigned int dmem_addr; + + /* firmware-specific configuration data */ + void *specific_addr; + unsigned int specific_size; + + /* if true; secure syscom in VTIO Case + * if false, non-secure syscom + */ + bool secure; + unsigned int vtl0_addr_mask; /* only applicable in 'secure' case */ +}; + +#endif /* __IA_CSS_SYSCOM_CONFIG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/interface/ia_css_syscom_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/interface/ia_css_syscom_trace.h new file mode 100644 index 0000000000000..2c32693c2a82e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/interface/ia_css_syscom_trace.h @@ -0,0 +1,51 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_SYSCOM_TRACE_H +#define __IA_CSS_SYSCOM_TRACE_H + +#include "ia_css_trace.h" + +#define SYSCOM_TRACE_LEVEL_DEFAULT 1 +#define SYSCOM_TRACE_LEVEL_DEBUG 2 + +/* Set to default level if no level is defined */ +#ifndef SYSCOM_TRACE_LEVEL +#define SYSCOM_TRACE_LEVEL SYSCOM_TRACE_LEVEL_DEFAULT +#endif /* SYSCOM_TRACE_LEVEL */ + +/* SYSCOM Module tracing backend is mapped to TUNIT tracing for target platforms */ +#ifdef __HIVECC +# ifndef HRT_CSIM +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_TRACE +# else +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +# endif +#else +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#endif + +#define SYSCOM_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED +#define SYSCOM_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED +#define SYSCOM_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + +#if (SYSCOM_TRACE_LEVEL == SYSCOM_TRACE_LEVEL_DEFAULT) +# define SYSCOM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED +#elif (SYSCOM_TRACE_LEVEL == SYSCOM_TRACE_LEVEL_DEBUG) +# define SYSCOM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED +#else +# error "Connection manager trace level not defined!" +#endif /* SYSCOM_TRACE_LEVEL */ + +#endif /* __IA_CSS_SYSCOM_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/src/ia_css_syscom.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/src/ia_css_syscom.c new file mode 100644 index 0000000000000..2a5ebd88f28bf --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/src/ia_css_syscom.c @@ -0,0 +1,647 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_syscom.h" + +#include "ia_css_syscom_context.h" +#include "ia_css_syscom_config_fw.h" +#include "ia_css_syscom_trace.h" + +#include "queue.h" +#include "send_port.h" +#include "recv_port.h" +#include "regmem_access.h" + +#include "error_support.h" +#include "cpu_mem_support.h" + +#include "queue_struct.h" +#include "send_port_struct.h" +#include "recv_port_struct.h" + +#include "type_support.h" +#include +#include +#include "platform_support.h" + +#include "ia_css_cell.h" + +/* struct of internal buffer sizes */ +struct ia_css_syscom_size_intern { + unsigned int context; + unsigned int input_queue; + unsigned int output_queue; + unsigned int input_port; + unsigned int output_port; + + unsigned int fw_config; + unsigned int specific; + + unsigned int input_buffer; + unsigned int output_buffer; +}; + +/* Allocate buffers internally, when no buffers are provided */ +static int +ia_css_syscom_alloc( + unsigned int ssid, + unsigned int mmid, + const struct ia_css_syscom_size *size, + struct ia_css_syscom_buf *buf) +{ + /* zero the buffer to set all pointers to zero */ + memset(buf, 0, sizeof(*buf)); + + /* allocate cpu_mem */ + buf->cpu = (char *)ia_css_cpu_mem_alloc(size->cpu); + if (!buf->cpu) + goto EXIT7; + + /* allocate and map shared config buffer */ + buf->shm_host = shared_memory_alloc(mmid, size->shm); + if (!buf->shm_host) + goto EXIT6; + buf->shm_cell = shared_memory_map(ssid, mmid, buf->shm_host); + if (!buf->shm_cell) + goto EXIT5; + + /* allocate and map input queue buffer */ + buf->ibuf_host = shared_memory_alloc(mmid, size->ibuf); + if (!buf->ibuf_host) + goto EXIT4; + buf->ibuf_cell = shared_memory_map(ssid, mmid, buf->ibuf_host); + if (!buf->ibuf_cell) + goto EXIT3; + + /* allocate and map output queue buffer */ + buf->obuf_host = shared_memory_alloc(mmid, size->obuf); + if (!buf->obuf_host) + goto EXIT2; + buf->obuf_cell = shared_memory_map(ssid, mmid, buf->obuf_host); + if (!buf->obuf_cell) + goto EXIT1; + + return 0; + +EXIT1: shared_memory_free(mmid, buf->obuf_host); +EXIT2: shared_memory_unmap(ssid, mmid, buf->ibuf_cell); +EXIT3: shared_memory_free(mmid, buf->ibuf_host); +EXIT4: shared_memory_unmap(ssid, mmid, buf->shm_cell); +EXIT5: shared_memory_free(mmid, buf->shm_host); +EXIT6: ia_css_cpu_mem_free(buf->cpu); +EXIT7: return FW_ERROR_NO_MEMORY; +} + +static void +ia_css_syscom_size_intern( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size_intern *size) +{ + /* convert syscom config into syscom internal size struct */ + + unsigned int i; + + size->context = sizeof(struct ia_css_syscom_context); + size->input_queue = cfg->num_input_queues * sizeof(struct sys_queue); + size->output_queue = cfg->num_output_queues * sizeof(struct sys_queue); + size->input_port = cfg->num_input_queues * sizeof(struct send_port); + size->output_port = cfg->num_output_queues * sizeof(struct recv_port); + + size->fw_config = sizeof(struct ia_css_syscom_config_fw); + size->specific = cfg->specific_size; + + /* accumulate input queue buffer sizes */ + size->input_buffer = 0; + for (i = 0; i < cfg->num_input_queues; i++) { + size->input_buffer += + sys_queue_buf_size(cfg->input[i].queue_size, + cfg->input[i].token_size); + } + + /* accumulate outut queue buffer sizes */ + size->output_buffer = 0; + for (i = 0; i < cfg->num_output_queues; i++) { + size->output_buffer += + sys_queue_buf_size(cfg->output[i].queue_size, + cfg->output[i].token_size); + } +} + +static void +ia_css_syscom_size_extern( + const struct ia_css_syscom_size_intern *i, + struct ia_css_syscom_size *e) +{ + /* convert syscom internal size struct into external size struct */ + + e->cpu = i->context + i->input_queue + i->output_queue + + i->input_port + i->output_port; + e->shm = i->fw_config + i->input_queue + i->output_queue + i->specific; + e->ibuf = i->input_buffer; + e->obuf = i->output_buffer; +} + +/* Function that provides buffer sizes to be allocated */ +void +ia_css_syscom_size( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size *size) +{ + struct ia_css_syscom_size_intern i; + + ia_css_syscom_size_intern(cfg, &i); + ia_css_syscom_size_extern(&i, size); +} + +static struct ia_css_syscom_context* +ia_css_syscom_assign_buf( + const struct ia_css_syscom_size_intern *i, + const struct ia_css_syscom_buf *buf) +{ + struct ia_css_syscom_context *ctx; + char *cpu_mem_buf; + host_virtual_address_t shm_buf_host; + vied_virtual_address_t shm_buf_cell; + + /* host context */ + cpu_mem_buf = buf->cpu; + + ctx = (struct ia_css_syscom_context *)cpu_mem_buf; + ia_css_cpu_mem_set_zero(ctx, i->context); + cpu_mem_buf += i->context; + + ctx->input_queue = (struct sys_queue *) cpu_mem_buf; + cpu_mem_buf += i->input_queue; + + ctx->output_queue = (struct sys_queue *) cpu_mem_buf; + cpu_mem_buf += i->output_queue; + + ctx->send_port = (struct send_port *) cpu_mem_buf; + cpu_mem_buf += i->input_port; + + ctx->recv_port = (struct recv_port *) cpu_mem_buf; + + + /* cell config */ + shm_buf_host = buf->shm_host; + shm_buf_cell = buf->shm_cell; + + ctx->config_host_addr = shm_buf_host; + shm_buf_host += i->fw_config; + ctx->config_vied_addr = shm_buf_cell; + shm_buf_cell += i->fw_config; + + ctx->input_queue_host_addr = shm_buf_host; + shm_buf_host += i->input_queue; + ctx->input_queue_vied_addr = shm_buf_cell; + shm_buf_cell += i->input_queue; + + ctx->output_queue_host_addr = shm_buf_host; + shm_buf_host += i->output_queue; + ctx->output_queue_vied_addr = shm_buf_cell; + shm_buf_cell += i->output_queue; + + ctx->specific_host_addr = shm_buf_host; + ctx->specific_vied_addr = shm_buf_cell; + + ctx->ibuf_host_addr = buf->ibuf_host; + ctx->ibuf_vied_addr = buf->ibuf_cell; + + ctx->obuf_host_addr = buf->obuf_host; + ctx->obuf_vied_addr = buf->obuf_cell; + + return ctx; +} + +struct ia_css_syscom_context* +ia_css_syscom_open( + struct ia_css_syscom_config *cfg, + struct ia_css_syscom_buf *buf_extern +) +{ + struct ia_css_syscom_size_intern size_intern; + struct ia_css_syscom_size size; + struct ia_css_syscom_buf buf_intern; + struct ia_css_syscom_buf *buf; + struct ia_css_syscom_context *ctx; + struct ia_css_syscom_config_fw fw_cfg; + unsigned int i; + struct sys_queue_res res; + + IA_CSS_TRACE_0(SYSCOM, INFO, "Entered: ia_css_syscom_open\n"); + + /* error handling */ + if (cfg == NULL) + return NULL; + + IA_CSS_TRACE_1(SYSCOM, INFO, "ia_css_syscom_open (secure %d) start\n", cfg->secure); + + /* check members of cfg: TBD */ + + /* + * Check if SP is in valid state, have to wait if not ready. + * In some platform (Such as VP), it will need more time to wait due to system performance; + * If return NULL without wait for SPC0 ready, Driver load FW will failed + */ + ia_css_cell_wait(cfg->ssid, SPC0); + + ia_css_syscom_size_intern(cfg, &size_intern); + ia_css_syscom_size_extern(&size_intern, &size); + + if (buf_extern) { + /* use externally allocated buffers */ + buf = buf_extern; + } else { + /* use internally allocated buffers */ + buf = &buf_intern; + if (ia_css_syscom_alloc(cfg->ssid, cfg->mmid, &size, buf) != 0) + return NULL; + } + + /* assign buffer pointers */ + ctx = ia_css_syscom_assign_buf(&size_intern, buf); + /* only need to free internally allocated buffers */ + ctx->free_buf = !buf_extern; + + ctx->cell_regs_addr = cfg->regs_addr; + /* regmem is at cell_dmem_addr + REGMEM_OFFSET */ + ctx->cell_dmem_addr = cfg->dmem_addr; + + ctx->num_input_queues = cfg->num_input_queues; + ctx->num_output_queues = cfg->num_output_queues; + + ctx->env.mmid = cfg->mmid; + ctx->env.ssid = cfg->ssid; + ctx->env.mem_addr = cfg->dmem_addr; + + ctx->regmem_idx = SYSCOM_QPR_BASE_REG; + + /* initialize input queues */ + res.reg = SYSCOM_QPR_BASE_REG; + res.host_address = ctx->ibuf_host_addr; + res.vied_address = ctx->ibuf_vied_addr; + for (i = 0; i < cfg->num_input_queues; i++) { + sys_queue_init(ctx->input_queue + i, + cfg->input[i].queue_size, + cfg->input[i].token_size, &res); + } + + /* initialize output queues */ + res.host_address = ctx->obuf_host_addr; + res.vied_address = ctx->obuf_vied_addr; + for (i = 0; i < cfg->num_output_queues; i++) { + sys_queue_init(ctx->output_queue + i, + cfg->output[i].queue_size, + cfg->output[i].token_size, &res); + } + + /* fill shared queue structs */ + shared_memory_store(cfg->mmid, ctx->input_queue_host_addr, + ctx->input_queue, + cfg->num_input_queues * sizeof(struct sys_queue)); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->input_queue_host_addr), + cfg->num_input_queues * sizeof(struct sys_queue)); + shared_memory_store(cfg->mmid, ctx->output_queue_host_addr, + ctx->output_queue, + cfg->num_output_queues * sizeof(struct sys_queue)); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->output_queue_host_addr), + cfg->num_output_queues * sizeof(struct sys_queue)); + + /* Zero the queue buffers. Is this really needed? */ + shared_memory_zero(cfg->mmid, buf->ibuf_host, size.ibuf); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(buf->ibuf_host), + size.ibuf); + shared_memory_zero(cfg->mmid, buf->obuf_host, size.obuf); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(buf->obuf_host), + size.obuf); + + /* copy firmware specific data */ + if (cfg->specific_addr && cfg->specific_size) { + shared_memory_store(cfg->mmid, ctx->specific_host_addr, + cfg->specific_addr, cfg->specific_size); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->specific_host_addr), + cfg->specific_size); + } + + fw_cfg.num_input_queues = cfg->num_input_queues; + fw_cfg.num_output_queues = cfg->num_output_queues; + fw_cfg.input_queue = ctx->input_queue_vied_addr; + fw_cfg.output_queue = ctx->output_queue_vied_addr; + fw_cfg.specific_addr = ctx->specific_vied_addr; + fw_cfg.specific_size = cfg->specific_size; + + shared_memory_store(cfg->mmid, ctx->config_host_addr, + &fw_cfg, sizeof(struct ia_css_syscom_config_fw)); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(ctx->config_host_addr), + sizeof(struct ia_css_syscom_config_fw)); + +#if !HAS_DUAL_CMD_CTX_SUPPORT + /* store syscom uninitialized state */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store STATE_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_STATE_UNINIT, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + SYSCOM_STATE_UNINIT, cfg->ssid); + /* store syscom uninitialized command */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store COMMAND_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_COMMAND_UNINIT, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_UNINIT, cfg->ssid); + /* store firmware configuration address */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store CONFIG_REG (%#x) @ dmem_addr %#x ssid %d\n", + ctx->config_vied_addr, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_CONFIG_REG, + ctx->config_vied_addr, cfg->ssid); +#endif + + /* Indicate if ctx is created for secure stream purpose */ + ctx->secure = cfg->secure; + + IA_CSS_TRACE_1(SYSCOM, INFO, "ia_css_syscom_open (secure %d) completed\n", cfg->secure); + return ctx; +} + + +int ia_css_syscom_close(struct ia_css_syscom_context *ctx) +{ + int state; + + state = regmem_load_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle close request yet */ + return FW_ERROR_BUSY; + } + + /* set close request flag */ + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_INACTIVE, ctx->env.ssid); + + return 0; +} + +static void ia_css_syscom_free(struct ia_css_syscom_context *ctx) +{ + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, ctx->ibuf_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->ibuf_host_addr); + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, ctx->obuf_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->obuf_host_addr); + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, + ctx->config_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->config_host_addr); + ia_css_cpu_mem_free(ctx); +} + +int +ia_css_syscom_release( + struct ia_css_syscom_context *ctx, + unsigned int force) +{ + /* check if release is forced, an verify cell state if it is not */ + if (!force) { + if (!ia_css_cell_is_ready(ctx->env.ssid, SPC0)) + return FW_ERROR_BUSY; + } + + /* Reset the regmem idx */ + ctx->regmem_idx = 0; + + if (ctx->free_buf) + ia_css_syscom_free(ctx); + + return 0; +} + +int ia_css_syscom_send_port_open( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + int state; + + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + /* check if SP syscom is ready to open the queue */ + state = regmem_load_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle messages yet */ + return FW_ERROR_BUSY; + } + + /* initialize the port */ + send_port_open(ctx->send_port + port, + ctx->input_queue + port, &(ctx->env)); + + return 0; +} + +int ia_css_syscom_send_port_close( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return 0; +} + +int ia_css_syscom_send_port_available( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return send_port_available(ctx->send_port + port); +} + +int ia_css_syscom_send_port_transfer( + struct ia_css_syscom_context *ctx, + unsigned int port, + const void *token +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return send_port_transfer(ctx->send_port + port, token); +} + +int ia_css_syscom_recv_port_open( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + int state; + + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + /* check if SP syscom is ready to open the queue */ + state = regmem_load_32(ctx->cell_dmem_addr, + SYSCOM_STATE_REG, ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle messages yet */ + return FW_ERROR_BUSY; + } + + /* initialize the port */ + recv_port_open(ctx->recv_port + port, + ctx->output_queue + port, &(ctx->env)); + + return 0; +} + +int ia_css_syscom_recv_port_close( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return 0; +} + +/* + * Get the number of responses in the response queue + */ +int +ia_css_syscom_recv_port_available( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return recv_port_available(ctx->recv_port + port); +} + + +/* + * Dequeue the head of the response queue + * returns an error when the response queue is empty + */ +int +ia_css_syscom_recv_port_transfer( + struct ia_css_syscom_context *ctx, + unsigned int port, + void *token +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return recv_port_transfer(ctx->recv_port + port, token); +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +/* + * store subsystem context information in DMEM + */ +int +ia_css_syscom_store_dmem( + struct ia_css_syscom_context *ctx, + unsigned int ssid, + unsigned int vtl0_addr_mask +) +{ + unsigned int read_back; + + NOT_USED(vtl0_addr_mask); + NOT_USED(read_back); + + if (ctx->secure) { + /* store VTL0 address mask in 'secure' context */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem VTL0_ADDR_MASK (%#x) @ dmem_addr %#x ssid %d\n", + vtl0_addr_mask, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_VTL0_ADDR_MASK, vtl0_addr_mask, ssid); + } + /* store firmware configuration address */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem CONFIG_REG (%#x) @ dmem_addr %#x ssid %d\n", + ctx->config_vied_addr, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_CONFIG_REG, + ctx->config_vied_addr, ssid); + /* store syscom uninitialized state */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem STATE_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_STATE_UNINIT, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + SYSCOM_STATE_UNINIT, ssid); + /* store syscom uninitialized command */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem COMMAND_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_COMMAND_UNINIT, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_UNINIT, ssid); + + return 0; +} + +/* + * store truslet configuration status setting + */ +void +ia_css_syscom_set_trustlet_status( + unsigned int dmem_addr, + unsigned int ssid, + bool trustlet_exist +) +{ + unsigned int value; + + value = trustlet_exist ? TRUSTLET_EXIST : TRUSTLET_NOT_EXIST; + IA_CSS_TRACE_3(SYSCOM, INFO, + "ia_css_syscom_set_trustlet_status TRUSTLET_STATUS (%#x) @ dmem_addr %#x ssid %d\n", + value, dmem_addr, ssid); + regmem_store_32(dmem_addr, TRUSTLET_STATUS, value, ssid); +} + +/* + * check if SPC access blocker programming is completed + */ +bool +ia_css_syscom_is_ab_spc_ready( + struct ia_css_syscom_context *ctx +) +{ + unsigned int value; + + /* We only expect the call from non-secure context only */ + if (ctx->secure) { + IA_CSS_TRACE_0(SYSCOM, ERROR, "ia_css_syscom_is_spc_ab_ready - Please call from non-secure context\n"); + return false; + } + + value = regmem_load_32(ctx->cell_dmem_addr, AB_SPC_STATUS, ctx->env.ssid); + IA_CSS_TRACE_3(SYSCOM, INFO, + "ia_css_syscom_is_spc_ab_ready AB_SPC_STATUS @ dmem_addr %#x ssid %d - value %#x\n", + ctx->cell_dmem_addr, ctx->env.ssid, value); + + return (value == AB_SPC_READY); +} +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/src/ia_css_syscom_config_fw.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/src/ia_css_syscom_config_fw.h new file mode 100644 index 0000000000000..0cacd5a34934d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/src/ia_css_syscom_config_fw.h @@ -0,0 +1,69 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONFIG_FW_H +#define __IA_CSS_SYSCOM_CONFIG_FW_H + +#include "type_support.h" + +enum { + /* Program load or explicit host setting should init to this */ + SYSCOM_STATE_UNINIT = 0x57A7E000, + /* SP Syscom sets this when it is ready for use */ + SYSCOM_STATE_READY = 0x57A7E001, + /* SP Syscom sets this when no more syscom accesses will happen */ + SYSCOM_STATE_INACTIVE = 0x57A7E002 +}; + +enum { + /* Program load or explicit host setting should init to this */ + SYSCOM_COMMAND_UNINIT = 0x57A7F000, + /* Host Syscom requests syscom to become inactive */ + SYSCOM_COMMAND_INACTIVE = 0x57A7F001 +}; + +#if HAS_DUAL_CMD_CTX_SUPPORT +enum { + /* Program load or explicit host setting should init to this */ + TRUSTLET_UNINIT = 0x57A8E000, + /* Host Syscom informs SP that Trustlet exists */ + TRUSTLET_EXIST = 0x57A8E001, + /* Host Syscom informs SP that Trustlet does not exist */ + TRUSTLET_NOT_EXIST = 0x57A8E002 +}; + +enum { + /* Program load or explicit setting initialized by SP */ + AB_SPC_NOT_READY = 0x57A8F000, + /* SP informs host that SPC access programming is completed */ + AB_SPC_READY = 0x57A8F001 +}; +#endif + +/* firmware config: data that sent from the host to SP via DDR */ +/* Cell copies data into a context */ + +struct ia_css_syscom_config_fw { + unsigned int firmware_address; + + unsigned int num_input_queues; + unsigned int num_output_queues; + unsigned int input_queue; /* hmm_ptr / struct queue* */ + unsigned int output_queue; /* hmm_ptr / struct queue* */ + + unsigned int specific_addr; /* vied virtual address */ + unsigned int specific_size; +}; + +#endif /* __IA_CSS_SYSCOM_CONFIG_FW_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/src/ia_css_syscom_context.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/src/ia_css_syscom_context.h new file mode 100644 index 0000000000000..ecf22f6b7ac53 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/src/ia_css_syscom_context.h @@ -0,0 +1,65 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONTEXT_H +#define __IA_CSS_SYSCOM_CONTEXT_H + +#include + +#include "port_env_struct.h" +#include + +/* host context */ +struct ia_css_syscom_context { + vied_virtual_address_t cell_firmware_addr; + unsigned int cell_regs_addr; + unsigned int cell_dmem_addr; + + struct port_env env; + + unsigned int num_input_queues; + unsigned int num_output_queues; + + /* array of input queues (from host to SP) */ + struct sys_queue *input_queue; + /* array of output queues (from SP to host) */ + struct sys_queue *output_queue; + + struct send_port *send_port; + struct recv_port *recv_port; + + unsigned int regmem_idx; + unsigned int free_buf; + + host_virtual_address_t config_host_addr; + host_virtual_address_t input_queue_host_addr; + host_virtual_address_t output_queue_host_addr; + host_virtual_address_t specific_host_addr; + host_virtual_address_t ibuf_host_addr; + host_virtual_address_t obuf_host_addr; + + vied_virtual_address_t config_vied_addr; + vied_virtual_address_t input_queue_vied_addr; + vied_virtual_address_t output_queue_vied_addr; + vied_virtual_address_t specific_vied_addr; + vied_virtual_address_t ibuf_vied_addr; + vied_virtual_address_t obuf_vied_addr; + + /* if true; secure syscom object as in VTIO Case + * if false, non-secure syscom + */ + bool secure; +}; + +#endif /* __IA_CSS_SYSCOM_CONTEXT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/syscom.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/syscom.mk new file mode 100644 index 0000000000000..8d36b8928af55 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/syscom/syscom.mk @@ -0,0 +1,42 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is SYSCOM + +SYSCOM_DIR=$${MODULES_DIR}/syscom + +SYSCOM_INTERFACE=$(SYSCOM_DIR)/interface +SYSCOM_SOURCES1=$(SYSCOM_DIR)/src + +SYSCOM_HOST_FILES += $(SYSCOM_SOURCES1)/ia_css_syscom.c + +SYSCOM_HOST_CPPFLAGS += -I$(SYSCOM_INTERFACE) +SYSCOM_HOST_CPPFLAGS += -I$(SYSCOM_SOURCES1) +SYSCOM_HOST_CPPFLAGS += -I$${MODULES_DIR}/devices +ifdef REGMEM_SECURE_OFFSET +SYSCOM_HOST_CPPFLAGS += -DREGMEM_SECURE_OFFSET=$(REGMEM_SECURE_OFFSET) +else +SYSCOM_HOST_CPPFLAGS += -DREGMEM_SECURE_OFFSET=0 +endif + +SYSCOM_FW_FILES += $(SYSCOM_SOURCES1)/ia_css_syscom_fw.c + +SYSCOM_FW_CPPFLAGS += -I$(SYSCOM_INTERFACE) +SYSCOM_FW_CPPFLAGS += -I$(SYSCOM_SOURCES1) +SYSCOM_FW_CPPFLAGS += -DREGMEM_OFFSET=$(REGMEM_OFFSET) +ifdef REGMEM_SECURE_OFFSET +SYSCOM_FW_CPPFLAGS += -DREGMEM_SECURE_OFFSET=$(REGMEM_SECURE_OFFSET) +else +SYSCOM_FW_CPPFLAGS += -DREGMEM_SECURE_OFFSET=0 +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/trace/interface/ia_css_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/trace/interface/ia_css_trace.h new file mode 100644 index 0000000000000..b85b1810f1070 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/trace/interface/ia_css_trace.h @@ -0,0 +1,883 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/*! \file */ + +#ifndef __IA_CSS_TRACE_H +#define __IA_CSS_TRACE_H + +/* +** Configurations +*/ + +/** + * STEP 1: Define {Module Name}_TRACE_METHOD to one of the following. + * Where: + * {Module Name} is the name of the targeted module. + * + * Example: + * #define NCI_DMA_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + */ + +/**< Use whatever method of tracing that best suits the platform + * this code is compiled for. + */ +#define IA_CSS_TRACE_METHOD_NATIVE 1 +/**< Use the Tracing NCI. */ +#define IA_CSS_TRACE_METHOD_TRACE 2 + +/** + * STEP 2: Define {Module Name}_TRACE_LEVEL_{Level} to one of the following. + * Where: + * {Module Name} is the name of the targeted module. + * {Level}, in decreasing order of severity, is one of the + * following values: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * + * Example: + * #define NCI_DMA_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED + * #define NCI_DMA_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + */ +/**< Disables the corresponding trace level. */ +#define IA_CSS_TRACE_LEVEL_DISABLED 0 +/**< Enables the corresponding trace level. */ +#define IA_CSS_TRACE_LEVEL_ENABLED 1 + +/* + * Used in macro definition with do-while loop + * for removing checkpatch warnings + */ +#define IA_CSS_TRACE_FILE_DUMMY_DEFINE + +/** + * STEP 3: Define IA_CSS_TRACE_PRINT_FILE_LINE to have file name and + * line printed with every log message. + * + * Example: + * #define IA_CSS_TRACE_PRINT_FILE_LINE + */ + +/* +** Interface +*/ + +/* +** Static +*/ + +/** + * Logs a message with zero arguments if the targeted severity level is enabled + * at compile-time. + * @param module The targeted module. + * @param severity The severity level of the trace message. In decreasing order: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * @param format The message to be traced. + */ +#define IA_CSS_TRACE_0(module, severity, format) \ + IA_CSS_TRACE_IMPL(module, 0, severity, format) + +/** + * Logs a message with one argument if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_1(module, severity, format, a1) \ + IA_CSS_TRACE_IMPL(module, 1, severity, format, a1) + +/** + * Logs a message with two arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_2(module, severity, format, a1, a2) \ + IA_CSS_TRACE_IMPL(module, 2, severity, format, a1, a2) + +/** + * Logs a message with three arguments if the targeted severity level + * is enabled at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_3(module, severity, format, a1, a2, a3) \ + IA_CSS_TRACE_IMPL(module, 3, severity, format, a1, a2, a3) + +/** + * Logs a message with four arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_4(module, severity, format, a1, a2, a3, a4) \ + IA_CSS_TRACE_IMPL(module, 4, severity, format, a1, a2, a3, a4) + +/** + * Logs a message with five arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_5(module, severity, format, a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_IMPL(module, 5, severity, format, a1, a2, a3, a4, a5) + +/** + * Logs a message with six arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_6(module, severity, format, a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_IMPL(module, 6, severity, format, a1, a2, a3, a4, a5, a6) + +/** + * Logs a message with seven arguments if the targeted severity level + * is enabled at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_7(module, severity, format, a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_IMPL(module, 7, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) + +/* +** Dynamic +*/ + +/** +* Declares, but does not define, dynamic tracing functions and variables +* for module \p module. For each module, place an instance of this macro +* in the compilation unit in which you want to use dynamic tracing facility +* so as to inform the compiler of the declaration of the available functions. +* An invocation of this function does not enable any of the available tracing +* levels. Do not place a semicolon after a call to this macro. +* @see IA_CSS_TRACE_DYNAMIC_DEFINE +*/ +#define IA_CSS_TRACE_DYNAMIC_DECLARE(module) \ + IA_CSS_TRACE_DYNAMIC_DECLARE_IMPL(module) +/** +* Declares the configuration function for the dynamic api seperatly, if one +* wants to use it. +*/ +#define IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC(module) \ + IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC_IMPL(module) + +/** +* Defines dynamic tracing functions and variables for module \p module. +* For each module, place an instance of this macro in one, and only one, +* of your SOURCE files so as to allow the linker resolve the related symbols. +* An invocation of this macro does not enable any of the available tracing +* levels. Do not place a semicolon after a call to this macro. +* @see IA_CSS_TRACE_DYNAMIC_DECLARE +*/ +#define IA_CSS_TRACE_DYNAMIC_DEFINE(module) \ + IA_CSS_TRACE_DYNAMIC_DEFINE_IMPL(module) +/** +* Defines the configuration function for the dynamic api seperatly, if one +* wants to use it. +*/ +#define IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC(module) \ + IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC_IMPL(module) + +/** + * Logs a message with zero arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @param module The targeted module. + * @param severity The severity level of the trace message. In decreasing order: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * @param format The message to be traced. + */ +#define IA_CSS_TRACE_DYNAMIC_0(module, severity, format) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 0, severity, format) + +/** + * Logs a message with one argument if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_1(module, severity, format, a1) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 1, severity, format, a1) + +/** + * Logs a message with two arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_2(module, severity, format, a1, a2) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 2, severity, format, a1, a2) + +/** + * Logs a message with three arguments if the targeted severity level + * is enabled both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_3(module, severity, format, a1, a2, a3) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 3, severity, format, a1, a2, a3) + +/** + * Logs a message with four arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_4(module, severity, format, a1, a2, a3, a4) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 4, severity, format, a1, a2, a3, a4) + +/** + * Logs a message with five arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_5(module, severity, format, a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 5, severity, format, \ + a1, a2, a3, a4, a5) + +/** + * Logs a message with six arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_6(module, severity, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 6, severity, format, \ + a1, a2, a3, a4, a5, a6) + +/** + * Logs a message with seven arguments if the targeted severity level + * is enabled both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_7(module, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 7, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) + +/* +** Implementation +*/ + +/* CAT */ +#define IA_CSS_TRACE_CAT_IMPL(a, b) a ## b +#define IA_CSS_TRACE_CAT(a, b) IA_CSS_TRACE_CAT_IMPL(a, b) + +/* Bridge */ +#if defined(__HIVECC) || defined(__GNUC__) +#define IA_CSS_TRACE_IMPL(module, argument_count, severity, arguments ...) \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_, \ + argument_count \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_LEVEL_ \ + ), \ + severity \ + ) \ + ( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_SEVERITY_, \ + severity \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + #module, \ + ## arguments \ + ) \ + ) + +/* Bridge */ +#define IA_CSS_TRACE_DYNAMIC_IMPL(module, argument_count, severity, \ + arguments ...) \ + do { \ + if (IA_CSS_TRACE_CAT(IA_CSS_TRACE_CAT(module, _trace_level_), \ + severity)) { \ + IA_CSS_TRACE_IMPL(module, argument_count, severity, \ + ## arguments); \ + } \ + } while (0) +#elif defined(_MSC_VER) +#define IA_CSS_TRACE_IMPL(module, argument_count, severity, ...) \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_, \ + argument_count \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_LEVEL_ \ + ), \ + severity \ + ) \ + ( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_SEVERITY_, \ + severity \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + #module, \ + __VA_ARGS__ \ + ) \ + ) + +/* Bridge */ +#define IA_CSS_TRACE_DYNAMIC_IMPL(module, argument_count, severity, ...) \ + do { \ + if (IA_CSS_TRACE_CAT(IA_CSS_TRACE_CAT(module, _trace_level_), \ + severity)) { \ + IA_CSS_TRACE_IMPL(module, argument_count, severity, \ + __VA_ARGS__); \ + } \ + } while (0) +#endif + +/* +** Native Backend +*/ + +#if defined(__HIVECC) + #define IA_CSS_TRACE_PLATFORM_CELL +#elif defined(__GNUC__) + #define IA_CSS_TRACE_PLATFORM_HOST + + #define IA_CSS_TRACE_NATIVE(severity, module, format, arguments ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, module, \ + format), ## arguments); \ + } while (0) + /* TODO: In case Host Side tracing is needed to be mapped to the + * Tunit, the following "IA_CSS_TRACE_TRACE" needs to be modified from + * PRINT to vied_nci_tunit_print function calls + */ + #define IA_CSS_TRACE_TRACE(severity, module, format, arguments ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, module, \ + format), ## arguments); \ + } while (0) + +#elif defined(_MSC_VER) + #define IA_CSS_TRACE_PLATFORM_HOST + + #define IA_CSS_TRACE_NATIVE(severity, module, format, ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, \ + module, format), __VA_ARGS__); \ + } while (0) + /* TODO: In case Host Side tracing is needed to be mapped to the + * Tunit, the following "IA_CSS_TRACE_TRACE" needs to be modified from + * PRINT to vied_nci_tunit_print function calls + */ + #define IA_CSS_TRACE_TRACE(severity, module, format, ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, \ + module, format), __VA_ARGS__); \ + } while (0) +#else + #error Unsupported platform! +#endif /* Platform */ + +#if defined(IA_CSS_TRACE_PLATFORM_CELL) + #include /* VOLATILE */ + + #ifdef IA_CSS_TRACE_PRINT_FILE_LINE + #define IA_CSS_TRACE_FILE_PRINT_COMMAND \ + do { \ + OP___printstring(__FILE__":") VOLATILE; \ + OP___printdec(__LINE__) VOLATILE; \ + OP___printstring("\n") VOLATILE; \ + } while (0) + #else + #define IA_CSS_TRACE_FILE_PRINT_COMMAND + #endif + + #define IA_CSS_TRACE_MODULE_SEVERITY_PRINT(module, severity) \ + do { \ + IA_CSS_TRACE_FILE_DUMMY_DEFINE; \ + OP___printstring("["module"]:["severity"]:") \ + VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_MSG_NATIVE(severity, module, format) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + OP___printstring("["module"]:["severity"]: "format) \ + VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_ARG_NATIVE(module, severity, i, value) \ + do { \ + IA_CSS_TRACE_MODULE_SEVERITY_PRINT(module, severity); \ + OP___dump(i, value) VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_0(severity, module, format) \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format) + + #define IA_CSS_TRACE_NATIVE_1(severity, module, format, a1) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_2(severity, module, format, a1, a2) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_3(severity, module, format, a1, a2, a3) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_4(severity, module, format, \ + a1, a2, a3, a4) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 6, a6); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 6, a6); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 7, a7); \ + } while (0) + /* + ** Tracing Backend + */ +#if !defined(HRT_CSIM) && !defined(NO_TUNIT) + #include "vied_nci_tunit.h" +#endif + #define IA_CSS_TRACE_AUG_FORMAT_TRACE(format, module) \ + "[" module "]" format " : PID = %x : Timestamp = %d : PC = %x" + + #define IA_CSS_TRACE_TRACE_0(severity, module, format) \ + vied_nci_tunit_print(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity) + + #define IA_CSS_TRACE_TRACE_1(severity, module, format, a1) \ + vied_nci_tunit_print1i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1) + + #define IA_CSS_TRACE_TRACE_2(severity, module, format, a1, a2) \ + vied_nci_tunit_print2i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2) + + #define IA_CSS_TRACE_TRACE_3(severity, module, format, a1, a2, a3) \ + vied_nci_tunit_print3i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3) + + #define IA_CSS_TRACE_TRACE_4(severity, module, format, a1, a2, a3, a4) \ + vied_nci_tunit_print4i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4) + + #define IA_CSS_TRACE_TRACE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + vied_nci_tunit_print5i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_TRACE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + vied_nci_tunit_print6i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_TRACE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + vied_nci_tunit_print7i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5, a6, a7) + +#elif defined(IA_CSS_TRACE_PLATFORM_HOST) + #include "print_support.h" + + #ifdef IA_CSS_TRACE_PRINT_FILE_LINE + #define IA_CSS_TRACE_FILE_PRINT_COMMAND \ + PRINT("%s:%d:\n", __FILE__, __LINE__) + #else + #define IA_CSS_TRACE_FILE_PRINT_COMMAND + #endif + + #define IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, module, format) \ + "[" module "]:[" severity "]: " format + + #define IA_CSS_TRACE_NATIVE_0(severity, module, format) \ + IA_CSS_TRACE_NATIVE(severity, module, format) + + #define IA_CSS_TRACE_NATIVE_1(severity, module, format, a1) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1) + + #define IA_CSS_TRACE_NATIVE_2(severity, module, format, a1, a2) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2) + + #define IA_CSS_TRACE_NATIVE_3(severity, module, format, a1, a2, a3) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2, a3) + + #define IA_CSS_TRACE_NATIVE_4(severity, module, format, \ + a1, a2, a3, a4) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2, a3, a4) + + #define IA_CSS_TRACE_NATIVE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_NATIVE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_NATIVE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) + + #define IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, module, format) \ + "["module"]:["severity"]: "format + + #define IA_CSS_TRACE_TRACE_0(severity, module, format) \ + IA_CSS_TRACE_TRACE(severity, module, format) + + #define IA_CSS_TRACE_TRACE_1(severity, module, format, a1) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1) + + #define IA_CSS_TRACE_TRACE_2(severity, module, format, a1, a2) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2) + + #define IA_CSS_TRACE_TRACE_3(severity, module, format, a1, a2, a3) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2, a3) + + #define IA_CSS_TRACE_TRACE_4(severity, module, format, \ + a1, a2, a3, a4) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2, a3, a4) + + #define IA_CSS_TRACE_TRACE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_TRACE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_TRACE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) +#endif + +/* Disabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_1_0(severity, module, format) +#define IA_CSS_TRACE_1_1_0(severity, module, format, arg1) +#define IA_CSS_TRACE_2_1_0(severity, module, format, arg1, arg2) +#define IA_CSS_TRACE_3_1_0(severity, module, format, arg1, arg2, arg3) +#define IA_CSS_TRACE_4_1_0(severity, module, format, arg1, arg2, arg3, arg4) +#define IA_CSS_TRACE_5_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5) +#define IA_CSS_TRACE_6_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6) +#define IA_CSS_TRACE_7_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7) + +/* Enabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_1_1 IA_CSS_TRACE_NATIVE_0 +#define IA_CSS_TRACE_1_1_1 IA_CSS_TRACE_NATIVE_1 +#define IA_CSS_TRACE_2_1_1 IA_CSS_TRACE_NATIVE_2 +#define IA_CSS_TRACE_3_1_1 IA_CSS_TRACE_NATIVE_3 +#define IA_CSS_TRACE_4_1_1 IA_CSS_TRACE_NATIVE_4 +#define IA_CSS_TRACE_5_1_1 IA_CSS_TRACE_NATIVE_5 +#define IA_CSS_TRACE_6_1_1 IA_CSS_TRACE_NATIVE_6 +#define IA_CSS_TRACE_7_1_1 IA_CSS_TRACE_NATIVE_7 + +/* Enabled */ +/* Legend: IA_CSS_TRACE_SEVERITY_{Severity Level}_{Backend ID} */ +#define IA_CSS_TRACE_SEVERITY_ASSERT_1 "Assert" +#define IA_CSS_TRACE_SEVERITY_ERROR_1 "Error" +#define IA_CSS_TRACE_SEVERITY_WARNING_1 "Warning" +#define IA_CSS_TRACE_SEVERITY_INFO_1 "Info" +#define IA_CSS_TRACE_SEVERITY_DEBUG_1 "Debug" +#define IA_CSS_TRACE_SEVERITY_VERBOSE_1 "Verbose" + +/* Disabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_2_0(severity, module, format) +#define IA_CSS_TRACE_1_2_0(severity, module, format, arg1) +#define IA_CSS_TRACE_2_2_0(severity, module, format, arg1, arg2) +#define IA_CSS_TRACE_3_2_0(severity, module, format, arg1, arg2, arg3) +#define IA_CSS_TRACE_4_2_0(severity, module, format, arg1, arg2, arg3, arg4) +#define IA_CSS_TRACE_5_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5) +#define IA_CSS_TRACE_6_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6) +#define IA_CSS_TRACE_7_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7) + +/* Enabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_2_1 IA_CSS_TRACE_TRACE_0 +#define IA_CSS_TRACE_1_2_1 IA_CSS_TRACE_TRACE_1 +#define IA_CSS_TRACE_2_2_1 IA_CSS_TRACE_TRACE_2 +#define IA_CSS_TRACE_3_2_1 IA_CSS_TRACE_TRACE_3 +#define IA_CSS_TRACE_4_2_1 IA_CSS_TRACE_TRACE_4 +#define IA_CSS_TRACE_5_2_1 IA_CSS_TRACE_TRACE_5 +#define IA_CSS_TRACE_6_2_1 IA_CSS_TRACE_TRACE_6 +#define IA_CSS_TRACE_7_2_1 IA_CSS_TRACE_TRACE_7 + +/* Enabled */ +/* Legend: IA_CSS_TRACE_SEVERITY_{Severity Level}_{Backend ID} */ +#define IA_CSS_TRACE_SEVERITY_ASSERT_2 VIED_NCI_TUNIT_MSG_SEVERITY_FATAL +#define IA_CSS_TRACE_SEVERITY_ERROR_2 VIED_NCI_TUNIT_MSG_SEVERITY_ERROR +#define IA_CSS_TRACE_SEVERITY_WARNING_2 VIED_NCI_TUNIT_MSG_SEVERITY_WARNING +#define IA_CSS_TRACE_SEVERITY_INFO_2 VIED_NCI_TUNIT_MSG_SEVERITY_NORMAL +#define IA_CSS_TRACE_SEVERITY_DEBUG_2 VIED_NCI_TUNIT_MSG_SEVERITY_USER1 +#define IA_CSS_TRACE_SEVERITY_VERBOSE_2 VIED_NCI_TUNIT_MSG_SEVERITY_USER2 + +/* +** Dynamicism +*/ + +#define IA_CSS_TRACE_DYNAMIC_DECLARE_IMPL(module) \ + do { \ + void IA_CSS_TRACE_CAT(module, _trace_assert_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_assert_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_error_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_error_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_warning_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_warning_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_info_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_info_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_debug_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_debug_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_disable)(void); \ + } while (0) + +#define IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC_IMPL(module) \ + do { \ + IA_CSS_TRACE_FILE_DUMMY_DEFINE; \ + void IA_CSS_TRACE_CAT(module, _trace_configure)\ + (int argc, const char *const *argv); \ + } while (0) + +#include "platform_support.h" +#include "type_support.h" + +#define IA_CSS_TRACE_DYNAMIC_DEFINE_IMPL(module) \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_assert); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_error); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_warning); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_info); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_debug); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_verbose); \ + \ + void IA_CSS_TRACE_CAT(module, _trace_assert_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_assert) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_assert_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_assert) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_error_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_error) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_error_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_error) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_warning_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_warning) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_warning_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_warning) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_info_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_info) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_info_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_info) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_debug_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_debug) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_debug_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_debug) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_verbose) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_verbose) = 0; \ + } + +#define IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC_IMPL(module) \ +void IA_CSS_TRACE_CAT(module, _trace_configure)(const int argc, \ + const char *const *const argv) \ +{ \ + int i = 1; \ + const char *levels = 0; \ + \ + while (i < argc) { \ + if (!strcmp(argv[i], "-" #module "_trace")) { \ + ++i; \ + \ + if (i < argc) { \ + levels = argv[i]; \ + \ + while (*levels) { \ + switch (*levels++) { \ + case 'a': \ + IA_CSS_TRACE_CAT \ + (module, _trace_assert_enable)(); \ + break; \ + \ + case 'e': \ + IA_CSS_TRACE_CAT \ + (module, _trace_error_enable)(); \ + break; \ + \ + case 'w': \ + IA_CSS_TRACE_CAT \ + (module, _trace_warning_enable)(); \ + break; \ + \ + case 'i': \ + IA_CSS_TRACE_CAT \ + (module, _trace_info_enable)(); \ + break; \ + \ + case 'd': \ + IA_CSS_TRACE_CAT \ + (module, _trace_debug_enable)(); \ + break; \ + \ + case 'v': \ + IA_CSS_TRACE_CAT \ + (module, _trace_verbose_enable)(); \ + break; \ + \ + default: \ + } \ + } \ + } \ + } \ + \ + ++i; \ + } \ +} + +#endif /* __IA_CSS_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/trace/trace.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/trace/trace.mk new file mode 100644 index 0000000000000..b232880b882bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/trace/trace.mk @@ -0,0 +1,40 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE Trace + +# Dependencies +IA_CSS_TRACE_SUPPORT = $${MODULES_DIR}/support + +# API +IA_CSS_TRACE = $${MODULES_DIR}/trace +IA_CSS_TRACE_INTERFACE = $(IA_CSS_TRACE)/interface + +# +# Host +# + +# Host CPP Flags +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE_SUPPORT) +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE_INTERFACE) +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE)/trace_modules + +# +# Firmware +# + +# Firmware CPP Flags +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE_SUPPORT) +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE_INTERFACE) +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE)/trace_modules diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/utils/system_defs/system_const.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/utils/system_defs/system_const.h new file mode 100644 index 0000000000000..161f28fced973 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/utils/system_defs/system_const.h @@ -0,0 +1,26 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __SYSTEM_CONST_H +#define __SYSTEM_CONST_H + +/* The values included in this file should have been + * taken from system/device properties which + * are not currently available in SDK + */ + +#define XMEM_WIDTH (512) +#define MG_PPC (4) + +#endif /* __SYSTEM_CONST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/shared_memory_access.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/shared_memory_access.h new file mode 100644 index 0000000000000..fd11c12367fec --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/shared_memory_access.h @@ -0,0 +1,138 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _SHARED_MEMORY_ACCESS_H +#define _SHARED_MEMORY_ACCESS_H + +#include +#include +#include + +typedef enum { + sm_esuccess, + sm_enomem, + sm_ezeroalloc, + sm_ebadvaddr, + sm_einternalerror, + sm_ecorruption, + sm_enocontiguousmem, + sm_enolocmem, + sm_emultiplefree, +} shared_memory_error; + +/** + * \brief Virtual address of (DDR) shared memory space as seen from the VIED subsystem + */ +typedef uint32_t vied_virtual_address_t; + +/** + * \brief Virtual address of (DDR) shared memory space as seen from the host + */ +typedef unsigned long long host_virtual_address_t; + +/** + * \brief List of physical addresses of (DDR) shared memory space. This is used to represent a list of physical pages. + */ +typedef struct shared_memory_physical_page_list_s *shared_memory_physical_page_list; +typedef struct shared_memory_physical_page_list_s { + shared_memory_physical_page_list next; + vied_physical_address_t address; +} shared_memory_physical_page_list_s; + + +/** + * \brief Initialize the shared memory interface administration on the host. + * \param idm: id of ddr memory + * \param host_ddr_addr: physical address of memory as seen from host + * \param memory_size: size of ddr memory in bytes + * \param ps: size of page in bytes (for instance 4096) + */ +int shared_memory_allocation_initialize(vied_memory_t idm, vied_physical_address_t host_ddr_addr, size_t memory_size, size_t ps); + +/** + * \brief De-initialize the shared memory interface administration on the host. + * + */ +void shared_memory_allocation_uninitialize(vied_memory_t idm); + +/** + * \brief Allocate (DDR) shared memory space and return a host virtual address. Returns NULL when insufficient memory available + */ +host_virtual_address_t shared_memory_alloc(vied_memory_t idm, size_t bytes); + +/** + * \brief Free (DDR) shared memory space. +*/ +void shared_memory_free(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Translate a virtual host.address to a physical address. +*/ +vied_physical_address_t shared_memory_virtual_host_to_physical_address(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Return the allocated physical pages for a virtual host.address. +*/ +shared_memory_physical_page_list shared_memory_virtual_host_to_physical_pages(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Destroy a shared_memory_physical_page_list. +*/ +void shared_memory_physical_pages_list_destroy(shared_memory_physical_page_list ppl); + +/** + * \brief Store a byte into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_8(vied_memory_t idm, host_virtual_address_t addr, uint8_t data); + +/** + * \brief Store a 16-bit word into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_16(vied_memory_t idm, host_virtual_address_t addr, uint16_t data); + +/** + * \brief Store a 32-bit word into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_32(vied_memory_t idm, host_virtual_address_t addr, uint32_t data); + +/** + * \brief Store a number of bytes into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store(vied_memory_t idm, host_virtual_address_t addr, const void *data, size_t bytes); + +/** + * \brief Set a number of bytes of (DDR) shared memory space to 0 using a host virtual address + */ +void shared_memory_zero(vied_memory_t idm, host_virtual_address_t addr, size_t bytes); + +/** + * \brief Load a byte from (DDR) shared memory space using a host virtual address + */ +uint8_t shared_memory_load_8(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a 16-bit word from (DDR) shared memory space using a host virtual address + */ +uint16_t shared_memory_load_16(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a 32-bit word from (DDR) shared memory space using a host virtual address + */ +uint32_t shared_memory_load_32(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a number of bytes from (DDR) shared memory space using a host virtual address + */ +void shared_memory_load(vied_memory_t idm, host_virtual_address_t addr, void *data, size_t bytes); + +#endif /* _SHARED_MEMORY_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/shared_memory_map.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/shared_memory_map.h new file mode 100644 index 0000000000000..1bbedcf9e7fd8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/shared_memory_map.h @@ -0,0 +1,53 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _SHARED_MEMORY_MAP_H +#define _SHARED_MEMORY_MAP_H + +#include +#include +#include + +typedef void (*shared_memory_invalidate_mmu_tlb)(void); +typedef void (*shared_memory_set_page_table_base_address)(vied_physical_address_t); + +typedef void (*shared_memory_invalidate_mmu_tlb_ssid)(vied_subsystem_t id); +typedef void (*shared_memory_set_page_table_base_address_ssid)(vied_subsystem_t id, vied_physical_address_t); + +/** + * \brief Initialize the CSS virtual address system and MMU. The subsystem id will NOT be taken into account. +*/ +int shared_memory_map_initialize(vied_subsystem_t id, vied_memory_t idm, size_t mmu_ps, size_t mmu_pnrs, vied_physical_address_t ddr_addr, shared_memory_invalidate_mmu_tlb inv_tlb, shared_memory_set_page_table_base_address sbt); + +/** + * \brief Initialize the CSS virtual address system and MMU. The subsystem id will be taken into account. +*/ +int shared_memory_map_initialize_ssid(vied_subsystem_t id, vied_memory_t idm, size_t mmu_ps, size_t mmu_pnrs, vied_physical_address_t ddr_addr, shared_memory_invalidate_mmu_tlb_ssid inv_tlb, shared_memory_set_page_table_base_address_ssid sbt); + +/** + * \brief De-initialize the CSS virtual address system and MMU. +*/ +void shared_memory_map_uninitialize(vied_subsystem_t id, vied_memory_t idm); + +/** + * \brief Convert a host virtual address to a CSS virtual address and update the MMU. +*/ +vied_virtual_address_t shared_memory_map(vied_subsystem_t id, vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Free a CSS virtual address and update the MMU. +*/ +void shared_memory_unmap(vied_subsystem_t id, vied_memory_t idm, vied_virtual_address_t addr); + + +#endif /* _SHARED_MEMORY_MAP_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_config.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_config.h new file mode 100644 index 0000000000000..33ae98e27605d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_config.h @@ -0,0 +1,33 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_CONFIG_H +#define _HRT_VIED_CONFIG_H + +/* Defines from the compiler: + * HRT_HOST - this is code running on the host + * HRT_CELL - this is code running on a cell + */ +#ifdef HRT_HOST +# define CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL 1 +# undef CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL + +#elif defined(HRT_CELL) +# undef CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL +# define CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL 1 + +#else /* !HRT_CELL */ +/* Allow neither HRT_HOST nor HRT_CELL for testing purposes */ +#endif /* !HRT_CELL */ + +#endif /* _HRT_VIED_CONFIG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_memory_access_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_memory_access_types.h new file mode 100644 index 0000000000000..0b44492789e37 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_memory_access_types.h @@ -0,0 +1,36 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_MEMORY_ACCESS_TYPES_H +#define _HRT_VIED_MEMORY_ACCESS_TYPES_H + +/** Types for the VIED memory access interface */ + +#include "vied_types.h" + +/** + * \brief An identifier for a system memory. + * + * This identifier must be a compile-time constant. It is used in + * access to system memory. + */ +typedef unsigned int vied_memory_t; + +#ifndef __HIVECC +/** + * \brief The type for a physical address + */ +typedef unsigned long long vied_physical_address_t; +#endif + +#endif /* _HRT_VIED_MEMORY_ACCESS_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_subsystem_access.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_subsystem_access.h new file mode 100644 index 0000000000000..879bcb41253a9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_subsystem_access.h @@ -0,0 +1,70 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_H + +#include +#include "vied_config.h" +#include "vied_subsystem_access_types.h" + +#if !defined(CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL) && \ + !defined(CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL) +#error Implementation selection macro for vied subsystem access not defined +#endif + +#if defined(CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL) +#ifndef __HIVECC +#error "Inline implementation of subsystem access not supported for host" +#endif +#define _VIED_SUBSYSTEM_ACCESS_INLINE static inline +#include "vied_subsystem_access_impl.h" +#else +#define _VIED_SUBSYSTEM_ACCESS_INLINE +#endif + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_8(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint8_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_16(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint16_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_32(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint32_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store(vied_subsystem_t dev, + vied_subsystem_address_t addr, + const void *data, unsigned int size); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint8_t vied_subsystem_load_8(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint16_t vied_subsystem_load_16(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint32_t vied_subsystem_load_32(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_load(vied_subsystem_t dev, + vied_subsystem_address_t addr, + void *data, unsigned int size); + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_subsystem_access_initialization.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_subsystem_access_initialization.h new file mode 100644 index 0000000000000..344f31c4df104 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_subsystem_access_initialization.h @@ -0,0 +1,44 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H + +#include "vied_subsystem_access_types.h" + +/** @brief Initialises the access of a subsystem. + * @param[in] system The subsystem for which the access has to be initialised. + * + * vied_subsystem_access_initialize initilalises the access a subsystem. + * It sets the base address of the subsystem. This base address is extracted from the hsd file. + * + */ +void +vied_subsystem_access_initialize(vied_subsystem_t system); + + +/** @brief Initialises the access of multiple subsystems. + * @param[in] nr _subsystems The number of subsystems for which the access has to be initialised. + * @param[in] dev_base_addresses A pointer to an array of base addresses of subsystems. + * The size of this array must be "nr_subsystems". + * This array must be available during the accesses of the subsystem. + * + * vied_subsystems_access_initialize initilalises the access to multiple subsystems. + * It sets the base addresses of the subsystems that are provided by the array dev_base_addresses. + * + */ +void +vied_subsystems_access_initialize(unsigned int nr_subsystems + , const vied_subsystem_base_address_t *base_addresses); + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_subsystem_access_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_subsystem_access_types.h new file mode 100644 index 0000000000000..75fef6c4ddba2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_subsystem_access_types.h @@ -0,0 +1,34 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H + +/** Types for the VIED subsystem access interface */ +#include + +/** \brief An identifier for a VIED subsystem. + * + * This identifier must be a compile-time constant. It is used in + * access to a VIED subsystem. + */ +typedef unsigned int vied_subsystem_t; + + +/** \brief An address within a VIED subsystem */ +typedef uint32_t vied_subsystem_address_t; + +/** \brief A base address of a VIED subsystem seen from the host */ +typedef unsigned long long vied_subsystem_base_address_t; + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_types.h new file mode 100644 index 0000000000000..0acfdbb00cfa3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600/vied/vied/vied_types.h @@ -0,0 +1,45 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_TYPES_H +#define _HRT_VIED_TYPES_H + +/** Types shared by VIED interfaces */ + +#include + +/** \brief An address within a VIED subsystem + * + * This will eventually replace teh vied_memory_address_t and vied_subsystem_address_t + */ +typedef uint32_t vied_address_t; + +/** \brief Memory address type + * + * A memory address is an offset within a memory. + */ +typedef uint32_t vied_memory_address_t; + +/** \brief Master port id */ +typedef int vied_master_port_id_t; + +/** + * \brief Require the existence of a certain type + * + * This macro can be used in interface header files to ensure that + * an implementation define type with a specified name exists. + */ +#define _VIED_REQUIRE_TYPE(T) enum { _VIED_SIZEOF_##T = sizeof(T) } + + +#endif /* _HRT_VIED_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/Makefile b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/Makefile new file mode 100644 index 0000000000000..94630f4df5df1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/Makefile @@ -0,0 +1,49 @@ +# +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# + +ifneq ($(EXTERNAL_BUILD), 1) +srcpath := $(srctree) +endif + +include $(srcpath)/$(src)/../Makefile.ipu4psys_src +include $(srcpath)/$(src)/../Makefile.ipu4psys_inc + +SSID = 0 +MMID = 0 + +IPU_PSYSLIB_ROOT_REL = lib +IPU_PSYSLIB_ROOT = $(srcpath)/$(src)/$(IPU_PSYSLIB_ROOT_REL) + +ccflags-y += -I$(srcpath)/$(src)/../../../ +ccflags-y += -I$(srcpath)/$(src)/../../ +ccflags-y += -DHAS_DUAL_CMD_CTX_SUPPORT=0 -DHAS_LATE_BINDING_SUPPORT=0 -DIPU_PSYS_LEGACY + +IPU_PSYSLIB_SRC += libcsspsys2600.o + +#CFLAGS = -W -Wall -Wstrict-prototypes -Wmissing-prototypes -O2 -fomit-frame-pointer -Wno-unused-variable +HOST_DEFINES += -DSSID=$(SSID) +HOST_DEFINES += -DMMID=$(MMID) +HOST_DEFINES += -DHRT_ON_VIED_SUBSYSTEM_ACCESS=$(SSID) +HOST_DEFINES += -DCFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL +HOST_DEFINES += -DHRT_USE_VIR_ADDRS +HOST_DEFINES += -DHRT_HW +HOST_DEFINES += -DVIED_NCI_TUNIT_PSYS +HOST_DEFINES += -DFIRMWARE_RELEASE_VERSION +HOST_DEFINES += -DPSYS_SERVER_ON_SPC +HOST_DEFINES += -DAPI_SPLIT_START_STATE_UPDATE + +intel-ipu4-psys-csslib-objs := ../../../ipu-wrapper.o \ + $(IPU_PSYSLIB_SRC) + +obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu4-psys-csslib.o +ccflags-y += $(IPU_PSYSLIB_INC) $(HOST_DEFINES) -fno-common diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/DSS_V2_program_group/ia_css_fw_pkg_release.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/DSS_V2_program_group/ia_css_fw_pkg_release.h new file mode 100644 index 0000000000000..408726c817146 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/DSS_V2_program_group/ia_css_fw_pkg_release.h @@ -0,0 +1,14 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#define IA_CSS_FW_PKG_RELEASE 0x20181222 diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/buffer.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/buffer.mk new file mode 100644 index 0000000000000..c00a1133b440f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/buffer.mk @@ -0,0 +1,43 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is BUFFER + +ifdef _H_BUFFER_MK +$(error ERROR: buffer.mk included multiple times, please check makefile) +else +_H_BUFFER_MK=1 +endif + +BUFFER_DIR=$${MODULES_DIR}/buffer + +BUFFER_INTERFACE=$(BUFFER_DIR)/interface +BUFFER_SOURCES_CPU=$(BUFFER_DIR)/src/cpu +BUFFER_SOURCES_CSS=$(BUFFER_DIR)/src/css + +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_output_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_input_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_shared_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/buffer_access.c +BUFFER_HOST_CPPFLAGS += -I$(BUFFER_INTERFACE) +BUFFER_HOST_CPPFLAGS += -I$${MODULES_DIR}/support + +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_input_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_output_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_shared_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/buffer_access.c + +BUFFER_FW_CPPFLAGS += -I$(BUFFER_INTERFACE) +BUFFER_FW_CPPFLAGS += -I$${MODULES_DIR}/support diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/buffer_access.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/buffer_access.h new file mode 100644 index 0000000000000..e5fe647742c9f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/buffer_access.h @@ -0,0 +1,36 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __BUFFER_ACCESS_H +#define __BUFFER_ACCESS_H + +#include "buffer_type.h" +/* #def to keep consistent the buffer load interfaces for host and css */ +#define IDM 0 + +void +buffer_load( + buffer_address address, + void *data, + unsigned int size, + unsigned int mm_id); + +void +buffer_store( + buffer_address address, + const void *data, + unsigned int size, + unsigned int mm_id); + +#endif /* __BUFFER_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/buffer_type.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/buffer_type.h new file mode 100644 index 0000000000000..de51f23941582 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/buffer_type.h @@ -0,0 +1,29 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __BUFFER_TYPE_H +#define __BUFFER_TYPE_H + +/* portable access to buffers in DDR */ + +#ifdef __VIED_CELL +typedef unsigned int buffer_address; +#else +/* workaround needed because shared_memory_access.h uses size_t */ +#include "type_support.h" +#include "vied/shared_memory_access.h" +typedef host_virtual_address_t buffer_address; +#endif + +#endif /* __BUFFER_TYPE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_buffer_address.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_buffer_address.h new file mode 100644 index 0000000000000..137bfb1fda166 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_buffer_address.h @@ -0,0 +1,24 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BUFFER_ADDRESS_H +#define __IA_CSS_BUFFER_ADDRESS_H + +#include "type_support.h" + +typedef uint32_t ia_css_buffer_address; /* CSS virtual address */ + +#define ia_css_buffer_address_null ((ia_css_buffer_address)0) + +#endif /* __IA_CSS_BUFFER_ADDRESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer.h new file mode 100644 index 0000000000000..4e92e35b61843 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_INPUT_BUFFER_H +#define __IA_CSS_INPUT_BUFFER_H + + +/* Input Buffers */ + +/* A CSS input buffer is a buffer in DDR that can be written by the CPU, + * and that can be read by CSS hardware, after the buffer has been handed over. + * Examples: command buffer, input frame buffer, parameter buffer + * An input buffer must be mapped into the CPU address space before it can be + * written by the CPU. + * After mapping, writing, and unmapping, the buffer can be handed over to the + * firmware. An input buffer is handed over to the CSS by mapping it to the + * CSS address space (by the CPU), and by passing the resulting CSS (virtial) + * address of the input buffer to the DA CSS hardware. + * The firmware can read from an input buffer as soon as it has been received + * CSS virtual address. + * The firmware should not write into an input buffer. + * The firmware hands over the input buffer (back to the CPU) by sending the + * buffer handle via a response. The host should unmap the buffer, + * before reusing it. + * The firmware should not read from the input buffer after returning the + * buffer handle to the CPU. + * + * A buffer may be pre-mapped to the CPU and/or to the CSS upon allocation, + * depending on the allocator's preference. In case of pre-mapped buffers, + * the map and unmap functions will only manage read and write access. + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_input_buffer; /* input buffer handle */ +typedef void *ia_css_input_buffer_cpu_address; /* CPU virtual address */ +/* CSS virtual address */ +typedef ia_css_buffer_address ia_css_input_buffer_css_address; + +#endif /* __IA_CSS_INPUT_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer_cpu.h new file mode 100644 index 0000000000000..d3d01353ce431 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer_cpu.h @@ -0,0 +1,49 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_INPUT_BUFFER_CPU_H +#define __IA_CSS_INPUT_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_input_buffer.h" + +ia_css_input_buffer +ia_css_input_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_input_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_input_buffer b); + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_map(ia_css_input_buffer b); + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_unmap(ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map(vied_memory_t mid, ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map_no_invalidate(vied_memory_t mid, ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_unmap(ia_css_input_buffer b); + + +#endif /* __IA_CSS_INPUT_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer.h new file mode 100644 index 0000000000000..2c310ea92c6af --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer.h @@ -0,0 +1,30 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_OUTPUT_BUFFER_H +#define __IA_CSS_OUTPUT_BUFFER_H + +/* Output Buffers */ +/* A CSS output buffer a buffer in DDR that can be written by CSS hardware + * and that can be read by the host, after the buffer has been handed over + * Examples: output frame buffer + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_output_buffer; +typedef void *ia_css_output_buffer_cpu_address; +typedef ia_css_buffer_address ia_css_output_buffer_css_address; + +#endif /* __IA_CSS_OUTPUT_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer_cpu.h new file mode 100644 index 0000000000000..0299fc3b7eb66 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer_cpu.h @@ -0,0 +1,48 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_OUTPUT_BUFFER_CPU_H +#define __IA_CSS_OUTPUT_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_output_buffer.h" + +ia_css_output_buffer +ia_css_output_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_output_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_output_buffer b); + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_map(ia_css_output_buffer b); + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_unmap(ia_css_output_buffer b); + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map(vied_memory_t mid, ia_css_output_buffer b); +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map_no_invalidate(vied_memory_t mid, ia_css_output_buffer b); + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_unmap(ia_css_output_buffer b); + + +#endif /* __IA_CSS_OUTPUT_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer.h new file mode 100644 index 0000000000000..558ec679f98a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SHARED_BUFFER_H +#define __IA_CSS_SHARED_BUFFER_H + +/* Shared Buffers */ +/* A CSS shared buffer is a buffer in DDR that can be read and written by the + * CPU and CSS. + * Both the CPU and CSS can have the buffer mapped simultaneously. + * Access rights are not managed by this interface, this could be done by means + * the read and write pointer of a queue, for example. + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_shared_buffer; +typedef void *ia_css_shared_buffer_cpu_address; +typedef ia_css_buffer_address ia_css_shared_buffer_css_address; + +#endif /* __IA_CSS_SHARED_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer_cpu.h new file mode 100644 index 0000000000000..ff62914f99dc3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer_cpu.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SHARED_BUFFER_CPU_H +#define __IA_CSS_SHARED_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_shared_buffer.h" + +ia_css_shared_buffer +ia_css_shared_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_shared_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_shared_buffer b); + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_map(ia_css_shared_buffer b); + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_unmap(ia_css_shared_buffer b); + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_map(ia_css_shared_buffer b); + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_unmap(ia_css_shared_buffer b); + +ia_css_shared_buffer +ia_css_shared_buffer_css_update(vied_memory_t mid, ia_css_shared_buffer b); + +ia_css_shared_buffer +ia_css_shared_buffer_cpu_update(vied_memory_t mid, ia_css_shared_buffer b); + +#endif /* __IA_CSS_SHARED_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/buffer_access.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/buffer_access.c new file mode 100644 index 0000000000000..f0c617fe501a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/buffer_access.c @@ -0,0 +1,39 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/* implementation of buffer access from the CPU */ +/* using shared_memory interface */ + +#include "buffer_access.h" +#include "vied/shared_memory_access.h" + +void +buffer_load( + buffer_address address, + void *data, + unsigned int bytes, + unsigned int mm_id) +{ + shared_memory_load(mm_id, address, data, bytes); +} + +void +buffer_store( + buffer_address address, + const void *data, + unsigned int bytes, + unsigned int mm_id) +{ + shared_memory_store(mm_id, address, data, bytes); +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.c new file mode 100644 index 0000000000000..146d4109de440 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.c @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/* provided interface */ +#include "ia_css_buffer.h" + +/* used interfaces */ +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + +ia_css_buffer_t +ia_css_buffer_alloc(vied_subsystem_t sid, vied_memory_t mid, unsigned int size) +{ + ia_css_buffer_t b; + + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + + b->css_address = shared_memory_map(sid, mid, b->mem); + b->size = size; + return b; +} + + +void +ia_css_buffer_free(vied_subsystem_t sid, vied_memory_t mid, ia_css_buffer_t b) +{ + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.h new file mode 100644 index 0000000000000..a8959fdcd04ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.h @@ -0,0 +1,58 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BUFFER_H +#define __IA_CSS_BUFFER_H + +/* workaround: needed because uses size_t */ +#include "type_support.h" +#include "vied/shared_memory_map.h" + +typedef enum { + buffer_unmapped, /* buffer is not accessible by cpu, nor css */ + buffer_write, /* output buffer: css has write access */ + /* input buffer: cpu has write access */ + buffer_read, /* input buffer: css has read access */ + /* output buffer: cpu has read access */ + buffer_cpu, /* shared buffer: cpu has read/write access */ + buffer_css /* shared buffer: css has read/write access */ +} buffer_state; + +struct ia_css_buffer_s { + /* number of bytes allocated */ + unsigned int size; + /* allocated virtual memory object */ + host_virtual_address_t mem; + /* virtual address to be used on css/firmware */ + vied_virtual_address_t css_address; + /* virtual address to be used on cpu/host */ + void *cpu_address; + buffer_state state; +}; + +typedef struct ia_css_buffer_s *ia_css_buffer_t; + +ia_css_buffer_t +ia_css_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_buffer_t b); + +#endif /* __IA_CSS_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_input_buffer.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_input_buffer.c new file mode 100644 index 0000000000000..2a128795d03e2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_input_buffer.c @@ -0,0 +1,184 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_input_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_input_buffer +ia_css_input_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_input_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_input_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_input_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_map(ia_css_input_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map input buffer to CPU address space, acquire write access */ + b->state = buffer_write; + + /* return pre-mapped buffer */ + return b->cpu_address; +} + + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_unmap(ia_css_input_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_write) + return NULL; + + /* unmap input buffer from CPU address space, release write access */ + b->state = buffer_unmapped; + + /* return pre-mapped buffer */ + return b->cpu_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map(vied_memory_t mid, ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map input buffer to CSS address space, acquire read access */ + b->state = buffer_read; + + /* now flush the cache */ + ia_css_cpu_mem_cache_flush(b->cpu_address, b->size); +#ifndef HRT_HW + /* only copy in case of simulation, otherwise it should just work */ + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return (ia_css_input_buffer_css_address)b->css_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map_no_invalidate(vied_memory_t mid, ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map input buffer to CSS address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only copy in case of simulation, otherwise it should just work */ + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return (ia_css_input_buffer_css_address)b->css_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_unmap(ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_read) + return 0; + + /* unmap input buffer from CSS address space, release read access */ + b->state = buffer_unmapped; + + /* input buffer only, no need to invalidate cache */ + + return (ia_css_input_buffer_css_address)b->css_address; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_output_buffer.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_output_buffer.c new file mode 100644 index 0000000000000..30bc8d52a5a9e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_output_buffer.c @@ -0,0 +1,181 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_output_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_output_buffer +ia_css_output_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_output_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_output_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_output_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_map(ia_css_output_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map output buffer to CSS address space, acquire write access */ + b->state = buffer_write; + + return (ia_css_output_buffer_css_address)b->css_address; +} + + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_unmap(ia_css_output_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_write) + return 0; + + /* unmap output buffer from CSS address space, release write access */ + b->state = buffer_unmapped; + + return (ia_css_output_buffer_css_address)b->css_address; +} + + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map(vied_memory_t mid, ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map output buffer to CPU address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only in simulation */ + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + /* now invalidate the cache */ + ia_css_cpu_mem_cache_invalidate(b->cpu_address, b->size); + + return b->cpu_address; +} + + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map_no_invalidate(vied_memory_t mid, ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map output buffer to CPU address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only in simulation */ + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return b->cpu_address; +} + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_unmap(ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_read) + return NULL; + + /* unmap output buffer from CPU address space, release read access */ + b->state = buffer_unmapped; + + /* output only, no need to flush cache */ + + return b->cpu_address; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_shared_buffer.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_shared_buffer.c new file mode 100644 index 0000000000000..92b7110644fe3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/buffer/src/cpu/ia_css_shared_buffer.c @@ -0,0 +1,187 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_shared_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_shared_buffer +ia_css_shared_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_shared_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_shared_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_shared_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_map(ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map shared buffer to CPU address space */ + b->state = buffer_cpu; + + return b->cpu_address; +} + + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_unmap(ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_cpu) + return NULL; + + /* unmap shared buffer from CPU address space */ + b->state = buffer_unmapped; + + return b->cpu_address; +} + + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_map(ia_css_shared_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map shared buffer to CSS address space */ + b->state = buffer_css; + + return (ia_css_shared_buffer_css_address)b->css_address; +} + + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_unmap(ia_css_shared_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_css) + return 0; + + /* unmap shared buffer from CSS address space */ + b->state = buffer_unmapped; + + return (ia_css_shared_buffer_css_address)b->css_address; +} + + +ia_css_shared_buffer +ia_css_shared_buffer_css_update(vied_memory_t mid, ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + + /* flush the buffer to CSS after it was modified by the CPU */ + /* flush cache to ddr */ + ia_css_cpu_mem_cache_flush(b->cpu_address, b->size); +#ifndef HRT_HW + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return b; +} + + +ia_css_shared_buffer +ia_css_shared_buffer_cpu_update(vied_memory_t mid, ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + + /* flush the buffer to the CPU after it has been modified by CSS */ +#ifndef HRT_HW + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + /* flush cache to ddr */ + ia_css_cpu_mem_cache_invalidate(b->cpu_address, b->size); + + return b; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cell/cell.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cell/cell.mk new file mode 100644 index 0000000000000..fa5e650226017 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cell/cell.mk @@ -0,0 +1,43 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +ifndef _CELL_MK_ +_CELL_MK_ = 1 + + +CELL_DIR=$${MODULES_DIR}/cell +CELL_INTERFACE=$(CELL_DIR)/interface +CELL_SOURCES=$(CELL_DIR)/src + +CELL_HOST_FILES = +CELL_FW_FILES = + +CELL_HOST_CPPFLAGS = \ + -I$(CELL_INTERFACE) \ + -I$(CELL_SOURCES) + +CELL_FW_CPPFLAGS = \ + -I$(CELL_INTERFACE) \ + -I$(CELL_SOURCES) + +ifdef 0 +# Disabled until it is decided to go this way or not +include $(MODULES_DIR)/device_access/device_access.mk +CELL_HOST_FILES += $(DEVICE_ACCESS_HOST_FILES) +CELL_FW_FILES += $(DEVICE_ACCESS_FW_FILES) +CELL_HOST_CPPFLAGS += $(DEVICE_ACCESS_HOST_CPPFLAGS) +CELL_FW_CPPFLAGS += $(DEVICE_ACCESS_FW_CPPFLAGS) +endif + +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cell/interface/ia_css_cell.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cell/interface/ia_css_cell.h new file mode 100644 index 0000000000000..3fac3c791b6e6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cell/interface/ia_css_cell.h @@ -0,0 +1,112 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_H +#define __IA_CSS_CELL_H + +#include "storage_class.h" +#include "type_support.h" + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stat_ctrl(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_stat_ctrl(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_pc(unsigned int ssid, unsigned int cell_id, + unsigned int pc); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +#if 0 /* To be implemented after completing cell device properties */ +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_info_bits(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_debug_pc(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stall_bits(unsigned int ssid, unsigned int cell_id); +#endif + +/* configure master ports */ + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_base_address(unsigned int ssid, + unsigned int cell_id, + unsigned int master, unsigned int segment, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_bits(unsigned int ssid, unsigned int cell_id, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_bits(unsigned int ssid, + unsigned int cell_id, + unsigned int master, unsigned int segment, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_override_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_override_bits(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value); + +/* Access memories */ + +STORAGE_CLASS_INLINE void +ia_css_cell_mem_store_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr, unsigned int value); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_mem_load_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr); + +/***********************************************************************/ + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_is_ready(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_bit(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_run_bit(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_start(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_start_prefetch(unsigned int ssid, unsigned int cell_id, + bool prefetch); + +STORAGE_CLASS_INLINE void +ia_css_cell_wait(unsigned int ssid, unsigned int cell_id); + +/* include inline implementation */ +#include "ia_css_cell_impl.h" + +#endif /* __IA_CSS_CELL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cell/src/ia_css_cell_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cell/src/ia_css_cell_impl.h new file mode 100644 index 0000000000000..60b2e234da1a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cell/src/ia_css_cell_impl.h @@ -0,0 +1,272 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_IMPL_H +#define __IA_CSS_CELL_IMPL_H + +#include "ia_css_cell.h" + +#include "ia_css_cmem.h" +#include "ipu_device_cell_properties.h" +#include "storage_class.h" +#include "assert_support.h" +#include "platform_support.h" +#include "misc_support.h" + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_regs_addr(unsigned int cell_id) +{ + /* mem_id 0 is for registers */ + return ipu_device_cell_memory_address(cell_id, 0); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_dmem_addr(unsigned int cell_id) +{ + /* mem_id 1 is for DMEM */ + return ipu_device_cell_memory_address(cell_id, 1); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_mem_store_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr, unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ipu_device_cell_memory_address( + cell_id, mem_id) + addr, value); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_mem_load_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr) +{ + return ia_css_cmem_load_32( + ssid, ipu_device_cell_memory_address(cell_id, mem_id) + addr); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stat_ctrl(unsigned int ssid, unsigned int cell_id) +{ + return ia_css_cmem_load_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_stat_ctrl(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS, value); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_is_ready(unsigned int ssid, unsigned int cell_id) +{ + unsigned int reg; + + reg = ia_css_cell_get_stat_ctrl(ssid, cell_id); + /* READY must be 1, START must be 0 */ + return (reg & (1 << IPU_DEVICE_CELL_STAT_CTRL_READY_BIT)) && + ((~reg) & (1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT)); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_pc(unsigned int ssid, unsigned int cell_id, + unsigned int pc) +{ + /* set start PC */ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_START_PC_REG_ADDRESS, pc); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_bit(unsigned int ssid, unsigned int cell_id) +{ + unsigned int reg; + + reg = 1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT; + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_run_bit(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + unsigned int reg; + + reg = value << IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT; + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_start(unsigned int ssid, unsigned int cell_id) +{ + ia_css_cell_start_prefetch(ssid, cell_id, 0); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_start_prefetch(unsigned int ssid, unsigned int cell_id, + bool prefetch) +{ + unsigned int reg = 0; + + /* Set run bit and start bit */ + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT); + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT); + /* Invalidate the icache */ + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_INVALIDATE_ICACHE_BIT); + /* Optionally enable prefetching */ + reg |= ((prefetch == 1) ? + (1 << IPU_DEVICE_CELL_STAT_CTRL_ICACHE_ENABLE_PREFETCH_BIT) : + 0); + + /* store into register */ + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_wait(unsigned int ssid, unsigned int cell_id) +{ + do { + ia_css_sleep(); + } while (!ia_css_cell_is_ready(ssid, cell_id)); +}; + +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_ICACHE_BASE_REG_ADDRESS, value); +} + +/* master port configuration */ + + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_override_bits(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_override_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_base_address(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) + +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_base_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_override_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_override_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_base_address(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments, segment_size; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_base_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + segment_size = ipu_device_cell_master_segment_size(cell, master); + + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + value += segment_size; + } +} + +#endif /* __IA_CSS_CELL_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg.h new file mode 100644 index 0000000000000..e8b0a48b27e33 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg.h @@ -0,0 +1,60 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CLIENT_PKG_H +#define __IA_CSS_CLIENT_PKG_H + +#include "type_support.h" +#include "ia_css_client_pkg_storage_class.h" +/* for ia_css_client_pkg_header_s (ptr only), ia_css_client_pkg_t */ +#include "ia_css_client_pkg_types.h" + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +int ia_css_client_pkg_get_pg_manifest_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size); + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +int ia_css_client_pkg_get_prog_list_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size); + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +int ia_css_client_pkg_get_prog_desc_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size); + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +int ia_css_client_pkg_get_prog_bin_entry_offset_size( + const ia_css_client_pkg_t *client_pkg, + uint32_t program_id, + uint32_t *offset, + uint32_t *size); + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +int ia_css_client_pkg_get_indexed_prog_desc_entry_offset_size( + const ia_css_client_pkg_t *client_pkg, + uint32_t program_id, + uint32_t program_index, + uint32_t *offset, + uint32_t *size); + +#ifdef __INLINE_CLIENT_PKG__ +#include "ia_css_client_pkg_impl.h" +#endif + +#endif /* __IA_CSS_CLIENT_PKG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_storage_class.h new file mode 100644 index 0000000000000..98af98d5d824d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_storage_class.h @@ -0,0 +1,28 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +#define __IA_CSS_CLIENT_PKG_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __INLINE_CLIENT_PKG__ +#define IA_CSS_CLIENT_PKG_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +#else +#define IA_CSS_CLIENT_PKG_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_CLIENT_PKG_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_CLIENT_PKG_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_types.h new file mode 100644 index 0000000000000..ff5bf01358f1a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_types.h @@ -0,0 +1,44 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CLIENT_PKG_TYPES_H +#define __IA_CSS_CLIENT_PKG_TYPES_H + +#include "type_support.h" + +typedef void ia_css_client_pkg_t; + +struct ia_css_client_pkg_header_s { + uint32_t prog_list_offset; + uint32_t prog_list_size; + uint32_t prog_desc_offset; + uint32_t prog_desc_size; + uint32_t pg_manifest_offset; + uint32_t pg_manifest_size; + uint32_t prog_bin_offset; + uint32_t prog_bin_size; +}; + +struct ia_css_client_pkg_prog_s { + uint32_t prog_id; + uint32_t prog_offset; + uint32_t prog_size; +}; + +struct ia_css_client_pkg_prog_list_s { + uint32_t prog_desc_count; + uint32_t prog_bin_count; +}; + +#endif /* __IA_CSS_CLIENT_PKG_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg.c new file mode 100644 index 0000000000000..0b2fd86d09f36 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg.c @@ -0,0 +1,20 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifdef __INLINE_CLIENT_PKG__ +#include "storage_class.h" +STORAGE_CLASS_INLINE int __ia_css_client_pkg_avoid_warning_on_empty_file(void) { return 0; } +#else /* __INLINE_CLIENT_PKG__ */ +#include "ia_css_client_pkg_impl.h" +#endif /* __INLINE_CLIENT_PKG__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg_impl.h new file mode 100644 index 0000000000000..11ce55d8c669e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg_impl.h @@ -0,0 +1,161 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CLIENT_PKG_IMPL_H +#define __IA_CSS_CLIENT_PKG_IMPL_H + +#include "ia_css_client_pkg.h" +#include "ia_css_client_pkg_types.h" +#include "error_support.h" + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +int ia_css_client_pkg_get_pg_manifest_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size) +{ + int ret_val = -1; + + verifjmpexit(client_pkg_header != NULL); + verifjmpexit(offset != NULL); + verifjmpexit(size != NULL); + + *(offset) = client_pkg_header->pg_manifest_offset; + *(size) = client_pkg_header->pg_manifest_size; + ret_val = 0; +EXIT: + return ret_val; +} + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +int ia_css_client_pkg_get_prog_list_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size) +{ + int ret_val = -1; + + verifjmpexit(client_pkg_header != NULL); + verifjmpexit(offset != NULL); + verifjmpexit(size != NULL); + + *(offset) = client_pkg_header->prog_list_offset; + *(size) = client_pkg_header->prog_list_size; + ret_val = 0; +EXIT: + return ret_val; +} + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +int ia_css_client_pkg_get_prog_desc_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size) +{ + int ret_val = -1; + + verifjmpexit(client_pkg_header != NULL); + verifjmpexit(offset != NULL); + verifjmpexit(size != NULL); + + *(offset) = client_pkg_header->prog_desc_offset; + *(size) = client_pkg_header->prog_desc_size; + ret_val = 0; +EXIT: + return ret_val; +} + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +int ia_css_client_pkg_get_prog_bin_entry_offset_size( + const ia_css_client_pkg_t *client_pkg, + uint32_t program_id, + uint32_t *offset, + uint32_t *size) +{ + uint8_t i; + int ret_val = -1; + struct ia_css_client_pkg_header_s *client_pkg_header = NULL; + const struct ia_css_client_pkg_prog_list_s *pkg_prog_list = NULL; + const struct ia_css_client_pkg_prog_s *pkg_prog_bin_entry = NULL; + + verifjmpexit(client_pkg != NULL); + verifjmpexit(offset != NULL); + verifjmpexit(size != NULL); + + client_pkg_header = + (struct ia_css_client_pkg_header_s *)((uint8_t *)client_pkg); + pkg_prog_list = + (struct ia_css_client_pkg_prog_list_s *)((uint8_t *)client_pkg + + client_pkg_header->prog_list_offset); + pkg_prog_bin_entry = + (struct ia_css_client_pkg_prog_s *)((uint8_t *)pkg_prog_list + + sizeof(struct ia_css_client_pkg_prog_list_s)); + pkg_prog_bin_entry += pkg_prog_list->prog_desc_count; + + for (i = 0; i < pkg_prog_list->prog_bin_count; i++) { + if (program_id == pkg_prog_bin_entry->prog_id) { + *(offset) = pkg_prog_bin_entry->prog_offset; + *(size) = pkg_prog_bin_entry->prog_size; + ret_val = 0; + break; + } else if (pkg_prog_bin_entry->prog_size == 0) { + /* We can have a variable number of program descriptors. + * The first non-valid one will have size set to 0 + */ + break; + } + pkg_prog_bin_entry++; + } +EXIT: + return ret_val; +} + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +int ia_css_client_pkg_get_indexed_prog_desc_entry_offset_size( + const ia_css_client_pkg_t *client_pkg, + uint32_t program_id, + uint32_t program_index, + uint32_t *offset, + uint32_t *size) +{ + int ret_val = -1; + struct ia_css_client_pkg_header_s *client_pkg_header = NULL; + const struct ia_css_client_pkg_prog_list_s *pkg_prog_list = NULL; + const struct ia_css_client_pkg_prog_s *pkg_prog_desc_entry = NULL; + + verifjmpexit(client_pkg != NULL); + verifjmpexit(offset != NULL); + verifjmpexit(size != NULL); + + client_pkg_header = + (struct ia_css_client_pkg_header_s *)((uint8_t *)client_pkg); + pkg_prog_list = + (struct ia_css_client_pkg_prog_list_s *)((uint8_t *)client_pkg + + client_pkg_header->prog_list_offset); + pkg_prog_desc_entry = + (struct ia_css_client_pkg_prog_s *)((uint8_t *)pkg_prog_list + + sizeof(struct ia_css_client_pkg_prog_list_s)); + + verifjmpexit(program_index < pkg_prog_list->prog_desc_count); + verifjmpexit(program_id == pkg_prog_desc_entry[program_index].prog_id); + verifjmpexit(pkg_prog_desc_entry[program_index].prog_size > 0); + *(offset) = pkg_prog_desc_entry[program_index].prog_offset; + *(size) = pkg_prog_desc_entry[program_index].prog_size; + ret_val = 0; + +EXIT: + return ret_val; +} + +#endif /* __IA_CSS_CLIENT_PKG_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/config/psys/subsystem_bxtB0.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/config/psys/subsystem_bxtB0.mk new file mode 100644 index 0000000000000..2f60853f00894 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/config/psys/subsystem_bxtB0.mk @@ -0,0 +1,109 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +############################################################################ +# This file is used to specify versions and properties of PSYS firmware +# components. Please note that these are subsystem specific. System specific +# properties should go to system_$IPU_SYSVER.mk. Also the device versions +# should be defined under "devices" or should be taken from the SDK. +############################################################################ + +# Activate loading params and storing stats DDR<->REGs with DMA +PSYS_USE_ISA_DMA = 1 + +# Used in ISA module +PSYS_ISL_DPC_DPC_V2 = 0 + +# Assume OFS will be running concurrently with IPF, and prioritize according to rates of services on devproxy +CONCURRENT_OFS_IPF_PRIORITY_OPTIMIZATION_ENABLED = 1 + +# Use the DMA for terminal loading in Psys server +PSYS_SERVER_ENABLE_TERMINAL_LOAD_DMA = 1 + +HAS_GMEM = 1 +# use DMA NCI for OFS Service to reduce load in tproxy +DMA_NCI_IN_OFS_SERVICE = 1 + +# See HSD 1805169230 +HAS_FWDMA_ALIGNMENT_ISSUE_SIGHTING = 1 + +HAS_SPC = 1 +HAS_SPP0 = 1 +HAS_SPP1 = 1 +HAS_ISP0 = 1 +HAS_ISP1 = 1 +HAS_ISP2 = 1 +HAS_ISP3 = 1 + +# Specification for Psys server's fixed globals' locations +REGMEM_OFFSET = 0 # Starting from 0 +REGMEM_SIZE = 18 +REGMEM_WORD_BYTES = 4 +REGMEM_SIZE_BYTES = 72 +GPC_ISP_PERF_DATA_OFFSET = 72 # Taken from REGMEM_OFFSET + REGMEM_SIZE_BYTES +GPC_ISP_PERF_DATA_SIZE_BYTES = 80 +FW_LOAD_NO_OF_REQUEST_OFFSET = 152 # Taken from GPC_ISP_PERF_DATA_OFFSET + GPC_ISP_PERF_DATA_SIZE_BYTES +FW_LOAD_NO_OF_REQUEST_SIZE_BYTES = 4 +DISPATCHER_SCRATCH_SPACE_OFFSET = 156 # Taken from FW_LOAD_NO_OF_REQUEST_OFFSET + FW_LOAD_NO_OF_REQUEST_SIZE_BYTES + +# TODO use version naming scheme "v#" to decouple +# IPU_SYSVER from version. +PSYS_SERVER_MANIFEST_VERSION = bxtB0 +PSYS_RESOURCE_MODEL_VERSION = bxtB0 +PSYS_ACCESS_BLOCKER_VERSION = v1 + +# Disable support for PPG protocol to save codesize +PSYS_HAS_PPG_SUPPORT = 0 +# Disable support for late binding +PSYS_HAS_LATE_BINDING_SUPPORT = 0 + +# Specify PSYS server context spaces for caching context from DDR +PSYS_SERVER_NOF_CACHES = 4 +PSYS_SERVER_MAX_NUM_PROC_GRP = $(PSYS_SERVER_NOF_CACHES) +PSYS_SERVER_MAX_NUM_EXEC_PROC_GRP = 8 # Max PG's running, 4 running on Cores, 4 being updated on the host upon executing. +PSYS_SERVER_MAX_PROC_GRP_SIZE = 4052 +PSYS_SERVER_MAX_MANIFEST_SIZE = 3732 +PSYS_SERVER_MAX_CLIENT_PKG_SIZE = 2420 +PSYS_SERVER_MAX_BUFFER_SET_SIZE = 0 +PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_SECTIONS = 88 +PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_STORE_SECTIONS = 1 +# The caching scheme for this subsystem suits the method of queueing ahead separate PGs for frames in an interleaved +# fashion. As such there should be as many caches to support to heaviest two concurrent PGs, times two. This results +# in the following distribution of caches: two large ones for the maximum sized PG, two smaller ones for the +# second-largest sized PG. +PSYS_SERVER_CACHE_0_PROC_GRP_SIZE = $(PSYS_SERVER_MAX_PROC_GRP_SIZE) +PSYS_SERVER_CACHE_0_MANIFEST_SIZE = $(PSYS_SERVER_MAX_MANIFEST_SIZE) +PSYS_SERVER_CACHE_0_CLIENT_PKG_SIZE = $(PSYS_SERVER_MAX_CLIENT_PKG_SIZE) +PSYS_SERVER_CACHE_0_BUFFER_SET_SIZE = $(PSYS_SERVER_MAX_BUFFER_SET_SIZE) +PSYS_SERVER_CACHE_0_NUMBER_OF_TERMINAL_SECTIONS = $(PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_SECTIONS) +PSYS_SERVER_CACHE_0_NUMBER_OF_TERMINAL_STORE_SECTIONS = $(PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_STORE_SECTIONS) +PSYS_SERVER_CACHE_1_PROC_GRP_SIZE = $(PSYS_SERVER_CACHE_0_PROC_GRP_SIZE) +PSYS_SERVER_CACHE_1_MANIFEST_SIZE = $(PSYS_SERVER_CACHE_0_MANIFEST_SIZE) +PSYS_SERVER_CACHE_1_CLIENT_PKG_SIZE = $(PSYS_SERVER_CACHE_0_CLIENT_PKG_SIZE) +PSYS_SERVER_CACHE_1_BUFFER_SET_SIZE = $(PSYS_SERVER_CACHE_0_BUFFER_SET_SIZE) +PSYS_SERVER_CACHE_1_NUMBER_OF_TERMINAL_SECTIONS = $(PSYS_SERVER_CACHE_0_NUMBER_OF_TERMINAL_SECTIONS) +PSYS_SERVER_CACHE_1_NUMBER_OF_TERMINAL_STORE_SECTIONS = $(PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_STORE_SECTIONS) +PSYS_SERVER_CACHE_2_PROC_GRP_SIZE = 1800 +PSYS_SERVER_CACHE_2_MANIFEST_SIZE = 2344 +PSYS_SERVER_CACHE_2_CLIENT_PKG_SIZE = 1240 +PSYS_SERVER_CACHE_2_BUFFER_SET_SIZE = 0 +PSYS_SERVER_CACHE_2_NUMBER_OF_TERMINAL_SECTIONS = 45 +PSYS_SERVER_CACHE_2_NUMBER_OF_TERMINAL_STORE_SECTIONS = $(PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_STORE_SECTIONS) + +PSYS_SERVER_CACHE_3_PROC_GRP_SIZE = $(PSYS_SERVER_CACHE_2_PROC_GRP_SIZE) +PSYS_SERVER_CACHE_3_MANIFEST_SIZE = $(PSYS_SERVER_CACHE_2_MANIFEST_SIZE) +PSYS_SERVER_CACHE_3_CLIENT_PKG_SIZE = $(PSYS_SERVER_CACHE_2_CLIENT_PKG_SIZE) +PSYS_SERVER_CACHE_3_BUFFER_SET_SIZE = $(PSYS_SERVER_CACHE_2_BUFFER_SET_SIZE) +PSYS_SERVER_CACHE_3_NUMBER_OF_TERMINAL_SECTIONS = $(PSYS_SERVER_CACHE_2_NUMBER_OF_TERMINAL_SECTIONS) +PSYS_SERVER_CACHE_3_NUMBER_OF_TERMINAL_STORE_SECTIONS = $(PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_STORE_SECTIONS) diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/config/system_bxtB0.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/config/system_bxtB0.mk new file mode 100644 index 0000000000000..24d079b405167 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/config/system_bxtB0.mk @@ -0,0 +1,88 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +LOGICAL_FW_INPUT_SYSTEM = input_system_system +LOGICAL_FW_PROCESSING_SYSTEM = processing_system_system +LOGICAL_FW_IPU_SYSTEM = css_broxton_system +LOGICAL_FW_ISP_SYSTEM = isp2601_default_system +SP_CONTROL_CELL = sp2601_control +SP_PROXY_CELL = sp2601_proxy +SP_FP_CELL = sp2601_fp +ISP_CELL = isp2601 +# The non-capital define isp2601 is used in the sdk, in order to distinguish +# between different isp versions the ISP_CELL_IDENTIFIER define is added. +ISP_CELL_IDENTIFIER = ISP2601 +HAS_IPFD = 1 +HAS_S2M_IN_ISYS_ISL_NONSOC_PATH = 0 +HAS_S2V_IN_ISYS_ISL_NONSOC_PATH = 1 +# ISL-IS non-SoC path has ISA without PAF and DPC-Pext support for IPU4-B0 +HAS_ISA_IN_ISYS_ISL = 1 +HAS_PAF_IN_ISYS_ISL = 0 +HAS_DPC_PEXT_IN_ISYS_ISL = 0 +HAS_PMA_IF = 0 + +HAS_MIPIBE_IN_PSYS_ISL = 1 + +HAS_VPLESS_SUPPORT = 0 + +DLI_SYSTEM = hive_isp_css_2600_system +RESOURCE_MANAGER_VERSION = v1 +MEM_RESOURCE_VALIDATION_ERROR = 0 +OFS_SCALER_1_4K_TILEY_422_SUPPORT= 1 +PROGDESC_ACC_SYMBOLS_VERSION = v1 +DEVPROXY_INTERFACE_VERSION = v1 +FW_ABI_IPU_TYPES_VERSION = v1 + +HAS_ONLINE_MODE_SUPPORT_IN_ISYS_PSYS = 0 + +MMU_INTERFACE_VERSION = v1 +DEVICE_ACCESS_VERSION = v2 +PSYS_SERVER_VERSION = v2 +PSYS_SERVER_LOADER_VERSION = v1 +PSYS_HW_VERSION = BXT_B0_HW + +# Enable FW_DMA for loading firmware +PSYS_SERVER_ENABLE_FW_LOAD_DMA = 1 + +NCI_SPA_VERSION = v1 +MANIFEST_TOOL_VERSION = v2 +PSYS_CON_MGR_TOOL_VERSION = v1 +# TODO: Should be removed after performance issues OTF are solved +PSYS_PROC_MGR_VERSION = v1 +IPU_RESOURCES_VERSION = v1 + +HAS_ACC_CLUSTER_PAF_PAL = 0 +HAS_ACC_CLUSTER_PEXT_PAL = 0 +HAS_ACC_CLUSTER_GBL_PAL = 1 + +# TODO use version naming scheme "v#" to decouple +# IPU_SYSVER from version. +PARAMBINTOOL_ISA_INIT_VERSION = bxtB0 + +# Select EQC2EQ version +# Version 1: uniform address space, equal EQ addresses regardless of EQC device +# Version 2: multiple addresses per EQ, depending on location of EQC device +EQC2EQ_VERSION = v1 + +# Select DMA instance for fw_load +FW_LOAD_DMA_INSTANCE = NCI_DMA_FW + +HAS_DMA_FW = 1 + +HAS_SIS = 0 +HAS_IDS = 1 + +PSYS_SERVER_ENABLE_TPROXY = 1 +PSYS_SERVER_ENABLE_DEVPROXY = 1 +NCI_OFS_VERSION = v1 diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_component/cpd_component.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_component/cpd_component.mk new file mode 100644 index 0000000000000..8ecc3e42e55d3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_component/cpd_component.mk @@ -0,0 +1,28 @@ +## +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +## + +# MODULE is cpd/cpd_component + +CPD_DIR = $${MODULES_DIR}/cpd +CPD_COMPONENT_DIR = $${MODULES_DIR}/cpd/cpd_component +CPD_COMPONENT_INTERFACE = $(CPD_COMPONENT_DIR)/interface +CPD_COMPONENT_SOURCES = $(CPD_COMPONENT_DIR)/src + +CPD_COMPONENT_FILES = $(CPD_COMPONENT_SOURCES)/ia_css_cpd_component_create.c +CPD_COMPONENT_FILES += $(CPD_COMPONENT_SOURCES)/ia_css_cpd_component.c +CPD_COMPONENT_CPPFLAGS = -I$(CPD_COMPONENT_INTERFACE) +CPD_COMPONENT_CPPFLAGS += -I$(CPD_COMPONENT_SOURCES) +CPD_COMPONENT_CPPFLAGS += -I$(CPD_DIR) diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_component/interface/ia_css_cpd_component_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_component/interface/ia_css_cpd_component_types.h new file mode 100644 index 0000000000000..7ad3070b2fd72 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_component/interface/ia_css_cpd_component_types.h @@ -0,0 +1,90 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_CPD_COMPONENT_TYPES_H +#define __IA_CSS_CPD_COMPONENT_TYPES_H + +/** @file + * This file contains datastructure related to generation of CPD file + */ + +#include "type_support.h" + +#define SIZE_OF_FW_ARCH_VERSION 7 +#define SIZE_OF_SYSTEM_VERSION 11 +#define SIZE_OF_COMPONENT_NAME 12 + +enum ia_css_cpd_component_endianness { + IA_CSSCPD_COMP_ENDIAN_RSVD, + IA_CSS_CPD_COMP_LITTLE_ENDIAN, + IA_CSS_CPD_COMP_BIG_ENDIAN +}; + +/** Module Data (components) Header + * Following data structure has been created using FAS section 5.25 + * Open : Should we add padding at the end of module directory + * (the component must be 512 aligned) + */ +typedef struct { + uint32_t header_size; + /**< Specifies endianness of the binary data */ + unsigned int endianness; + /**< fw_pkg_date is current date stored in 'binary decimal' + * representation e.g. 538248729 (0x20150619) + */ + uint32_t fw_pkg_date; + /**< hive_sdk_date is date of HIVE_SDK stored in + * 'binary decimal' representation + */ + uint32_t hive_sdk_date; + /**< compiler_date is date of ptools stored in + * 'binary decimal' representation + */ + uint32_t compiler_date; + /**< UNSCHED / SCHED / TARGET / CRUN */ + unsigned int target_platform_type; + /**< specifies the system version stored as string + * e.g. BXTB0_IPU4'\0' + */ + uint8_t system_version[SIZE_OF_SYSTEM_VERSION]; + /**< specifies fw architecture version e.g. for BXT CSS3.0'\0' */ + uint8_t fw_arch_version[SIZE_OF_FW_ARCH_VERSION]; + uint8_t rsvd[2]; +} ia_css_header_component_t; + +/** Module Data Directory = Directory Header + Directory Entry (0..n) + * Following two Data Structure has been taken from CSE Storage FAS (CPD desgin) + * Module Data Directory Header + */ +typedef struct { + uint32_t header_marker; + uint32_t number_of_entries; + uint8_t header_version; + uint8_t entry_version; + uint8_t header_length; /**< 0x10 (16) Fixed for this version*/ + uint8_t checksum; + uint32_t partition_name; +} ia_css_directory_header_component_t; + +/** Module Date Directory Entry + */ +typedef struct { + /**< character string describing the component name */ + uint8_t entry_name[SIZE_OF_COMPONENT_NAME]; + uint32_t offset; + uint32_t length; + uint32_t rsvd; /**< Must be 0 */ +} ia_css_directory_entry_component_t; + +#endif /* __IA_CSS_CPD_COMPONENT_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_metadata/cpd_metadata.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_metadata/cpd_metadata.mk new file mode 100644 index 0000000000000..ac78815dfbd8c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_metadata/cpd_metadata.mk @@ -0,0 +1,29 @@ +## +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +## + + +# MODULE is CPD UTL (Metadata File Extension) + +CPD_DIR = $${MODULES_DIR}/cpd/ +CPD_METADATA_DIR = $${MODULES_DIR}/cpd/cpd_metadata +CPD_METADATA_INTERFACE = $(CPD_METADATA_DIR)/interface +CPD_METADATA_SOURCES = $(CPD_METADATA_DIR)/src + +CPD_METADATA_FILES = $(CPD_METADATA_SOURCES)/ia_css_cpd_metadata_create.c +CPD_METADATA_FILES += $(CPD_METADATA_SOURCES)/ia_css_cpd_metadata.c +CPD_METADATA_CPPFLAGS = -I$(CPD_METADATA_INTERFACE) \ + -I$(CPD_METADATA_SOURCES) \ + -I$(CPD_DIR) diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_metadata/interface/ia_css_cpd_metadata_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_metadata/interface/ia_css_cpd_metadata_types.h new file mode 100644 index 0000000000000..a88c6aede08c5 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/cpd/cpd_metadata/interface/ia_css_cpd_metadata_types.h @@ -0,0 +1,111 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_CPD_METADATA_TYPES_H +#define __IA_CSS_CPD_METADATA_TYPES_H + +/** @file + * This file contains data structures related to generation of + * metadata file extension + */ +#include + +/* As per v0.2 manifest document + * Header = Extension Type (4) + Extension Length (4) + + * iUnit Image Type (4) + Reserved (16) + */ +#define IPU_METADATA_HEADER_RSVD_SIZE 16 +#define IPU_METADATA_HEADER_FIELDS_SIZE 12 +#define IPU_METADATA_HEADER_SIZE \ + (IPU_METADATA_HEADER_FIELDS_SIZE + IPU_METADATA_HEADER_RSVD_SIZE) + +/* iUnit metadata extension tpye value */ +#define IPU_METADATA_EXTENSION_TYPE 16 + +/* Unique id for level 0 bootloader component */ +#define IA_CSS_IUNIT_BTLDR_ID 0 +/* Unique id for psys server program group component */ +#define IA_CSS_IUNIT_PSYS_SERVER_ID 1 +/* Unique id for isys server program group component */ +#define IA_CSS_IUNIT_ISYS_SERVER_ID 2 +/* Initial Identifier for client program group component */ +#define IA_CSS_IUNIT_CLIENT_ID 3 + +/* Use this to parse date from release version from the iUnit component + * e.g. 20150701 + */ +#define IA_CSS_IUNIT_COMP_DATE_SIZE 8 +/* offset of release version in program group binary + * e.g. release_version = "scci_gerrit_20150716_2117" + * In cpd file we only use date/version for the component + */ +#define IA_CSS_IUNIT_DATE_OFFSET 12 + +#define IPU_METADATA_HASH_KEY_SIZE 32 +#define IPU_METADATA_ATTRIBUTE_SIZE 16 +#define IA_CSE_METADATA_COMPONENT_ID_MAX 127 + +typedef enum { + IA_CSS_CPD_METADATA_IMAGE_TYPE_RESERVED, + IA_CSS_CPD_METADATA_IMAGE_TYPE_BOOTLOADER, + IA_CSS_CPD_METADATA_IMAGE_TYPE_MAIN_FIRMWARE +} ia_css_cpd_metadata_image_type_t; + +typedef enum { + IA_CSS_CPD_MAIN_FW_TYPE_RESERVED, + IA_CSS_CPD_MAIN_FW_TYPE_PSYS_SERVER, + IA_CSS_CPD_MAIN_FW_TYPE_ISYS_SERVER, + IA_CSS_CPD_MAIN_FW_TYPE_CLIENT +} ia_css_cpd_iunit_main_fw_type_t; + +/** Data structure for component specific information + * Following data structure has been taken from CSE Manifest v0.2 + */ +typedef struct { + /**< Component ID - unique for each component */ + uint32_t id; + /**< Size of the components */ + uint32_t size; + /**< Version/date of when the components is being generated/created */ + uint32_t version; + /**< SHA 256 Hash Key for component */ + uint8_t sha2_hash[IPU_METADATA_HASH_KEY_SIZE]; + /**< component sp entry point + * - Only valid for btldr/psys/isys server component + */ + uint32_t entry_point; + /**< component icache base address + * - Only valid for btldr/psys/isys server component + */ + uint32_t icache_base_offset; + /**< Resevred - must be 0 */ + uint8_t attributes[IPU_METADATA_ATTRIBUTE_SIZE]; +} ia_css_cpd_metadata_component_t; + +/** Data structure for Metadata File Extension Header + */ +typedef struct { + /**< Specifies the binary image type + * - could be bootloader or main firmware + */ + ia_css_cpd_metadata_image_type_t image_type; + /**< Number of components available in metadata file extension + * (For btldr always 1) + */ + uint32_t component_count; + /**< Component specific information */ + ia_css_cpd_metadata_component_t *components; +} ia_css_cpd_metadata_desc_t; + +#endif /* __IA_CSS_CPD_METADATA_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/device_access.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/device_access.mk new file mode 100644 index 0000000000000..1629d9af803b6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/device_access.mk @@ -0,0 +1,40 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# + +ifndef _DEVICE_ACCESS_MK_ +_DEVICE_ACCESS_MK_ = 1 + +# DEVICE_ACCESS_VERSION= +include $(MODULES_DIR)/config/system_$(IPU_SYSVER).mk + +DEVICE_ACCESS_DIR=$${MODULES_DIR}/device_access +DEVICE_ACCESS_INTERFACE=$(DEVICE_ACCESS_DIR)/interface +DEVICE_ACCESS_SOURCES=$(DEVICE_ACCESS_DIR)/src + +DEVICE_ACCESS_HOST_FILES = + +DEVICE_ACCESS_FW_FILES = + +DEVICE_ACCESS_HOST_CPPFLAGS = \ + -I$(DEVICE_ACCESS_INTERFACE) \ + -I$(DEVICE_ACCESS_SOURCES) + +DEVICE_ACCESS_FW_CPPFLAGS = \ + -I$(DEVICE_ACCESS_INTERFACE) \ + -I$(DEVICE_ACCESS_SOURCES) + +DEVICE_ACCESS_FW_CPPFLAGS += \ + -I$(DEVICE_ACCESS_SOURCES)/$(DEVICE_ACCESS_VERSION) +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/interface/ia_css_cmem.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/interface/ia_css_cmem.h new file mode 100644 index 0000000000000..3dc47c29fcab7 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/interface/ia_css_cmem.h @@ -0,0 +1,58 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CMEM_H +#define __IA_CSS_CMEM_H + +#include "type_support.h" +#include "storage_class.h" + +#ifdef __VIED_CELL +typedef unsigned int ia_css_cmem_address_t; +#else +#include +typedef vied_subsystem_address_t ia_css_cmem_address_t; +#endif + +STORAGE_CLASS_INLINE uint32_t +ia_css_cmem_load_32(unsigned int ssid, ia_css_cmem_address_t address); + +STORAGE_CLASS_INLINE void +ia_css_cmem_store_32(unsigned int ssid, ia_css_cmem_address_t address, + uint32_t value); + +STORAGE_CLASS_INLINE void +ia_css_cmem_load(unsigned int ssid, ia_css_cmem_address_t address, void *data, + unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_cmem_store(unsigned int ssid, ia_css_cmem_address_t address, + const void *data, unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_cmem_zero(unsigned int ssid, ia_css_cmem_address_t address, + unsigned int size); + +STORAGE_CLASS_INLINE ia_css_cmem_address_t +ia_css_cmem_get_cmem_addr_from_dmem(unsigned int base_addr, void *p); + +/* Include inline implementation */ + +#ifdef __VIED_CELL +#include "ia_css_cmem_cell.h" +#else +#include "ia_css_cmem_host.h" +#endif + +#endif /* __IA_CSS_CMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/interface/ia_css_xmem.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/interface/ia_css_xmem.h new file mode 100644 index 0000000000000..de2b94d8af541 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/interface/ia_css_xmem.h @@ -0,0 +1,65 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_H +#define __IA_CSS_XMEM_H + +#include "type_support.h" +#include "storage_class.h" + +#ifdef __VIED_CELL +typedef unsigned int ia_css_xmem_address_t; +#else +#include +typedef host_virtual_address_t ia_css_xmem_address_t; +#endif + +STORAGE_CLASS_INLINE uint8_t +ia_css_xmem_load_8(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE uint16_t +ia_css_xmem_load_16(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE uint32_t +ia_css_xmem_load_32(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE void +ia_css_xmem_load(unsigned int mmid, ia_css_xmem_address_t address, void *data, + unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_8(unsigned int mmid, ia_css_xmem_address_t address, + uint8_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_16(unsigned int mmid, ia_css_xmem_address_t address, + uint16_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_32(unsigned int mmid, ia_css_xmem_address_t address, + uint32_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store(unsigned int mmid, ia_css_xmem_address_t address, + const void *data, unsigned int bytes); + +/* Include inline implementation */ + +#ifdef __VIED_CELL +#include "ia_css_xmem_cell.h" +#else +#include "ia_css_xmem_host.h" +#endif + +#endif /* __IA_CSS_XMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/interface/ia_css_xmem_cmem.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/interface/ia_css_xmem_cmem.h new file mode 100644 index 0000000000000..57aab3323c739 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/interface/ia_css_xmem_cmem.h @@ -0,0 +1,35 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_CMEM_H +#define __IA_CSS_XMEM_CMEM_H + +#include "ia_css_cmem.h" +#include "ia_css_xmem.h" + +/* Copy data from xmem to cmem, e.g., from a program in DDR to a cell's DMEM */ +/* This may also be implemented using DMA */ + +STORAGE_CLASS_INLINE void +ia_css_xmem_to_cmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size); + +/* include inline implementation */ +#include "ia_css_xmem_cmem_impl.h" + +#endif /* __IA_CSS_XMEM_CMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/src/ia_css_cmem_host.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/src/ia_css_cmem_host.h new file mode 100644 index 0000000000000..22799e67214c1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/src/ia_css_cmem_host.h @@ -0,0 +1,121 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CMEM_HOST_H +#define __IA_CSS_CMEM_HOST_H + +/* This file is an inline implementation for the interface ia_css_cmem.h + * and should only be included there. */ + +#include "assert_support.h" +#include "misc_support.h" + +STORAGE_CLASS_INLINE uint32_t +ia_css_cmem_load_32(unsigned int ssid, ia_css_cmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + return vied_subsystem_load_32(ssid, address); +} + +STORAGE_CLASS_INLINE uint32_t +ia_css_cond_cmem_load_32(bool cond, unsigned int ssid, + ia_css_cmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + if (cond) + return vied_subsystem_load_32(ssid, address); + else + return 0; +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_store_32(unsigned int ssid, ia_css_cmem_address_t address, + uint32_t data) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + vied_subsystem_store_32(ssid, address, data); +} + +STORAGE_CLASS_INLINE void +ia_css_cond_cmem_store_32(bool cond, unsigned int ssid, + ia_css_cmem_address_t address, uint32_t data) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + if (cond) + vied_subsystem_store_32(ssid, address, data); +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_load(unsigned int ssid, ia_css_cmem_address_t address, void *data, + unsigned int size) +{ + uint32_t *data32 = (uint32_t *)data; + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + assert((long)data % 4 == 0); + + while (address != end) { + *data32 = ia_css_cmem_load_32(ssid, address); + address += 4; + data32 += 1; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_store(unsigned int ssid, ia_css_cmem_address_t address, + const void *data, unsigned int size) +{ + uint32_t *data32 = (uint32_t *)data; + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + assert((long)data % 4 == 0); + + while (address != end) { + ia_css_cmem_store_32(ssid, address, *data32); + address += 4; + data32 += 1; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_zero(unsigned int ssid, ia_css_cmem_address_t address, + unsigned int size) +{ + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + + while (address != end) { + ia_css_cmem_store_32(ssid, address, 0); + address += 4; + } +} + +STORAGE_CLASS_INLINE ia_css_cmem_address_t +ia_css_cmem_get_cmem_addr_from_dmem(unsigned int base_addr, void *p) +{ + NOT_USED(base_addr); + return (ia_css_cmem_address_t)(uintptr_t)p; +} + +#endif /* __IA_CSS_CMEM_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/src/ia_css_xmem_cmem_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/src/ia_css_xmem_cmem_impl.h new file mode 100644 index 0000000000000..adc178b75059a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/src/ia_css_xmem_cmem_impl.h @@ -0,0 +1,79 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_CMEM_IMPL_H +#define __IA_CSS_XMEM_CMEM_IMPL_H + +#include "ia_css_xmem_cmem.h" + +#include "ia_css_cmem.h" +#include "ia_css_xmem.h" + +/* Copy data from xmem to cmem, e.g., from a program in DDR to a cell's DMEM */ +/* This may also be implemented using DMA */ + +STORAGE_CLASS_INLINE void +ia_css_xmem_to_cmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size) +{ + /* copy from ddr to subsystem, e.g., cell dmem */ + ia_css_cmem_address_t end = dst + size; + + assert(size % 4 == 0); + assert((uintptr_t) dst % 4 == 0); + assert((uintptr_t) src % 4 == 0); + + while (dst != end) { + uint32_t data; + + data = ia_css_xmem_load_32(mmid, src); + ia_css_cmem_store_32(ssid, dst, data); + dst += 4; + src += 4; + } +} + +/* Copy data from cmem to xmem */ + +STORAGE_CLASS_INLINE void +ia_css_cmem_to_xmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_cmem_address_t src, + ia_css_xmem_address_t dst, + unsigned int size) +{ + /* copy from ddr to subsystem, e.g., cell dmem */ + ia_css_xmem_address_t end = dst + size; + + assert(size % 4 == 0); + assert((uintptr_t) dst % 4 == 0); + assert((uintptr_t) src % 4 == 0); + + while (dst != end) { + uint32_t data; + + data = ia_css_cmem_load_32(mmid, src); + ia_css_xmem_store_32(ssid, dst, data); + dst += 4; + src += 4; + } +} + + +#endif /* __IA_CSS_XMEM_CMEM_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/src/ia_css_xmem_host.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/src/ia_css_xmem_host.h new file mode 100644 index 0000000000000..d94991fc11143 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/device_access/src/ia_css_xmem_host.h @@ -0,0 +1,84 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_HOST_H +#define __IA_CSS_XMEM_HOST_H + +#include "ia_css_xmem.h" +#include +#include "assert_support.h" +#include + +STORAGE_CLASS_INLINE uint8_t +ia_css_xmem_load_8(unsigned int mmid, ia_css_xmem_address_t address) +{ + return shared_memory_load_8(mmid, address); +} + +STORAGE_CLASS_INLINE uint16_t +ia_css_xmem_load_16(unsigned int mmid, ia_css_xmem_address_t address) +{ + /* Address has to be half-word aligned */ + assert(0 == (uintptr_t) address % 2); + return shared_memory_load_16(mmid, address); +} + +STORAGE_CLASS_INLINE uint32_t +ia_css_xmem_load_32(unsigned int mmid, ia_css_xmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == (uintptr_t) address % 4); + return shared_memory_load_32(mmid, address); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_load(unsigned int mmid, ia_css_xmem_address_t address, void *data, + unsigned int size) +{ + shared_memory_load(mmid, address, data, size); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_8(unsigned int mmid, ia_css_xmem_address_t address, + uint8_t value) +{ + shared_memory_store_8(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_16(unsigned int mmid, ia_css_xmem_address_t address, + uint16_t value) +{ + /* Address has to be half-word aligned */ + assert(0 == (uintptr_t) address % 2); + shared_memory_store_16(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_32(unsigned int mmid, ia_css_xmem_address_t address, + uint32_t value) +{ + /* Address has to be word aligned */ + assert(0 == (uintptr_t) address % 4); + shared_memory_store_32(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store(unsigned int mmid, ia_css_xmem_address_t address, + const void *data, unsigned int bytes) +{ + shared_memory_store(mmid, address, data, bytes); +} + +#endif /* __IA_CSS_XMEM_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/bxtB0/ipu_device_buttress_properties_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/bxtB0/ipu_device_buttress_properties_struct.h new file mode 100644 index 0000000000000..5102f6e44d2f6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/bxtB0/ipu_device_buttress_properties_struct.h @@ -0,0 +1,68 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H +#define __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H + +/* Destination values for master port 0 and bitfield "request_dest" */ +enum cio_M0_btrs_dest { + DEST_IS_BUT_REGS = 0, + DEST_IS_DDR, + RESERVED, + DEST_IS_SUBSYSTEM, + N_BTRS_DEST +}; + +/* Bit-field positions for M0 info bits */ +enum ia_css_info_bits_m0_pos { + IA_CSS_INFO_BITS_M0_SNOOPABLE_POS = 0, + IA_CSS_INFO_BITS_M0_IMR_DESTINED_POS = 1, + IA_CSS_INFO_BITS_M0_REQUEST_DEST_POS = 4 +}; + +#define IA_CSS_INFO_BITS_M0_DDR \ + (DEST_IS_DDR << IA_CSS_INFO_BITS_M0_REQUEST_DEST_POS) +#define IA_CSS_INFO_BITS_M0_SNOOPABLE (1 << IA_CSS_INFO_BITS_M0_SNOOPABLE_POS) + +/* Info bits as expected by the buttress */ +/* Deprecated because bit fields are not portable */ + +/* For master port 0*/ +union cio_M0_t { + struct { + unsigned int snoopable : 1; + unsigned int imr_destined : 1; + unsigned int spare0 : 2; + unsigned int request_dest : 2; + unsigned int spare1 : 26; + } as_bitfield; + unsigned int as_word; +}; + +/* For master port 1*/ +union cio_M1_t { + struct { + unsigned int spare0 : 1; + unsigned int deadline_pointer : 1; + unsigned int reserved : 1; + unsigned int zlw : 1; + unsigned int stream_id : 4; + unsigned int address_swizzling : 1; + unsigned int spare1 : 23; + } as_bitfield; + unsigned int as_word; +}; + + +#endif /* __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties.h new file mode 100644 index 0000000000000..e6e1e9dcbe80c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties.h @@ -0,0 +1,76 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_H +#define __IPU_DEVICE_CELL_PROPERTIES_H + +#include "storage_class.h" +#include "ipu_device_cell_type_properties.h" + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_devices(void); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_memories(const unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_size(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_address(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_databus_memory_address(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_masters(const unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_bits(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_num_segments(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_size(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_stride(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_base_reg(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_reg(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_icache_align(unsigned int cell_id); + +#ifdef C_RUN +STORAGE_CLASS_INLINE int +ipu_device_cell_id_crun(int cell_id); +#endif + +#include "ipu_device_cell_properties_func.h" + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_func.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_func.h new file mode 100644 index 0000000000000..481b0504a2378 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_func.h @@ -0,0 +1,164 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_FUNC_H +#define __IPU_DEVICE_CELL_PROPERTIES_FUNC_H + +/* define properties for all cells uses in ISYS */ + +#include "ipu_device_cell_properties_impl.h" +#include "ipu_device_cell_devices.h" +#include "assert_support.h" +#include "storage_class.h" + +enum {IA_CSS_CELL_MASTER_ADDRESS_WIDTH = 32}; + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_devices(void) +{ + return NUM_CELLS; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_memories(const unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + num_memories; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_size(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + return ipu_device_cell_properties[cell_id].type_properties-> + mem_size[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_address(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + return ipu_device_cell_properties[cell_id].mem_address[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_databus_memory_address(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + assert(mem_id != 0); + return ipu_device_cell_properties[cell_id].mem_databus_address[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_masters(const unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + num_master_ports; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_bits(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].segment_bits; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_num_segments(const unsigned int cell_id, + const unsigned int master_id) +{ + return 1u << ipu_device_cell_master_segment_bits(cell_id, master_id); +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_size(const unsigned int cell_id, + const unsigned int master_id) +{ + return 1u << (IA_CSS_CELL_MASTER_ADDRESS_WIDTH - + ipu_device_cell_master_segment_bits(cell_id, master_id)); +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_stride(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].stride; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_base_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].base_address_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].info_bits_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_override_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].info_override_bits_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_icache_align(unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + icache_align; +} + +#ifdef C_RUN +STORAGE_CLASS_INLINE int +ipu_device_cell_id_crun(int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_map_cell_id_to_crun_proc_id[cell_id]; +} +#endif + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_FUNC_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_struct.h new file mode 100644 index 0000000000000..63397dc0b7fe6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_struct.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H +#define __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H + +/* definitions for all cell types */ + +struct ipu_device_cell_count_s { + unsigned int num_memories; + unsigned int num_master_ports; + unsigned int num_stall_bits; + unsigned int icache_align; +}; + +struct ipu_device_cell_master_properties_s { + unsigned int segment_bits; + unsigned int stride; /* offset to register of next segment */ + unsigned int base_address_register; /* address of first base address + register */ + unsigned int info_bits_register; + unsigned int info_override_bits_register; +}; + +struct ipu_device_cell_type_properties_s { + const struct ipu_device_cell_count_s *count; + const struct ipu_device_cell_master_properties_s *master; + const unsigned int *reg_offset; /* offsets of registers, some depend + on cell type */ + const unsigned int *mem_size; +}; + +struct ipu_device_cell_properties_s { + const struct ipu_device_cell_type_properties_s *type_properties; + const unsigned int *mem_address; + const unsigned int *mem_databus_address; + /* const cell_master_port_properties_s* master_port_properties; */ +}; + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_type_properties.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_type_properties.h new file mode 100644 index 0000000000000..72caed3eef0c9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_cell_type_properties.h @@ -0,0 +1,69 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_TYPE_PROPERTIES_H +#define __IPU_DEVICE_CELL_TYPE_PROPERTIES_H + +#define IPU_DEVICE_INVALID_MEM_ADDRESS 0xFFFFFFFF + +enum ipu_device_cell_stat_ctrl_bit { + IPU_DEVICE_CELL_STAT_CTRL_RESET_BIT = 0, + IPU_DEVICE_CELL_STAT_CTRL_START_BIT = 1, + IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT = 3, + IPU_DEVICE_CELL_STAT_CTRL_READY_BIT = 5, + IPU_DEVICE_CELL_STAT_CTRL_SLEEP_BIT = 6, + IPU_DEVICE_CELL_STAT_CTRL_STALL_BIT = 7, + IPU_DEVICE_CELL_STAT_CTRL_CLEAR_IRQ_MASK_FLAG_BIT = 8, + IPU_DEVICE_CELL_STAT_CTRL_BROKEN_IRQ_MASK_FLAG_BIT = 9, + IPU_DEVICE_CELL_STAT_CTRL_READY_IRQ_MASK_FLAG_BIT = 10, + IPU_DEVICE_CELL_STAT_CTRL_SLEEP_IRQ_MASK_FLAG_BIT = 11, + IPU_DEVICE_CELL_STAT_CTRL_INVALIDATE_ICACHE_BIT = 12, + IPU_DEVICE_CELL_STAT_CTRL_ICACHE_ENABLE_PREFETCH_BIT = 13 +}; + +enum ipu_device_cell_reg_addr { + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS = 0x0, + IPU_DEVICE_CELL_START_PC_REG_ADDRESS = 0x4, + IPU_DEVICE_CELL_ICACHE_BASE_REG_ADDRESS = 0x10, + IPU_DEVICE_CELL_ICACHE_INFO_BITS_REG_ADDRESS = 0x14 +}; + +enum ipu_device_cell_reg { + IPU_DEVICE_CELL_STAT_CTRL_REG, + IPU_DEVICE_CELL_START_PC_REG, + IPU_DEVICE_CELL_ICACHE_BASE_REG, + IPU_DEVICE_CELL_DEBUG_PC_REG, + IPU_DEVICE_CELL_STALL_REG, + IPU_DEVICE_CELL_NUM_REGS +}; + +enum ipu_device_cell_mem { + IPU_DEVICE_CELL_REGS, /* memory id of registers */ + IPU_DEVICE_CELL_PMEM, /* memory id of pmem */ + IPU_DEVICE_CELL_DMEM, /* memory id of dmem */ + IPU_DEVICE_CELL_BAMEM, /* memory id of bamem */ + IPU_DEVICE_CELL_VMEM /* memory id of vmem */ +}; +#define IPU_DEVICE_CELL_NUM_MEMORIES (IPU_DEVICE_CELL_VMEM + 1) + +enum ipu_device_cell_master { + IPU_DEVICE_CELL_MASTER_ICACHE, /* master port id of icache */ + IPU_DEVICE_CELL_MASTER_QMEM, + IPU_DEVICE_CELL_MASTER_CMEM, + IPU_DEVICE_CELL_MASTER_XMEM, + IPU_DEVICE_CELL_MASTER_XVMEM +}; +#define IPU_DEVICE_CELL_MASTER_NUM_MASTERS (IPU_DEVICE_CELL_MASTER_XVMEM + 1) + +#endif /* __IPU_DEVICE_CELL_TYPE_PROPERTIES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties.h new file mode 100644 index 0000000000000..fd0c5a586c949 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties.h @@ -0,0 +1,26 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_GP_PROPERTIES_H +#define __IPU_DEVICE_GP_PROPERTIES_H + +#include "storage_class.h" +#include "ipu_device_gp_properties_types.h" + +STORAGE_CLASS_INLINE unsigned int +ipu_device_gp_mux_addr(const unsigned int device_id, const unsigned int mux_id); + +#include "ipu_device_gp_properties_func.h" + +#endif /* __IPU_DEVICE_GP_PROPERTIES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties_types.h new file mode 100644 index 0000000000000..3032273696eab --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties_types.h @@ -0,0 +1,103 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_GP_PROPERTIES_TYPES_H +#define __IPU_DEVICE_GP_PROPERTIES_TYPES_H + +enum ipu_device_gp_isa_value { + /* ISA_MUX_SEL options */ + IPU_DEVICE_GP_ISA_MUX_SEL_ICA = 0, /* Enable output after FF ICA */ + IPU_DEVICE_GP_ISA_MUX_SEL_LSC = 1, /* Enable output after FF LSC */ + IPU_DEVICE_GP_ISA_MUX_SEL_DPC = 2, /* Enable output after FF DPC */ + /* ICA stream block options */ + /* UNBLOCK signal received from ICA */ + IPU_DEVICE_GP_ISA_ICA_UNBLOCK = 0, + /* BLOCK signal received from ICA */ + IPU_DEVICE_GP_ISA_ICA_BLOCK = 1, + /* LSC stream block options */ + /* UNBLOCK signal received from LSC */ + IPU_DEVICE_GP_ISA_LSC_UNBLOCK = 0, + /* BLOCK signal received from LSC */ + IPU_DEVICE_GP_ISA_LSC_BLOCK = 1, + /* DPC stream block options */ + /* UNBLOCK signal received from DPC */ + IPU_DEVICE_GP_ISA_DPC_UNBLOCK = 0, + /* BLOCK signal received from DPC */ + IPU_DEVICE_GP_ISA_DPC_BLOCK = 1, + /* Defines needed only for bxtB0 */ + /* ISA_AWB_MUX_SEL options */ + /* Input Correction input */ + IPU_DEVICE_GP_ISA_AWB_MUX_SEL_ICA = 0, + /* DPC input */ + IPU_DEVICE_GP_ISA_AWB_MUX_SEL_DPC = 1, + /* ISA_AWB_MUX_SEL options */ + /* UNBLOCK DPC input */ + IPU_DEVICE_GP_ISA_AWB_MUX_ICA_UNBLOCK = 0, + /* BLOCK DPC input */ + IPU_DEVICE_GP_ISA_AWB_MUX_ICA_BLOCK = 1, + /* ISA_AWB_MUX_SEL options */ + /* UNBLOCK Input Correction input */ + IPU_DEVICE_GP_ISA_AWB_MUX_DPC_UNBLOCK = 0, + /* BLOCK Input Correction input */ + IPU_DEVICE_GP_ISA_AWB_MUX_DPC_BLOCK = 1, + + /* PAF STRM options */ + /* Disable streaming to PAF FF*/ + IPU_DEVICE_GP_ISA_PAF_DISABLE_STREAM = 0, + /* Enable stream0 to PAF FF*/ + IPU_DEVICE_GP_ISA_PAF_ENABLE_STREAM0 = 1, + /* Enable stream1 to PAF FF*/ + IPU_DEVICE_GP_ISA_PAF_ENABLE_STREAM1 = 2, + /* PAF SRC SEL options */ + /* External channel input */ + IPU_DEVICE_GP_ISA_PAF_SRC_SEL0 = 0, + /* DPC extracted input */ + IPU_DEVICE_GP_ISA_PAF_SRC_SEL1 = 1, + /* PAF_GDDPC_BLK options */ + IPU_DEVICE_GP_ISA_PAF_GDDPC_PORT_BLK0 = 0, + IPU_DEVICE_GP_ISA_PAF_GDDPC_PORT_BLK1 = 1, + /* PAF ISA STR_PORT options */ + IPU_DEVICE_GP_ISA_PAF_STR_PORT0 = 0, + IPU_DEVICE_GP_ISA_PAF_STR_PORT1 = 1, + + /* sis port block options */ + IPU_DEVICE_GP_ISA_SIS_PORT_UNBLOCK = 0, + IPU_DEVICE_GP_ISA_SIS_PORT_BLOCK = 1, + IPU_DEVICE_GP_ISA_CONF_INVALID = 0xFF +}; + +enum ipu_device_gp_psa_value { + /* Defines needed for bxtB0 */ + /* PSA_STILLS_MODE_MUX */ + IPU_DEVICE_GP_PSA_MUX_POST_RYNR_ROUTE_WO_DM = 0, + IPU_DEVICE_GP_PSA_MUX_POST_RYNR_ROUTE_W_DM = 1, + /* PSA_ACM_DEMUX */ + IPU_DEVICE_GP_PSA_DEMUX_PRE_ACM_ROUTE_TO_ACM = 0, + IPU_DEVICE_GP_PSA_DEMUX_PRE_ACM_ROUTE_TO_S2V = 1, + /* PSA_S2V_RGB_F_MUX */ + IPU_DEVICE_GP_PSA_MUX_PRE_S2V_RGB_F_FROM_ACM = 0, + IPU_DEVICE_GP_PSA_MUX_PRE_S2V_RGB_F_FROM_DM_OR_SPLITTER = 1, + /* PSA_V2S_RGB_4_DEMUX */ + IPU_DEVICE_GP_PSA_DEMUX_POST_V2S_RGB_4_TO_GTM = 0, + IPU_DEVICE_GP_PSA_DEMUX_POST_V2S_RGB_4_TO_ACM = 1, +}; + +enum ipu_device_gp_isl_value { + /* choose and route pixel stream to CSI BE */ + IPU_DEVICE_GP_ISL_CSI_BE_IN_USE = 0, + /* choose and route pixel stream bypass CSI BE */ + IPU_DEVICE_GP_ISL_CSI_BE_BYPASS +}; + +#endif /* __IPU_DEVICE_GP_PROPERTIES_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_acb_devices.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_acb_devices.h new file mode 100644 index 0000000000000..d9472a5d33cad --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_acb_devices.h @@ -0,0 +1,43 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IPU_DEVICE_ACB_DEVICES_H +#define __IPU_DEVICE_ACB_DEVICES_H + +enum ipu_device_acb_id { + /* PSA accelerators */ + IPU_DEVICE_ACB_WBA_ID = 0, + IPU_DEVICE_ACB_RYNR_ID, + IPU_DEVICE_ACB_DEMOSAIC_ID, + IPU_DEVICE_ACB_ACM_ID, + IPU_DEVICE_ACB_GTC_ID, + IPU_DEVICE_ACB_YUV1_ID, + IPU_DEVICE_ACB_DVS_ID, + IPU_DEVICE_ACB_LACE_ID, + /* ISA accelerators */ + IPU_DEVICE_ACB_ICA_ID, + IPU_DEVICE_ACB_LSC_ID, + IPU_DEVICE_ACB_DPC_ID, + IPU_DEVICE_ACB_IDS_ID, + IPU_DEVICE_ACB_AWB_ID, + IPU_DEVICE_ACB_AF_ID, + IPU_DEVICE_ACB_AE_ID, + IPU_DEVICE_ACB_NUM_ACB +}; + +#define IPU_DEVICE_ACB_NUM_PSA_ACB (IPU_DEVICE_ACB_LACE_ID + 1) +#define IPU_DEVICE_ACB_NUM_ISA_ACB \ + (IPU_DEVICE_ACB_NUM_ACB - IPU_DEVICE_ACB_NUM_PSA_ACB) + +#endif /* __IPU_DEVICE_ACB_DEVICES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_cell_devices.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_cell_devices.h new file mode 100644 index 0000000000000..7a57967cb6eb7 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_cell_devices.h @@ -0,0 +1,38 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IPU_DEVICE_CELL_DEVICES_H +#define __IPU_DEVICE_CELL_DEVICES_H + +#define SPC0_CELL processing_system_sp_cluster_sp_cluster_logic_spc_tile_sp +#define SPP0_CELL processing_system_sp_cluster_sp_cluster_logic_spp_tile0_sp +#define SPP1_CELL processing_system_sp_cluster_sp_cluster_logic_spp_tile1_sp +#define ISP0_CELL processing_system_isp_tile0_logic_isp +#define ISP1_CELL processing_system_isp_tile1_logic_isp +#define ISP2_CELL processing_system_isp_tile2_logic_isp +#define ISP3_CELL processing_system_isp_tile3_logic_isp + +enum ipu_device_psys_cell_id { + SPC0, + SPP0, + SPP1, + ISP0, + ISP1, + ISP2, + ISP3, + NUM_CELLS +}; +#define NUM_ISP_CELLS 4 + +#endif /* __IPU_DEVICE_CELL_DEVICES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_cell_properties_defs.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_cell_properties_defs.h new file mode 100644 index 0000000000000..2b80e2822a906 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_cell_properties_defs.h @@ -0,0 +1,65 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +/* Generated file - please do not edit. */ + +#ifndef _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ +#define _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ +#define SPC0_REGS_CBUS_ADDRESS 0x00000000 +#define SPC0_DMEM_CBUS_ADDRESS 0x00008000 +#define SPC0_DMEM_DBUS_ADDRESS 0x02000000 +#define SPC0_DMEM_DMA_M0_ADDRESS SPC0_DMEM_DBUS_ADDRESS +#define SPC0_DMEM_INT_DMA_M0_ADDRESS SPC0_DMEM_DBUS_ADDRESS +#define SPP0_REGS_CBUS_ADDRESS 0x00020000 +#define SPP0_DMEM_CBUS_ADDRESS 0x00028000 +#define SPP0_DMEM_DBUS_ADDRESS 0x02020000 +#define SPP1_REGS_CBUS_ADDRESS 0x00030000 +#define SPP1_DMEM_CBUS_ADDRESS 0x00038000 +#define SPP1_DMEM_DBUS_ADDRESS 0x02030000 +#define ISP0_REGS_CBUS_ADDRESS 0x001C0000 +#define ISP0_PMEM_CBUS_ADDRESS 0x001D0000 +#define ISP0_DMEM_CBUS_ADDRESS 0x001F0000 +#define ISP0_BAMEM_CBUS_ADDRESS 0x00200000 +#define ISP0_VMEM_CBUS_ADDRESS 0x00220000 +#define ISP1_REGS_CBUS_ADDRESS 0x00240000 +#define ISP1_PMEM_CBUS_ADDRESS 0x00250000 +#define ISP1_DMEM_CBUS_ADDRESS 0x00270000 +#define ISP1_BAMEM_CBUS_ADDRESS 0x00280000 +#define ISP1_VMEM_CBUS_ADDRESS 0x002A0000 +#define ISP2_REGS_CBUS_ADDRESS 0x002C0000 +#define ISP2_PMEM_CBUS_ADDRESS 0x002D0000 +#define ISP2_DMEM_CBUS_ADDRESS 0x002F0000 +#define ISP2_BAMEM_CBUS_ADDRESS 0x00300000 +#define ISP2_VMEM_CBUS_ADDRESS 0x00320000 +#define ISP3_REGS_CBUS_ADDRESS 0x00340000 +#define ISP3_PMEM_CBUS_ADDRESS 0x00350000 +#define ISP3_DMEM_CBUS_ADDRESS 0x00370000 +#define ISP3_BAMEM_CBUS_ADDRESS 0x00380000 +#define ISP3_VMEM_CBUS_ADDRESS 0x003A0000 +#define ISP0_PMEM_DBUS_ADDRESS 0x08000000 +#define ISP0_DMEM_DBUS_ADDRESS 0x08400000 +#define ISP0_BAMEM_DBUS_ADDRESS 0x09000000 +#define ISP0_VMEM_DBUS_ADDRESS 0x08800000 +#define ISP1_PMEM_DBUS_ADDRESS 0x0A000000 +#define ISP1_DMEM_DBUS_ADDRESS 0x0A400000 +#define ISP1_BAMEM_DBUS_ADDRESS 0x0B000000 +#define ISP1_VMEM_DBUS_ADDRESS 0x0A800000 +#define ISP2_PMEM_DBUS_ADDRESS 0x0C000000 +#define ISP2_DMEM_DBUS_ADDRESS 0x0C400000 +#define ISP2_BAMEM_DBUS_ADDRESS 0x0D000000 +#define ISP2_VMEM_DBUS_ADDRESS 0x0C800000 +#define ISP3_PMEM_DBUS_ADDRESS 0x0E000000 +#define ISP3_DMEM_DBUS_ADDRESS 0x0E400000 +#define ISP3_BAMEM_DBUS_ADDRESS 0x0F000000 +#define ISP3_VMEM_DBUS_ADDRESS 0x0E800000 +#endif /* _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_cell_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_cell_properties_impl.h new file mode 100644 index 0000000000000..10c28983eeb6f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_cell_properties_impl.h @@ -0,0 +1,193 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_IMPL_H +#define __IPU_DEVICE_CELL_PROPERTIES_IMPL_H + +#include "ipu_device_sp2600_control_properties_impl.h" +#include "ipu_device_sp2600_proxy_properties_impl.h" +#include "ipu_device_isp2600_properties_impl.h" +#include "ipu_device_cell_properties_defs.h" +#include "ipu_device_cell_devices.h" +#include "ipu_device_cell_type_properties.h"/* IPU_DEVICE_INVALID_MEM_ADDRESS */ + +static const unsigned int +ipu_device_spc0_mem_address[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + SPC0_REGS_CBUS_ADDRESS, + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPC0_DMEM_CBUS_ADDRESS +}; + +static const unsigned int +ipu_device_spp0_mem_address[IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES] = { + SPP0_REGS_CBUS_ADDRESS, + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPP0_DMEM_CBUS_ADDRESS +}; + +static const unsigned int +ipu_device_spp1_mem_address[IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES] = { + SPP1_REGS_CBUS_ADDRESS, + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPP1_DMEM_CBUS_ADDRESS +}; + +static const unsigned int +ipu_device_isp0_mem_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + ISP0_REGS_CBUS_ADDRESS, /* reg addr */ + ISP0_PMEM_CBUS_ADDRESS, /* pmem addr */ + ISP0_DMEM_CBUS_ADDRESS, /* dmem addr */ + ISP0_BAMEM_CBUS_ADDRESS,/* bamem addr */ + ISP0_VMEM_CBUS_ADDRESS /* vmem addr */ +}; + +static const unsigned int +ipu_device_isp1_mem_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + ISP1_REGS_CBUS_ADDRESS, /* reg addr */ + ISP1_PMEM_CBUS_ADDRESS, /* pmem addr */ + ISP1_DMEM_CBUS_ADDRESS, /* dmem addr */ + ISP1_BAMEM_CBUS_ADDRESS,/* bamem addr */ + ISP1_VMEM_CBUS_ADDRESS /* vmem addr */ +}; + +static const unsigned int +ipu_device_isp2_mem_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + ISP2_REGS_CBUS_ADDRESS, /* reg addr */ + ISP2_PMEM_CBUS_ADDRESS, /* pmem addr */ + ISP2_DMEM_CBUS_ADDRESS, /* dmem addr */ + ISP2_BAMEM_CBUS_ADDRESS,/* bamem addr */ + ISP2_VMEM_CBUS_ADDRESS /* vmem addr */ +}; + +static const unsigned int +ipu_device_isp3_mem_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + ISP3_REGS_CBUS_ADDRESS, /* reg addr */ + ISP3_PMEM_CBUS_ADDRESS, /* pmem addr */ + ISP3_DMEM_CBUS_ADDRESS, /* dmem addr */ + ISP3_BAMEM_CBUS_ADDRESS,/* bamem addr */ + ISP3_VMEM_CBUS_ADDRESS /* vmem addr */ +}; + +static const unsigned int +ipu_device_spc0_mem_databus_address[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPC0_DMEM_DBUS_ADDRESS +}; + +static const unsigned int +ipu_device_spp0_mem_databus_address[IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPP0_DMEM_DBUS_ADDRESS +}; + +static const unsigned int +ipu_device_spp1_mem_databus_address[IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPP1_DMEM_DBUS_ADDRESS +}; + +static const unsigned int +ipu_device_isp0_mem_databus_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + ISP0_PMEM_DBUS_ADDRESS, /* pmem databus addr */ + ISP0_DMEM_DBUS_ADDRESS, /* dmem databus addr */ + ISP0_BAMEM_DBUS_ADDRESS, /* bamem databus addr */ + ISP0_VMEM_DBUS_ADDRESS /* vmem databus addr */ +}; + +static const unsigned int +ipu_device_isp1_mem_databus_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + ISP1_PMEM_DBUS_ADDRESS, /* pmem databus addr */ + ISP1_DMEM_DBUS_ADDRESS, /* dmem databus addr */ + ISP1_BAMEM_DBUS_ADDRESS, /* bamem databus addr */ + ISP1_VMEM_DBUS_ADDRESS /* vmem databus addr */ +}; + +static const unsigned int +ipu_device_isp2_mem_databus_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + ISP2_PMEM_DBUS_ADDRESS, /* pmem databus addr */ + ISP2_DMEM_DBUS_ADDRESS, /* dmem databus addr */ + ISP2_BAMEM_DBUS_ADDRESS, /* bamem databus addr */ + ISP2_VMEM_DBUS_ADDRESS /* vmem databus addr */ +}; + +static const unsigned int +ipu_device_isp3_mem_databus_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + ISP3_PMEM_DBUS_ADDRESS, /* pmem databus addr */ + ISP3_DMEM_DBUS_ADDRESS, /* dmem databus addr */ + ISP3_BAMEM_DBUS_ADDRESS, /* bamem databus addr */ + ISP3_VMEM_DBUS_ADDRESS /* vmem databus addr */ +}; + +static const struct ipu_device_cell_properties_s +ipu_device_cell_properties[NUM_CELLS] = { + { + &ipu_device_sp2600_control_properties, + ipu_device_spc0_mem_address, + ipu_device_spc0_mem_databus_address + }, + { + &ipu_device_sp2600_proxy_properties, + ipu_device_spp0_mem_address, + ipu_device_spp0_mem_databus_address + }, + { + &ipu_device_sp2600_proxy_properties, + ipu_device_spp1_mem_address, + ipu_device_spp1_mem_databus_address + }, + { + &ipu_device_isp2600_properties, + ipu_device_isp0_mem_address, + ipu_device_isp0_mem_databus_address + }, + { + &ipu_device_isp2600_properties, + ipu_device_isp1_mem_address, + ipu_device_isp1_mem_databus_address + }, + { + &ipu_device_isp2600_properties, + ipu_device_isp2_mem_address, + ipu_device_isp2_mem_databus_address + }, + { + &ipu_device_isp2600_properties, + ipu_device_isp3_mem_address, + ipu_device_isp3_mem_databus_address + } +}; + +#ifdef C_RUN + +/* Mapping between hrt_hive_processors enum and cell_id's used in FW */ +static const int ipu_device_map_cell_id_to_crun_proc_id[NUM_CELLS] = { + 4, /* SPC0 */ + 5, /* SPP0 */ + 6, /* SPP1 */ + 0, /* ISP0 */ + 1, /* ISP1 */ + 2, /* ISP2 */ + 3 /* ISP3 */ +}; + +#endif + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_ff_devices.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_ff_devices.h new file mode 100644 index 0000000000000..3af7ba63a3644 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_ff_devices.h @@ -0,0 +1,55 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IPU_DEVICE_FF_DEVICES_H +#define __IPU_DEVICE_FF_DEVICES_H + +enum ipu_device_ff_id { + /* PSA fixed functions */ + IPU_DEVICE_FF_WBA_WBA = 0, + IPU_DEVICE_FF_RYNR_SPLITTER, + IPU_DEVICE_FF_RYNR_COLLECTOR, + IPU_DEVICE_FF_RYNR_BNLM, + IPU_DEVICE_FF_RYNR_VCUD, + IPU_DEVICE_FF_DEMOSAIC_DEMOSAIC, + IPU_DEVICE_FF_ACM_CCM, + IPU_DEVICE_FF_ACM_ACM, + IPU_DEVICE_FF_GTC_CSC_CDS, + IPU_DEVICE_FF_GTC_GTM, + IPU_DEVICE_FF_YUV1_SPLITTER, + IPU_DEVICE_FF_YUV1_IEFD, + IPU_DEVICE_FF_YUV1_YDS, + IPU_DEVICE_FF_YUV1_TCC, + IPU_DEVICE_FF_DVS_YBIN, + IPU_DEVICE_FF_DVS_DVS, + IPU_DEVICE_FF_LACE_LACE, + /* ISA fixed functions */ + IPU_DEVICE_FF_ICA_INL, + IPU_DEVICE_FF_ICA_GBL, + IPU_DEVICE_FF_ICA_PCLN, + IPU_DEVICE_FF_LSC_LSC, + IPU_DEVICE_FF_DPC_DPC, + IPU_DEVICE_FF_IDS_SCALER, + IPU_DEVICE_FF_AWB_AWRG, + IPU_DEVICE_FF_AF_AF, + IPU_DEVICE_FF_AE_WGHT_HIST, + IPU_DEVICE_FF_AE_CCM, + IPU_DEVICE_FF_NUM_FF +}; + +#define IPU_DEVICE_FF_NUM_PSA_FF (IPU_DEVICE_FF_LACE_LACE + 1) +#define IPU_DEVICE_FF_NUM_ISA_FF \ + (IPU_DEVICE_FF_NUM_FF - IPU_DEVICE_FF_NUM_PSA_FF) + +#endif /* __IPU_DEVICE_FF_DEVICES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_gp_devices.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_gp_devices.h new file mode 100644 index 0000000000000..f6afd6003324a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/psys/bxtB0/ipu_device_gp_devices.h @@ -0,0 +1,67 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_GP_DEVICES_H +#define __IPU_DEVICE_GP_DEVICES_H +#include "math_support.h" +#include "type_support.h" + +enum ipu_device_gp_id { + IPU_DEVICE_GP_PSA = 0, /* PSA */ + IPU_DEVICE_GP_ISA_STATIC, /* ISA Static */ + IPU_DEVICE_GP_ISA_RUNTIME, /* ISA Runtime */ + IPU_DEVICE_GP_ISL, /* ISL */ + IPU_DEVICE_GP_NUM_GP +}; + +enum ipu_device_gp_psa_mux_id { + /* Post RYNR/CCN: 0-To ACM (Video), 1-To Demosaic (Stills)*/ + IPU_DEVICE_GP_PSA_STILLS_MODE_MUX = 0, + /* Post Vec2Str 4: 0-To GTC, 1-To ACM */ + IPU_DEVICE_GP_PSA_V2S_RGB_4_DEMUX, + /* Post DM and pre ACM 0-CCM/ACM: 1-DM Component Splitter */ + IPU_DEVICE_GP_PSA_S2V_RGB_F_MUX, + /* Pre ACM/CCM: 0-To CCM/ACM, 1-To str2vec id_f */ + IPU_DEVICE_GP_PSA_ACM_DEMUX, + IPU_DEVICE_GP_PSA_MUX_NUM_MUX +}; + +enum ipu_device_gp_isa_static_mux_id { + IPU_DEVICE_GP_ISA_STATIC_MUX_SEL = 0, + IPU_DEVICE_GP_ISA_STATIC_PORTA_BLK, + IPU_DEVICE_GP_ISA_STATIC_PORTB_BLK, + IPU_DEVICE_GP_ISA_STATIC_PORTC_BLK, + IPU_DEVICE_GP_ISA_STATIC_AWB_MUX_SEL, + IPU_DEVICE_GP_ISA_STATIC_AWB_MUX_INPUT_CORR_PORT_BLK, + IPU_DEVICE_GP_ISA_STATIC_AWB_MUX_DPC_PORT_BLK, + IPU_DEVICE_GP_ISA_STATIC_MUX_NUM_MUX +}; + +enum ipu_device_gp_isa_runtime_mux_id { + IPU_DEVICE_GP_ISA_RUNTIME_FRAME_SIZE = 0, + IPU_DEVICE_GP_ISA_RUNTIME_SCALED_FRAME_SIZE, + IPU_DEVICE_GP_ISA_RUNTIME_MUX_NUM_MUX +}; + +enum ipu_device_gp_isl_mux_id { + IPU_DEVICE_GP_ISL_MIPI_BE_MUX = 0, + IPU_DEVICE_GP_ISL_MUX_NUM_MUX +}; + +#define IPU_DEVICE_GP_MAX_NUM MAX4((uint32_t)IPU_DEVICE_GP_PSA_MUX_NUM_MUX, \ + (uint32_t)IPU_DEVICE_GP_ISA_STATIC_MUX_NUM_MUX, \ + (uint32_t)IPU_DEVICE_GP_ISA_RUNTIME_MUX_NUM_MUX, \ + (uint32_t)IPU_DEVICE_GP_ISL_MUX_NUM_MUX) + +#endif /* __IPU_DEVICE_GP_DEVICES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_isp2600_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_isp2600_properties_impl.h new file mode 100644 index 0000000000000..de733be679986 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_isp2600_properties_impl.h @@ -0,0 +1,151 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_ISP2600_PROPERTIES_IMPL_H +#define __IPU_DEVICE_ISP2600_PROPERTIES_IMPL_H + +/* isp2600 definition */ + +#include "ipu_device_cell_properties_struct.h" + +enum ipu_device_isp2600_registers { + /* control registers */ + IPU_DEVICE_ISP2600_STAT_CTRL = 0x0, + IPU_DEVICE_ISP2600_START_PC = 0x4, + + /* master port registers */ + IPU_DEVICE_ISP2600_ICACHE_BASE = 0x10, + IPU_DEVICE_ISP2600_ICACHE_INFO = 0x14, + IPU_DEVICE_ISP2600_ICACHE_INFO_OVERRIDE = 0x18, + + IPU_DEVICE_ISP2600_QMEM_BASE = 0x1C, + + IPU_DEVICE_ISP2600_CMEM_BASE = 0x28, + + IPU_DEVICE_ISP2600_XMEM_BASE = 0x88, + IPU_DEVICE_ISP2600_XMEM_INFO = 0x8C, + IPU_DEVICE_ISP2600_XMEM_INFO_OVERRIDE = 0x90, + + IPU_DEVICE_ISP2600_XVMEM_BASE = 0xB8, + + /* debug registers */ + IPU_DEVICE_ISP2600_DEBUG_PC = 0x130, + IPU_DEVICE_ISP2600_STALL = 0x134 +}; + + +enum ipu_device_isp2600_memories { + IPU_DEVICE_ISP2600_REGS, + IPU_DEVICE_ISP2600_PMEM, + IPU_DEVICE_ISP2600_DMEM, + IPU_DEVICE_ISP2600_BAMEM, + IPU_DEVICE_ISP2600_VMEM, + IPU_DEVICE_ISP2600_NUM_MEMORIES +}; + +static const unsigned int +ipu_device_isp2600_mem_size[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + 0x00140, + 0x14000, + 0x04000, + 0x20000, + 0x20000 +}; + + +enum ipu_device_isp2600_masters { + IPU_DEVICE_ISP2600_ICACHE, + IPU_DEVICE_ISP2600_QMEM, + IPU_DEVICE_ISP2600_CMEM, + IPU_DEVICE_ISP2600_XMEM, + IPU_DEVICE_ISP2600_XVMEM, + IPU_DEVICE_ISP2600_NUM_MASTERS +}; + +static const struct ipu_device_cell_master_properties_s +ipu_device_isp2600_masters[IPU_DEVICE_ISP2600_NUM_MASTERS] = { + { + 0, + 0xC, + IPU_DEVICE_ISP2600_ICACHE_BASE, + IPU_DEVICE_ISP2600_ICACHE_INFO, + IPU_DEVICE_ISP2600_ICACHE_INFO_OVERRIDE + }, + { + 0, + 0xC, + IPU_DEVICE_ISP2600_QMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 3, + 0xC, + IPU_DEVICE_ISP2600_CMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 2, + 0xC, + IPU_DEVICE_ISP2600_XMEM_BASE, + IPU_DEVICE_ISP2600_XMEM_INFO, + IPU_DEVICE_ISP2600_XMEM_INFO_OVERRIDE + }, + { + 3, + 0xC, + IPU_DEVICE_ISP2600_XVMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + } +}; + +enum ipu_device_isp2600_stall_bits { + IPU_DEVICE_ISP2600_STALL_ICACHE0, + IPU_DEVICE_ISP2600_STALL_ICACHE1, + IPU_DEVICE_ISP2600_STALL_DMEM, + IPU_DEVICE_ISP2600_STALL_QMEM, + IPU_DEVICE_ISP2600_STALL_CMEM, + IPU_DEVICE_ISP2600_STALL_XMEM, + IPU_DEVICE_ISP2600_STALL_BAMEM, + IPU_DEVICE_ISP2600_STALL_VMEM, + IPU_DEVICE_ISP2600_STALL_XVMEM, + IPU_DEVICE_ISP2600_NUM_STALL_BITS +}; + +#define IPU_DEVICE_ISP2600_ICACHE_WORD_SIZE 64 /* 512 bits per instruction */ +#define IPU_DEVICE_ISP2600_ICACHE_BURST_SIZE 8 /* 8 instructions per burst */ + +static const struct ipu_device_cell_count_s ipu_device_isp2600_count = { + IPU_DEVICE_ISP2600_NUM_MEMORIES, + IPU_DEVICE_ISP2600_NUM_MASTERS, + IPU_DEVICE_ISP2600_NUM_STALL_BITS, + IPU_DEVICE_ISP2600_ICACHE_WORD_SIZE * + IPU_DEVICE_ISP2600_ICACHE_BURST_SIZE +}; + +static const unsigned int ipu_device_isp2600_reg_offset[/* CELL_NUM_REGS */] = { + 0x0, 0x4, 0x10, 0x130, 0x134 +}; + +static const struct ipu_device_cell_type_properties_s +ipu_device_isp2600_properties = { + &ipu_device_isp2600_count, + ipu_device_isp2600_masters, + ipu_device_isp2600_reg_offset, + ipu_device_isp2600_mem_size +}; + +#endif /* __IPU_DEVICE_ISP2600_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_sp2600_control_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_sp2600_control_properties_impl.h new file mode 100644 index 0000000000000..430295cd9d949 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_sp2600_control_properties_impl.h @@ -0,0 +1,136 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H +#define __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H + +/* sp2600_control definition */ + +#include "ipu_device_cell_properties_struct.h" + +enum ipu_device_sp2600_control_registers { + /* control registers */ + IPU_DEVICE_SP2600_CONTROL_STAT_CTRL = 0x0, + IPU_DEVICE_SP2600_CONTROL_START_PC = 0x4, + + /* master port registers */ + IPU_DEVICE_SP2600_CONTROL_ICACHE_BASE = 0x10, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO = 0x14, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO_OVERRIDE = 0x18, + + IPU_DEVICE_SP2600_CONTROL_QMEM_BASE = 0x1C, + + IPU_DEVICE_SP2600_CONTROL_CMEM_BASE = 0x28, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO = 0x2C, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO_OVERRIDE = 0x30, + + IPU_DEVICE_SP2600_CONTROL_XMEM_BASE = 0x58, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO = 0x5C, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO_OVERRIDE = 0x60, + + /* debug registers */ + IPU_DEVICE_SP2600_CONTROL_DEBUG_PC = 0x9C, + IPU_DEVICE_SP2600_CONTROL_STALL = 0xA0 +}; + +enum ipu_device_sp2600_control_mems { + IPU_DEVICE_SP2600_CONTROL_REGS, + IPU_DEVICE_SP2600_CONTROL_PMEM, + IPU_DEVICE_SP2600_CONTROL_DMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES +}; + +static const unsigned int +ipu_device_sp2600_control_mem_size[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + 0x000AC, + 0x00000, + 0x10000 +}; + +enum ipu_device_sp2600_control_masters { + IPU_DEVICE_SP2600_CONTROL_ICACHE, + IPU_DEVICE_SP2600_CONTROL_QMEM, + IPU_DEVICE_SP2600_CONTROL_CMEM, + IPU_DEVICE_SP2600_CONTROL_XMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS +}; + +static const struct ipu_device_cell_master_properties_s +ipu_device_sp2600_control_masters[IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS] = { + { + 0, + 0xC, + IPU_DEVICE_SP2600_CONTROL_ICACHE_BASE, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO_OVERRIDE + }, + { + 0, + 0xC, + IPU_DEVICE_SP2600_CONTROL_QMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_CONTROL_CMEM_BASE, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO_OVERRIDE + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_CONTROL_XMEM_BASE, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO_OVERRIDE + } +}; + +enum ipu_device_sp2600_control_stall_bits { + IPU_DEVICE_SP2600_CONTROL_STALL_ICACHE, + IPU_DEVICE_SP2600_CONTROL_STALL_DMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_QMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_CMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_XMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_STALL_BITS +}; + +/* 32 bits per instruction */ +#define IPU_DEVICE_SP2600_CONTROL_ICACHE_WORD_SIZE 4 +/* 32 instructions per burst */ +#define IPU_DEVICE_SP2600_CONTROL_ICACHE_BURST_SIZE 32 + +static const struct ipu_device_cell_count_s ipu_device_sp2600_control_count = { + IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES, + IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS, + IPU_DEVICE_SP2600_CONTROL_NUM_STALL_BITS, + IPU_DEVICE_SP2600_CONTROL_ICACHE_WORD_SIZE * + IPU_DEVICE_SP2600_CONTROL_ICACHE_BURST_SIZE +}; + +static const unsigned int +ipu_device_sp2600_control_reg_offset[/* CELL_NUM_REGS */] = { + 0x0, 0x4, 0x10, 0x9C, 0xA0 +}; + +static const struct ipu_device_cell_type_properties_s +ipu_device_sp2600_control_properties = { + &ipu_device_sp2600_control_count, + ipu_device_sp2600_control_masters, + ipu_device_sp2600_control_reg_offset, + ipu_device_sp2600_control_mem_size +}; + +#endif /* __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_sp2600_fp_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_sp2600_fp_properties_impl.h new file mode 100644 index 0000000000000..b3f120f9fea86 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_sp2600_fp_properties_impl.h @@ -0,0 +1,140 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_SP2600_FP_PROPERTIES_IMPL_H +#define __IPU_DEVICE_SP2600_FP_PROPERTIES_IMPL_H + +/* sp2600_fp definition */ + +#include "ipu_device_cell_properties_struct.h" + +enum ipu_device_sp2600_fp_registers { + /* control registers */ + IPU_DEVICE_SP2600_FP_STAT_CTRL = 0x0, + IPU_DEVICE_SP2600_FP_START_PC = 0x4, + + /* master port registers */ + IPU_DEVICE_SP2600_FP_ICACHE_BASE = 0x10, + IPU_DEVICE_SP2600_FP_ICACHE_INFO = 0x14, + IPU_DEVICE_SP2600_FP_ICACHE_INFO_OVERRIDE = 0x18, + + IPU_DEVICE_SP2600_FP_QMEM_BASE = 0x1C, + + IPU_DEVICE_SP2600_FP_CMEM_BASE = 0x28, + IPU_DEVICE_SP2600_FP_CMEM_INFO = 0x2C, + IPU_DEVICE_SP2600_FP_CMEM_INFO_OVERRIDE = 0x30, + + IPU_DEVICE_SP2600_FP_XMEM_BASE = 0x88, + IPU_DEVICE_SP2600_FP_XMEM_INFO = 0x8C, + IPU_DEVICE_SP2600_FP_XMEM_INFO_OVERRIDE = 0x90, + + /* debug registers */ + IPU_DEVICE_SP2600_FP_DEBUG_PC = 0xCC, + IPU_DEVICE_SP2600_FP_STALL = 0xD0 +}; + + +enum ipu_device_sp2600_fp_memories { + IPU_DEVICE_SP2600_FP_REGS, + IPU_DEVICE_SP2600_FP_PMEM, + IPU_DEVICE_SP2600_FP_DMEM, + IPU_DEVICE_SP2600_FP_DMEM1, + IPU_DEVICE_SP2600_FP_NUM_MEMORIES +}; + +static const unsigned int +ipu_device_sp2600_fp_mem_size[IPU_DEVICE_SP2600_FP_NUM_MEMORIES] = { + 0x000DC, + 0x00000, + 0x10000, + 0x08000 +}; + +enum ipu_device_sp2600_fp_masters { + IPU_DEVICE_SP2600_FP_ICACHE, + IPU_DEVICE_SP2600_FP_QMEM, + IPU_DEVICE_SP2600_FP_CMEM, + IPU_DEVICE_SP2600_FP_XMEM, + IPU_DEVICE_SP2600_FP_NUM_MASTERS +}; + +static const struct ipu_device_cell_master_properties_s +ipu_device_sp2600_fp_masters[IPU_DEVICE_SP2600_FP_NUM_MASTERS] = { + { + 0, + 0xC, + IPU_DEVICE_SP2600_FP_ICACHE_BASE, + IPU_DEVICE_SP2600_FP_ICACHE_INFO, + IPU_DEVICE_SP2600_FP_ICACHE_INFO_OVERRIDE + }, + { + 0, + 0xC, + IPU_DEVICE_SP2600_FP_QMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 3, + 0xC, + IPU_DEVICE_SP2600_FP_CMEM_BASE, + IPU_DEVICE_SP2600_FP_CMEM_INFO, + IPU_DEVICE_SP2600_FP_CMEM_INFO_OVERRIDE + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_FP_XMEM_BASE, + IPU_DEVICE_SP2600_FP_XMEM_INFO, + IPU_DEVICE_SP2600_FP_XMEM_INFO_OVERRIDE + } +}; + +enum ipu_device_sp2600_fp_stall_bits { + IPU_DEVICE_SP2600_FP_STALL_ICACHE, + IPU_DEVICE_SP2600_FP_STALL_DMEM, + IPU_DEVICE_SP2600_FP_STALL_QMEM, + IPU_DEVICE_SP2600_FP_STALL_CMEM, + IPU_DEVICE_SP2600_FP_STALL_XMEM, + IPU_DEVICE_SP2600_FP_STALL_DMEM1, + IPU_DEVICE_SP2600_FP_NUM_STALL_BITS +}; + +/* 32 bits per instruction */ +#define IPU_DEVICE_SP2600_FP_ICACHE_WORD_SIZE 4 +/* 32 instructions per burst */ +#define IPU_DEVICE_SP2600_FP_ICACHE_BURST_SIZE 32 + +static const struct ipu_device_cell_count_s ipu_device_sp2600_fp_count = { + IPU_DEVICE_SP2600_FP_NUM_MEMORIES, + IPU_DEVICE_SP2600_FP_NUM_MASTERS, + IPU_DEVICE_SP2600_FP_NUM_STALL_BITS, + IPU_DEVICE_SP2600_FP_ICACHE_WORD_SIZE * + IPU_DEVICE_SP2600_FP_ICACHE_BURST_SIZE +}; + +static const unsigned int +ipu_device_sp2600_fp_reg_offset[/* CELL_NUM_REGS */] = { + 0x0, 0x4, 0x10, 0x9C, 0xA0 +}; + +static const struct ipu_device_cell_type_properties_s +ipu_device_sp2600_fp_properties = { + &ipu_device_sp2600_fp_count, + ipu_device_sp2600_fp_masters, + ipu_device_sp2600_fp_reg_offset, + ipu_device_sp2600_fp_mem_size +}; + +#endif /* __IPU_DEVICE_SP2600_FP_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_sp2600_proxy_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_sp2600_proxy_properties_impl.h new file mode 100644 index 0000000000000..6fdcd7faea9b8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/devices/src/ipu_device_sp2600_proxy_properties_impl.h @@ -0,0 +1,138 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_SP2600_PROXY_PROPERTIES_IMPL_H +#define __IPU_DEVICE_SP2600_PROXY_PROPERTIES_IMPL_H + +/* sp2600_proxy definition */ + +#include "ipu_device_cell_properties_struct.h" + +enum ipu_device_sp2600_proxy_registers { + /* control registers */ + IPU_DEVICE_SP2600_PROXY_STAT_CTRL = 0x0, + IPU_DEVICE_SP2600_PROXY_START_PC = 0x4, + + /* THESE ADDRESSES NEED TO BE CHECKED !!!! */ + /* master port registers */ + IPU_DEVICE_SP2600_PROXY_ICACHE_BASE = 0x10, + IPU_DEVICE_SP2600_PROXY_ICACHE_INFO = 0x14, + IPU_DEVICE_SP2600_PROXY_ICACHE_INFO_OVERRIDE = 0x18, + + IPU_DEVICE_SP2600_PROXY_QMEM_BASE = 0x1C, + + IPU_DEVICE_SP2600_PROXY_CMEM_BASE = 0x28, + IPU_DEVICE_SP2600_PROXY_CMEM_INFO = 0x2C, + IPU_DEVICE_SP2600_PROXY_CMEM_INFO_OVERRIDE = 0x30, + + IPU_DEVICE_SP2600_PROXY_XMEM_BASE = 0x58, + IPU_DEVICE_SP2600_PROXY_XMEM_INFO = 0x5C, + IPU_DEVICE_SP2600_PROXY_XMEM_INFO_OVERRIDE = 0x60, + + /* debug registers */ + IPU_DEVICE_SP2600_PROXY_DEBUG_PC = 0x9C, + IPU_DEVICE_SP2600_PROXY_STALL = 0xA0 +}; + + +enum ipu_device_sp2600_proxy_memories { + IPU_DEVICE_SP2600_PROXY_REGS, + IPU_DEVICE_SP2600_PROXY_PMEM, + IPU_DEVICE_SP2600_PROXY_DMEM, + IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES +}; + +static const unsigned int +ipu_device_sp2600_proxy_mem_size[IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES] = { + 0x00AC, + 0x0000, + 0x4000 +}; + +enum ipu_device_sp2600_proxy_masters { + IPU_DEVICE_SP2600_PROXY_ICACHE, + IPU_DEVICE_SP2600_PROXY_QMEM, + IPU_DEVICE_SP2600_PROXY_CMEM, + IPU_DEVICE_SP2600_PROXY_XMEM, + IPU_DEVICE_SP2600_PROXY_NUM_MASTERS +}; + +static const struct ipu_device_cell_master_properties_s +ipu_device_sp2600_proxy_masters[IPU_DEVICE_SP2600_PROXY_NUM_MASTERS] = { + { + 0, + 0xC, + IPU_DEVICE_SP2600_PROXY_ICACHE_BASE, + IPU_DEVICE_SP2600_PROXY_ICACHE_INFO, + IPU_DEVICE_SP2600_PROXY_ICACHE_INFO_OVERRIDE + }, + { + 0, + 0xC, + IPU_DEVICE_SP2600_PROXY_QMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_PROXY_CMEM_BASE, + IPU_DEVICE_SP2600_PROXY_CMEM_INFO, + IPU_DEVICE_SP2600_PROXY_CMEM_INFO_OVERRIDE + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_PROXY_XMEM_BASE, + IPU_DEVICE_SP2600_PROXY_XMEM_INFO, + IPU_DEVICE_SP2600_PROXY_XMEM_INFO_OVERRIDE + } +}; + +enum ipu_device_sp2600_proxy_stall_bits { + IPU_DEVICE_SP2600_PROXY_STALL_ICACHE, + IPU_DEVICE_SP2600_PROXY_STALL_DMEM, + IPU_DEVICE_SP2600_PROXY_STALL_QMEM, + IPU_DEVICE_SP2600_PROXY_STALL_CMEM, + IPU_DEVICE_SP2600_PROXY_STALL_XMEM, + IPU_DEVICE_SP2600_PROXY_NUM_STALL_BITS +}; + +/* 32 bits per instruction */ +#define IPU_DEVICE_SP2600_PROXY_ICACHE_WORD_SIZE 4 +/* 32 instructions per burst */ +#define IPU_DEVICE_SP2600_PROXY_ICACHE_BURST_SIZE 32 + +static const struct ipu_device_cell_count_s ipu_device_sp2600_proxy_count = { + IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES, + IPU_DEVICE_SP2600_PROXY_NUM_MASTERS, + IPU_DEVICE_SP2600_PROXY_NUM_STALL_BITS, + IPU_DEVICE_SP2600_PROXY_ICACHE_WORD_SIZE * + IPU_DEVICE_SP2600_PROXY_ICACHE_BURST_SIZE +}; + +static const unsigned int +ipu_device_sp2600_proxy_reg_offset[/* CELL_NUM_REGS */] = { + 0x0, 0x4, 0x10, 0xCC, 0xD0 +}; + +static const struct ipu_device_cell_type_properties_s +ipu_device_sp2600_proxy_properties = { + &ipu_device_sp2600_proxy_count, + ipu_device_sp2600_proxy_masters, + ipu_device_sp2600_proxy_reg_offset, + ipu_device_sp2600_proxy_mem_size +}; + +#endif /* __IPU_DEVICE_SP2600_PROXY_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/cpu/fw_abi_cpu_types.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/cpu/fw_abi_cpu_types.mk new file mode 100644 index 0000000000000..b1ffbf7ea21ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/cpu/fw_abi_cpu_types.mk @@ -0,0 +1,24 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +# MODULE is FW ABI COMMON TYPES + +FW_ABI_COMMON_TYPES_DIRS = -I$${MODULES_DIR}/fw_abi_common_types +FW_ABI_COMMON_TYPES_DIRS += -I$${MODULES_DIR}/fw_abi_common_types/cpu + +FW_ABI_COMMON_TYPES_HOST_FILES = +FW_ABI_COMMON_TYPES_HOST_CPPFLAGS = $(FW_ABI_COMMON_TYPES_DIRS) + +FW_ABI_COMMON_TYPES_FW_FILES = +FW_ABI_COMMON_TYPES_FW_CPPFLAGS = $(FW_ABI_COMMON_TYPES_DIRS) diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_base_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_base_types.h new file mode 100644 index 0000000000000..21cc3f43f485e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_base_types.h @@ -0,0 +1,42 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_BASE_TYPES_H +#define __IA_CSS_TERMINAL_BASE_TYPES_H + + +#include "type_support.h" +#include "ia_css_terminal_defs.h" + +#define N_UINT16_IN_TERMINAL_STRUCT 3 +#define N_PADDING_UINT8_IN_TERMINAL_STRUCT 5 + +#define SIZE_OF_TERMINAL_STRUCT_BITS \ + (IA_CSS_TERMINAL_TYPE_BITS \ + + IA_CSS_TERMINAL_ID_BITS \ + + N_UINT16_IN_TERMINAL_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_IN_TERMINAL_STRUCT * IA_CSS_UINT8_T_BITS) + +/* ==================== Base Terminal - START ==================== */ +struct ia_css_terminal_s { /**< Base terminal */ + ia_css_terminal_type_t terminal_type; /**< Type ia_css_terminal_type_t */ + int16_t parent_offset; /**< Offset to the process group */ + uint16_t size; /**< Size of this whole terminal layout-structure */ + uint16_t tm_index; /**< Index of the terminal manifest object */ + ia_css_terminal_ID_t ID; /**< Absolute referal ID for this terminal, valid ID's != 0 */ + uint8_t padding[N_PADDING_UINT8_IN_TERMINAL_STRUCT]; +}; +/* ==================== Base Terminal - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h new file mode 100644 index 0000000000000..056e1b6d5d4bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h @@ -0,0 +1,42 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H +#define __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H + +#include "ia_css_terminal_defs.h" + +#define N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT 5 +#define SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + (IA_CSS_UINT16_T_BITS \ + + IA_CSS_TERMINAL_ID_BITS \ + + IA_CSS_TERMINAL_TYPE_BITS \ + + IA_CSS_UINT32_T_BITS \ + + (N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT*IA_CSS_UINT8_T_BITS)) + +/* ==================== Base Terminal Manifest - START ==================== */ +struct ia_css_terminal_manifest_s { + ia_css_terminal_type_t terminal_type; /**< Type ia_css_terminal_type_t */ + int16_t parent_offset; /**< Offset to the program group manifest */ + uint16_t size; /**< Size of this whole terminal-manifest layout-structure */ + ia_css_terminal_ID_t ID; + uint8_t padding[N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT]; +}; + +typedef struct ia_css_terminal_manifest_s + ia_css_terminal_manifest_t; + +/* ==================== Base Terminal Manifest - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/ia_css_base_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/ia_css_base_types.h new file mode 100644 index 0000000000000..3b80a17a6ad38 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/ia_css_base_types.h @@ -0,0 +1,38 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BASE_TYPES_H +#define __IA_CSS_BASE_TYPES_H + +#include "type_support.h" + +#define VIED_VADDRESS_BITS 32 +typedef uint32_t vied_vaddress_t; + +#define DEVICE_DESCRIPTOR_ID_BITS 32 +typedef struct { + uint8_t device_id; + uint8_t instance_id; + uint8_t channel_id; + uint8_t section_id; +} device_descriptor_fields_t; + +typedef union { + device_descriptor_fields_t fields; + uint32_t data; +} device_descriptor_id_t; + +typedef uint16_t ia_css_process_id_t; + +#endif /* __IA_CSS_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/ia_css_terminal_defs.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/ia_css_terminal_defs.h new file mode 100644 index 0000000000000..dbf1cf93756ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/fw_abi_common_types/ia_css_terminal_defs.h @@ -0,0 +1,105 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_DEFS_H +#define __IA_CSS_TERMINAL_DEFS_H + + +#include "type_support.h" + +#define IA_CSS_TERMINAL_ID_BITS 8 +typedef uint8_t ia_css_terminal_ID_t; +#define IA_CSS_TERMINAL_INVALID_ID ((ia_css_terminal_ID_t)(-1)) + +/* + * Terminal Base Type + */ +typedef enum ia_css_terminal_type { + /**< Data input */ + IA_CSS_TERMINAL_TYPE_DATA_IN = 0, + /**< Data output */ + IA_CSS_TERMINAL_TYPE_DATA_OUT, + /**< Type 6 parameter input */ + IA_CSS_TERMINAL_TYPE_PARAM_STREAM, + /**< Type 1-5 parameter input */ + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN, + /**< Type 1-5 parameter output */ + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT, + /**< Represent the new type of terminal for the + * "spatial dependent parameters", when params go in + */ + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN, + /**< Represent the new type of terminal for the + * "spatial dependent parameters", when params go out + */ + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT, + /**< Represent the new type of terminal for the + * explicit slicing, when params go in + */ + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN, + /**< Represent the new type of terminal for the + * explicit slicing, when params go out + */ + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT, + /**< State (private data) input */ + IA_CSS_TERMINAL_TYPE_STATE_IN, + /**< State (private data) output */ + IA_CSS_TERMINAL_TYPE_STATE_OUT, + IA_CSS_TERMINAL_TYPE_PROGRAM, + IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT, + IA_CSS_N_TERMINAL_TYPES +} ia_css_terminal_type_t; + +#define IA_CSS_TERMINAL_TYPE_BITS 32 + +/* Temporary redirection needed to facilicate merging with the drivers + in a backwards compatible manner */ +#define IA_CSS_TERMINAL_TYPE_PARAM_CACHED IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN + +/* + * Dimensions of the data objects. Note that a C-style + * data order is assumed. Data stored by row. + */ +typedef enum ia_css_dimension { + /**< The number of columns, i.e. the size of the row */ + IA_CSS_COL_DIMENSION = 0, + /**< The number of rows, i.e. the size of the column */ + IA_CSS_ROW_DIMENSION = 1, + IA_CSS_N_DATA_DIMENSION = 2 +} ia_css_dimension_t; + +#define IA_CSS_N_COMMAND_COUNT (4) + +#ifndef PIPE_GENERATION +/* Don't include these complex enum structures in Genpipe, it can't handle and it does not need them */ +/* + * enum ia_css_isys_link_id. Lists the link IDs used by the FW for On The Fly feature + */ +typedef enum ia_css_isys_link_id { + IA_CSS_ISYS_LINK_OFFLINE = 0, + IA_CSS_ISYS_LINK_MAIN_OUTPUT = 1, + IA_CSS_ISYS_LINK_PDAF_OUTPUT = 2 +} ia_css_isys_link_id_t; +#define N_IA_CSS_ISYS_LINK_ID (IA_CSS_ISYS_LINK_PDAF_OUTPUT + 1) + +/* + * enum ia_css_data_barrier_link_id. Lists the link IDs used by the FW for data barrier feature + */ +typedef enum ia_css_data_barrier_link_id { + IA_CSS_DATA_BARRIER_LINK_MEMORY = N_IA_CSS_ISYS_LINK_ID, + N_IA_CSS_DATA_BARRIER_LINK_ID +} ia_css_data_barrier_link_id_t; + +#endif /* #ifndef PIPE_GENERATION */ +#endif /* __IA_CSS_TERMINAL_DEFS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir.h new file mode 100644 index 0000000000000..a284d74bb4a67 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir.h @@ -0,0 +1,99 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_H +#define __IA_CSS_PKG_DIR_H + +#include "ia_css_pkg_dir_storage_class.h" +#include "ia_css_pkg_dir_types.h" +#include "type_support.h" + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +const ia_css_pkg_dir_entry_t *ia_css_pkg_dir_get_entry( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index +); + +/* User is expected to call the verify function manually, + * other functions do not call it internally + */ +IA_CSS_PKG_DIR_STORAGE_CLASS_H +int ia_css_pkg_dir_verify_header( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_get_num_entries( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_get_size_in_bytes( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +enum ia_css_pkg_dir_version ia_css_pkg_dir_get_version( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint16_t ia_css_pkg_dir_set_version( + ia_css_pkg_dir_entry_t *pkg_dir_header, + enum ia_css_pkg_dir_version version +); + + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_address_lo( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_address_hi( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_size( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint16_t ia_css_pkg_dir_entry_get_version( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint8_t ia_css_pkg_dir_entry_get_type( + const ia_css_pkg_dir_entry_t *entry +); + +/* Get the address of the specified entry in the PKG_DIR + * Note: This function expects the complete PKG_DIR in the same memory space + * and the entries contains offsets and not addresses. + */ +IA_CSS_PKG_DIR_STORAGE_CLASS_H +void *ia_css_pkg_dir_get_entry_address( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index +); + +#ifdef __IA_CSS_PKG_DIR_INLINE__ + +#include "ia_css_pkg_dir_impl.h" + +#endif + +#endif /* __IA_CSS_PKG_DIR_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_iunit.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_iunit.h new file mode 100644 index 0000000000000..ad194b0389eb7 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_iunit.h @@ -0,0 +1,46 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_IUNIT_H +#define __IA_CSS_PKG_DIR_IUNIT_H + +/* In bootflow, pkg_dir only supports upto 16 entries in pkg_dir + * pkg_dir_header + Psys_server pg + Isys_server pg + 13 Client pg + */ + +enum { + IA_CSS_PKG_DIR_SIZE = 16, + IA_CSS_PKG_DIR_ENTRIES = IA_CSS_PKG_DIR_SIZE - 1 +}; + +#define IUNIT_MAX_CLIENT_PKG_ENTRIES 13 + +/* Example assignment of unique identifiers for the FW components + * This should match the identifiers in the manifest + */ +enum ia_css_pkg_dir_entry_type { + IA_CSS_PKG_DIR_HEADER = 0, + IA_CSS_PKG_DIR_PSYS_SERVER_PG, + IA_CSS_PKG_DIR_ISYS_SERVER_PG, + IA_CSS_PKG_DIR_CLIENT_PG +}; + +/* Fixed entries in the package directory */ +enum ia_css_pkg_dir_index { + IA_CSS_PKG_DIR_PSYS_INDEX = 0, + IA_CSS_PKG_DIR_ISYS_INDEX = 1, + IA_CSS_PKG_DIR_CLIENT_0 = 2 +}; + +#endif /* __IA_CSS_PKG_DIR_IUNIT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_storage_class.h new file mode 100644 index 0000000000000..cb64172151f92 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_storage_class.h @@ -0,0 +1,29 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_STORAGE_CLASS_H +#define __IA_CSS_PKG_DIR_STORAGE_CLASS_H + + +#include "storage_class.h" + +#ifndef __IA_CSS_PKG_DIR_INLINE__ +#define IA_CSS_PKG_DIR_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PKG_DIR_STORAGE_CLASS_C +#else +#define IA_CSS_PKG_DIR_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PKG_DIR_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PKG_DIR_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_types.h new file mode 100644 index 0000000000000..b024b3da2f9e6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_types.h @@ -0,0 +1,41 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_TYPES_H +#define __IA_CSS_PKG_DIR_TYPES_H + +#include "type_support.h" + +struct ia_css_pkg_dir_entry { + uint32_t address[2]; + uint32_t size; + uint16_t version; + uint8_t type; + uint8_t unused; +}; + +typedef void ia_css_pkg_dir_t; +typedef struct ia_css_pkg_dir_entry ia_css_pkg_dir_entry_t; + +/* The version field of the pkg_dir header defines + * if entries contain offsets or pointers + */ +/* This is temporary, until all pkg_dirs use pointers */ +enum ia_css_pkg_dir_version { + IA_CSS_PKG_DIR_POINTER, + IA_CSS_PKG_DIR_OFFSET +}; + + +#endif /* __IA_CSS_PKG_DIR_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/pkg_dir.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/pkg_dir.mk new file mode 100644 index 0000000000000..32c8a68f3653c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/pkg_dir.mk @@ -0,0 +1,29 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PKG DIR + +PKG_DIR_DIR = $${MODULES_DIR}/pkg_dir +PKG_DIR_INTERFACE = $(PKG_DIR_DIR)/interface +PKG_DIR_SOURCES = $(PKG_DIR_DIR)/src + +PKG_DIR_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir.c +PKG_DIR_CPPFLAGS = -I$(PKG_DIR_INTERFACE) +PKG_DIR_CPPFLAGS += -I$(PKG_DIR_SOURCES) +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/../isp/kernels/io_ls/common +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/fw_abi_common_types/ipu +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/fw_abi_common_types/ipu/$(FW_ABI_IPU_TYPES_VERSION) + +PKG_DIR_CREATE_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir_create.c +PKG_DIR_UPDATE_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir_update.c diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir.c new file mode 100644 index 0000000000000..348b56833e060 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir.c @@ -0,0 +1,27 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifdef __IA_CSS_PKG_DIR_INLINE__ + +#include "storage_class.h" + +STORAGE_CLASS_INLINE int __ia_css_pkg_dir_avoid_warning_on_empty_file(void) +{ + return 0; +} + +#else +#include "ia_css_pkg_dir_impl.h" + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_impl.h new file mode 100644 index 0000000000000..d5067d21398f9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_impl.h @@ -0,0 +1,201 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_IMPL_H +#define __IA_CSS_PKG_DIR_IMPL_H + +#include "ia_css_pkg_dir.h" +#include "ia_css_pkg_dir_int.h" +#include "error_support.h" +#include "type_support.h" +#include "assert_support.h" + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +const ia_css_pkg_dir_entry_t *ia_css_pkg_dir_get_entry( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index) +{ + DECLARE_ERRVAL + struct ia_css_pkg_dir_entry *pkg_dir_header = NULL; + + verifexitval(pkg_dir != NULL, EFAULT); + + pkg_dir_header = (struct ia_css_pkg_dir_entry *)pkg_dir; + + /* First entry of the structure is the header, skip that */ + index++; + verifexitval(index < pkg_dir_header->size, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + return NULL; + } + return &(pkg_dir_header[index]); +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +int ia_css_pkg_dir_verify_header(const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + verifexitval(pkg_dir_header != NULL, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + return -1; + } + return ((pkg_dir_header->address[0] == PKG_DIR_MAGIC_VAL_0) + && (pkg_dir_header->address[1] == PKG_DIR_MAGIC_VAL_1)) ? + 0 : -1; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_get_num_entries( + const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + uint32_t size = 0; + + verifexitval(pkg_dir_header != NULL, EFAULT); + size = pkg_dir_header->size; + verifexitval(size > 0, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return size - 1; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +enum ia_css_pkg_dir_version +ia_css_pkg_dir_get_version(const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + assert(pkg_dir_header != NULL); + return pkg_dir_header->version; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint16_t ia_css_pkg_dir_set_version(ia_css_pkg_dir_entry_t *pkg_dir_header, + enum ia_css_pkg_dir_version version) +{ + DECLARE_ERRVAL + + verifexitval(pkg_dir_header != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 1; + } + pkg_dir_header->version = version; + return 0; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_get_size_in_bytes( + const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + + verifexitval(pkg_dir_header != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return sizeof(struct ia_css_pkg_dir_entry) * pkg_dir_header->size; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_address_lo( + const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->address[0]; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_address_hi( + const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->address[1]; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_size(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->size; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint16_t ia_css_pkg_dir_entry_get_version(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->version; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint8_t ia_css_pkg_dir_entry_get_type(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->type; +} + + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +void *ia_css_pkg_dir_get_entry_address(const ia_css_pkg_dir_t *pkg_dir, + uint32_t index) +{ + void *entry_blob = NULL; + const ia_css_pkg_dir_entry_t *pkg_dir_entry = + ia_css_pkg_dir_get_entry(pkg_dir, index-1); + + if ((pkg_dir_entry != NULL) && + (ia_css_pkg_dir_entry_get_size(pkg_dir_entry) > 0)) { + assert(ia_css_pkg_dir_entry_get_address_hi(pkg_dir_entry) == 0); + entry_blob = (void *)((char *)pkg_dir + + ia_css_pkg_dir_entry_get_address_lo(pkg_dir_entry)); + } + return entry_blob; +} + +#endif /* __IA_CSS_PKG_DIR_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_int.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_int.h new file mode 100644 index 0000000000000..203505fbee54e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_int.h @@ -0,0 +1,49 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_INT_H +#define __IA_CSS_PKG_DIR_INT_H + +/* + * Package Dir structure as specified in CSE FAS + * + * PKG DIR Header + * Qword 63:56 55 54:48 47:32 31:24 23:0 + * 0 "_IUPKDR_" + * 1 Rsvd Rsvd Type Version Rsvd Size + * + * Version: Version of the Structure + * Size: Size of the entire table (including header) in 16 byte chunks + * Type: Must be 0 for header + * + * Figure 13: PKG DIR Header + * + * + * PKG DIR Entry + * Qword 63:56 55 54:48 47:32 31:24 23:0 + * N Address/Offset + * N+1 Rsvd Rsvd Type Version Rsvd Size + * + * Version: Version # of the Component + * Size: Size of the component in bytes + * Type: Component Identifier + */ + +#define PKG_DIR_SIZE_BITS 24 +#define PKG_DIR_TYPE_BITS 7 + +#define PKG_DIR_MAGIC_VAL_1 (('_' << 24) | ('I' << 16) | ('U' << 8) | 'P') +#define PKG_DIR_MAGIC_VAL_0 (('K' << 24) | ('D' << 16) | ('R' << 8) | '_') + +#endif /* __IA_CSS_PKG_DIR_INT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/port_env_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/port_env_struct.h new file mode 100644 index 0000000000000..4d39a4739a8b0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/port_env_struct.h @@ -0,0 +1,24 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PORT_ENV_STRUCT_H +#define __PORT_ENV_STRUCT_H + +struct port_env { + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; +}; + +#endif /* __PORT_ENV_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/queue.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/queue.h new file mode 100644 index 0000000000000..b233ab3baf014 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/queue.h @@ -0,0 +1,40 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __QUEUE_H +#define __QUEUE_H + +#include "queue_struct.h" +#include "port_env_struct.h" + +/* + * SYS queues are created by the host + * SYS queues cannot be accessed through the queue interface + * To send data into a queue a send_port must be opened. + * To receive data from a queue, a recv_port must be opened. + */ + +/* return required buffer size for queue */ +unsigned int +sys_queue_buf_size(unsigned int size, unsigned int token_size); + +/* + * initialize a queue that can hold at least 'size' tokens of + * 'token_size' bytes. + */ +void +sys_queue_init(struct sys_queue *q, unsigned int size, + unsigned int token_size, struct sys_queue_res *res); + +#endif /* __QUEUE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/queue_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/queue_struct.h new file mode 100644 index 0000000000000..ef48fcfded2b6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/queue_struct.h @@ -0,0 +1,47 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __QUEUE_STRUCT_H +#define __QUEUE_STRUCT_H + +/* queue description, shared between sender and receiver */ + +#include "type_support.h" + +#ifdef __VIED_CELL +typedef struct {uint32_t v[2]; } host_buffer_address_t; +#else +typedef uint64_t host_buffer_address_t; +#endif + +typedef uint32_t vied_buffer_address_t; + + +struct sys_queue { + host_buffer_address_t host_address; + vied_buffer_address_t vied_address; + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* reg no in subsystem's regmem */ + unsigned int rd_reg; + unsigned int _align; +}; + +struct sys_queue_res { + host_buffer_address_t host_address; + vied_buffer_address_t vied_address; + unsigned int reg; +}; + +#endif /* __QUEUE_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/recv_port.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/recv_port.h new file mode 100644 index 0000000000000..cce253b266687 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/recv_port.h @@ -0,0 +1,34 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __RECV_PORT_H +#define __RECV_PORT_H + + +struct recv_port; +struct sys_queue; +struct port_env; + +void +recv_port_open(struct recv_port *p, const struct sys_queue *q, + const struct port_env *env); + +unsigned int +recv_port_available(const struct recv_port *p); + +unsigned int +recv_port_transfer(const struct recv_port *p, void *data); + + +#endif /* __RECV_PORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/recv_port_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/recv_port_struct.h new file mode 100644 index 0000000000000..52ec563b13cf5 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/recv_port_struct.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __RECV_PORT_STRUCT_H +#define __RECV_PORT_STRUCT_H + +#include "buffer_type.h" + +struct recv_port { + buffer_address buffer; /* address of buffer in DDR */ + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* index of write pointer located in regmem */ + unsigned int rd_reg; /* index read pointer located in regmem */ + + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; /* address of memory containing regmem */ +}; + +#endif /* __RECV_PORT_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/send_port.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/send_port.h new file mode 100644 index 0000000000000..04a160f3f0199 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/send_port.h @@ -0,0 +1,52 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __SEND_PORT_H +#define __SEND_PORT_H + + +/* + * A send port can be used to send tokens into a queue. + * The interface can be used on any type of processor (host, SP, ...) + */ + +struct send_port; +struct sys_queue; +struct port_env; + +/* + * Open a send port on a queue. After the port is opened, tokens can be sent + */ +void +send_port_open(struct send_port *p, const struct sys_queue *q, + const struct port_env *env); + +/* + * Determine how many tokens can be sent + */ +unsigned int +send_port_available(const struct send_port *p); + +/* + * Send a token via a send port. The function returns the number of + * tokens that have been sent: + * 1: the token was accepted + * 0: the token was not accepted (full queue) + * The size of a token is determined at initialization. + */ +unsigned int +send_port_transfer(const struct send_port *p, const void *data); + + +#endif /* __SEND_PORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/send_port_struct.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/send_port_struct.h new file mode 100644 index 0000000000000..f834c62bc3db6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/interface/send_port_struct.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __SEND_PORT_STRUCT_H +#define __SEND_PORT_STRUCT_H + +#include "buffer_type.h" + +struct send_port { + buffer_address buffer; + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* index of write pointer in regmem */ + unsigned int rd_reg; /* index of read pointer in regmem */ + + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; +}; + +#endif /* __SEND_PORT_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/port.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/port.mk new file mode 100644 index 0000000000000..b3801247802e9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/port.mk @@ -0,0 +1,31 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PORT + +PORT_DIR=$${MODULES_DIR}/port + +PORT_INTERFACE=$(PORT_DIR)/interface +PORT_SOURCES1=$(PORT_DIR)/src + +PORT_HOST_FILES += $(PORT_SOURCES1)/send_port.c +PORT_HOST_FILES += $(PORT_SOURCES1)/recv_port.c +PORT_HOST_FILES += $(PORT_SOURCES1)/queue.c + +PORT_HOST_CPPFLAGS += -I$(PORT_INTERFACE) + +PORT_FW_FILES += $(PORT_SOURCES1)/send_port.c +PORT_FW_FILES += $(PORT_SOURCES1)/recv_port.c + +PORT_FW_CPPFLAGS += -I$(PORT_INTERFACE) diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/src/queue.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/src/queue.c new file mode 100644 index 0000000000000..eeec99dfe2d0d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/src/queue.c @@ -0,0 +1,47 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "queue.h" + +#include "regmem_access.h" +#include "port_env_struct.h" + +unsigned int sys_queue_buf_size(unsigned int size, unsigned int token_size) +{ + return (size + 1) * token_size; +} + +void +sys_queue_init(struct sys_queue *q, unsigned int size, unsigned int token_size, + struct sys_queue_res *res) +{ + unsigned int buf_size; + + q->size = size + 1; + q->token_size = token_size; + buf_size = sys_queue_buf_size(size, token_size); + + /* acquire the shared buffer space */ + q->host_address = res->host_address; + res->host_address += buf_size; + q->vied_address = res->vied_address; + res->vied_address += buf_size; + + /* acquire the shared read and writer pointers */ + q->wr_reg = res->reg; + res->reg++; + q->rd_reg = res->reg; + res->reg++; + +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/src/recv_port.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/src/recv_port.c new file mode 100644 index 0000000000000..2433ba9659aa4 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/src/recv_port.c @@ -0,0 +1,96 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "recv_port.h" +#include "port_env_struct.h" /* for port_env */ +#include "queue_struct.h" /* for sys_queue */ +#include "recv_port_struct.h" /* for recv_port */ +#include "buffer_access.h" /* for buffer_load, buffer_address */ +#include "regmem_access.h" /* for regmem_load_32, regmem_store_32 */ +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "type_support.h" /* for HOST_ADDRESS */ + +#ifndef __VIED_CELL +#include "cpu_mem_support.h" /* for ia_css_cpu_mem_cache_invalidate */ +#endif + +#include "math_support.h" /* for OP_std_modadd */ + +void +recv_port_open(struct recv_port *p, const struct sys_queue *q, + const struct port_env *env) +{ + p->mmid = env->mmid; + p->ssid = env->ssid; + p->mem_addr = env->mem_addr; + + p->size = q->size; + p->token_size = q->token_size; + p->wr_reg = q->wr_reg; + p->rd_reg = q->rd_reg; + +#ifdef __VIED_CELL + p->buffer = q->vied_address; +#else + p->buffer = q->host_address; +#endif +} + +STORAGE_CLASS_INLINE unsigned int +recv_port_index(const struct recv_port *p, unsigned int i) +{ + unsigned int rd = regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + + return OP_std_modadd(rd, i, p->size); +} + +unsigned int +recv_port_available(const struct recv_port *p) +{ + int wr = (int)regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + int rd = (int)regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + + return OP_std_modadd(wr, -rd, p->size); +} + +STORAGE_CLASS_INLINE void +recv_port_copy(const struct recv_port *p, unsigned int i, void *data) +{ + unsigned int rd = recv_port_index(p, i); + unsigned int token_size = p->token_size; + buffer_address addr = p->buffer + (rd * token_size); +#ifndef __VIED_CELL + ia_css_cpu_mem_cache_invalidate((void *)HOST_ADDRESS(p->buffer), + token_size*p->size); +#endif + buffer_load(addr, data, token_size, p->mmid); +} + +STORAGE_CLASS_INLINE void +recv_port_release(const struct recv_port *p, unsigned int i) +{ + unsigned int rd = recv_port_index(p, i); + + regmem_store_32(p->mem_addr, p->rd_reg, rd, p->ssid); +} + +unsigned int +recv_port_transfer(const struct recv_port *p, void *data) +{ + if (!recv_port_available(p)) + return 0; + recv_port_copy(p, 0, data); + recv_port_release(p, 1); + return 1; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/src/send_port.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/src/send_port.c new file mode 100644 index 0000000000000..b0dfe41cb1046 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/port/src/send_port.c @@ -0,0 +1,95 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "send_port.h" +#include "queue_struct.h" /* for sys_queue */ +#include "send_port_struct.h" /* for send_port */ +#include "port_env_struct.h" /* for port_env */ +#include "regmem_access.h" /* for regmem_load_32, regmem_store_32 */ +#include "buffer_access.h" /* for buffer_store, buffer_address */ +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "type_support.h" /* for HOST_ADDRESS */ + +#ifndef __VIED_CELL +#include "cpu_mem_support.h" /* for ia_css_cpu_mem_cache_flush */ +#endif + +#include "math_support.h" /* for OP_std_modadd */ + +void +send_port_open(struct send_port *p, const struct sys_queue *q, + const struct port_env *env) +{ + p->mmid = env->mmid; + p->ssid = env->ssid; + p->mem_addr = env->mem_addr; + + p->size = q->size; + p->token_size = q->token_size; + p->wr_reg = q->wr_reg; + p->rd_reg = q->rd_reg; +#ifdef __VIED_CELL + p->buffer = q->vied_address; +#else + p->buffer = q->host_address; +#endif +} + +STORAGE_CLASS_INLINE unsigned int +send_port_index(const struct send_port *p, unsigned int i) +{ + unsigned int wr = regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + + return OP_std_modadd(wr, i, p->size); +} + +unsigned int +send_port_available(const struct send_port *p) +{ + int rd = (int)regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + int wr = (int)regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + + return OP_std_modadd(rd, -(wr+1), p->size); +} + +STORAGE_CLASS_INLINE void +send_port_copy(const struct send_port *p, unsigned int i, const void *data) +{ + unsigned int wr = send_port_index(p, i); + unsigned int token_size = p->token_size; + buffer_address addr = p->buffer + (wr * token_size); + + buffer_store(addr, data, token_size, p->mmid); +#ifndef __VIED_CELL + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(addr), token_size); +#endif +} + +STORAGE_CLASS_INLINE void +send_port_release(const struct send_port *p, unsigned int i) +{ + unsigned int wr = send_port_index(p, i); + + regmem_store_32(p->mem_addr, p->wr_reg, wr, p->ssid); +} + +unsigned int +send_port_transfer(const struct send_port *p, const void *data) +{ + if (!send_port_available(p)) + return 0; + send_port_copy(p, 0, data); + send_port_release(p, 1); + return 1; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_private_pg/interface/ia_css_psys_private_pg_data.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_private_pg/interface/ia_css_psys_private_pg_data.h new file mode 100644 index 0000000000000..6b2387352ae36 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_private_pg/interface/ia_css_psys_private_pg_data.h @@ -0,0 +1,43 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PRIVATE_PG_DATA_H +#define __IA_CSS_PSYS_PRIVATE_PG_DATA_H + +#include "ipu_device_acb_devices.h" +#include "ipu_device_gp_devices.h" +#include "type_support.h" +#include "vied_nci_acb_route_type.h" + +#define PRIV_CONF_INVALID 0xFF + +struct ia_css_psys_pg_buffer_information_s { + unsigned int buffer_base_addr; + unsigned int bpe; + unsigned int buffer_width; + unsigned int buffer_height; + unsigned int num_of_buffers; + unsigned int dfm_port_addr; +}; + +typedef struct ia_css_psys_pg_buffer_information_s ia_css_psys_pg_buffer_information_t; + +struct ia_css_psys_private_pg_data { + nci_acb_route_t acb_route[IPU_DEVICE_ACB_NUM_ACB]; + uint8_t psa_mux_conf[IPU_DEVICE_GP_PSA_MUX_NUM_MUX]; + uint8_t isa_mux_conf[IPU_DEVICE_GP_ISA_STATIC_MUX_NUM_MUX]; + ia_css_psys_pg_buffer_information_t input_buffer_info; +}; + +#endif /* __IA_CSS_PSYS_PRIVATE_PG_DATA_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_server/interface/ia_css_bxt_spctrl_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_server/interface/ia_css_bxt_spctrl_trace.h new file mode 100644 index 0000000000000..eee1d6ab0a496 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_server/interface/ia_css_bxt_spctrl_trace.h @@ -0,0 +1,107 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BXT_SPCTRL_TRACE_H +#define __IA_CSS_BXT_SPCTRL_TRACE_H + +#include "ia_css_trace.h" + +/* Not using 0 to identify wrong configuration being passed from + * the .mk file outside. + * Log levels not in the range below will cause a + * "No BXT_SPCTRL_TRACE_CONFIG Tracing level defined" + */ +#define BXT_SPCTRL_TRACE_LOG_LEVEL_OFF 1 +#define BXT_SPCTRL_TRACE_LOG_LEVEL_NORMAL 2 +#define BXT_SPCTRL_TRACE_LOG_LEVEL_DEBUG 3 + +/* BXT_SPCTRL and all the submodules in BXT_SPCTRL will have the + * default tracing level set to the BXT_SPCTRL_TRACE_CONFIG level. + * If not defined in the psysapi.mk fill it will be set by + * default to no trace (BXT_SPCTRL_TRACE_LOG_LEVEL_NORMAL) + */ +#define BXT_SPCTRL_TRACE_CONFIG_DEFAULT BXT_SPCTRL_TRACE_LOG_LEVEL_NORMAL + +#if !defined(BXT_SPCTRL_TRACE_CONFIG) +# define BXT_SPCTRL_TRACE_CONFIG BXT_SPCTRL_TRACE_CONFIG_DEFAULT +#endif + +/* BXT_SPCTRL Module tracing backend is mapped to TUNIT tracing for + * target platforms + */ +#ifdef __HIVECC +# ifndef HRT_CSIM +# define BXT_SPCTRL_TRACE_METHOD IA_CSS_TRACE_METHOD_TRACE +# else +# define BXT_SPCTRL_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +# endif +#else +# define BXT_SPCTRL_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#endif + +#if (defined(BXT_SPCTRL_TRACE_CONFIG)) + /* Module specific trace setting */ +# if BXT_SPCTRL_TRACE_CONFIG == BXT_SPCTRL_TRACE_LOG_LEVEL_OFF + /* BXT_SPCTRL_TRACE_LOG_LEVEL_OFF */ +# define BXT_SPCTRL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED +# elif BXT_SPCTRL_TRACE_CONFIG == BXT_SPCTRL_TRACE_LOG_LEVEL_NORMAL + /* BXT_SPCTRL_TRACE_LOG_LEVEL_NORMAL */ +# define BXT_SPCTRL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED +# elif BXT_SPCTRL_TRACE_CONFIG == BXT_SPCTRL_TRACE_LOG_LEVEL_DEBUG + /* BXT_SPCTRL_TRACE_LOG_LEVEL_DEBUG */ +# define BXT_SPCTRL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED +# else +# error "No BXT_SPCTRL_TRACE_CONFIG Tracing level defined" +# endif +#else +# error "BXT_SPCTRL_TRACE_CONFIG not defined" +#endif + +/* Overriding submodules in BXT_SPCTRL with a specific tracing level */ +/* #define BXT_SPCTRL_DYNAMIC_TRACING_OVERRIDE TRACE_LOG_LEVEL_VERBOSE */ + +#endif /* __IA_CSS_BXT_SPCTRL_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_server/psys_server.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_server/psys_server.mk new file mode 100644 index 0000000000000..c4462c9847935 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_server/psys_server.mk @@ -0,0 +1,81 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PSYS_SERVER + +include $(MODULES_DIR)/config/system_$(IPU_SYSVER).mk +include $(MODULES_DIR)/config/$(SUBSYSTEM)/subsystem_$(IPU_SYSVER).mk + +PSYS_SERVER_DIR=${MODULES_DIR}/psys_server + +# The watchdog should never be merged enabled +PSYS_SERVER_WATCHDOG_ENABLE ?= 0 + +PSYS_SERVER_INTERFACE=$(PSYS_SERVER_DIR)/interface +PSYS_SERVER_SOURCES=$(PSYS_SERVER_DIR)/src + +# PSYS API implementation files. Consider a new module for those to avoid +# having them together with firmware. +PSYS_SERVER_HOST_FILES += $${MODULES_DIR}/psysapi/device/src/ia_css_psys_device.c +PSYS_SERVER_HOST_FILES += $(PSYS_SERVER_SOURCES)/bxt_spctrl_process_group_cmd_impl.c + +PSYS_SERVER_HOST_CPPFLAGS += -I$(PSYS_SERVER_INTERFACE) + +PSYS_SERVER_HOST_CPPFLAGS += -DSSID=$(SSID) +PSYS_SERVER_HOST_CPPFLAGS += -DMMID=$(MMID) + + +PSYS_SERVER_FW_FILES += $(PSYS_SERVER_SOURCES)/psys_cmd_queue_fw.c +PSYS_SERVER_FW_FILES += $(PSYS_SERVER_SOURCES)/psys_event_queue_fw.c +PSYS_SERVER_FW_FILES += $(PSYS_SERVER_SOURCES)/psys_init_fw.c +PSYS_SERVER_FW_FILES += $(PSYS_SERVER_SOURCES)/psys_process_group_fw.c + +# Files that server modules need to use +PSYS_SERVER_SUPPORT_FILES = $(PSYS_SERVER_SOURCES)/dev_access_conv/$(IPU_SYSVER)/ia_css_psys_server_dev_access_type_conv.c +PSYS_SERVER_SUPPORT_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_config.c + +# Include those to build the release firmware. Otherwise replace by test code. +PSYS_SERVER_RELEASE_FW_FILES = $(PSYS_SERVER_SOURCES)/psys_server.c +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_proxy.c +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_dev_access.c +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_terminal_load.c +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_remote_obj_access.c +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_dma_access.c +ifeq ($(HAS_DEC400), 1) +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_dec400_access.c +endif +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SUPPORT_FILES) + +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_INTERFACE) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES)/$(IPU_SYSVER) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES)/$(PSYS_SERVER_VERSION) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES)/loader/$(PSYS_SERVER_LOADER_VERSION) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES)/access_blocker/$(PSYS_ACCESS_BLOCKER_VERSION) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES)/access_blocker/src + +PSYS_SERVER_FW_CPPFLAGS += -DSSID=$(SSID) +PSYS_SERVER_FW_CPPFLAGS += -DMMID=$(MMID) +PSYS_SERVER_FW_CPPFLAGS += -DHAS_DPCM=$(if $(HAS_DPCM),1,0) + +# PSYS server watchdog for debugging +ifeq ($(PSYS_SERVER_WATCHDOG_ENABLE), 1) + PSYS_SERVER_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_watchdog.c + PSYS_SERVER_FW_CPPFLAGS += -DPSYS_SERVER_WATCHDOG_DEBUG +endif + +PSYS_SERVER_FW_CPPFLAGS += -D$(PSYS_HW_VERSION) + +PSYS_SERVER_FW_CPPFLAGS += -DENABLE_TPROXY=$(PSYS_SERVER_ENABLE_TPROXY) +PSYS_SERVER_FW_CPPFLAGS += -DENABLE_DEVPROXY=$(PSYS_SERVER_ENABLE_DEVPROXY) diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_server/src/bxt_spctrl_process_group_cmd_impl.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_server/src/bxt_spctrl_process_group_cmd_impl.c new file mode 100644 index 0000000000000..0a1ef5dfcae77 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psys_server/src/bxt_spctrl_process_group_cmd_impl.c @@ -0,0 +1,332 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_device.h" +#include "ia_css_psys_process_group_cmd_impl.h" +#include "ia_css_psysapi.h" +#include "ia_css_psys_terminal.h" +#include "ia_css_psys_process.h" +#include "ia_css_psys_process.psys.h" +#include "ia_css_psys_process_group.h" +#include "ia_css_psys_process_group.psys.h" +#include "ia_css_psys_program_group_manifest.h" +#include "type_support.h" +#include "error_support.h" +#include "misc_support.h" +#include "cpu_mem_support.h" +#include "ia_css_bxt_spctrl_trace.h" + +#if HAS_DUAL_CMD_CTX_SUPPORT +#define MAX_CLIENT_PGS 8 /* same as test_params.h */ +struct ia_css_process_group_context { + ia_css_process_group_t *pg; + bool secure; +}; +struct ia_css_process_group_context pg_contexts[MAX_CLIENT_PGS]; +static unsigned int num_of_pgs; + +STORAGE_CLASS_INLINE +struct ia_css_syscom_context *ia_css_process_group_get_context(ia_css_process_group_t *process_group) +{ + unsigned int i; + bool secure = false; + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_get_context(): enter:\n"); + + for (i = 0; i < num_of_pgs; i++) { + if (pg_contexts[i].pg == process_group) { + secure = pg_contexts[i].secure; + break; + } + } + + IA_CSS_TRACE_1(BXT_SPCTRL, INFO, + "ia_css_process_group_get_context(): secure %d\n", secure); + return secure ? psys_syscom_secure : psys_syscom; +} + +int ia_css_process_group_store(ia_css_process_group_t *process_group, bool secure) +{ + IA_CSS_TRACE_2(BXT_SPCTRL, INFO, + "ia_css_process_group_store(): pg instance %d secure %d\n", num_of_pgs, secure); + + pg_contexts[num_of_pgs].pg = process_group; + pg_contexts[num_of_pgs].secure = secure; + num_of_pgs++; + return 0; +} +#else /* HAS_DUAL_CMD_CTX_SUPPORT */ +STORAGE_CLASS_INLINE +struct ia_css_syscom_context *ia_css_process_group_get_context(ia_css_process_group_t *process_group) +{ + NOT_USED(process_group); + + return psys_syscom; +} + +int ia_css_process_group_store(ia_css_process_group_t *process_group, bool secure) +{ + NOT_USED(process_group); + NOT_USED(secure); + + return 0; +} +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +int ia_css_process_group_on_create( + ia_css_process_group_t *process_group, + const ia_css_program_group_manifest_t *program_group_manifest, + const ia_css_program_group_param_t *program_group_param) +{ + NOT_USED(process_group); + NOT_USED(program_group_manifest); + NOT_USED(program_group_param); + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_on_create(): enter:\n"); + + return 0; +} + +int ia_css_process_group_on_destroy( + ia_css_process_group_t *process_group) +{ + NOT_USED(process_group); + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_on_destroy(): enter:\n"); + + return 0; +} + +int ia_css_process_group_exec_cmd( + ia_css_process_group_t *process_group, + const ia_css_process_group_cmd_t cmd) +{ + int retval = -1; + ia_css_process_group_state_t state; + struct ia_css_psys_cmd_s psys_cmd; + bool cmd_queue_full; + unsigned int queue_id; + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): enter:\n"); + + verifexit(process_group != NULL); + + state = ia_css_process_group_get_state(process_group); + + verifexit(state != IA_CSS_PROCESS_GROUP_ERROR); + verifexit(state < IA_CSS_N_PROCESS_GROUP_STATES); + + switch (cmd) { + case IA_CSS_PROCESS_GROUP_CMD_SUBMIT: + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): IA_CSS_PROCESS_GROUP_CMD_SUBMIT:\n"); + verifexit(state == IA_CSS_PROCESS_GROUP_READY); + + /* External resource availability checks */ + verifexit(ia_css_can_process_group_submit(process_group)); + + process_group->state = IA_CSS_PROCESS_GROUP_BLOCKED; + break; + case IA_CSS_PROCESS_GROUP_CMD_START: + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): IA_CSS_PROCESS_GROUP_CMD_START:\n"); + verifexit(state == IA_CSS_PROCESS_GROUP_BLOCKED); + + /* External resource state checks */ + verifexit(ia_css_can_process_group_start(process_group)); + + process_group->state = IA_CSS_PROCESS_GROUP_STARTED; + break; + case IA_CSS_PROCESS_GROUP_CMD_DISOWN: + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): IA_CSS_PROCESS_GROUP_CMD_DISOWN:\n"); + verifexit(state == IA_CSS_PROCESS_GROUP_STARTED); + + cmd_queue_full = ia_css_is_psys_cmd_queue_full(ia_css_process_group_get_context(process_group), + IA_CSS_PSYS_CMD_QUEUE_COMMAND_ID); + retval = EBUSY; + verifexit(cmd_queue_full == false); + + psys_cmd.command = IA_CSS_PROCESS_GROUP_CMD_START; + psys_cmd.msg = 0; + psys_cmd.context_handle = process_group->ipu_virtual_address; + + verifexit(ia_css_process_group_print(process_group, NULL) == 0); + + retval = ia_css_psys_cmd_queue_send(ia_css_process_group_get_context(process_group), + IA_CSS_PSYS_CMD_QUEUE_COMMAND_ID, &psys_cmd); + verifexit(retval > 0); + break; + case IA_CSS_PROCESS_GROUP_CMD_STOP: + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): IA_CSS_PROCESS_GROUP_CMD_STOP:\n"); + + cmd_queue_full = ia_css_is_psys_cmd_queue_full(ia_css_process_group_get_context(process_group), + IA_CSS_PSYS_CMD_QUEUE_COMMAND_ID); + retval = EBUSY; + verifexit(cmd_queue_full == false); + + psys_cmd.command = IA_CSS_PROCESS_GROUP_CMD_STOP; + psys_cmd.msg = 0; + psys_cmd.context_handle = process_group->ipu_virtual_address; + + queue_id = ia_css_process_group_get_base_queue_id(process_group); + verifexit(queue_id < IA_CSS_N_PSYS_CMD_QUEUE_ID); + + retval = ia_css_psys_cmd_queue_send(ia_css_process_group_get_context(process_group), + queue_id, &psys_cmd); + verifexit(retval > 0); + break; + case IA_CSS_PROCESS_GROUP_CMD_ABORT: + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): IA_CSS_PROCESS_GROUP_CMD_ABORT:\n"); + + /* Once the flushing of shared buffers is fixed this verifexit + * should be changed to be state = IA_CSS_PROCESS_GROUP_STARTED + */ + verifexit(state == IA_CSS_PROCESS_GROUP_BLOCKED); + + cmd_queue_full = ia_css_is_psys_cmd_queue_full(ia_css_process_group_get_context(process_group), + IA_CSS_PSYS_CMD_QUEUE_COMMAND_ID); + retval = EBUSY; + verifexit(cmd_queue_full == false); + + psys_cmd.command = IA_CSS_PROCESS_GROUP_CMD_ABORT; + psys_cmd.msg = 0; + psys_cmd.context_handle = process_group->ipu_virtual_address; + + retval = ia_css_psys_cmd_queue_send(ia_css_process_group_get_context(process_group), + IA_CSS_PSYS_CMD_QUEUE_DEVICE_ID, &psys_cmd); + verifexit(retval > 0); + break; + default: + verifexit(false); + break; + } + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(BXT_SPCTRL, ERROR, + "ia_css_process_group_exec_cmd failed (%i)\n", retval); + } + return retval; +} + +STORAGE_CLASS_INLINE int enqueue_buffer_set_cmd( + ia_css_process_group_t *process_group, + ia_css_buffer_set_t *buffer_set, + unsigned int queue_offset, + uint16_t command + ) +{ + int retval = -1; + struct ia_css_psys_cmd_s psys_cmd; + bool cmd_queue_full; + unsigned int queue_id; + + verifexit(ia_css_process_group_get_state(process_group) + == IA_CSS_PROCESS_GROUP_STARTED); + + verifexit(queue_offset < + ia_css_process_group_get_num_queues(process_group)); + + queue_id = + ia_css_process_group_get_base_queue_id(process_group) + + queue_offset; + verifexit(queue_id < IA_CSS_N_PSYS_CMD_QUEUE_ID); + + cmd_queue_full = ia_css_is_psys_cmd_queue_full(ia_css_process_group_get_context(process_group), queue_id); + retval = EBUSY; + verifexit(cmd_queue_full == false); + + psys_cmd.command = command; + psys_cmd.msg = 0; + psys_cmd.context_handle = + ia_css_buffer_set_get_ipu_address(buffer_set); + + retval = ia_css_psys_cmd_queue_send(ia_css_process_group_get_context(process_group), queue_id, &psys_cmd); + verifexit(retval > 0); + + retval = 0; + +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(BXT_SPCTRL, ERROR, + "enqueue_buffer_set failed (%i)\n", retval); + } + return retval; +} + +int ia_css_enqueue_buffer_set( + ia_css_process_group_t *process_group, + ia_css_buffer_set_t *buffer_set, + unsigned int queue_offset) +{ + int retval = -1; + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_enqueue_buffer_set():\n"); + retval = enqueue_buffer_set_cmd( + process_group, + buffer_set, + queue_offset, + IA_CSS_PROCESS_GROUP_CMD_RUN); + + if (retval != 0) { + IA_CSS_TRACE_1(BXT_SPCTRL, ERROR, + "ia_css_enqueue_buffer_set failed (%i)\n", retval); + } + return retval; +} + +int ia_css_enqueue_param_buffer_set( + ia_css_process_group_t *process_group, + ia_css_buffer_set_t *param_buffer_set) +{ +#if (HAS_LATE_BINDING_SUPPORT == 1) + int retval = -1; + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_enqueue_param_buffer_set():\n"); + + retval = enqueue_buffer_set_cmd( + process_group, + param_buffer_set, + IA_CSS_PSYS_LATE_BINDING_QUEUE_OFFSET, + IA_CSS_PROCESS_GROUP_CMD_SUBMIT); + + if (retval != 0) { + IA_CSS_TRACE_1(BXT_SPCTRL, ERROR, + "ia_css_enqueue_param_buffer_set failed (%i)\n", retval); + } +#else + int retval = -1; + + NOT_USED(process_group); + NOT_USED(param_buffer_set); + IA_CSS_TRACE_0(BXT_SPCTRL, ERROR, + "ia_css_enqueue_param_buffer_set failed, no late binding supported\n"); +#endif /* (HAS_LATE_BINDING_SUPPORT == 1) */ + return retval; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data.h new file mode 100644 index 0000000000000..0f6fb5542913e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data.h @@ -0,0 +1,418 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_DATA_H +#define __IA_CSS_PROGRAM_GROUP_DATA_H + +#include "ia_css_psys_data_storage_class.h" + +/*! \file */ + +/** @file ia_css_program_group_data.h + * + * Define the data objects that are passed to the process groups + * i.e. frames and matrices with their sub-structures + * + * The data objects are separate from the process group terminal, + * although they are stored by value rather than by reference and + * make the process group terminal dependendent on its definition + * + * This frame definition overloads the current CSS frame definition + * they are the same object, just a slightly different implementation + */ + +#include /* vied_vaddress_t */ + +#include +#include "ia_css_program_group_data_defs.h" /* ia_css_frame_format_type */ + +#include "ia_css_terminal_defs.h" + +/* + * Frame buffer state used for sequencing + * (see FAS 5.5.3) + * + * The buffer can be in DDR or a handle to a stream + */ +typedef enum ia_css_buffer_state { + IA_CSS_BUFFER_NULL = 0, + IA_CSS_BUFFER_UNDEFINED, + IA_CSS_BUFFER_EMPTY, + IA_CSS_BUFFER_NONEMPTY, + IA_CSS_BUFFER_FULL, + IA_CSS_N_BUFFER_STATES +} ia_css_buffer_state_t; + +#define IA_CSS_BUFFER_STATE_IN_BITS 32 + +/* + * Pointer state used to signal MMU invalidation + */ +typedef enum ia_css_pointer_state { + IA_CSS_POINTER_INVALID = 0, + IA_CSS_POINTER_VALID, + IA_CSS_N_POINTER_STATES +} ia_css_pointer_state_t; + +#define IA_CSS_POINTER_STATE_IN_BITS 32 + +/* + * Access direction needed to select the access port + */ +typedef enum ia_css_access_type { + IA_CSS_ACCESS_LOCKED = 0, + IA_CSS_ACCESS_READ, + IA_CSS_ACCESS_WRITE, + IA_CSS_ACCESS_MODIFY, + IA_CSS_N_ACCESS_TYPES +} ia_css_access_type_t; + +#define IA_CSS_ACCESS_TYPE_IN_BITS 32 + +/* + * Access attribute needed to select the access port + * - public : snooped + * - private: non-snooped + * Naming is a bit awkward, lack of inspiration + */ +typedef enum ia_css_access_scope { + IA_CSS_ACCESS_PRIVATE = 0, + IA_CSS_ACCESS_PUBLIC, + IA_CSS_N_ACCESS_SCOPES +} ia_css_access_scopes_t; + +#define IA_CSS_ACCESS_SCOPES_IN_BITS 32 + +#define IA_CSS_N_FRAME_PLANES 6 + +#define IA_CSS_FRAME_FORMAT_BITMAP_BITS 64 +typedef uint64_t ia_css_frame_format_bitmap_t; + +typedef struct ia_css_param_frame_descriptor_s ia_css_param_frame_descriptor_t; +typedef struct ia_css_param_frame_s ia_css_param_frame_t; + +typedef struct ia_css_frame_descriptor_s ia_css_frame_descriptor_t; +typedef struct ia_css_frame_s ia_css_frame_t; +typedef struct ia_css_fragment_descriptor_s ia_css_fragment_descriptor_t; + +typedef struct ia_css_stream_s ia_css_stream_t; + + +#define N_UINT64_IN_STREAM_STRUCT 1 + +#define IA_CSS_STREAM_STRUCT_BITS \ + (N_UINT64_IN_STREAM_STRUCT * 64) + +struct ia_css_stream_s { + uint64_t dummy; +}; + +struct ia_css_param_frame_descriptor_s { + uint16_t size; /**< Size of the descriptor */ + uint32_t buffer_count; /**< Number of parameter buffers */ +}; + +struct ia_css_param_frame_s { + /*< Base virtual addresses to parameters in subsystem virtual + * memory space + */ + vied_vaddress_t *data; +}; + +#define N_UINT32_IN_FRAME_DESC_STRUCT \ + (1 + IA_CSS_N_FRAME_PLANES + (IA_CSS_N_DATA_DIMENSION - 1)) +#define N_UINT16_IN_FRAME_DESC_STRUCT (1 + IA_CSS_N_DATA_DIMENSION) +#define N_UINT8_IN_FRAME_DESC_STRUCT 3 +#define N_PADDING_UINT8_IN_FRAME_DESC_STRUCT 3 + +#define IA_CSS_FRAME_DESCRIPTOR_STRUCT_BITS \ + (IA_CSS_FRAME_FORMAT_TYPE_BITS \ + + (N_UINT32_IN_FRAME_DESC_STRUCT * 32) \ + + (N_UINT16_IN_FRAME_DESC_STRUCT * 16) \ + + (N_UINT8_IN_FRAME_DESC_STRUCT * 8) \ + + (N_PADDING_UINT8_IN_FRAME_DESC_STRUCT * 8)) + +/* + * Structure defining the frame (size and access) properties for + * inbuild types only. + * + * The inbuild types like FourCC, MIPI and CSS private types are supported + * by FW all other types are custom types which interpretation must be encoded + * on the buffer itself or known by the source and sink + */ +struct ia_css_frame_descriptor_s { + /**< Indicates if this is a generic type or inbuild with + * variable size descriptor + */ + ia_css_frame_format_type_t frame_format_type; + /**< Number of data planes (pointers) */ + uint32_t plane_count; + /**< Plane offsets accounting for fragments */ + uint32_t plane_offsets[IA_CSS_N_FRAME_PLANES]; + /**< Physical size aspects */ + uint32_t stride[IA_CSS_N_DATA_DIMENSION - 1]; + /**< Logical dimensions */ + uint16_t dimension[IA_CSS_N_DATA_DIMENSION]; + /**< Size of this descriptor */ + uint16_t size; + /**< Bits per pixel */ + uint8_t bpp; + /**< Bits per element */ + uint8_t bpe; + /**< 1 if terminal uses compressed datatype, 0 otherwise */ + uint8_t is_compressed; + /**< Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_FRAME_DESC_STRUCT]; +}; + +#define N_UINT32_IN_FRAME_STRUCT 2 +#define N_PADDING_UINT8_IN_FRAME_STRUCT 4 + +#define IA_CSS_FRAME_STRUCT_BITS \ + (IA_CSS_BUFFER_STATE_IN_BITS \ + + IA_CSS_ACCESS_TYPE_IN_BITS \ + + IA_CSS_POINTER_STATE_IN_BITS \ + + IA_CSS_ACCESS_SCOPES_IN_BITS \ + + VIED_VADDRESS_BITS \ + + (N_UINT32_IN_FRAME_STRUCT * 32) \ + + (N_PADDING_UINT8_IN_FRAME_STRUCT * 8)) + + +/* + * Main frame structure holding the main store and auxilary access properties + * the "pointer_state" and "access_scope" should be encoded on the + * "vied_vaddress_t" type + */ +struct ia_css_frame_s { + /**< State of the frame for purpose of sequencing */ + ia_css_buffer_state_t buffer_state; + /**< Access direction, may change when buffer state changes */ + ia_css_access_type_t access_type; + /**< State of the pointer for purpose of embedded MMU coherency */ + ia_css_pointer_state_t pointer_state; + /**< Access to the pointer for purpose of host cache coherency */ + ia_css_access_scopes_t access_scope; + /**< Base virtual address to data in subsystem virtual memory space */ + vied_vaddress_t data; + /**< Offset to buffer address within external buffer set structure */ + uint32_t data_index; + /**< Total allocation size in bytes */ + uint32_t data_bytes; + /**< Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_FRAME_STRUCT]; +}; + +#define N_UINT16_IN_FRAGMENT_DESC_STRUCT (3 * IA_CSS_N_DATA_DIMENSION) +#define N_PADDING_UINT8_IN_FRAGMENT_DESC_STRUCT 4 + +#define IA_CSS_FRAGMENT_DESCRIPTOR_STRUCT_BITS \ + ((N_UINT16_IN_FRAME_DESC_STRUCT * 16) \ + + (N_PADDING_UINT8_IN_FRAGMENT_DESC_STRUCT * 8)) + +/* + * Structure defining the fragment (size and access) properties. + * + * All cropping and padding effects are described by the difference between + * the frame size and its location and the fragment size(s) and location(s) + */ +struct ia_css_fragment_descriptor_s { + /**< Logical dimensions of the fragment */ + uint16_t dimension[IA_CSS_N_DATA_DIMENSION]; + /**< Logical location of the fragment in the frame */ + uint16_t index[IA_CSS_N_DATA_DIMENSION]; + /**< Fractional start (phase) of the fragment in the access unit */ + uint16_t offset[IA_CSS_N_DATA_DIMENSION]; + /**< Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_FRAGMENT_DESC_STRUCT]; +}; + + +/*! Print the frame object to file/stream + + @param frame[in] frame object + @param fid[out] file/stream handle + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_print( + const ia_css_frame_t *frame, void *fid); + +/*! Get the data buffer handle from the frame object + +@param frame[in] frame object + +@return buffer pointer, VIED_NULL on error +*/ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +const vied_vaddress_t *ia_css_frame_get_buffer_host_virtual_address( + const ia_css_frame_t *frame); + +/*! Get the data buffer handle from the frame object + + @param frame[in] frame object + + @return buffer pointer, VIED_NULL on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +vied_vaddress_t ia_css_frame_get_buffer(const ia_css_frame_t *frame); + +/*! Set the data buffer handle on the frame object + + @param frame[in] frame object + @param buffer[in] buffer pointer + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_set_buffer( + ia_css_frame_t *frame, vied_vaddress_t buffer); + +/*! Get the data buffer index in the frame object + + @param frame[in] frame object + + @return data buffer index on success, -1 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_get_data_index( + const ia_css_frame_t *frame); + +/*! Set the data buffer index in the frame object + + @param frame[in] frame object + @param data_index[in] data buffer index + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_set_data_index( + ia_css_frame_t *frame, + unsigned int data_index); + +/*! Set the data buffer size on the frame object + + @param frame[in] frame object + @param size[in] number of data bytes + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_set_data_bytes( + ia_css_frame_t *frame, unsigned int size); + +/*! Get the data buffer state from the frame object + + @param frame[in] frame object + + @return buffer state, limit value on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +ia_css_buffer_state_t ia_css_frame_get_buffer_state( + const ia_css_frame_t *frame); + +/*! Set the data buffer state of the frame object + + @param frame[in] frame object + @param buffer_state[in] buffer state + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_set_buffer_state(ia_css_frame_t *frame, + const ia_css_buffer_state_t buffer_state); + +/*! Get the data pointer state from the frame object + + @param frame[in] frame object + + @return pointer state, limit value on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +ia_css_pointer_state_t ia_css_frame_get_pointer_state( + const ia_css_frame_t *frame); + +/*! Set the data pointer state of the frame object + + @param frame[in] frame object + @param pointer_state[in] pointer state + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_set_pointer_state(ia_css_frame_t *frame, + const ia_css_pointer_state_t pointer_state); + +/*! Print the frame descriptor object to file/stream + + @param frame_descriptor[in] frame descriptor object + @param fid[out] file/stream handle + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_descriptor_print( + const ia_css_frame_descriptor_t *frame_descriptor, void *fid); + +/*! Print the fragment descriptor object to file/stream + + @param fragment_descriptor[in] fragment descriptor object + @param fid[out] file/stream handle + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_fragment_descriptor_print( + const ia_css_fragment_descriptor_t *fragment_descriptor, void *fid); + +/*! Compute the bitmap for the frame format type + + @param frame_format_type[in] frame format type + + @return 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +ia_css_frame_format_bitmap_t ia_css_frame_format_bit_mask( + const ia_css_frame_format_type_t frame_format_type); + +/*! clear frame format bitmap + + @return cleared bitmap + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +ia_css_frame_format_bitmap_t ia_css_frame_format_bitmap_clear(void); + + +/*! Compute the size of storage required for the data descriptor object + * on a terminal + *@param plane_count[in] The number of data planes in the buffer + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +size_t ia_css_sizeof_frame_descriptor( + const uint8_t plane_count); +/*! Compute the size of storage required for the kernel parameter descriptor + * object on a terminal + + @param section_count[in] The number of parameter sections in the buffer + + @return 0 on error + */ +extern size_t ia_css_sizeof_kernel_param_descriptor( + const uint16_t section_count); + +#ifdef __IA_CSS_PSYS_DATA_INLINE__ +#include "ia_css_program_group_data_impl.h" +#endif /* __IA_CSS_PSYS_DATA_INLINE__ */ + +#endif /* __IA_CSS_PROGRAM_GROUP_DATA_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data_defs.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data_defs.h new file mode 100644 index 0000000000000..d3caacdc192fb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data_defs.h @@ -0,0 +1,196 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_DATA_DEFS_H +#define __IA_CSS_PROGRAM_GROUP_DATA_DEFS_H + + +/* + * Pre-defined frame format + * + * Those formats have inbuild support of traffic + * and access functions + * + * Note that the formats are for terminals, so there + * is no distinction between input and output formats + * - Custom formats with ot without descriptor + * - 4CC formats such as YUV variants + * - MIPI (line) formats as produced by CSI receivers + * - MIPI (sensor) formats such as Bayer or RGBC + * - CSS internal formats (private types) + * - CSS parameters (type 1 - 6) + */ +#define IA_CSS_FRAME_FORMAT_TYPE_BITS 32 +typedef enum ia_css_frame_format_type { + IA_CSS_DATA_CUSTOM_NO_DESCRIPTOR = 0, + IA_CSS_DATA_CUSTOM, + + /* 12 bit YUV 411, Y, UV 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV11, + /* bpp bit YUV 420, Y, U, V 3-plane (bpp/1.5 bpe) */ + IA_CSS_DATA_FORMAT_YUV420, + /* 12 bit YUV 420, Y, V, U 3-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_YV12, + /* 12 bit YUV 420, Y, UV 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV12, + /* 16 bit YUV 420, Y, UV 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV12_16, + /* 12 bit YUV 420, Intel proprietary tiled format, TileY */ + IA_CSS_DATA_FORMAT_NV12_TILEY, + /* 12 bit YUV 420, Y, VU 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV21, + /* bpp bit YUV 422, Y, U, V 3-plane (bpp/2 bpe) */ + IA_CSS_DATA_FORMAT_YUV422, + /* 16 bit YUV 422, Y, V, U 3-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_YV16, + /* 16 bit YUV 422, Y, UV 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV16, + /* 16 bit YUV 422, Y, VU 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV61, + /* 16 bit YUV 422, UYVY 1-plane interleaved (8 bit per element) */ + IA_CSS_DATA_FORMAT_UYVY, + /* 16 bit YUV 422, YUYV 1-plane interleaved (8 bit per element) */ + IA_CSS_DATA_FORMAT_YUYV, + /* bpp bit YUV 444, Y, U, V 3-plane (bpp/3 bpe) */ + IA_CSS_DATA_FORMAT_YUV444, + /* 8 bit monochrome plane */ + IA_CSS_DATA_FORMAT_Y800, + + /* 5-6-5 bit packed (1-plane) RGB (16bpp, ~5 bpe) */ + IA_CSS_DATA_FORMAT_RGB565, + /* 24 bit RGB, 3 planes (8 bit per element) */ + IA_CSS_DATA_FORMAT_RGB888, + /* 32 bit RGB-Alpha, 1 plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_RGBA888, + + /* bpp bit raw, [[Gr, R];[B, Gb]] 1-plane (bpp == bpe) */ + IA_CSS_DATA_FORMAT_BAYER_GRBG, + /* bpp bit raw, [[R, Gr];[Gb, B]] 1-plane (bpp == bpe) */ + IA_CSS_DATA_FORMAT_BAYER_RGGB, + /* bpp bit raw, [[B, Gb];[Gr, R]] 1-plane (bpp == bpe) */ + IA_CSS_DATA_FORMAT_BAYER_BGGR, + /* bpp bit raw, [[Gb, B];[R, Gr]] 1-plane (bpp == bpe) */ + IA_CSS_DATA_FORMAT_BAYER_GBRG, + + /* bpp bit (NV12) YUV 420, Y, UV 2-plane derived 3-line, + * 2-Y, 1-UV (bpp/1.5 bpe): M420 format + */ + IA_CSS_DATA_FORMAT_YUV420_LINE, + /* Deprecated RAW, 1 plane */ + IA_CSS_DATA_FORMAT_RAW, + /* Deprecated RAW, 1 plane, packed */ + IA_CSS_DATA_FORMAT_RAW_PACKED, + /* Internal, for advanced ISP */ + IA_CSS_DATA_FORMAT_QPLANE6, + /* 1D byte stream, used for jpeg 1-plane */ + IA_CSS_DATA_FORMAT_BINARY_8, + /* Deprecated MIPI frame, 1D byte stream 1 plane */ + IA_CSS_DATA_FORMAT_MIPI, + /* 12 bit [[YY];[UYVY]] 1-plane interleaved 2-line + * (8 bit per element) + */ + IA_CSS_DATA_FORMAT_MIPI_YUV420_8, + /* 15 bit [[YY];[UYVY]] 1-plane interleaved 2-line + * (10 bit per element) + */ + IA_CSS_DATA_FORMAT_MIPI_YUV420_10, + /* 12 bit [[UY];[VY]] 1-plane interleaved 2-line (8 bit per element) */ + IA_CSS_DATA_FORMAT_MIPI_LEGACY_YUV420_8, + + /* Type 1-5 parameter, not fragmentable */ + IA_CSS_DATA_GENERIC_PARAMETER, + /* Video stabilisation Type 6 parameter, fragmentable */ + IA_CSS_DATA_DVS_PARAMETER, + /* Video stabilisation Type 6 parameter, coordinates */ + IA_CSS_DATA_DVS_COORDINATES, + /* Dead Pixel correction Type 6 parameter, fragmentable */ + IA_CSS_DATA_DPC_PARAMETER, + /* Lens Shading Correction Type 6 parameter, fragmentable */ + IA_CSS_DATA_LSC_PARAMETER, + /* 3A statistics output HI. */ + IA_CSS_DATA_S3A_STATISTICS_HI, + /* 3A statistics output LO. */ + IA_CSS_DATA_S3A_STATISTICS_LO, + /* histogram output */ + IA_CSS_DATA_S3A_HISTOGRAM, + /* GammaStar grid */ + IA_CSS_DATA_GAMMASTAR_GRID, + + /* Gr R B Gb Gr R B Gb in PIXELS (also called isys interleaved) */ + IA_CSS_DATA_FORMAT_BAYER_LINE_INTERLEAVED, + /* Gr R B Gb Gr R B Gb in VECTORS (VCC IMAGE, ISP NWAY depentdent) */ + IA_CSS_DATA_FORMAT_BAYER_VECTORIZED, + /* Gr R Gr R ... | B Gb B Gb .. in VECTORS (ISP NWAY depentdent) */ + IA_CSS_DATA_FORMAT_BAYER_GRBG_VECTORIZED, + + /* 16 bit YUV 420, Y even plane, Y uneven plane, + * UV plane vector interleaved + */ + IA_CSS_DATA_FORMAT_YUV420_VECTORIZED, + /* 16 bit YUV 420, YYUVYY vector interleaved */ + IA_CSS_DATA_FORMAT_YYUVYY_VECTORIZED, + + /* 12 bit YUV 420, Intel proprietary tiled format, TileYf */ + IA_CSS_DATA_FORMAT_NV12_TILEYF, + + /*Y samples appear first in the memory. All Y samples are array of WORDs; + * even number of lines ; + * Surface stride can be larger than the width of Y plane. + * This array is followed immediately by chroma array. + * Chroma array is an array of WORDs, with interleaved U/V samples. + * If the interleaved U/V plane is addresses as an * array of DWORDs, + * the least significant word contains U sample. The stride of the + * interleaved U/V plane is equal to Y plane. 10 bit data. + */ + IA_CSS_DATA_FORMAT_P010, + + /* MSB aligned version of P010*/ + IA_CSS_DATA_FORMAT_P010_MSB, + + /* P016/P012 Y samples appear first in the memory. + * All Y samples are array of WORDs; + * even number of lines ; + * Surface stride can be larger than the width of Y plane. + * This array is followed immediately by chroma array. + * Chroma array is an array of WORDs, with interleaved U/V samples. + * If the interleaved U/V plane is addresses as an * array of DWORDs, + * the least significant word contains U sample. The stride of the + * interleaved U/V plane is equal to Y plane. 12 bit data. + */ + IA_CSS_DATA_FORMAT_P016, + + /* MSB aligned version of P016*/ + IA_CSS_DATA_FORMAT_P016_MSB, + + /* TILEYYf representation of P010*/ + IA_CSS_DATA_FORMAT_P010_TILEYF, + + /* TILEYYf representation of P010 MSB aligned*/ + IA_CSS_DATA_FORMAT_P010_MSB_TILEYF, + + /* TILEYYf representation of P016*/ + IA_CSS_DATA_FORMAT_P016_TILEYF, + + /* TILEYYf representation of P016 MSB aligned*/ + IA_CSS_DATA_FORMAT_P016_MSB_TILEYF, + + /* consists of L and R PDAF pixel pairs. + * L and R can be interleaved or not. 1-plane (bpp == bpe) */ + IA_CSS_DATA_FORMAT_PAF, + + IA_CSS_N_FRAME_FORMAT_TYPES +} ia_css_frame_format_type_t; + + +#endif /* __IA_CSS_PROGRAM_GROUP_DATA_DEFS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_storage_class.h new file mode 100644 index 0000000000000..6a4e3a28e5336 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_storage_class.h @@ -0,0 +1,28 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DATA_STORAGE_CLASS_H +#define __IA_CSS_PSYS_DATA_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __IA_CSS_PSYS_DATA_INLINE__ +#define IA_CSS_PSYS_DATA_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PSYS_DATA_STORAGE_CLASS_C +#else +#define IA_CSS_PSYS_DATA_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PSYS_DATA_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PSYS_DATA_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_trace.h new file mode 100644 index 0000000000000..49afed9ce9dfc --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_trace.h @@ -0,0 +1,102 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DATA_TRACE_H +#define __IA_CSS_PSYS_DATA_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_DATA_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_DATA_TRACING_OVERRIDE)) + #define PSYS_DATA_TRACE_LEVEL_CONFIG PSYS_DATA_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_DATA_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_DATA_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_DATA_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_DATA_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DATA_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DATA_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_DATA_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DATA_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DATA_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_DATA_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DATA_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_DATA_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_DATA_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_DATA_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_DATA_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_DATA_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_DATA_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_DATA_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_DATA_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data.c new file mode 100644 index 0000000000000..779d98741cfa7 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data.c @@ -0,0 +1,29 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_data_storage_class.h" + +/* + * Functions to possibly inline + */ + +#ifdef __IA_CSS_PSYS_DATA_INLINE__ +STORAGE_CLASS_INLINE int +__ia_css_program_group_data_avoid_warning_on_empty_file(void) +{ + return 0; +} +#else /* __IA_CSS_PSYS_DATA_INLINE__ */ +#include "ia_css_program_group_data_impl.h" +#endif /* __IA_CSS_PSYS_DATA_INLINE__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data_impl.h new file mode 100644 index 0000000000000..3e6fca051ee9c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data_impl.h @@ -0,0 +1,456 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_DATA_IMPL_H +#define __IA_CSS_PROGRAM_GROUP_DATA_IMPL_H + +#include "ia_css_program_group_data.h" +#include "ia_css_psys_data_trace.h" +#include "ia_css_terminal_defs.h" +#include /* for verifexit */ +#include /* for COMPILATION_ERROR_IF */ +#include /* for NOT_USED */ + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_print( + const ia_css_frame_t *frame, void *fid) +{ + int retval = -1; + + NOT_USED(fid); + + IA_CSS_TRACE_0(PSYSAPI_DATA, INFO, "ia_css_frame_print(): enter:\n"); + + verifexit(frame != NULL); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tbuffer = %d\n", ia_css_frame_get_buffer(frame)); + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tbuffer_state = %d\n", ia_css_frame_get_buffer_state(frame)); + /* IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, "\tbuffer_state = %s\n", + * ia_css_buffer_state_string(ia_css_frame_get_buffer_state(frame))); + */ + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tpointer_state = %d\n", ia_css_frame_get_pointer_state(frame)); + /* IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, "\tpointer_state = %s\n", + * ia_css_pointer_state_string(ia_css_frame_get_pointer_state(frame))); + */ + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tdata_bytes = %d\n", frame->data_bytes); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_print failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +const vied_vaddress_t *ia_css_frame_get_buffer_host_virtual_address( + const ia_css_frame_t *frame) +{ + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_get_buffer_host_virtual_address(): enter:\n"); + + verifexit(frame != NULL); + return &(frame->data); + +EXIT: + if (frame == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_get_buffer_host_virtual_address invalid argument\n"); + } + return NULL; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +vied_vaddress_t ia_css_frame_get_buffer( + const ia_css_frame_t *frame) +{ + vied_vaddress_t buffer = VIED_NULL; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_get_buffer(): enter:\n"); + + verifexit(frame != NULL); + buffer = frame->data; + +EXIT: + if (frame == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_get_buffer invalid argument\n"); + } + return buffer; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_set_buffer( + ia_css_frame_t *frame, + vied_vaddress_t buffer) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_set_buffer(): enter:\n"); + + verifexit(frame != NULL); + frame->data = buffer; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_set_buffer failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_get_data_index( + const ia_css_frame_t *frame) +{ + int data_index = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_get_data_index(): enter:\n"); + + verifexit(frame != NULL); + + data_index = frame->data_index; + +EXIT: + if (frame == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_get_data_index invalid argument\n"); + } + return data_index; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_set_data_index( + ia_css_frame_t *frame, + unsigned int data_index) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_set_data_index(): enter:\n"); + + verifexit(frame != NULL); + + frame->data_index = data_index; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_set_data_index failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_set_data_bytes( + ia_css_frame_t *frame, + unsigned int size) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_set_data_bytes(): enter:\n"); + + verifexit(frame != NULL); + frame->data_bytes = size; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_set_data_bytes failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +ia_css_buffer_state_t ia_css_frame_get_buffer_state( + const ia_css_frame_t *frame) +{ + ia_css_buffer_state_t buffer_state = IA_CSS_N_BUFFER_STATES; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_get_buffer_state(): enter:\n"); + + verifexit(frame != NULL); + buffer_state = frame->buffer_state; + +EXIT: + if (frame == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_get_buffer_state invalid argument\n"); + } + return buffer_state; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_set_buffer_state( + ia_css_frame_t *frame, + const ia_css_buffer_state_t buffer_state) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_set_buffer_state(): enter:\n"); + + verifexit(frame != NULL); + frame->buffer_state = buffer_state; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_set_buffer_state failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +ia_css_pointer_state_t ia_css_frame_get_pointer_state( + const ia_css_frame_t *frame) +{ + ia_css_pointer_state_t pointer_state = IA_CSS_N_POINTER_STATES; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_get_pointer_state(): enter:\n"); + + verifexit(frame != NULL); + pointer_state = frame->pointer_state; + +EXIT: + if (frame == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_get_pointer_state invalid argument\n"); + } + return pointer_state; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_set_pointer_state( + ia_css_frame_t *frame, + const ia_css_pointer_state_t pointer_state) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_set_pointer_state(): enter:\n"); + + verifexit(frame != NULL); + frame->pointer_state = pointer_state; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_set_pointer_state failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_descriptor_print( + const ia_css_frame_descriptor_t *frame_descriptor, + void *fid) +{ + int retval = -1; + int i; + uint8_t frame_plane_count; + + NOT_USED(fid); + + IA_CSS_TRACE_0(PSYSAPI_DATA, INFO, + "ia_css_frame_descriptor_print(): enter:\n"); + + COMPILATION_ERROR_IF(IA_CSS_N_DATA_DIMENSION <= 0); + + verifexit(frame_descriptor != NULL); + + IA_CSS_TRACE_0(PSYSAPI_DATA, INFO, + "ia_css_frame_descriptor_print(): enter:\n"); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tframe_format_type = %d\n", + frame_descriptor->frame_format_type); + /* IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, "\tframe_format_type = %s\n", + * ia_css_frame_format_string(frame_descriptor->frame_format_type)); + */ + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tbpp = %d\n", frame_descriptor->bpp); + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tbpe = %d\n", frame_descriptor->bpe); + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tis_compressed = %d\n", frame_descriptor->is_compressed); + + frame_plane_count = IA_CSS_N_FRAME_PLANES; + /* frame_plane_count = + * ia_css_frame_plane_count(frame_descriptor->frame_format_type); + */ + + verifexit(frame_plane_count > 0); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tplane_offsets[%d]: [\n", frame_plane_count); + for (i = 0; i < (int)frame_plane_count - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", frame_descriptor->plane_offsets[i]); + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d ]\n", frame_descriptor->plane_offsets[i]); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tdimension[%d] = {\n", IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", frame_descriptor->dimension[i]); + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d }\n", frame_descriptor->dimension[i]); + + COMPILATION_ERROR_IF(0 > (IA_CSS_N_DATA_DIMENSION - 2)); + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tstride[%d] = {\n", IA_CSS_N_DATA_DIMENSION - 1); + i = 0; + if (IA_CSS_N_DATA_DIMENSION > 2) { + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 2; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", frame_descriptor->stride[i]); + } + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d }\n", frame_descriptor->stride[i]); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_descriptor_print failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_fragment_descriptor_print( + const ia_css_fragment_descriptor_t *fragment_descriptor, + void *fid) +{ + int retval = -1; + int i; + + NOT_USED(fid); + + IA_CSS_TRACE_0(PSYSAPI_DATA, INFO, + "ia_css_fragment_descriptor_print(): enter:\n"); + + verifexit(fragment_descriptor != NULL); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "dimension[%d] = {\n", IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", fragment_descriptor->dimension[i]); + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d }\n", fragment_descriptor->dimension[i]); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "index[%d] = {\n", IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", fragment_descriptor->index[i]); + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d }\n", fragment_descriptor->index[i]); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "offset[%d] = {\n", IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", fragment_descriptor->offset[i]); + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, "\t%4d }\n", + fragment_descriptor->offset[i]); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_fragment_descriptor_print failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +ia_css_frame_format_bitmap_t ia_css_frame_format_bit_mask( + const ia_css_frame_format_type_t frame_format_type) +{ + ia_css_frame_format_bitmap_t bit_mask = 0; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_format_bit_mask(): enter:\n"); + + if ((frame_format_type < IA_CSS_N_FRAME_FORMAT_TYPES) && + (frame_format_type < IA_CSS_FRAME_FORMAT_BITMAP_BITS)) { + bit_mask = (ia_css_frame_format_bitmap_t)1 << frame_format_type; + } else { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_format_bit_mask invalid argument\n"); + } + + return bit_mask; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +ia_css_frame_format_bitmap_t ia_css_frame_format_bitmap_clear(void) +{ + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_format_bitmap_clear(): enter:\n"); + + return 0; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +size_t ia_css_sizeof_frame_descriptor( + const uint8_t plane_count) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_sizeof_frame_descriptor(): enter:\n"); + + verifexit(plane_count > 0); + size += sizeof(ia_css_frame_descriptor_t); + size += plane_count * sizeof(uint32_t); + +EXIT: + if (plane_count == 0) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_sizeof_frame_descriptor invalid argument\n"); + } + return size; +} + +#endif /* __IA_CSS_PROGRAM_GROUP_DATA_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/bxtB0/ia_css_psys_transport_dep.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/bxtB0/ia_css_psys_transport_dep.h new file mode 100644 index 0000000000000..7bb145c1b183b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/bxtB0/ia_css_psys_transport_dep.h @@ -0,0 +1,35 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TRANSPORT_DEP_H +#define __IA_CSS_PSYS_TRANSPORT_DEP_H + +/* + * The ID's of the Psys specific queues. + */ +typedef enum ia_css_psys_cmd_queues { + /**< The in-order queue for scheduled process groups */ + IA_CSS_PSYS_CMD_QUEUE_COMMAND_ID = 0, + /**< The in-order queue for commands changing psys or + * process group state + */ + IA_CSS_PSYS_CMD_QUEUE_DEVICE_ID, + /**< An in-order queue for dedicated PPG commands */ + IA_CSS_PSYS_CMD_QUEUE_PPG0_COMMAND_ID, + /**< An in-order queue for dedicated PPG commands */ + IA_CSS_PSYS_CMD_QUEUE_PPG1_COMMAND_ID, + IA_CSS_N_PSYS_CMD_QUEUE_ID +} ia_css_psys_cmd_queue_ID_t; + +#endif /* __IA_CSS_PSYS_TRANSPORT_DEP_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device.h new file mode 100644 index 0000000000000..dc8fa531b11e3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device.h @@ -0,0 +1,516 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DEVICE_H +#define __IA_CSS_PSYS_DEVICE_H + +#include "ia_css_psys_init.h" +#include "ia_css_psys_transport.h" + +/*! \file */ + +/** @file ia_css_psys_device.h + * + * Define the interface to open the psys specific communication layer + * instance + */ + +#include /* vied_vaddress_t */ + +#include +#include + +#include +#include + +#define IA_CSS_PSYS_STATE_READY_PATTERN (0xF7F7F7F7) +#define IA_CSS_PSYS_STATE_RUNNING_PATTERN (0xE6E6E6E6) +#define IA_CSS_PSYS_STATE_STARTING_PATTERN (0xD5D5D5D5) +#define IA_CSS_PSYS_STATE_STARTED_PATTERN (0xC4C4C4C4) +#define IA_CSS_PSYS_STATE_INITIALIZING_PATTERN (0xB3B3B3B3) +#define IA_CSS_PSYS_STATE_INITIALIZED_PATTERN (0xA0A0A0A0) + +/* + * Defines the state of psys: + * - IA_CSS_PSYS_STATE_UNKNOWN = psys status is unknown (or not recognized) + * - IA_CSS_PSYS_STATE_INITIALING = some of the psys components are + * not initialized yet + * - IA_CSS_PSYS_STATE_INITIALIZED = psys components are initialized + * - IA_CSS_PSYS_STATE_STARTING = some of the psys components are initialized + * but not started yet + * - IA_CSS_PSYS_STATE_STARTED = psys components are started + * - IA_CSS_PSYS_STATE_RUNNING = some of the psys components are started + * but not ready yet + * - IA_CSS_PSYS_STATE_READY = psys is ready + * The state of psys can be obtained calling ia_css_psys_check_state() +*/ +typedef enum ia_css_psys_state { + IA_CSS_PSYS_STATE_UNKNOWN = 0, /**< psys state is unknown */ + /*< some of the psys components are not initialized yet*/ + IA_CSS_PSYS_STATE_INITIALIZING = IA_CSS_PSYS_STATE_INITIALIZING_PATTERN, + /**< psys components are initialized */ + IA_CSS_PSYS_STATE_INITIALIZED = IA_CSS_PSYS_STATE_INITIALIZED_PATTERN, + /**< some of the psys components are not started yet */ + IA_CSS_PSYS_STATE_STARTING = IA_CSS_PSYS_STATE_STARTING_PATTERN, + /**< psys components are started */ + IA_CSS_PSYS_STATE_STARTED = IA_CSS_PSYS_STATE_STARTED_PATTERN, + /**< some of the psys components are not ready yet */ + IA_CSS_PSYS_STATE_RUNNING = IA_CSS_PSYS_STATE_RUNNING_PATTERN, + /**< psys is ready */ + IA_CSS_PSYS_STATE_READY = IA_CSS_PSYS_STATE_READY_PATTERN, +} ia_css_psys_state_t; + +extern struct ia_css_syscom_context *psys_syscom; +#if HAS_DUAL_CMD_CTX_SUPPORT +extern struct ia_css_syscom_context *psys_syscom_secure; +#endif + +/*! Print the syscom creation descriptor to file/stream + + @param config[in] Psys syscom descriptor + @param fid[out] file/stream handle + + @return < 0 on error +*/ +extern int ia_css_psys_config_print( + const struct ia_css_syscom_config *config, void *fid); + +/*! Print the Psys syscom object to file/stream + + @param context[in] Psys syscom object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_psys_print( + const struct ia_css_syscom_context *context, void *fid); + +/*! Create the syscom creation descriptor + + @return NULL on error + */ +extern struct ia_css_syscom_config *ia_css_psys_specify(void); + +#if HAS_DUAL_CMD_CTX_SUPPORT +/*! Create the syscom creation descriptor for secure stream + + @param vtl0_addr_mask[in] VTL0 address mask that will be stored in 'secure' ctx + @return NULL on error + */ +extern struct ia_css_syscom_config *ia_css_psys_specify_secure(unsigned int vtl0_addr_mask); +#endif + +/*! Compute the size of storage required for allocating the Psys syscom object + + @param config[in] Psys syscom descriptor + + @return 0 on error + */ +extern size_t ia_css_sizeof_psys( + struct ia_css_syscom_config *config); + +#if HAS_DUAL_CMD_CTX_SUPPORT +/*! Open (and map the storage for) the Psys syscom object + This is the same as ia_css_psys_open() excluding server start. + Target for VTIO usage where multiple syscom objects need to be + created first before this API is invoked. + + @param buffer[in] storage buffers for the syscom object + in the kernel virtual memory space and + its Psys mapped version + @param config[in] Psys syscom descriptor + @return NULL on error + */ + +extern struct ia_css_syscom_context *ia_css_psys_context_create( + const struct ia_css_psys_buffer_s *buffer, + struct ia_css_syscom_config *config); + +/*! Store the parameters of the Psys syscom object in DMEM, so + they can be communicated with FW. This step needs to be invoked + after SPC starts in ia_css_psys_open(), so SPC DMEM access blocker + programming already takes effective. + + @param context[in] Psys syscom object + @param config[in] Psys syscom descriptor + @return 0 if successful + */ +extern int ia_css_psys_context_store_dmem( + struct ia_css_syscom_context *context, + struct ia_css_syscom_config *config); + +/*! Start PSYS Server. Psys syscom object must have been created already. + Target for VTIO usage where multiple syscom objects need to be + created first before this API is invoked. + @param config[in] Psys syscom descriptor + + @return true if psys open started successfully + */ +extern int ia_css_psys_open( + struct ia_css_syscom_config *config); +#else +/*! Open (and map the storage for) the Psys syscom object + + @param buffer[in] storage buffers for the syscom object + in the kernel virtual memory space and + its Psys mapped version + @param config[in] Psys syscom descriptor + + Precondition(1): The buffer must be large enough to hold the syscom object. + Its size must be computed with the function "ia_css_sizeof_psys()". + The buffer must be created in the kernel memory space. + + Precondition(2): If buffer == NULL, the storage allocations and mapping + is performed in this function. Config must hold the handle to the Psys + virtual memory space + + Postcondition: The context is initialised in the provided/created buffer. + The syscom context pointer is the kernel space handle to the syscom object + + @return NULL on error + */ +extern struct ia_css_syscom_context *ia_css_psys_open( + const struct ia_css_psys_buffer_s *buffer, + struct ia_css_syscom_config *config); +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +/*! completes the psys open procedure. Must be called multiple times + until it succeeds or driver determines the boot sequence has failed. + + @param context[in] Psys syscom object + + @return false if psys open has not completed successfully + */ +extern bool ia_css_psys_open_is_ready( + struct ia_css_syscom_context *context); + +#if HAS_DUAL_CMD_CTX_SUPPORT +/*! Request close of a PSYS context + * The functionatlity is the same as ia_css_psys_close() which closes PSYS syscom object. + * Counterpart of ia_css_psys_context_create() + * @param context[in]: Psys context + * @return NULL if close is successful context otherwise + */ +extern struct ia_css_syscom_context *ia_css_psys_context_destroy( + struct ia_css_syscom_context *context); + +/*! Request close of a PSYS device for VTIO case + * @param None + * @return 0 if successful + */ +extern int ia_css_psys_close(void); +#else +/*! Request close of a PSYS context + * @param context[in]: Psys context + * @return NULL if close is successful context otherwise + */ +extern struct ia_css_syscom_context *ia_css_psys_close( + struct ia_css_syscom_context *context); +#endif /* HAS_DUAL_CMD_CTX_SUPPORT*/ + +/*! Unmap and free the storage of the PSYS context + * @param context[in] Psys context + * @param force[in] Force release even if device is busy + * @return 0 if release is successful + * EINVAL if context is invalid + * EBUSY if device is not yet idle, and force==0 + */ +extern int ia_css_psys_release( + struct ia_css_syscom_context *context, + bool force); + +/*! Checks the state of the Psys syscom object + + @param context[in] Psys syscom object + + @return State of the syscom object + */ +extern ia_css_psys_state_t ia_css_psys_check_state( + struct ia_css_syscom_context *context); + +/*!Indicate if the designated cmd queue in the Psys syscom object is full + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + + @return false if the cmd queue is not full or on error + */ + +extern bool ia_css_is_psys_cmd_queue_full( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id); + +/*!Indicate if the designated cmd queue in the Psys syscom object is notfull + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + + @return false if the cmd queue is full on error + */ +extern bool ia_css_is_psys_cmd_queue_not_full( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id); + +/*!Indicate if the designated cmd queue in the Psys syscom object holds N space + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + @param N[in] Number of messages + + @return false if the cmd queue space is unavailable or on error + */ +extern bool ia_css_has_psys_cmd_queue_N_space( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const unsigned int N); + +/*!Return the free space count in the designated cmd queue in the + * Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + + @return the space, < 0 on error + */ +extern int ia_css_psys_cmd_queue_get_available_space( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id); + +/*!Indicate if there are any messages pending in the Psys syscom + * object event queues + + @param context[in] Psys syscom object + + @return false if there are no messages or on error + */ +extern bool ia_css_any_psys_event_queue_not_empty( + struct ia_css_syscom_context *context); + +/*!Indicate if the designated event queue in the Psys syscom object is empty + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + + @return false if the event queue is not empty or on error + */ +extern bool ia_css_is_psys_event_queue_empty( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id); + +/*!Indicate if the designated event queue in the Psys syscom object is not empty + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + + @return false if the receive queue is empty or on error + */ +extern bool ia_css_is_psys_event_queue_not_empty( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id); + +/*!Indicate if the designated event queue + * in the Psys syscom object holds N items + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + @param N[in] Number of messages + + @return false if the event queue has insufficient messages + available or on error +*/ +extern bool ia_css_has_psys_event_queue_N_msgs( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + const unsigned int N); + +/*!Return the message count in the designated event queue in the + * Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + + @return the messages, < 0 on error + */ +extern int ia_css_psys_event_queue_get_available_msgs( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id); + +/*! Send (pass by value) a command on a queue in the Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID +@param cmd_msg_buffer[in] pointer to the command message buffer + +Precondition: The command message buffer must be large enough + to hold the command + +Postcondition: Either 0 or 1 commands have been sent + +Note: The message size is fixed and determined on creation + + @return the number of sent commands (1), <= 0 on error + */ +extern int ia_css_psys_cmd_queue_send( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const void *cmd_msg_buffer); + +/*! Send (pass by value) N commands on a queue in the Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + @param cmd_msg_buffer[in] Pointer to the command message buffer +@param N[in] Number of commands + +Precondition: The command message buffer must be large enough + to hold the commands + +Postcondition: Either 0 or up to and including N commands have been sent + + Note: The message size is fixed and determined on creation + + @return the number of sent commands, <= 0 on error + */ +extern int ia_css_psys_cmd_queue_send_N( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const void *cmd_msg_buffer, + const unsigned int N); + +/*! Receive (pass by value) an event from an event queue in the + * Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + @param event_msg_buffer[out] pointer to the event message buffer + + Precondition: The event message buffer must be large enough to hold the event + + Postcondition: Either 0 or 1 events have been received + + Note: The event size is fixed and determined on creation + + @return the number of received events (1), <= 0 on error + */ +extern int ia_css_psys_event_queue_receive( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + void *event_msg_buffer); + +/*! Receive (pass by value) N events from an event queue in the + * Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + @param event_msg_buffer[out] pointer to the event message buffer + @param N[in] Number of events + + Precondition: The event buffer must be large enough to hold the events + + Postcondition: Either 0 or up to and including N events have been received + + Note: The message size is fixed and determined on creation + + @return the number of received event messages, <= 0 on error + */ +extern int ia_css_psys_event_queue_receive_N( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + void *event_msg_buffer, + const unsigned int N); + + +/* + * Access functions to query the object stats + */ + + +/*!Return the size of the Psys syscom object + + @param context[in] Psys syscom object + + @return 0 on error + */ +extern size_t ia_css_psys_get_size( + const struct ia_css_syscom_context *context); + +/*!Return the number of cmd queues in the Psys syscom object + + @param context[in] Psys syscom object + + @return 0 on error + */ +extern unsigned int ia_css_psys_get_cmd_queue_count( + const struct ia_css_syscom_context *context); + +/*!Return the number of event queues in the Psys syscom object + + @param context[in] Psys syscom object + + @return 0 on error + */ +extern unsigned int ia_css_psys_get_event_queue_count( + const struct ia_css_syscom_context *context); + +/*!Return the size of the indicated Psys command queue + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + + Note: The queue size is expressed in the number of fields + + @return 0 on error + */ +extern size_t ia_css_psys_get_cmd_queue_size( + const struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id); + +/*!Return the size of the indicated Psys event queue + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + + Note: The queue size is expressed in the number of fields + + @return 0 on error + */ +extern size_t ia_css_psys_get_event_queue_size( + const struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id); + +/*!Return the command message size of the indicated Psys command queue + + @param context[in] Psys syscom object + + Note: The message size is expressed in uint8_t + + @return 0 on error + */ +extern size_t ia_css_psys_get_cmd_msg_size( + const struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id); + +/*!Return the event message size of the indicated Psys event queue + + @param context[in] Psys syscom object + + Note: The message size is expressed in uint8_t + + @return 0 on error + */ +extern size_t ia_css_psys_get_event_msg_size( + const struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id); + +#endif /* __IA_CSS_PSYS_DEVICE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device_trace.h new file mode 100644 index 0000000000000..8e5899bc66dba --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device_trace.h @@ -0,0 +1,103 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DEVICE_TRACE_H +#define __IA_CSS_PSYS_DEVICE_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_DEVICE_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_DEVICE_TRACING_OVERRIDE)) + #define PSYS_DEVICE_TRACE_LEVEL_CONFIG \ + PSYS_DEVICE_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_DEVICE_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_DEVICE_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_DEVICE_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_DEVICE_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DEVICE_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DEVICE_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_DEVICE_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DEVICE_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DEVICE_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_DEVICE_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DEVICE_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_DEVICE_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_DEVICE_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_DEVICE_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_DEVICE_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_DEVICE_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_DEVICE_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_DEVICE_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_DEVICE_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_init.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_init.h new file mode 100644 index 0000000000000..1120b357632cf --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_init.h @@ -0,0 +1,37 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_INIT_H +#define __IA_CSS_PSYS_INIT_H + +#include /* vied_vaddress_t */ + +/* Init parameters passed to the fw on device open (non secure mode) */ +typedef struct ia_css_psys_server_init { + /* These members are used in PSS only and will be removed */ + /* Shared memory host address of pkg dir */ + unsigned long long host_ddr_pkg_dir; + /* Address of pkg_dir structure in DDR */ + vied_vaddress_t ddr_pkg_dir_address; + /* Size of Package dir in DDR */ + uint32_t pkg_dir_size; + + /* Prefetch configiration */ + /* enable prefetching on SPC, SPP0 and SPP1 */ + uint32_t icache_prefetch_sp; + /* enable prefetching on ISP0..N */ + uint32_t icache_prefetch_isp; +} ia_css_psys_server_init_t; + +#endif /* __IA_CSS_PSYS_INIT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_transport.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_transport.h new file mode 100644 index 0000000000000..e0d1e935c2211 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_transport.h @@ -0,0 +1,92 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TRANSPORT_H +#define __IA_CSS_PSYS_TRANSPORT_H + +#include /* ia_css_psys_cmd_queues */ +#include /* vied_vaddress_t */ + +#include + +typedef enum ia_css_psys_event_queues { + /**< The in-order queue for event returns */ + IA_CSS_PSYS_EVENT_QUEUE_MAIN_ID, + IA_CSS_N_PSYS_EVENT_QUEUE_ID +} ia_css_psys_event_queue_ID_t; + +typedef enum ia_css_psys_event_types { + /**< No error to report. */ + IA_CSS_PSYS_EVENT_TYPE_SUCCESS = 0, + /**< Unknown unhandled error */ + IA_CSS_PSYS_EVENT_TYPE_UNKNOWN_ERROR = 1, + /* Retrieving remote object: */ + /**< Object ID not found */ + IA_CSS_PSYS_EVENT_TYPE_RET_REM_OBJ_NOT_FOUND = 2, + /**< Objects too big, or size is zero. */ + IA_CSS_PSYS_EVENT_TYPE_RET_REM_OBJ_TOO_BIG = 3, + /**< Failed to load whole process group from tproxy/dma */ + IA_CSS_PSYS_EVENT_TYPE_RET_REM_OBJ_DDR_TRANS_ERR = 4, + /**< The proper package could not be found */ + IA_CSS_PSYS_EVENT_TYPE_RET_REM_OBJ_NULL_PKG_DIR_ADDR = 5, + /* Process group: */ + /**< Failed to run, error while loading frame */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_LOAD_FRAME_ERR = 6, + /**< Failed to run, error while loading fragment */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_LOAD_FRAGMENT_ERR = 7, + /**< The process count of the process group is zero */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_PROCESS_COUNT_ZERO = 8, + /**< Process(es) initialization */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_PROCESS_INIT_ERR = 9, + /**< Aborted (after host request) */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_ABORT = 10, + /**< NULL pointer in the process group */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_NULL = 11, + /**< Process group validation failed */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_VALIDATION_ERR = 12 +} ia_css_psys_event_type_t; + +#define IA_CSS_PSYS_CMD_BITS 64 +struct ia_css_psys_cmd_s { + /**< The command issued to the process group */ + uint16_t command; + /**< Message field of the command */ + uint16_t msg; + /**< The context reference (process group/buffer set/...) */ + uint32_t context_handle; +}; + +#define IA_CSS_PSYS_EVENT_BITS 128 +struct ia_css_psys_event_s { + /**< The (return) status of the command issued to + * the process group this event refers to + */ + uint16_t status; + /**< The command issued to the process group this event refers to */ + uint16_t command; + /**< The context reference (process group/buffer set/...) */ + uint32_t context_handle; + /**< This token (size) must match the token registered + * in a process group + */ + uint64_t token; +}; + +struct ia_css_psys_buffer_s { + /**< The in-order queue for scheduled process groups */ + void *host_buffer; + vied_vaddress_t *isp_buffer; +}; + +#endif /* __IA_CSS_PSYS_TRANSPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/src/ia_css_psys_device.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/src/ia_css_psys_device.c new file mode 100644 index 0000000000000..658b377352a6d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/device/src/ia_css_psys_device.c @@ -0,0 +1,854 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_psys_device.h" +#include "ia_css_psys_device_trace.h" +#include "ia_css_psys_init.h" +#include "regmem_access.h" + +#include +#include +#include + +#include "ia_css_cell.h" + +#define IA_CSS_PSYS_CMD_QUEUE_SIZE 0x20 +#define IA_CSS_PSYS_EVENT_QUEUE_SIZE 0x40 + +static struct ia_css_syscom_queue_config ia_css_psys_cmd_queue_cfg[IA_CSS_N_PSYS_CMD_QUEUE_ID]; + +static struct ia_css_syscom_queue_config + ia_css_psys_event_queue_cfg[IA_CSS_N_PSYS_EVENT_QUEUE_ID] = { + {IA_CSS_PSYS_EVENT_QUEUE_SIZE, IA_CSS_PSYS_EVENT_BITS/8}, +}; + +static struct ia_css_syscom_config psys_syscom_config; +struct ia_css_syscom_context *psys_syscom; +#if HAS_DUAL_CMD_CTX_SUPPORT +static struct ia_css_syscom_config psys_syscom_config_secure; +struct ia_css_syscom_context *psys_syscom_secure; +#endif +static bool external_alloc = true; + +int ia_css_psys_config_print( + const struct ia_css_syscom_config *config, + void *fh) +{ + int retval = -1; + + NOT_USED(fh); + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "ia_css_frame_print(): enter:\n"); + + verifexit(config != NULL); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DEVICE, ERROR, + "ia_css_frame_print failed (%i)\n", retval); + } + return retval; +} + +int ia_css_psys_print( + const struct ia_css_syscom_context *context, + void *fh) +{ + int retval = -1; + + NOT_USED(fh); + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "ia_css_psys_print(): enter:\n"); + + verifexit(context != NULL); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_print failed (%i)\n", retval); + } + return retval; +} + +static void set_syscom_config(struct ia_css_syscom_config *config) +{ + int i; + + config->num_input_queues = IA_CSS_N_PSYS_CMD_QUEUE_ID; + config->num_output_queues = IA_CSS_N_PSYS_EVENT_QUEUE_ID; + /* The number of queues are different for different platforms + * so the array is initialized here + */ + for (i = 0; i < IA_CSS_N_PSYS_CMD_QUEUE_ID; i++) { + ia_css_psys_cmd_queue_cfg[i].queue_size = IA_CSS_PSYS_CMD_QUEUE_SIZE; + ia_css_psys_cmd_queue_cfg[i].token_size = IA_CSS_PSYS_CMD_BITS/8; + } + config->input = ia_css_psys_cmd_queue_cfg; + config->output = ia_css_psys_event_queue_cfg; + config->vtl0_addr_mask = 0; +} + +struct ia_css_syscom_config *ia_css_psys_specify(void) +{ + struct ia_css_syscom_config *config = &psys_syscom_config; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "ia_css_psys_specify(): enter:\n"); + set_syscom_config(config); + config->secure = false; + + return config; +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +struct ia_css_syscom_config *ia_css_psys_specify_secure(unsigned int vtl0_addr_mask) +{ + struct ia_css_syscom_config *config = &psys_syscom_config_secure; + + IA_CSS_TRACE_1(PSYSAPI_DEVICE, INFO, "ia_css_psys_specify_secure(mask %#x): enter:\n", vtl0_addr_mask); + set_syscom_config(config); + config->secure = true; + config->vtl0_addr_mask = vtl0_addr_mask; + return config; +} +#endif + +size_t ia_css_sizeof_psys( + struct ia_css_syscom_config *config) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_sizeof_psys(): enter:\n"); + + NOT_USED(config); + + return size; +} + +/* Internal function to create syscom_context */ +static struct ia_css_syscom_context *psys_context_create( + const struct ia_css_psys_buffer_s *buffer, + struct ia_css_syscom_config *config) +{ + struct ia_css_syscom_context *context; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "psys_context_create(): enter:\n"); + + if (config == NULL) + goto EXIT; + + if (buffer == NULL) { + /* Allocate locally */ + external_alloc = false; + } + + /* + * Here we would like to pass separately the sub-system ID + * and optionally the user pointer to be mapped, depending on + * where this open is called, and which virtual memory handles + * we see here. + */ + /* context = ia_css_syscom_open(get_virtual_memory_handle(vied_psys_ID), + * buffer, config); + */ + context = ia_css_syscom_open(config, NULL); + if (context == NULL) + goto EXIT; + + return context; + +EXIT: + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, "psys_context_create failed\n"); + return NULL; +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +struct ia_css_syscom_context *ia_css_psys_context_create( + const struct ia_css_psys_buffer_s *buffer, + struct ia_css_syscom_config *config) +{ + return psys_context_create(buffer, config); +} + +/* push context information to DMEM for FW to access */ +int ia_css_psys_context_store_dmem( + struct ia_css_syscom_context *context, + struct ia_css_syscom_config *config) +{ + return ia_css_syscom_store_dmem(context, config->ssid, config->vtl0_addr_mask); +} +#endif + +/* Internal function to start psys server */ +static int psys_start_server( + struct ia_css_syscom_config *config) +{ + ia_css_psys_server_init_t *server_config; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "psys_start_server(): enter:\n"); + + /* Configure SPC icache prefetching and start SPC */ + server_config = (ia_css_psys_server_init_t *)config->specific_addr; + IA_CSS_TRACE_1(PSYSAPI_DEVICE, INFO, "SPC prefetch: %d\n", + server_config->icache_prefetch_sp); + ia_css_cell_start_prefetch(config->ssid, SPC0, + server_config->icache_prefetch_sp); + return 0; +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +int ia_css_psys_open( + struct ia_css_syscom_config *config) +{ + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "ia_css_psys_open(): enter:\n"); + return psys_start_server(config); +} +#else +struct ia_css_syscom_context *ia_css_psys_open( + const struct ia_css_psys_buffer_s *buffer, + struct ia_css_syscom_config *config) +{ + struct ia_css_syscom_context *context; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "ia_css_psys_open(): enter:\n"); + + context = psys_context_create(buffer, config); + + /* Configure SPC icache prefetching and start SPC */ + psys_start_server(config); + + return context; +} +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +bool ia_css_psys_open_is_ready( + struct ia_css_syscom_context *context) +{ + int retval = -1; + bool ready = 0; + unsigned int i; + int syscom_retval; + + verifexit(context != NULL); + + for (i = 0; i < IA_CSS_N_PSYS_CMD_QUEUE_ID; i++) { + syscom_retval = ia_css_syscom_send_port_open(context, i); + if (syscom_retval != 0) { + if (syscom_retval == FW_ERROR_BUSY) { + /* Do not print error */ + retval = 0; + } + /* Not ready yet */ + goto EXIT; + } + } + + for (i = 0; i < IA_CSS_N_PSYS_EVENT_QUEUE_ID; i++) { + syscom_retval = ia_css_syscom_recv_port_open(context, i); + if (syscom_retval != 0) { + if (syscom_retval == FW_ERROR_BUSY) { + /* Do not print error */ + retval = 0; + } + /* Not ready yet */ + goto EXIT; + } + } + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, + "ia_css_psys_open_is_ready(): complete:\n"); + + /* If this point reached, do not print error */ + retval = 0; + /* If this point reached, ready */ + ready = 1; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_open_is_ready failed\n"); + } + return ready; +} + +/* Internal function to close syscom_context */ +static struct ia_css_syscom_context *psys_context_destroy( + struct ia_css_syscom_context *context) +{ + /* Success: return NULL, Error: return context pointer value + * Intention is to change return type to int (errno), + * see commented values. + */ + + unsigned int i; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "psys_context_destroy(): enter:\n"); + + /* NULL pointer check disabled, since there is no proper return value */ + + for (i = 0; i < IA_CSS_N_PSYS_CMD_QUEUE_ID; i++) { + if (ia_css_syscom_send_port_close(context, i) != 0) + return context; /* EINVAL */ + } + + for (i = 0; i < IA_CSS_N_PSYS_EVENT_QUEUE_ID; i++) { + if (ia_css_syscom_recv_port_close(context, i) != 0) + return context; /* EINVAL */ + } + + /* request device close */ + if (ia_css_syscom_close(context) != 0) + return context; /* EBUSY */ + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, + "psys_context_destroy(): leave: OK\n"); + return NULL; +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +struct ia_css_syscom_context *ia_css_psys_context_destroy( + struct ia_css_syscom_context *context) +{ + return psys_context_destroy(context); +} + +int ia_css_psys_close(void) +{ + /* Intentionally left blank for now since syscom objects should have + * been destroyed already by prior ia_css_psys_context_destroy() calls. + */ + return 0; +} +#else +struct ia_css_syscom_context *ia_css_psys_close( + struct ia_css_syscom_context *context) +{ + return psys_context_destroy(context); +} +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +int ia_css_psys_release( + struct ia_css_syscom_context *context, + bool force) +{ + if (context == NULL) + return -EFAULT; + + /* try to free resources */ + if (ia_css_syscom_release(context, force) != 0) + return -EBUSY; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, + "ia_css_psys_release(): leave: OK\n"); + return 0; +} + +ia_css_psys_state_t ia_css_psys_check_state( + struct ia_css_syscom_context *context) +{ + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_check_state(): enter:\n"); + + NOT_USED(context); + + /* For the time being, return the READY state to be used by SPC test */ + return IA_CSS_PSYS_STATE_READY; +} + +bool ia_css_is_psys_cmd_queue_full( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id) +{ + bool is_full = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_is_psys_cmd_queue_full(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_send_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + is_full = (num_tokens == 0); + retval = 0; +EXIT: + if (retval != 0) { + is_full = true; + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_is_psys_cmd_queue_full failed\n"); + } + return is_full; +} + +bool ia_css_is_psys_cmd_queue_not_full( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id) +{ + bool is_not_full = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_is_psys_cmd_queue_not_full(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_send_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + is_not_full = (num_tokens != 0); + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_is_psys_cmd_queue_not_full failed\n"); + } + return is_not_full; +} + +bool ia_css_has_psys_cmd_queue_N_space( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const unsigned int N) +{ + bool has_N_space = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_has_psys_cmd_queue_N_space(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_send_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + has_N_space = ((unsigned int)num_tokens >= N); +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_has_psys_cmd_queue_N_space failed\n"); + } + return has_N_space; +} + +int ia_css_psys_cmd_queue_get_available_space( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id) +{ + int N_space = -1; + int num_tokens; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_cmd_queue_get_available_space(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_send_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + N_space = (int)(num_tokens); +EXIT: + if (N_space < 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_cmd_queue_get_available_space failed\n"); + } + return N_space; +} + +bool ia_css_any_psys_event_queue_not_empty( + struct ia_css_syscom_context *context) +{ + ia_css_psys_event_queue_ID_t i; + bool any_msg = false; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_any_psys_event_queue_not_empty(): enter:\n"); + verifexit(context != NULL); + + for (i = (ia_css_psys_event_queue_ID_t)0; + i < IA_CSS_N_PSYS_EVENT_QUEUE_ID; i++) { + any_msg = + any_msg || ia_css_is_psys_event_queue_not_empty(context, i); + } + +EXIT: + return any_msg; +} + +bool ia_css_is_psys_event_queue_empty( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id) +{ + bool is_empty = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_is_psys_event_queue_empty(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_recv_port_available(context, (unsigned int)id); + verifexit(num_tokens >= 0); + + is_empty = (num_tokens == 0); + retval = 0; +EXIT: + if (retval != 0) { + is_empty = true; + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_is_psys_event_queue_empty failed\n"); + } + return is_empty; +} + +bool ia_css_is_psys_event_queue_not_empty( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id) +{ + bool is_not_empty = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_is_psys_event_queue_not_empty(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_recv_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + is_not_empty = (num_tokens != 0); + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_is_psys_event_queue_not_empty failed\n"); + } + return is_not_empty; +} + +bool ia_css_has_psys_event_queue_N_msgs( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + const unsigned int N) +{ + bool has_N_msgs = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_has_psys_event_queue_N_msgs(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_recv_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + has_N_msgs = ((unsigned int)num_tokens >= N); + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_has_psys_event_queue_N_msgs failed\n"); + } + return has_N_msgs; +} + +int ia_css_psys_event_queue_get_available_msgs( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id) +{ + int N_msgs = -1; + int num_tokens; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_event_queue_get_available_msgs(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_recv_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + N_msgs = (int)(num_tokens); +EXIT: + if (N_msgs < 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_event_queue_get_available_msgs failed\n"); + } + return N_msgs; +} + +int ia_css_psys_cmd_queue_send( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const void *cmd_msg_buffer) +{ + int count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_cmd_queue_send(): enter:\n"); + verifexit(context != NULL); + + verifexit(context != NULL); + /* The ~full check fails on receive queues */ + verifexit(ia_css_is_psys_cmd_queue_not_full(context, id)); + verifexit(cmd_msg_buffer != NULL); + + verifexit(ia_css_syscom_send_port_transfer(context, (unsigned int)id, + cmd_msg_buffer) >= 0); + + count = 1; +EXIT: + if (count == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_cmd_queue_send failed\n"); + } + return count; +} + +int ia_css_psys_cmd_queue_send_N( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const void *cmd_msg_buffer, + const unsigned int N) +{ + struct ia_css_psys_cmd_s *cmd_msg_buffer_loc = + (struct ia_css_psys_cmd_s *)cmd_msg_buffer; + int count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_cmd_queue_send_N(): enter:\n"); + verifexit(context != NULL); + + for (count = 0; count < (int)N; count++) { + int count_loc = ia_css_psys_cmd_queue_send(context, id, + (void *)(&cmd_msg_buffer_loc[count])); + + verifexit(count_loc == 1); + } + +EXIT: + if ((unsigned int) count < N) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_cmd_queue_send_N failed\n"); + } + return count; +} + +int ia_css_psys_event_queue_receive( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + void *event_msg_buffer) +{ + int count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_event_queue_receive(): enter:\n"); + + verifexit(context != NULL); + /* The ~empty check fails on send queues */ + verifexit(ia_css_is_psys_event_queue_not_empty(context, id)); + verifexit(event_msg_buffer != NULL); + + verifexit(ia_css_syscom_recv_port_transfer(context, (unsigned int)id, + event_msg_buffer) >= 0); + + count = 1; +EXIT: + if (count == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_event_queue_receive failed\n"); + } + return count; +} + +int ia_css_psys_event_queue_receive_N( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + void *event_msg_buffer, + const unsigned int N) +{ + struct ia_css_psys_event_s *event_msg_buffer_loc; + int count; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_event_queue_receive_N(): enter:\n"); + + event_msg_buffer_loc = (struct ia_css_psys_event_s *)event_msg_buffer; + + for (count = 0; count < (int)N; count++) { + int count_loc = ia_css_psys_event_queue_receive(context, id, + (void *)(&event_msg_buffer_loc[count])); + + verifexit(count_loc == 1); + } + +EXIT: + if ((unsigned int) count < N) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_event_queue_receive_N failed\n"); + } + return count; +} + +size_t ia_css_psys_get_size( + const struct ia_css_syscom_context *context) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_size(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ +EXIT: + if (size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_size failed\n"); + } + return size; +} + +unsigned int ia_css_psys_get_cmd_queue_count( + const struct ia_css_syscom_context *context) +{ + unsigned int count = 0; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_cmd_queue_count(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + count = (unsigned int)IA_CSS_N_PSYS_CMD_QUEUE_ID; + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_cmd_queue_count failed\n"); + } + return count; +} + +unsigned int ia_css_psys_get_event_queue_count( + const struct ia_css_syscom_context *context) +{ + unsigned int count = 0; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_event_queue_count(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + count = (unsigned int)IA_CSS_N_PSYS_EVENT_QUEUE_ID; + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_event_queue_count failed\n"); + } + return count; +} + +size_t ia_css_psys_get_cmd_queue_size( + const struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id) +{ + size_t queue_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_cmd_queue_size(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + queue_size = ia_css_psys_cmd_queue_cfg[id].queue_size; +EXIT: + if (queue_size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_cmd_queue_size failed\n"); + } + return queue_size; +} + +size_t ia_css_psys_get_event_queue_size( + const struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id) +{ + size_t queue_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_event_queue_size(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + queue_size = ia_css_psys_event_queue_cfg[id].queue_size; +EXIT: + if (queue_size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_event_queue_size failed\n"); + } + return queue_size; +} + +size_t ia_css_psys_get_cmd_msg_size( + const struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id) +{ + size_t msg_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_cmd_msg_size(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + msg_size = ia_css_psys_cmd_queue_cfg[id].token_size; +EXIT: + if (msg_size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_cmd_msg_size failed\n"); + } + return msg_size; +} + +size_t ia_css_psys_get_event_msg_size( + const struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id) +{ + size_t msg_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_event_msg_size(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + msg_size = ia_css_psys_event_queue_cfg[id].token_size; +EXIT: + if (msg_size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_cmd_msg_size failed\n"); + } + return msg_size; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_buffer_set.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_buffer_set.h new file mode 100644 index 0000000000000..392b4359353f4 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_buffer_set.h @@ -0,0 +1,174 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_PSYS_BUFFER_SET_H +#define __IA_CSS_PSYS_BUFFER_SET_H + +#include "ia_css_base_types.h" +#include "ia_css_psys_dynamic_storage_class.h" +#include "ia_css_psys_process_types.h" +#include "ia_css_terminal_types.h" + +#define N_UINT64_IN_BUFFER_SET_STRUCT 1 +#define N_UINT16_IN_BUFFER_SET_STRUCT 1 +#define N_UINT8_IN_BUFFER_SET_STRUCT 1 +#define N_PADDING_UINT8_IN_BUFFER_SET_STRUCT 5 +#define SIZE_OF_BUFFER_SET \ + (N_UINT64_IN_BUFFER_SET_STRUCT * IA_CSS_UINT64_T_BITS \ + + VIED_VADDRESS_BITS \ + + VIED_VADDRESS_BITS \ + + N_UINT16_IN_BUFFER_SET_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_UINT8_IN_BUFFER_SET_STRUCT * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_BUFFER_SET_STRUCT * IA_CSS_UINT8_T_BITS) + +typedef struct ia_css_buffer_set_s ia_css_buffer_set_t; + +struct ia_css_buffer_set_s { + /* Token for user context reference */ + uint64_t token; + /* IPU virtual address of this buffer set */ + vied_vaddress_t ipu_virtual_address; + /* IPU virtual address of the process group corresponding to this buffer set */ + vied_vaddress_t process_group_handle; + /* Number of terminal buffer addresses in this structure */ + uint16_t terminal_count; + /* Frame id to associate with this buffer set */ + uint8_t frame_counter; + /* Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_BUFFER_SET_STRUCT]; +}; + + +/*! Construct a buffer set object at specified location + + @param buffer_set_mem[in] memory location to create buffer set object + @param process_group[in] process group corresponding to this buffer set + @param frame_counter[in] frame number for this buffer set object + + @return pointer to buffer set object on success, NULL on error + */ +ia_css_buffer_set_t *ia_css_buffer_set_create( + void *buffer_set_mem, + const ia_css_process_group_t *process_group, + const unsigned int frame_counter); + +/*! Compute size (in bytes) required for full buffer set object + + @param process_group[in] process group corresponding to this buffer set + + @return size in bytes of buffer set object on success, 0 on error + */ +size_t ia_css_sizeof_buffer_set( + const ia_css_process_group_t *process_group); + +/*! Set a buffer address in a buffer set object + + @param buffer_set[in] buffer set object to set buffer in + @param terminal_index[in] terminal index to use as a reference between + buffer and terminal + @param buffer[in] buffer address to store + + @return 0 on success, -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_buffer_set_set_buffer( + ia_css_buffer_set_t *buffer_set, + const unsigned int terminal_index, + const vied_vaddress_t buffer); + +/*! Get virtual buffer address from a buffer set object and terminal object by + resolving the index used + + @param buffer_set[in] buffer set object to get buffer from + @param terminal[in] terminal object to get buffer of + + @return virtual buffer address on success, VIED_NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_vaddress_t ia_css_buffer_set_get_buffer( + const ia_css_buffer_set_t *buffer_set, + const ia_css_terminal_t *terminal); + +/*! Set ipu virtual address of a buffer set object within the buffer set object + + @param buffer_set[in] buffer set object to set ipu address in + @param ipu_vaddress[in] ipu virtual address of the buffer set object + + @return 0 on success, -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_buffer_set_set_ipu_address( + ia_css_buffer_set_t *buffer_set, + const vied_vaddress_t ipu_vaddress); + +/*! Get ipu virtual address from a buffer set object + + @param buffer_set[in] buffer set object to get ipu address from + + @return virtual buffer set address on success, VIED_NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_vaddress_t ia_css_buffer_set_get_ipu_address( + const ia_css_buffer_set_t *buffer_set); + +/*! Set process group handle in a buffer set object + + @param buffer_set[in] buffer set object to set handle in + @param process_group_handle[in] process group handle of the buffer set + object + + @return 0 on success, -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_buffer_set_set_process_group_handle( + ia_css_buffer_set_t *buffer_set, + const vied_vaddress_t process_group_handle); + +/*! Get process group handle from a buffer set object + + @param buffer_set[in] buffer set object to get handle from + + @return virtual process group address on success, VIED_NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_vaddress_t ia_css_buffer_set_get_process_group_handle( + const ia_css_buffer_set_t *buffer_set); + +/*! Set token of a buffer set object within the buffer set object + + @param buffer_set[in] buffer set object to set ipu address in + @param token[in] token of the buffer set object + + @return 0 on success, -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_buffer_set_set_token( + ia_css_buffer_set_t *buffer_set, + const uint64_t token); + +/*! Get token from a buffer set object + + @param buffer_set[in] buffer set object to get token from + + @return token on success, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint64_t ia_css_buffer_set_get_token( + const ia_css_buffer_set_t *buffer_set); + +#ifdef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_buffer_set_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +#endif /* __IA_CSS_PSYS_BUFFER_SET_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_storage_class.h new file mode 100644 index 0000000000000..9a1e3a7a12949 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_storage_class.h @@ -0,0 +1,28 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +#define __IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#define IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +#else +#define IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_trace.h new file mode 100644 index 0000000000000..e8a979dfce0bf --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_trace.h @@ -0,0 +1,103 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DYNAMIC_TRACE_H +#define __IA_CSS_PSYS_DYNAMIC_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_DYNAMIC_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_DYNAMIC_TRACING_OVERRIDE)) + #define PSYS_DYNAMIC_TRACE_LEVEL_CONFIG \ + PSYS_DYNAMIC_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_DYNAMIC_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_DYNAMIC_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_DYNAMIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_DYNAMIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DYNAMIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_DYNAMIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DYNAMIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_DYNAMIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_DYNAMIC_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_DYNAMIC_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.h new file mode 100644 index 0000000000000..fd4c6608c9310 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.h @@ -0,0 +1,396 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_H +#define __IA_CSS_PSYS_PROCESS_H + +/*! \file */ + +/** @file ia_css_psys_process.h + * + * Define the methods on the process object that are not part of + * a single interface + */ + +#include +#include + +#include + +#include /* uint8_t */ + +/* + * Creation + */ +#include + +/* + * Internal resources + */ +#include + +/* + * Process manager + */ +#include + +/* + * Command processor + */ + +/*! Execute a command locally or send it to be processed remotely + + @param process[in] process object + @param cmd[in] command + + @return < 0 on invalid argument(s) or process state + */ +extern int ia_css_process_cmd( + ia_css_process_t *process, + const ia_css_process_cmd_t cmd); + +/*! Get the internal memory offset of the process object + + @param process[in] process object + @param mem_id[in] memory id + + @return internal memory offset, + IA_CSS_PROCESS_INVALID_OFFSET on invalid argument(s) +*/ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_size_t ia_css_process_get_int_mem_offset( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_id); + + +/*! Get the external memory offset of the process object + + @param process[in] process object + @param mem_id[in] memory id + + @return external memory offset, + IA_CSS_PROCESS_INVALID_OFFSET on invalid argument(s) +*/ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_size_t ia_css_process_get_ext_mem_offset( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id); + + +/*! Get the stored size of the process object + + @param process[in] process object + + @return size, 0 on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +size_t ia_css_process_get_size(const ia_css_process_t *process); + +/*! Get the (pointer to) the process group parent of the process object + + @param process[in] process object + + @return the pointer to the parent, NULL on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_process_group_t *ia_css_process_get_parent( + const ia_css_process_t *process); + +/*! Set the (pointer to) the process group parent of the process object + + @param process[in] process object + @param parent[in] (pointer to the) process group parent object + + @return < 0 on invalid argument(s) + */ +extern int ia_css_process_set_parent( + ia_css_process_t *process, + ia_css_process_group_t *parent); + +/*! Get the unique ID of program used by the process object + + @param process[in] process object + + @return ID, 0 on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_program_ID_t ia_css_process_get_program_ID( + const ia_css_process_t *process); + +/*! Get the state of the process object + + @param process[in] process object + + @return state, limit value (IA_CSS_N_PROCESS_STATES) on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_process_state_t ia_css_process_get_state( + const ia_css_process_t *process); + +/*! Set the state of the process object + + @param process[in] process object + @param state[in] state of the process + + @return < 0 on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_set_state( + ia_css_process_t *process, + ia_css_process_state_t state); + +/*! Get the assigned cell of the process object + + @param process[in] process object + + @return cell ID, limit value (VIED_NCI_N_CELL_ID) on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_cell_ID_t ia_css_process_get_cell( + const ia_css_process_t *process); + +/*! Get the number of cells the process object depends on + + @param process[in] process object + + @return number of cells + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_get_cell_dependency_count( + const ia_css_process_t *process); + +/*! Get the number of terminals the process object depends on + + @param process[in] process object + + @return number of terminals + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_get_terminal_dependency_count( + const ia_css_process_t *process); + +/*! Set n-th cell dependency of a process object + + @param process[in] Process object + @param dep_index[in] dep index + @param id[in] dep id + + @return < 0 on invalid process argument + */ +extern int ia_css_process_set_cell_dependency( + const ia_css_process_t *process, + const unsigned int dep_index, + const vied_nci_resource_id_t id); + +/*! Get n-th cell dependency of a process object + + @param process[in] Process object + @param cell_num[in] n-th cell + + @return n-th cell dependency, + IA_CSS_PROCESS_INVALID_DEPENDENCY on invalid argument(s) +*/ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_id_t ia_css_process_get_cell_dependency( + const ia_css_process_t *process, + const unsigned int cell_num); + +/*! Set n-th terminal dependency of a process object + + @param process[in] Process object + @param dep_index[in] dep index + @param id[in] dep id + + @return < 0 on invalid argument(s) + */ +extern int ia_css_process_set_terminal_dependency( + const ia_css_process_t *process, + const unsigned int dep_index, + const vied_nci_resource_id_t id); + +/*! Get n-th terminal dependency of a process object + + @param process[in] Process object + @param terminal_num[in] n-th cell + + @return n-th terminal dependency, + IA_CSS_PROCESS_INVALID_DEPENDENCY on invalid argument(s) +*/ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_get_terminal_dependency( + const ia_css_process_t *process, + const unsigned int terminal_num); + +/*! Get the kernel bitmap of the process object + + @param process[in] process object + + @return process kernel bitmap + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_kernel_bitmap_t ia_css_process_get_kernel_bitmap( + const ia_css_process_t *process); + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t *ia_css_process_get_dfm_port_bitmap_ptr( + ia_css_process_t *process); + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t *ia_css_process_get_dfm_active_port_bitmap_ptr( + ia_css_process_t *process); + + +/*! Get the cells bitmap of the process object + + @param process[in] process object + + @return process cells bitmap + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t ia_css_process_get_cells_bitmap( + const ia_css_process_t *process); + +/*! Sets the dfm device resource allocation bitmap of + * the process object + + @param process[in] process object + @param dfm_dev_id[in] dfm device id + @param bitmap[in] resource bitmap + + @return < 0 on invalid argument(s) or process state + */ +int ia_css_process_set_dfm_port_bitmap( + ia_css_process_t *process, + const vied_nci_dev_dfm_id_t dfm_dev_id, + const vied_nci_resource_bitmap_t bitmap); + + +/*! Sets the active dfm ports bitmap of + * the process object + + @param process[in] process object + @param dfm_dev_id[in] dfm device id + @param bitmap[in] active ports bitmap + + @return < 0 on invalid argument(s) or process state + */ +int ia_css_process_set_dfm_active_port_bitmap( + ia_css_process_t *process, + const vied_nci_dev_dfm_id_t dfm_dev_id, + const vied_nci_resource_bitmap_t bitmap); + +/*! Get the dfm port bitmap of the process object + + @param process[in] process object + @param dfm_res_id dfm resource id + + @return bitmap of all DFM ports used by process, corresponding to the input dfm resource id + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t ia_css_process_get_dfm_port_bitmap( + const ia_css_process_t *process, + vied_nci_dev_dfm_id_t dfm_res_id); + +/*! Get the dfm active port bitmap of the process object + + @param process[in] process object + @param dfm_res_id[in] dfm resource id + + @return bitmap of all active DFM ports used by the process, corresponding to the input + dfm resource id + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t ia_css_process_get_dfm_active_port_bitmap( + const ia_css_process_t *process, + vied_nci_dev_dfm_id_t dfm_res_id); + + +/*! Sets the cells bitmap of + * the process object + + @param process[in] process object + @param bitmap[in] bitmap + + @return < 0 on invalid argument(s) or process state + */ +int ia_css_process_set_cells_bitmap( + ia_css_process_t *process, + const vied_nci_resource_bitmap_t bitmap); + +/*! Get the device channel id-n resource allocation offset of the process object + + @param process[in] process object + @param dev_chn_id[in] channel id + + @return resource offset, IA_CSS_PROCESS_INVALID_OFFSET on invalid argument(s) + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_size_t ia_css_process_get_dev_chn( + const ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id); + +/*! Get the ext mem type-n resource id of the process object + + @param process[in] process object + @param mem_type[in] mem type + + @return resource offset, IA_CSS_PROCESS_INVALID_OFFSET on invalid argument(s) + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_mem_ID_t ia_css_process_get_ext_mem_id( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type); + + +/*! Sets the device channel id-n resource allocation offset of + * the process object + + @param process[in] process object + @param dev_chn_id[in] channel id + @param offset[in] resource offset + + @return < 0 on invalid argument(s) or process state + */ +int ia_css_process_set_dev_chn( + ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t offset); + +/*! Boolean test if the process object type is valid + + @param process[in] process object + @param p_manifest[in] program manifest + + @return true if the process object is correct, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_process_valid( + const ia_css_process_t *process, + const ia_css_program_manifest_t *p_manifest); + +/*! Gets the program_idx from the process object + + @param process[in] process object + + @return program index + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_get_program_idx( + const ia_css_process_t *process); + +#ifdef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_process_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +#endif /* __IA_CSS_PSYS_PROCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.kernel.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.kernel.h new file mode 100644 index 0000000000000..cab7965604146 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.kernel.h @@ -0,0 +1,144 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_HSYS_KERNEL_H +#define __IA_CSS_PSYS_PROCESS_HSYS_KERNEL_H + +/*! \file */ + +/** @file ia_css_psys_process.hsys.kernel.h + * + * Define the methods on the process object: Hsys kernel interface + */ + +#include + +#include + +/* + * Internal resources + */ + +/*! Clear all resource (offset) specifications + + @param process[in] process object + + @return < 0 on error + */ +extern int ia_css_process_clear_all(ia_css_process_t *process); + +/*! Set the cell ID resource specification + + @param process[in] process object + @param cell_id[in] cell ID + + @return < 0 on error + */ +extern int ia_css_process_set_cell( + ia_css_process_t *process, + const vied_nci_cell_ID_t cell_id); + +/*! Clear cell ID resource specification + + @param process[in] process object + + @return < 0 on error + */ +extern int ia_css_process_clear_cell(ia_css_process_t *process); + +/*! Set the memory resource (offset) specification for a memory + that belongs to the cell that is assigned to the process + + @param process[in] process object + @param mem_type_id[in] mem type ID + @param offset[in] offset + + Precondition: The cell ID must be set + + @return < 0 on error + */ +extern int ia_css_process_set_int_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t offset); + +/*! Clear the memory resource (offset) specification for a memory + type that belongs to the cell that is assigned to the process + + @param process[in] process object + @param mem_id[in] mem ID + + Precondition: The cell ID must be set + + @return < 0 on error + */ +extern int ia_css_process_clear_int_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Set the memory resource (offset) specification for a memory + that does not belong to the cell that is assigned to the process + + @param process[in] process object + @param mem_type_id[in] mem type ID + @param offset[in] offset + + Precondition: The cell ID must be set + + @return < 0 on error + */ +extern int ia_css_process_set_ext_mem( + ia_css_process_t *process, + const vied_nci_mem_ID_t mem_id, + const vied_nci_resource_size_t offset); + +/*! Clear the memory resource (offset) specification for a memory + type that does not belong to the cell that is assigned to the process + + @param process[in] process object + @param mem_id[in] mem ID + + Precondition: The cell ID must be set + + @return < 0 on error + */ +extern int ia_css_process_clear_ext_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Set a device channel resource (offset) specification + + @param process[in] process object + @param dev_chn_id[in] device channel ID + @param offset[in] offset + + @return < 0 on error + */ +extern int ia_css_process_set_dev_chn( + ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t offset); + +/*! Clear a device channel resource (offset) specification + + @param process[in] process object + @param dev_chn_id[in] device channel ID + + @return < 0 on error + */ +extern int ia_css_process_clear_dev_chn( + ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id); + +#endif /* __IA_CSS_PSYS_PROCESS_HSYS_KERNEL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.user.h new file mode 100644 index 0000000000000..015a60b0e1afb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.user.h @@ -0,0 +1,85 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_HSYS_USER_H +#define __IA_CSS_PSYS_PROCESS_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_process.hsys.user.h + * + * Define the methods on the process object: Hsys user interface + */ + +#include /* ia_css_program_param_t */ + +#include +#include + +#include /* uint8_t */ + +/* + * Creation + */ + +/*! Compute the size of storage required for allocating the process object + + @param manifest[in] program manifest + @param param[in] program parameters + + @return 0 on error + */ +extern size_t ia_css_sizeof_process( + const ia_css_program_manifest_t *manifest, + const ia_css_program_param_t *param); + +/*! Create the process object + + @param raw_mem[in] pre allocated memory + @param manifest[in] program manifest + @param param[in] program parameters + + @return NULL on error + */ +extern ia_css_process_t *ia_css_process_create( + void *raw_mem, + const ia_css_program_manifest_t *manifest, + const ia_css_program_param_t *param, + const uint32_t program_idx); + +/*! Destroy (the storage of) the process object + + @param process[in] process object + + @return NULL + */ +extern ia_css_process_t *ia_css_process_destroy( + ia_css_process_t *process); + +/* + * Access functions + */ + +/*! Print the process object to file/stream + + @param process[in] process object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_process_print( + const ia_css_process_t *process, + void *fid); + +#endif /* __IA_CSS_PSYS_PROCESS_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.psys.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.psys.h new file mode 100644 index 0000000000000..ba1db574a4388 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.psys.h @@ -0,0 +1,53 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_PSYS_H +#define __IA_CSS_PSYS_PROCESS_PSYS_H + +/*! \file */ + +/** @file ia_css_psys_process.psys.h + * + * Define the methods on the process object: Psys embedded interface + */ + +#include + +/* + * Process manager + */ + +/*! Acquire the resources specificed in process object + + @param process[in] process object + + Postcondition: This is a try process if any of the + resources is not available, all succesfully acquired + ones will be release and the function will return an + error + + @return < 0 on error + */ +extern int ia_css_process_acquire(ia_css_process_t *process); + +/*! Release the resources specificed in process object + + @param process[in] process object + + @return < 0 on error + */ +extern int ia_css_process_release(ia_css_process_t *process); + + +#endif /* __IA_CSS_PSYS_PROCESS_PSYS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.h new file mode 100644 index 0000000000000..845590efd9039 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.h @@ -0,0 +1,366 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_H +#define __IA_CSS_PSYS_PROCESS_GROUP_H + +/*! \file */ + +/** @file ia_css_psys_process_group.h + * + * Define the methods on the process object that are not part of + * a single interface + */ +#include "ia_css_rbm.h" + +#include +#include + +#include /* uint8_t */ + +/* + * Creation + */ +#include + +/* + * Registration of user contexts / callback info + * External resources + * Sequencing resources + */ +#include + +/* + * Dispatcher + */ +#include + +/* + * Access to sub-structure handles / fields + */ + +#include "ia_css_terminal.h" + +/*! Get the number of fragments on the process group + + @param process_group[in] process group object + + Note: Future change is to have a fragment count per + independent subgraph + + @return the fragment count, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint16_t ia_css_process_group_get_fragment_count( + const ia_css_process_group_t *process_group); + + +/*! Get the fragment state on the process group + + @param process_group[in] process group object + @param fragment_state[in] current fragment of processing + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_get_fragment_state( + const ia_css_process_group_t *process_group, + uint16_t *fragment_state); + +/*! Set the fragment state on the process group + + @param process_group[in] process group object + @param fragment_state[in] current fragment of processing + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_fragment_state( + ia_css_process_group_t *process_group, + uint16_t fragment_state); + +/*! Get the number of processes on the process group + + @param process_group[in] process group object + + @return the process count, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_group_get_process_count( + const ia_css_process_group_t *process_group); + +/*! Get the number of terminals on the process group + + @param process_group[in] process group object + + Note: Future change is to have a terminal count per + independent subgraph + + @return the terminal count, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_group_get_terminal_count( + const ia_css_process_group_t *process_group); + +/*! Get the PG load start timestamp + + @param process_group[in] process group object + + @return PG load start timestamp, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_get_pg_load_start_ts( + const ia_css_process_group_t *process_group); + +/*! Get the PG load time in cycles + + @param process_group[in] process group object + + @return PG load time in cycles, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_get_pg_load_cycles( + const ia_css_process_group_t *process_group); + +/*! Get the PG init time in cycles + + @param process_group[in] process group object + + @return PG init time in cycles, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_get_pg_init_cycles( + const ia_css_process_group_t *process_group); + +/*! Get the PG processing time in cycles + + @param process_group[in] process group object + + @return PG processing time in cycles, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_get_pg_processing_cycles( + const ia_css_process_group_t *process_group); + +/*! Get the (pointer to) the terminal of the process group object + + @param process_group[in] process group object + @param terminal_type[in] terminal type of terminal + + @return the pointer to the terminal, NULL on error + */ + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_terminal_t *ia_css_process_group_get_terminal_from_type( + const ia_css_process_group_t *process_group, + const ia_css_terminal_type_t terminal_type); + +/*! Get the (pointer to) the terminal of the process group object + * for terminals which have only a single instance + * (cached in, cached out, program, program_ctrl_init) + + @param process_group[in] process group object + @param terminal_type[in] terminal type of terminal + + @return the pointer to the terminal, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +const ia_css_terminal_t *ia_css_process_group_get_single_instance_terminal( + const ia_css_process_group_t *process_group, + ia_css_terminal_type_t term_type); + +/*! Get the (pointer to) the indexed terminal of the process group object + + @param process_group[in] process group object + @param terminal_index[in] index of the terminal + + @return the pointer to the terminal, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_terminal_t *ia_css_process_group_get_terminal( + const ia_css_process_group_t *process_group, + const unsigned int terminal_index); + +/*! Get the (pointer to) the indexed process of the process group object + + @param process_group[in] process group object + @param process_index[in] index of the process + + @return the pointer to the process, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_process_t *ia_css_process_group_get_process( + const ia_css_process_group_t *process_group, + const unsigned int process_index); + +/*! Get the stored size of the process group object + + @param process_group[in] process group object + + @return size, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +size_t ia_css_process_group_get_size( + const ia_css_process_group_t *process_group); + +/*! Get the state of the process group object + + @param process_group[in] process group object + + @return state, limit value on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_process_group_state_t ia_css_process_group_get_state( + const ia_css_process_group_t *process_group); + +/*! Get the unique ID of program group used by the process group object + + @param process_group[in] process group object + + @return ID, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_program_group_ID_t ia_css_process_group_get_program_group_ID( + const ia_css_process_group_t *process_group); + +/*! Get the resource bitmap of the process group + + @param process_group[in] process group object + + @return the reource bitmap + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t ia_css_process_group_get_resource_bitmap( + const ia_css_process_group_t *process_group); + +/*! Set the resource bitmap of the process group + + @param process_group[in] process group object + @param resource_bitmap[in] the resource bitmap + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_resource_bitmap( + ia_css_process_group_t *process_group, + const vied_nci_resource_bitmap_t resource_bitmap); + +/*! Get the routing bitmap of the process group + + @param process_group[in] process group object + + @return routing bitmap (pointer) + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +const ia_css_rbm_t *ia_css_process_group_get_routing_bitmap( + const ia_css_process_group_t *process_group); + +/*! Set the routing bitmap of the process group + + @param process_group[in] process group object + @param rbm[in] routing bitmap + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_routing_bitmap( + ia_css_process_group_t *process_group, + const ia_css_rbm_t rbm); + +/*! Get IPU virtual address of process group + + @param process_group[in] process group object + @param ipu_vaddress[in/out] process group ipu virtual address + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_get_ipu_vaddress( + const ia_css_process_group_t *process_group, + vied_vaddress_t *ipu_vaddress); + +/*! Set IPU virtual address of process group + + @param process_group[in] process group object + @param ipu_vaddress[in] process group ipu address + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_ipu_vaddress( + ia_css_process_group_t *process_group, + vied_vaddress_t ipu_vaddress); + +/*! Get protocol version used by a process group + + @param process_group[in] process group object + + @return invalid protocol version on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_group_get_protocol_version( + const ia_css_process_group_t *process_group); + +/*! Get base queue id used by a process group + + @param process_group[in] process group object + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_group_get_base_queue_id( + ia_css_process_group_t *process_group); + +/*! Set base queue id used by a process group + + @param process_group[in] process group object + @param queue_id[in] process group queue id + + @return invalid queue id on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_base_queue_id( + ia_css_process_group_t *process_group, + uint8_t queue_id); + +/*! Get number of queues used by a process group + + @param process_group[in] process group object + + @return invalid number of queues (0) on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_group_get_num_queues( + ia_css_process_group_t *process_group); + +/*! Set number of queues used by a process group + + @param process_group[in] process group object + @param num_queues[in] process group number of queues + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_num_queues( + ia_css_process_group_t *process_group, + uint8_t num_queues); + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_process_group_has_vp(const ia_css_process_group_t *process_group); + +#ifdef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_process_group_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.kernel.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.kernel.h new file mode 100644 index 0000000000000..93cce2555de9f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.kernel.h @@ -0,0 +1,324 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_HSYS_KERNEL_H +#define __IA_CSS_PSYS_PROCESS_GROUP_HSYS_KERNEL_H + +/*! \file */ + +/** @file ia_css_psys_process_group.hsys.kernel.h + * + * Define the methods on the process group object: Hsys kernel interface + */ + +#include + +#include +#include + +#include /* uint8_t */ + +/* + * Registration of user contexts / callback info + */ + +/*! Get the user (callback) token as registered in the process group + + @param process_group[in] process group object + + @return 0 on error + */ +extern uint64_t ia_css_process_group_get_token( + ia_css_process_group_t *process_group); + +/*! Set (register) a user (callback) token in the process group + + @param process_group[in] process group object + @param token[in] user token + + Note: The token value shall be non-zero. This token is + returned in each return message related to the process + group the token is registered with. + + @return < 0 on error + */ +extern int ia_css_process_group_set_token( + ia_css_process_group_t *process_group, + const uint64_t token); + +/* + * Passing of a (fragment) watermark + */ + +/*! Get the fragment progress limit of the process group + + @param process_group[in] process group object + + @return 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint16_t ia_css_process_group_get_fragment_limit( + const ia_css_process_group_t *process_group); + +/*! Set the new fragment progress limit of the process group + + @param process_group[in] process group object + @param fragment_limit[in] New limit value + + Note: The limit value must be less or equal to the fragment + count value. The process group will not make progress beyond + the limit value. The limit value can be modified asynchronously + If the limit value is reached before an update happens, the + process group will suspend and will not automatically resume. + + The limit is monotonically increasing. The default value is + equal to the fragment count + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_fragment_limit( + ia_css_process_group_t *process_group, + const uint16_t fragment_limit); + +/*! Clear the fragment progress limit of the process group + + @param process_group[in] process group object + + Note: This function sets the fragment limit to zero. + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_clear_fragment_limit( + ia_css_process_group_t *process_group); + +/* + * Commands + */ + +/*! Perform the start command on the process group + + @param process_group[in] process group object + + Note: Start is an action of the l-Scheduler it makes the + process group eligible for execution + + Precondition: The external resources that are attached to + the process group must be in the correct state, i.e. input + buffers are not-empty and output buffers not-full + + @return < 0 on error + */ +extern int ia_css_process_group_start( + ia_css_process_group_t *process_group); + +/*! Perform the suspend command on the process group + + @param process_group[in] process group object + + Note: Suspend indicates that the process group execution + is halted at the next fragment boundary. The process group + will not automatically resume + + Precondition: The process group must be running + + @return < 0 on error + */ +extern int ia_css_process_group_suspend( + ia_css_process_group_t *process_group); + +/*! Perform the resume command on the process group + + @param process_group[in] process group object + + Note: Resume indicates that the process group is again + eligible for execution + + Precondition: The process group must be started + + @return < 0 on error + */ +extern int ia_css_process_group_resume( + ia_css_process_group_t *process_group); + +/*! Perform the reset command on the process group + + @param process_group[in] process group object + + Note: Return the process group to the started state + + Precondition: The process group must be running or stopped + + @return < 0 on error + */ +extern int ia_css_process_group_reset( + ia_css_process_group_t *process_group); + +/*! Perform the abort command on the process group + + @param process_group[in] process group object + + Note: Force the process group to the stopped state + + Precondition: The process group must be running or started + + @return < 0 on error + */ +extern int ia_css_process_group_abort( + ia_css_process_group_t *process_group); + +/*! Release ownership of the process group + + @param process_group[in] process group object + + Note: Release notifies PSYS and hands over ownership of the + process group from SW to FW + + Precondition: The process group must be in the started state + + @return < 0 on error + */ +extern int ia_css_process_group_disown( + ia_css_process_group_t *process_group); + +/* + * External resources + */ + +/*! Set (register) a data buffer to the indexed terminal in the process group + + @param process_group[in] process group object + @param buffer[in] buffer handle + @param buffer_state[in] state of the buffer + @param terminal_index[in] index of the terminal + + Note: The buffer handle shall not be VIED_NULL, the buffer + state can be undefined; BUFFER_UNDEFINED + + Note: The buffer can be in memory or streaming over memory + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_attach_buffer( + ia_css_process_group_t *process_group, + vied_vaddress_t buffer, + const ia_css_buffer_state_t buffer_state, + const unsigned int terminal_index); + +/*! Get (unregister) the data buffer on the indexed terminal of + * the process group + + @param process_group[in] process group object + @param terminal_index[in] index of the terminal + + Precondition: The process group must be stopped + + Postcondition: The buffer handle shall be reset to VIED_NULL, the buffer + state to BUFFER_NULL + + @return VIED_NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_vaddress_t ia_css_process_group_detach_buffer( + ia_css_process_group_t *process_group, + const unsigned int terminal_index); + +/*! Set (register) a data buffer to the indexed terminal in the process group + + @param process_group[in] process group object + @param stream[in] stream handle + @param buffer_state[in] state of the buffer + @param terminal_index[in] index of the terminal + + Note: The stream handle shall not be zero, the buffer + state can be undefined; BUFFER_UNDEFINED + + Note: The stream is used exclusive to a buffer; the latter can be in memory + or streaming over memory + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_attach_stream( + ia_css_process_group_t *process_group, + uint32_t stream, + const ia_css_buffer_state_t buffer_state, + const unsigned int terminal_index); + +/*! Get (unregister) the stream handle on the indexed terminal of + * the process group + + @param process_group[in] process group object + @param terminal_index[in] index of the terminal + + Precondition: The process group must be stopped + + Postcondition: The stream handle shall be reset to zero, the buffer + state to BUFFER_NULL + + @return 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_detach_stream( + ia_css_process_group_t *process_group, + const unsigned int terminal_index); + +/* + * Sequencing resources + */ + +/*! Set a(n artificial) blocking resource (barrier) in + * the process group resource map + + @param process_group[in] process group object + @param barrier_index[in] index of the barrier + + Note: The barriers have to be set to force sequence between started + process groups + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_barrier( + ia_css_process_group_t *process_group, + const vied_nci_barrier_ID_t barrier_index); + +/*! Clear a previously set blocking resource (barrier) in + * the process group resource map + + @param process_group[in] process group object + @param barrier_index[in] index of the barrier + + Precondition: The barriers must have been set + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_clear_barrier( + ia_css_process_group_t *process_group, + const vied_nci_barrier_ID_t barrier_index); + +/*! Boolean test if the process group preconditions for start are satisfied + + @param process_group[in] process group object + + @return true if the process group can be started + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_can_process_group_start( + const ia_css_process_group_t *process_group); + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_HSYS_KERNEL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.user.h new file mode 100644 index 0000000000000..dfbcc8815c1ef --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.user.h @@ -0,0 +1,199 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_HSYS_USER_H +#define __IA_CSS_PSYS_PROCESS_GROUP_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_process_group.hsys.user.h + * + * Define the methods on the process group object: Hsys user interface + */ + +#include /* ia_css_program_group_param_t */ + +#include +#include +#include + +#include "ia_css_psys_dynamic_storage_class.h" + +#include /* uint8_t */ + +/* + * Creation + */ + +/*! Compute the size of storage required for allocating the process group object + + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return 0 on error + */ +extern size_t ia_css_sizeof_process_group( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Create (the storage for) the process group object + + @param process_grp_mem[in/out] raw memory for process group + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return NULL on error + */ +extern ia_css_process_group_t *ia_css_process_group_create( + void *process_grp_mem, + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Destroy (the storage of) the process group object + + @param process_group[in] process group object + + @return NULL + */ +extern ia_css_process_group_t *ia_css_process_group_destroy( + ia_css_process_group_t *process_group); + +/*! Print the process group object to file/stream + + @param process_group[in] process group object + @param fid[out] file/stream handle + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_print( + const ia_css_process_group_t *process_group, + void *fid); + +/* + * Commands + */ + +/*! Perform the submit command on the process group + + @param process_group[in] process group object + + Note: Submit is an action of the h-Scheduler it makes the + process group eligible for the l-Scheduler + + Precondition: The external resources must be attached to + the process group + + @return < 0 on error + */ +extern int ia_css_process_group_submit( + ia_css_process_group_t *process_group); + +/*! Boolean test if the process group object type is valid + + @param process_group[in] process group object + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return true if the process group is correct, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_process_group_valid( + const ia_css_process_group_t *process_group, + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Boolean test if the process group preconditions for submit are satisfied + + @param process_group[in] process group object + + @return true if the process group can be submitted + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_can_process_group_submit( + const ia_css_process_group_t *process_group); + +/*! Boolean test if the preconditions on process group and buffer set are + satisfied for enqueuing buffer set + + @param process_group[in] process group object + @param buffer_set[in] buffer set object + + @return true if the buffer set can be enqueued + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_can_enqueue_buffer_set( + const ia_css_process_group_t *process_group, + const ia_css_buffer_set_t *buffer_set); + +/*! Compute the cyclecount required for executing the process group object + + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_compute_cycle_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Compute the number of processes required for + * executing the process group object + + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return 0 on error + */ +extern uint8_t ia_css_process_group_compute_process_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Compute the number of terminals required for + * executing the process group object + + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return 0 on error + */ +extern uint8_t ia_css_process_group_compute_terminal_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Get private token as registered in the process group by the implementation + + @param process_group[in] process group object + + @return 0 on error + */ +extern uint64_t ia_css_process_group_get_private_token( + ia_css_process_group_t *process_group); + +/*! Set private token in the process group as needed by the implementation + + @param process_group[in] process group object + @param token[in] user token + + Note: The token value shall be non-zero. This token is private + to the implementation. This is in addition to the user token + + @return < 0 on error, 0 on success + */ +extern int ia_css_process_group_set_private_token( + ia_css_process_group_t *process_group, + const uint64_t token); + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.psys.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.psys.h new file mode 100644 index 0000000000000..6ceccfc2f9bc3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.psys.h @@ -0,0 +1,60 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_PSYS_H +#define __IA_CSS_PSYS_PROCESS_GROUP_PSYS_H + +/*! \file */ + +/** @file ia_css_psys_process_group.psys.h + * + * Define the methods on the process group object: Psys embedded interface + */ + +#include + +/* + * Dispatcher + */ + +/*! Perform the run command on the process group + + @param process_group[in] process group object + + Note: Run indicates that the process group will execute + + Precondition: The process group must be started or + suspended and the processes have acquired the necessary + internal resources + + @return < 0 on error + */ +extern int ia_css_process_group_run( + ia_css_process_group_t *process_group); + +/*! Perform the stop command on the process group + + @param process_group[in] process group object + + Note: Stop indicates that the process group has completed execution + + Postcondition: The external resoruces can now be detached + + @return < 0 on error + */ +extern int ia_css_process_group_stop( + ia_css_process_group_t *process_group); + + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_PSYS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group_cmd_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group_cmd_impl.h new file mode 100644 index 0000000000000..530f93ef6ce03 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group_cmd_impl.h @@ -0,0 +1,178 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_CMD_IMPL_H +#define __IA_CSS_PSYS_PROCESS_GROUP_CMD_IMPL_H + +#include "type_support.h" +#include "ia_css_psys_process_group.h" +#include "ia_css_rbm_manifest_types.h" + +#define N_UINT64_IN_PROCESS_GROUP_STRUCT 2 +#define N_UINT32_IN_PROCESS_GROUP_STRUCT 5 +#define N_UINT16_IN_PROCESS_GROUP_STRUCT 5 +#define N_UINT8_IN_PROCESS_GROUP_STRUCT 7 +#define N_PADDING_UINT8_IN_PROCESS_GROUP_STRUCT 3 + +#define SIZE_OF_PROCESS_GROUP_STRUCT_BITS \ + (IA_CSS_RBM_BITS \ + + N_UINT64_IN_PROCESS_GROUP_STRUCT * IA_CSS_UINT64_T_BITS \ + + N_UINT32_IN_PROCESS_GROUP_STRUCT * IA_CSS_UINT32_T_BITS \ + + IA_CSS_PROGRAM_GROUP_ID_BITS \ + + IA_CSS_PROCESS_GROUP_STATE_BITS \ + + VIED_VADDRESS_BITS \ + + VIED_NCI_RESOURCE_BITMAP_BITS \ + + N_UINT16_IN_PROCESS_GROUP_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_UINT8_IN_PROCESS_GROUP_STRUCT * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_PROCESS_GROUP_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_process_group_s { + /**< User (callback) token / user context reference, + * zero is an error value + */ + uint64_t token; + /**< private token / context reference, zero is an error value */ + uint64_t private_token; + /**< PG routing bitmap used to set connection between programs >*/ + ia_css_rbm_t routing_bitmap; + /**< Size of this structure */ + uint32_t size; + /**< The timestamp when PG load starts */ + uint32_t pg_load_start_ts; + /**< PG load time in cycles */ + uint32_t pg_load_cycles; + /**< PG init time in cycles */ + uint32_t pg_init_cycles; + /**< PG processing time in cycles */ + uint32_t pg_processing_cycles; + /**< Referral ID to program group FW */ + ia_css_program_group_ID_t ID; + /**< State of the process group FSM */ + ia_css_process_group_state_t state; + /**< Virtual address of process group in IPU */ + vied_vaddress_t ipu_virtual_address; + /**< Bitmap of the compute resources used by the process group */ + vied_nci_resource_bitmap_t resource_bitmap; + /**< Number of fragments offered on each terminal */ + uint16_t fragment_count; + /**< Current fragment of processing */ + uint16_t fragment_state; + /**< Watermark to control fragment processing */ + uint16_t fragment_limit; + /**< Array[process_count] of process addresses in this process group */ + uint16_t processes_offset; + /**< Array[terminal_count] of terminal addresses on this process group */ + uint16_t terminals_offset; + /**< Parameter dependent number of processes in this process group */ + uint8_t process_count; + /**< Parameter dependent number of terminals on this process group */ + uint8_t terminal_count; + /**< Parameter dependent number of independent subgraphs in + * this process group + */ + uint8_t subgraph_count; + /**< Process group protocol version */ + uint8_t protocol_version; + /**< Dedicated base queue id used for enqueueing payload buffer sets */ + uint8_t base_queue_id; + /**< Number of dedicated queues used */ + uint8_t num_queues; + /**< Mask the send_pg_done IRQ */ + uint8_t mask_irq; + /**< Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_PROCESS_GROUP_STRUCT]; +}; + +/*! Callback after process group is created. Implementations can provide + * suitable actions needed when process group is created. + + @param process_group[in] process group object + @param program_group_manifest[in] program group manifest + @param program_group_param[in] program group parameters + + @return 0 on success and non-zero on failure + */ +extern int ia_css_process_group_on_create( + ia_css_process_group_t *process_group, + const ia_css_program_group_manifest_t *program_group_manifest, + const ia_css_program_group_param_t *program_group_param); + +/*! Callback before process group is about to be destoyed. Any implementation + * specific cleanups can be done here. + + @param process_group[in] process group object + + @return 0 on success and non-zero on failure + */ +extern int ia_css_process_group_on_destroy( + ia_css_process_group_t *process_group); + +/* + * Command processor + */ + +/*! Execute a command locally or send it to be processed remotely + + @param process_group[in] process group object + @param cmd[in] command + + @return < 0 on error + */ +extern int ia_css_process_group_exec_cmd( + ia_css_process_group_t *process_group, + const ia_css_process_group_cmd_t cmd); + + +/*! Enqueue a buffer set corresponding to a persistent program group by + * sending a command to subsystem. + + @param process_group[in] process group object + @param buffer_set[in] buffer set + @param queue_offset[in] offset to be used from the queue id + specified in the process group object + (0 for first buffer set for frame, 1 + for late binding) + + @return < 0 on error + */ +extern int ia_css_enqueue_buffer_set( + ia_css_process_group_t *process_group, + ia_css_buffer_set_t *buffer_set, + unsigned int queue_offset); + +/*! Enqueue a parameter buffer set corresponding to a persistent program + * group by sending a command to subsystem. + + @param process_group[in] process group object + @param buffer_set[in] parameter buffer set + + @return < 0 on error + */ +extern int ia_css_enqueue_param_buffer_set( + ia_css_process_group_t *process_group, + ia_css_buffer_set_t *buffer_set); + +/*! Need to store the 'secure' mode for each PG for FW test app only + * + * @param process_group[in] process group object + * @param secure[in] parameter buffer set + * + * @return < 0 on error + */ +extern int ia_css_process_group_store( + ia_css_process_group_t *process_group, + bool secure); + + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_CMD_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_types.h new file mode 100644 index 0000000000000..4fb064dc00df6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_types.h @@ -0,0 +1,95 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_TYPES_H +#define __IA_CSS_PSYS_PROCESS_TYPES_H + +/*! \file */ + +/** @file ia_css_psys_process_types.h + * + * The types belonging to the terminal/process/process group dynamic module + */ + +#include +#include + +#include + +#define IA_CSS_PROCESS_INVALID_PROGRAM_IDX ((uint32_t)-1) + +/* private */ +typedef enum ia_css_process_group_cmd { + IA_CSS_PROCESS_GROUP_CMD_NOP = 0, + IA_CSS_PROCESS_GROUP_CMD_SUBMIT, + IA_CSS_PROCESS_GROUP_CMD_ATTACH, + IA_CSS_PROCESS_GROUP_CMD_DETACH, + IA_CSS_PROCESS_GROUP_CMD_START, + IA_CSS_PROCESS_GROUP_CMD_DISOWN, + IA_CSS_PROCESS_GROUP_CMD_RUN, + IA_CSS_PROCESS_GROUP_CMD_STOP, + IA_CSS_PROCESS_GROUP_CMD_SUSPEND, + IA_CSS_PROCESS_GROUP_CMD_RESUME, + IA_CSS_PROCESS_GROUP_CMD_ABORT, + IA_CSS_PROCESS_GROUP_CMD_RESET, + IA_CSS_N_PROCESS_GROUP_CMDS +} ia_css_process_group_cmd_t; + +/* private */ +#define IA_CSS_PROCESS_GROUP_STATE_BITS 32 +typedef enum ia_css_process_group_state { + IA_CSS_PROCESS_GROUP_ERROR = 0, + IA_CSS_PROCESS_GROUP_CREATED, + IA_CSS_PROCESS_GROUP_READY, + IA_CSS_PROCESS_GROUP_BLOCKED, + IA_CSS_PROCESS_GROUP_STARTED, + IA_CSS_PROCESS_GROUP_RUNNING, + IA_CSS_PROCESS_GROUP_STALLED, + IA_CSS_PROCESS_GROUP_STOPPED, + IA_CSS_N_PROCESS_GROUP_STATES +} ia_css_process_group_state_t; + +/* private */ +typedef enum ia_css_process_cmd { + IA_CSS_PROCESS_CMD_NOP = 0, + IA_CSS_PROCESS_CMD_ACQUIRE, + IA_CSS_PROCESS_CMD_RELEASE, + IA_CSS_PROCESS_CMD_START, + IA_CSS_PROCESS_CMD_LOAD, + IA_CSS_PROCESS_CMD_STOP, + IA_CSS_PROCESS_CMD_SUSPEND, + IA_CSS_PROCESS_CMD_RESUME, + IA_CSS_N_PROCESS_CMDS +} ia_css_process_cmd_t; + +/* private */ +#define IA_CSS_PROCESS_STATE_BITS 32 +typedef enum ia_css_process_state { + IA_CSS_PROCESS_ERROR = 0, + IA_CSS_PROCESS_CREATED, + IA_CSS_PROCESS_READY, + IA_CSS_PROCESS_STARTED, + IA_CSS_PROCESS_RUNNING, + IA_CSS_PROCESS_STOPPED, + IA_CSS_PROCESS_SUSPENDED, + IA_CSS_N_PROCESS_STATES +} ia_css_process_state_t; + +/* public */ +typedef struct ia_css_process_group_s ia_css_process_group_t; +typedef struct ia_css_process_s ia_css_process_t; + +typedef struct ia_css_data_terminal_s ia_css_data_terminal_t; + +#endif /* __IA_CSS_PSYS_PROCESS_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.h new file mode 100644 index 0000000000000..7a164cd41b8fe --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.h @@ -0,0 +1,316 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_H +#define __IA_CSS_PSYS_TERMINAL_H + +/*! \file */ + +/** @file ia_css_psys_terminal.h + * + * Define the methods on the terminal object that are not part of + * a single interface + */ + +#include /* ia_css_frame_t */ +#include /* ia_css_program_group_param_t */ + +#include +#include + +#include /* bool */ +#include /* FILE */ +#include "ia_css_psys_dynamic_storage_class.h" +#include "ia_css_terminal.h" +#include "ia_css_terminal_manifest_base_types.h" + +/* + * Creation + */ +#include + +/*! Boolean test if the terminal object type is input + + @param terminal[in] terminal object + + @return true if the terminal is input, false otherwise or on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_input( + const ia_css_terminal_t *terminal); + +/*! Get the stored size of the terminal object + + @param terminal[in] terminal object + + @return size, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +size_t ia_css_terminal_get_size( + const ia_css_terminal_t *terminal); + +/*! Get the type of the terminal object + + @param terminal[in] terminal object + + @return the type of the terminal, limit value on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_terminal_type_t ia_css_terminal_get_type( + const ia_css_terminal_t *terminal); + +/*! Set the type of the terminal object + + @param terminal[in] terminal object + @param terminal_type[in] type of the terminal + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_terminal_set_type( + ia_css_terminal_t *terminal, + const ia_css_terminal_type_t terminal_type); + +/*! Get the index of the terminal manifest object + + @param terminal[in] terminal object + + @return the index of the terminal manifest object, limit value on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint16_t ia_css_terminal_get_terminal_manifest_index( + const ia_css_terminal_t *terminal); + +/*! Set the index of the terminal manifest object + + @param terminal[in] terminal object + @param tm_index[in] terminal manifest index + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_terminal_set_terminal_manifest_index( + ia_css_terminal_t *terminal, + const uint16_t tm_index); + +/*! Get id of the terminal object + + @param terminal[in] terminal object + + @return id of terminal + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_terminal_ID_t ia_css_terminal_get_ID( + const ia_css_terminal_t *terminal); + +/*! Get kernel id of the data terminal object + + @param dterminal[in] data terminal object + + @return kernel id of terminal + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_data_terminal_get_kernel_id( + const ia_css_data_terminal_t *dterminal); + +/*! Get the connection type from the terminal object + + @param terminal[in] terminal object + + @return buffer type, limit value on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_connection_type_t ia_css_data_terminal_get_connection_type( + const ia_css_data_terminal_t *dterminal); + +/*! Set the connection type of the terminal object + + @param terminal[in] terminal object + @param connection_type[in] connection type + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_data_terminal_set_connection_type( + ia_css_data_terminal_t *dterminal, + const ia_css_connection_type_t connection_type); + +/*! Get link id of the data terminal object + + @param dterminal[in] data terminal object + + @return link id of terminal + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_data_terminal_get_link_id( + const ia_css_data_terminal_t *dterminal); + + +/*! Set link id of the terminal object + + @param terminal[in] data terminal object + @param link_id[in] synchronization link id + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_data_terminal_set_link_id( + ia_css_data_terminal_t *dterminal, + const uint8_t link_id); + +/*! Get the (pointer to) the process group parent of the terminal object + + @param terminal[in] terminal object + + @return the pointer to the parent, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_process_group_t *ia_css_terminal_get_parent( + const ia_css_terminal_t *terminal); + +/*! Set the (pointer to) the process group parent of the terminal object + + @param terminal[in] terminal object + @param parent[in] (pointer to the) process group parent object + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_terminal_set_parent( + ia_css_terminal_t *terminal, + ia_css_process_group_t *parent); + +/*! Boolean test if the terminal object type is valid + + @param terminal[in] process terminal object + @param terminal_manifest[in] program terminal manifest + + @return true if the process terminal object is correct, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_valid( + const ia_css_terminal_t *terminal, + const ia_css_terminal_manifest_t *terminal_manifest); + +/* ================= Program Control Init Terminal - START ================= */ + +/*! + * Gets the program init terminal descripor size + * @param manifest[in] program control init terminal manifest + * @return size, error if < 0. + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +unsigned int +ia_css_program_control_init_terminal_get_descriptor_size( + const ia_css_program_control_init_terminal_manifest_t *manifest); + +/*! + * Initialize program control init terminal + * @param nof_fragments[in] Number of fragments + * @param terminal[in] program control init terminal + * @param manifest[in] program control init terminal manifest + * @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int +ia_css_program_control_init_terminal_init( + ia_css_program_control_init_terminal_t *terminal, + const ia_css_program_control_init_terminal_manifest_t *manifest); + +/*! + * Get a program desc for a program control init terminal + * @param terminal[in] program control init terminal + * @param manifest[in] program control init terminal manifest + * @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_program_control_init_program_desc_t * +ia_css_program_control_init_terminal_get_program_desc( + const ia_css_program_control_init_terminal_t *prog_ctrl_init_terminal, + const unsigned int program_index +); + +/*! + * Pretty prints the program control init termnial + * @param terminal[in] program control init terminal + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +void ia_css_program_control_init_terminal_print( + const ia_css_program_control_init_terminal_t *terminal); + +/*! + * Gets a load section desc for a program desc + * of a program control init terminal + * @param program_desc[in] program control init terminal program desc + * @param load_section_index[in] section index + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_program_control_init_load_section_desc_t * +ia_css_program_control_init_terminal_get_load_section_desc( + const ia_css_program_control_init_program_desc_t *program_desc, + const unsigned int load_section_index +); + +/*! + * Gets process_id from program desc + * of a program control init terminal + * @param program_desc[in] program control init terminal program desc + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_id_t ia_css_program_control_init_terminal_get_process_id( + const ia_css_program_control_init_program_desc_t *program_desc); + +/*! + * Set control info of program desc + * of a program control init terminal + * @param program_desc[in] program control init terminal program desc + * @param process_id unique process id used to identify the process + * among all active process + * @param num_done_events number of events required to close the process + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +void ia_css_program_control_init_terminal_set_control_info( + ia_css_program_control_init_program_desc_t *program_desc, + ia_css_process_id_t process_id, + uint8_t num_done_events); + +/*! + * Gets num_done_events value from program desc + * of a program control init terminal + * @param program_desc[in] program control init terminal program desc + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_program_control_init_terminal_get_num_done_events( + const ia_css_program_control_init_program_desc_t *program_desc); + +/*! + * Gets a connect section desc for a program desc + * of a program control init terminal + * @param program_desc[in] program control init terminal program desc + * @param connect_section_index[in] section index + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_program_control_init_connect_section_desc_t * +ia_css_program_control_init_terminal_get_connect_section_desc( + const ia_css_program_control_init_program_desc_t *program_desc, + const unsigned int connect_section_index +); + +/* ================= Program Control Init Terminal - END ================= */ + +#ifdef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_terminal_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +#endif /* __IA_CSS_PSYS_TERMINAL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.hsys.user.h new file mode 100644 index 0000000000000..b8aa08c19754a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.hsys.user.h @@ -0,0 +1,255 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_HSYS_USER_H +#define __IA_CSS_PSYS_TERMINAL_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_terminal.hsys.user.h + * + * Define the methods on the terminal object: Hsys user interface + */ + +#include /* ia_css_frame_t */ +#include /* ia_css_program_group_param_t */ + +#include +#include + +#include /* bool */ +#include "ia_css_psys_dynamic_storage_class.h" +#include "ia_css_terminal.h" +#include "ia_css_terminal_manifest.h" +#include "ia_css_kernel_bitmap.h" + +/* + * Creation + */ + +/* + * This source file is created with the intention of sharing and + * compiled for host and firmware. Since there is no native 64bit + * data type support for firmware this wouldn't compile for SP + * tile. The part of the file that is not compilable are marked + * with the following __VIED_CELL marker and this comment. Once we + * come up with a solution to address this issue this will be + * removed. + */ +#if !defined(__VIED_CELL) +/*! Compute the size of storage required for allocating the terminal object + + @param manifest[in] terminal manifest + @param param[in] program group parameters + + @return 0 on error + */ +extern size_t ia_css_sizeof_terminal( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Create the terminal object + + @param raw_mem[in] pre allocated memory + @param manifest[in] terminal manifest + @param terminal_param[in] terminal parameter + @param enable_bitmap program group enable bitmap + + @return NULL on error + */ +extern ia_css_terminal_t *ia_css_terminal_create( + void *raw_mem, + const ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_param_t *terminal_param, + ia_css_kernel_bitmap_t enable_bitmap); + +/*! Destroy (the storage of) the process object + + @param terminal[in] terminal object + + @return NULL + */ +extern ia_css_terminal_t *ia_css_terminal_destroy( + ia_css_terminal_t *terminal); +#endif /* !defined(__VIED_CELL) */ + +/*! Print the terminal object to file/stream + + @param terminal[in] terminal object + @param fid[out] file/stream handle + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_terminal_print( + const ia_css_terminal_t *terminal, + void *fid); + +/*! Get the (pointer to) the frame object in the terminal object + + @param terminal[in] terminal object + + @return the pointer to the frame, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_frame_t *ia_css_data_terminal_get_frame( + const ia_css_data_terminal_t *terminal); + +/*! Get the (pointer to) the frame descriptor object in the terminal object + + @param terminal[in] terminal object + + @return the pointer to the frame descriptor, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_frame_descriptor_t *ia_css_data_terminal_get_frame_descriptor( + const ia_css_data_terminal_t *dterminal); + +/*! Get the (pointer to) the fragment descriptor object in the terminal object + + @param terminal[in] terminal object + +@return the pointer to the fragment descriptor, NULL on error +*/ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_fragment_descriptor_t + *ia_css_data_terminal_get_fragment_descriptor( + const ia_css_data_terminal_t *dterminal, + const unsigned int fragment_index); + +/*! Get the number of fragments on the terminal + + @param terminal[in] terminal object + + @return the fragment count, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint16_t ia_css_data_terminal_get_fragment_count( + const ia_css_data_terminal_t *dterminal); + +/*! Get the number of section on the (param)terminal + @param manifest[in] terminal manifest + @param terminal_param[in] terminal parameter + + @return the section count, 0 on error + */ +extern uint16_t ia_css_param_terminal_compute_section_count( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Get the number of planes on the (data)terminal + @param manifest[in] terminal manifest + @param terminal_param[in] terminal parameter + + @return the plane count, 1(default) on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_data_terminal_compute_plane_count( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! check if given terminal is parameter terminal. + + @param terminal[in] (base)terminal object + + @return true on success, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_parameter_terminal( + const ia_css_terminal_t *terminal); + +/*! check if given terminal is program terminal. + + @program terminal[in] (base)terminal object + + @return true on success, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_program_terminal( + const ia_css_terminal_t *terminal); + +/*! check if given terminal is program control init terminal. + + @program control init terminal[in] (base)terminal object + + @return true on success, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_program_control_init_terminal( + const ia_css_terminal_t *terminal); + +/*! check if given terminal is spatial parameter terminal. + + @spatial terminal[in] (base)terminal object + + @return true on success, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_spatial_parameter_terminal( + const ia_css_terminal_t *terminal); + +/*! check if given terminal is data terminal. + + @param terminal[in] (base)terminal object + + @return true on success, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_data_terminal( + const ia_css_terminal_t *terminal); + +/*! obtain buffer out of terminal(both data & param terminals can call this) + + @param terminal[in] (base)terminal object of either data or param terminal. + + @return vied address of buffer stored in terminal + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_vaddress_t ia_css_terminal_get_buffer( + const ia_css_terminal_t *terminal); + +/*!store a buffer in the terminal. + + @param terminal[in] (base)terminal object of either data or param terminal. + @param buffer[in] buffer in vied (hrt address) space. + + @return 0 on success + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_terminal_set_buffer(ia_css_terminal_t *terminal, + vied_vaddress_t buffer); + +/*! Obtain terminal buffer index out of terminal object + + @param terminal[in] (base)terminal object of either data or param terminal. + + @return terminal buffer index stored in terminal object on success, -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_get_terminal_index( + const ia_css_terminal_t *terminal); + +/*! Store a terminal buffer index in the terminal object + + @param terminal[in] (base)terminal object of either data or param terminal. + @param terminal_index[in] terminal buffer index + + @return 0 on success + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_terminal_index( + ia_css_terminal_t *terminal, + unsigned int terminal_index); + +#endif /* __IA_CSS_PSYS_TERMINAL_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set.c new file mode 100644 index 0000000000000..82d53831f9a98 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set.c @@ -0,0 +1,111 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "assert_support.h" +#include "ia_css_psys_dynamic_trace.h" +#include "ia_css_psys_buffer_set.h" +#include "ia_css_psys_process_group.h" + +/* + * Functions to possibly inline + */ +#ifndef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_buffer_set_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +STORAGE_CLASS_INLINE void __buffer_set_dummy_check_alignment(void) +{ + COMPILATION_ERROR_IF(SIZE_OF_BUFFER_SET != + CHAR_BIT * sizeof(ia_css_buffer_set_t)); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_buffer_set_t) % sizeof(uint64_t)); +} + +/* + * Functions not to inline + */ + +/* The below functions are not to be compiled for firmware */ +#if !defined(__HIVECC) + +ia_css_buffer_set_t *ia_css_buffer_set_create( + void *buffer_set_mem, + const ia_css_process_group_t *process_group, + const unsigned int frame_counter) +{ + ia_css_buffer_set_t *buffer_set = NULL; + unsigned int i; + int ret = -1; + + verifexit(buffer_set_mem != NULL); + verifexit(process_group != NULL); + + buffer_set = (ia_css_buffer_set_t *)buffer_set_mem; + + /* + * Set base struct members + */ + buffer_set->ipu_virtual_address = VIED_NULL; + ia_css_process_group_get_ipu_vaddress(process_group, + &buffer_set->process_group_handle); + buffer_set->frame_counter = frame_counter; + buffer_set->terminal_count = + ia_css_process_group_get_terminal_count(process_group); + + /* + * Initialize adjacent buffer addresses + */ + for (i = 0; i < buffer_set->terminal_count; i++) { + vied_vaddress_t *buffer = + (vied_vaddress_t *)( + (char *)buffer_set + + sizeof(ia_css_buffer_set_t) + + sizeof(vied_vaddress_t) * i); + + *buffer = VIED_NULL; + } + ret = 0; + +EXIT: + if (ret != 0) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_create failed\n"); + } + return buffer_set; +} + +size_t ia_css_sizeof_buffer_set( + const ia_css_process_group_t *process_group) +{ + size_t size = 0; + + verifexit(process_group != NULL); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_sizeof_buffer_set(): enter:\n"); + + size = sizeof(ia_css_buffer_set_t) + + ia_css_process_group_get_terminal_count(process_group) * + sizeof(vied_vaddress_t); + +EXIT: + if (size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_sizeof_buffer_set failed\n"); + } + return size; +} + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set_impl.h new file mode 100644 index 0000000000000..0399d76f33315 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set_impl.h @@ -0,0 +1,241 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_PSYS_BUFFER_SET_IMPL_H +#define __IA_CSS_PSYS_BUFFER_SET_IMPL_H + +#include "error_support.h" +#include "ia_css_psys_dynamic_trace.h" +#include "vied_nci_psys_system_global.h" +#include "ia_css_psys_terminal.hsys.user.h" + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_buffer_set_set_buffer( + ia_css_buffer_set_t *buffer_set, + const unsigned int terminal_index, + const vied_vaddress_t buffer) +{ + DECLARE_ERRVAL + vied_vaddress_t *buffer_ptr; + int ret = -1; + + verifexitval(buffer_set != NULL, EFAULT); + verifexitval(terminal_index < buffer_set->terminal_count, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_set_buffer(): enter:\n"); + + /* + * Set address in buffer set object + */ + buffer_ptr = + (vied_vaddress_t *)( + (char *)buffer_set + + sizeof(ia_css_buffer_set_t) + + terminal_index * sizeof(vied_vaddress_t)); + *buffer_ptr = buffer; + + ret = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_set_buffer: invalid argument\n"); + } + return ret; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_vaddress_t ia_css_buffer_set_get_buffer( + const ia_css_buffer_set_t *buffer_set, + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + vied_vaddress_t buffer = VIED_NULL; + vied_vaddress_t *buffer_ptr; + int terminal_index; + + verifexitval(buffer_set != NULL, EFAULT); + verifexitval(terminal != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_get_buffer(): enter:\n"); + + /* + * Retrieve terminal index from terminal object + */ + terminal_index = ia_css_terminal_get_terminal_index(terminal); + verifexitval(terminal_index >= 0, EFAULT); + verifexitval(terminal_index < buffer_set->terminal_count, EFAULT); + + /* + * Retrieve address from buffer set object + */ + buffer_ptr = + (vied_vaddress_t *)( + (char *)buffer_set + + sizeof(ia_css_buffer_set_t) + + terminal_index * sizeof(vied_vaddress_t)); + buffer = *buffer_ptr; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_get_buffer: invalid argument\n"); + } + return buffer; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_buffer_set_set_ipu_address( + ia_css_buffer_set_t *buffer_set, + const vied_vaddress_t ipu_vaddress) +{ + DECLARE_ERRVAL + int ret = -1; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_set_ipu_address(): enter:\n"); + + buffer_set->ipu_virtual_address = ipu_vaddress; + + ret = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_set_ipu_address invalid argument\n"); + } + return ret; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_vaddress_t ia_css_buffer_set_get_ipu_address( + const ia_css_buffer_set_t *buffer_set) +{ + DECLARE_ERRVAL + vied_vaddress_t ipu_virtual_address = VIED_NULL; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_get_ipu_address(): enter:\n"); + + ipu_virtual_address = buffer_set->ipu_virtual_address; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_get_ipu_address: invalid argument\n"); + } + return ipu_virtual_address; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_buffer_set_set_process_group_handle( + ia_css_buffer_set_t *buffer_set, + const vied_vaddress_t process_group_handle) +{ + DECLARE_ERRVAL + int ret = -1; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_set_process_group_context(): enter:\n"); + + buffer_set->process_group_handle = process_group_handle; + + ret = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_set_process_group_context invalid argument\n"); + } + return ret; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_vaddress_t ia_css_buffer_set_get_process_group_handle( + const ia_css_buffer_set_t *buffer_set) +{ + DECLARE_ERRVAL + vied_vaddress_t process_group_handle = VIED_NULL; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_get_process_group_handle(): enter:\n"); + + process_group_handle = buffer_set->process_group_handle; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_get_process_group_handle: invalid argument\n"); + } + return process_group_handle; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_buffer_set_set_token( + ia_css_buffer_set_t *buffer_set, + const uint64_t token) +{ + DECLARE_ERRVAL + int ret = -1; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_set_token(): enter:\n"); + + buffer_set->token = token; + + ret = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_set_token invalid argument\n"); + } + return ret; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint64_t ia_css_buffer_set_get_token( + const ia_css_buffer_set_t *buffer_set) +{ + DECLARE_ERRVAL + uint64_t token = 0; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_get_token(): enter:\n"); + + token = buffer_set->token; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_get_token: invalid argument\n"); + } + return token; +} + +#endif /* __IA_CSS_PSYS_BUFFER_SET_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process.c new file mode 100644 index 0000000000000..04a837cb60f22 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process.c @@ -0,0 +1,1148 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_process.h" +#include "ia_css_psys_dynamic_storage_class.h" +#include "ia_css_psys_process_private_types.h" +#include /* for NOT_USED */ + +/* + * Functions to possibly inline + */ + +#ifndef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_process_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +/* + * Functions not to inline + */ + +/* This source file is created with the intention of sharing and + * compiled for host and firmware. Since there is no native 64bit + * data type support for firmware this wouldn't compile for SP + * tile. The part of the file that is not compilable are marked + * with the following __HIVECC marker and this comment. Once we + * come up with a solution to address this issue this will be + * removed. + */ +#if !defined(__HIVECC) +size_t ia_css_sizeof_process( + const ia_css_program_manifest_t *manifest, + const ia_css_program_param_t *param) +{ + size_t size = 0, tmp_size; + + uint8_t program_dependency_count; + uint8_t terminal_dependency_count; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_sizeof_process(): enter:\n"); + + COMPILATION_ERROR_IF( + SIZE_OF_PROCESS_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_process_t))); + + COMPILATION_ERROR_IF(0 != sizeof(ia_css_process_t)%sizeof(uint64_t)); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + size += sizeof(ia_css_process_t); + + program_dependency_count = + ia_css_program_manifest_get_program_dependency_count(manifest); + terminal_dependency_count = + ia_css_program_manifest_get_terminal_dependency_count(manifest); + + tmp_size = program_dependency_count*sizeof(vied_nci_resource_id_t); + size += tot_bytes_for_pow2_align(sizeof(uint64_t), tmp_size); + tmp_size = terminal_dependency_count*sizeof(uint8_t); + size += tot_bytes_for_pow2_align(sizeof(uint64_t), tmp_size); + +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_sizeof_process invalid argument\n"); + } + return size; +} + +ia_css_process_t *ia_css_process_create( + void *raw_mem, + const ia_css_program_manifest_t *manifest, + const ia_css_program_param_t *param, + const uint32_t program_idx) +{ + size_t tmp_size; + int retval = -1; + ia_css_process_t *process = NULL; + char *process_raw_ptr = (char *) raw_mem; + + /* size_t size = ia_css_sizeof_process(manifest, param); */ + uint8_t program_dependency_count; + uint8_t terminal_dependency_count; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_create(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(param != NULL); + verifexit(process_raw_ptr != NULL); + + process = (ia_css_process_t *) process_raw_ptr; + verifexit(process != NULL); + + process->kernel_bitmap = + ia_css_program_manifest_get_kernel_bitmap(manifest); + process->state = IA_CSS_PROCESS_CREATED; + + program_dependency_count = + ia_css_program_manifest_get_program_dependency_count(manifest); + terminal_dependency_count = + ia_css_program_manifest_get_terminal_dependency_count(manifest); + + /* A process requires at least one input or output */ + verifexit((program_dependency_count + + terminal_dependency_count) != 0); + + process_raw_ptr += sizeof(ia_css_process_t); + if (program_dependency_count != 0) { + process->cell_dependencies_offset = + (uint16_t) (process_raw_ptr - (char *)process); + tmp_size = + program_dependency_count * sizeof(vied_nci_resource_id_t); + process_raw_ptr += + tot_bytes_for_pow2_align(sizeof(uint64_t), tmp_size); + } else { + process->cell_dependencies_offset = 0; + } + + if (terminal_dependency_count != 0) { + process->terminal_dependencies_offset = + (uint16_t) (process_raw_ptr - (char *)process); + } + + process->size = (uint32_t)ia_css_sizeof_process(manifest, param); + + process->ID = ia_css_program_manifest_get_program_ID(manifest); + verifexit(process->ID != 0); + process->program_idx = program_idx; + + process->cell_dependency_count = program_dependency_count; + process->terminal_dependency_count = terminal_dependency_count; + + process->parent_offset = 0; + + verifexit(ia_css_process_clear_all(process) == 0); + + process->state = IA_CSS_PROCESS_READY; + retval = 0; + + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_create(): Created successfully process %p ID 0x%x\n", + process, process->ID); + +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_create invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_create failed (%i)\n", retval); + process = ia_css_process_destroy(process); + } + return process; +} + +ia_css_process_t *ia_css_process_destroy( + ia_css_process_t *process) +{ + + return process; +} +#endif + +int ia_css_process_set_cell( + ia_css_process_t *process, + const vied_nci_cell_ID_t cell_id) +{ + int retval = -1; + vied_nci_resource_bitmap_t bit_mask; + vied_nci_resource_bitmap_t resource_bitmap; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_cell(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + + verifexit(parent != NULL); + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + +/* Some programs are mapped on a fixed cell, + * when the process group is created + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_CREATED) || + /* If the process group has already been created, but no VP cell + * has been assigned to this process (i.e. not fixed in + * manifest), then we need to set the cell of this process + * while its parent state is READY (the ready state is set at + * the end of ia_css_process_group_create) + */ + (parent_state == IA_CSS_PROCESS_GROUP_READY))); + verifexit(state == IA_CSS_PROCESS_READY); + +/* Some programs are mapped on a fixed cell, thus check is not secure, + * but it will detect a preset, the process manager will do the secure check + */ + verifexit(ia_css_process_get_cell(process) == + VIED_NCI_N_CELL_ID); + + bit_mask = vied_nci_cell_bit_mask(cell_id); + resource_bitmap = ia_css_process_group_get_resource_bitmap(parent); + + verifexit(bit_mask != 0); + verifexit(vied_nci_is_bitmap_clear(bit_mask, resource_bitmap)); + + ia_css_process_cells_clear(process); + ia_css_process_cells_set_cell(process, 0, cell_id); + + resource_bitmap = vied_nci_bitmap_set(resource_bitmap, bit_mask); + + retval = ia_css_process_group_set_resource_bitmap( + parent, resource_bitmap); +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_cell invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_cell failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_clear_cell( + ia_css_process_t *process) +{ + int retval = -1; + vied_nci_cell_ID_t cell_id; + ia_css_process_group_t *parent; + vied_nci_resource_bitmap_t resource_bitmap; + vied_nci_resource_bitmap_t bit_mask; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_clear_cell(): enter:\n"); + verifexit(process != NULL); + + cell_id = ia_css_process_get_cell(process); + parent = ia_css_process_get_parent(process); + + verifexit(parent != NULL); + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) + || (parent_state == IA_CSS_PROCESS_GROUP_STARTED))); + verifexit(state == IA_CSS_PROCESS_READY); + + bit_mask = vied_nci_cell_bit_mask(cell_id); + resource_bitmap = ia_css_process_group_get_resource_bitmap(parent); + + verifexit(bit_mask != 0); + verifexit(vied_nci_is_bitmap_set(bit_mask, resource_bitmap)); + + ia_css_process_cells_clear(process); + + resource_bitmap = vied_nci_bitmap_clear(resource_bitmap, bit_mask); + + retval = ia_css_process_group_set_resource_bitmap( + parent, resource_bitmap); +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_clear_cell invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_clear_cell failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_set_int_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t offset) +{ + int retval = -1; + ia_css_process_group_t *parent; + vied_nci_cell_ID_t cell_id; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_int_mem(): enter:\n"); + + verifexit(process != NULL); + verifexit(mem_type_id < VIED_NCI_N_MEM_TYPE_ID); + + parent = ia_css_process_get_parent(process); + cell_id = ia_css_process_get_cell(process); + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + + /* TODO : separate process group start and run from + * process_group_exec_cmd() + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_RUNNING))); + verifexit(state == IA_CSS_PROCESS_READY); + + if (vied_nci_is_cell_mem_of_type(cell_id, mem_type_id, mem_type_id)) { + vied_nci_mem_ID_t mem_id = + vied_nci_cell_get_mem(cell_id, mem_type_id); + + process->int_mem_id[mem_type_id] = mem_id; + process->int_mem_offset[mem_type_id] = offset; + retval = 0; + } +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_int_mem failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_clear_int_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id) +{ + int retval = -1; + uint16_t mem_index; + ia_css_process_group_t *parent; + vied_nci_cell_ID_t cell_id; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_clear_int_mem(): enter:\n"); + + verifexit(process != NULL); + verifexit(mem_type_id < VIED_NCI_N_MEM_TYPE_ID); + + parent = ia_css_process_get_parent(process); + cell_id = ia_css_process_get_cell(process); + + /* We should have a check on NULL != parent but it parent is NULL + * ia_css_process_group_get_state will return + * IA_CSS_N_PROCESS_GROUP_STATES so it will be filtered anyway later. + */ + + /* verifexit(parent != NULL); */ + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) + || (parent_state == IA_CSS_PROCESS_GROUP_STARTED))); + verifexit(state == IA_CSS_PROCESS_READY); + +/* We could just clear the field, but lets check the state for + * consistency first + */ + for (mem_index = 0; mem_index < (int)VIED_NCI_N_MEM_TYPE_ID; + mem_index++) { + if (vied_nci_is_cell_mem_of_type( + cell_id, mem_index, mem_type_id)) { + vied_nci_mem_ID_t mem_id = + vied_nci_cell_get_mem(cell_id, mem_index); + int mem_of_type; + + mem_of_type = + vied_nci_is_mem_of_type(mem_id, mem_type_id); + + assert(mem_of_type); + assert((process->int_mem_id[mem_type_id] == mem_id) || + (process->int_mem_id[mem_type_id] == + VIED_NCI_N_MEM_ID)); + process->int_mem_id[mem_type_id] = VIED_NCI_N_MEM_ID; + process->int_mem_offset[mem_type_id] = + IA_CSS_PROCESS_INVALID_OFFSET; + retval = 0; + } + } + +EXIT: + if (NULL == process || mem_type_id >= VIED_NCI_N_MEM_TYPE_ID) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_clear_int_mem invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_clear_int_mem failed (%i)\n", retval); + } +return retval; +} + +int ia_css_process_set_ext_mem( + ia_css_process_t *process, + const vied_nci_mem_ID_t mem_id, + const vied_nci_resource_size_t offset) +{ + int retval = -1; + ia_css_process_group_t *parent; + vied_nci_cell_ID_t cell_id; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + vied_nci_mem_type_ID_t mem_type_id; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_ext_mem(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + cell_id = ia_css_process_get_cell(process); + + /* We should have a check on NULL != parent but it parent is NULL + * ia_css_process_group_get_state will return + * IA_CSS_N_PROCESS_GROUP_STATES so it will be filtered anyway later. + */ + + /* verifexit(parent != NULL); */ + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + + /* TODO : separate process group start and run from + * process_group_exec_cmd() + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_RUNNING))); + verifexit(state == IA_CSS_PROCESS_READY); + + /* Check that the memory actually exists, "vied_nci_has_cell_mem_of_id()" + * will return false on error + */ + + mem_type_id = vied_nci_mem_get_type(mem_id); + if (((!vied_nci_has_cell_mem_of_id(cell_id, mem_id) && + (mem_type_id != VIED_NCI_PMEM_TYPE_ID)) + || vied_nci_mem_is_ext_type(mem_type_id)) && + (mem_id < VIED_NCI_N_MEM_ID)) { + + verifexit(mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID); + process->ext_mem_id[mem_type_id] = mem_id; + process->ext_mem_offset[mem_type_id] = offset; + retval = 0; + } + +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_ext_mem invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_ext_mem failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_clear_ext_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_clear_ext_mem(): enter:\n"); + + verifexit(process != NULL); + verifexit(mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID); + + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + verifexit(parent != NULL); + verifexit(state == IA_CSS_PROCESS_READY); + + parent_state = ia_css_process_group_get_state(parent); + + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED))); + + process->ext_mem_id[mem_type_id] = VIED_NCI_N_MEM_ID; + process->ext_mem_offset[mem_type_id] = IA_CSS_PROCESS_INVALID_OFFSET; + + retval = 0; +EXIT: + if (NULL == process || mem_type_id >= VIED_NCI_N_DATA_MEM_TYPE_ID) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_clear_ext_mem invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_clear_ext_mem failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_set_cells_bitmap( + ia_css_process_t *process, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + int array_index = 0; + int bit_index; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_cells_bitmap(): enter:\n"); + + verifexit(process != NULL); + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + parent_state = ia_css_process_group_get_state(parent); + + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_CREATED) || + (parent_state == IA_CSS_PROCESS_GROUP_READY))); + verifexit(state == IA_CSS_PROCESS_READY); + + for (bit_index = 0; bit_index < VIED_NCI_N_CELL_ID; bit_index++) { + if (vied_nci_is_bit_set_in_bitmap(bitmap, bit_index)) { + verifexit(array_index < IA_CSS_PROCESS_MAX_CELLS); + ia_css_process_cells_set_cell(process, + array_index, (vied_nci_cell_ID_t)bit_index); + array_index++; + } + } + for (; array_index < IA_CSS_PROCESS_MAX_CELLS; array_index++) { + ia_css_process_cells_set_cell(process, + array_index, VIED_NCI_N_CELL_ID); + } + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_cells_bitmap invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_cells_bitmap failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_set_dev_chn( + ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t offset) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_dev_chn(): enter:\n"); + + verifexit(process != NULL); + verifexit(dev_chn_id <= VIED_NCI_N_DEV_CHN_ID); + + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + parent_state = ia_css_process_group_get_state(parent); + + /* TODO : separate process group start and run from + * process_group_exec_cmd() + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_RUNNING))); + verifexit(state == IA_CSS_PROCESS_READY); + + process->dev_chn_offset[dev_chn_id] = offset; + + retval = 0; +EXIT: + if (NULL == process || dev_chn_id >= VIED_NCI_N_DEV_CHN_ID) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_dev_chn invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_dev_chn invalid argument\n"); + } + return retval; +} + +int ia_css_process_set_dfm_port_bitmap( + ia_css_process_t *process, + const vied_nci_dev_dfm_id_t dfm_dev_id, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_dfm_port(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + parent_state = ia_css_process_group_get_state(parent); + + /* TODO : separate process group start and run from + * process_group_exec_cmd() + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_RUNNING))); + verifexit(state == IA_CSS_PROCESS_READY); + +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_dev_id <= VIED_NCI_N_DEV_DFM_ID); + process->dfm_port_bitmap[dfm_dev_id] = bitmap; +#else + (void)bitmap; + (void)dfm_dev_id; +#endif + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_dfm_port invalid argument\n"); + } + return retval; +} + +int ia_css_process_set_dfm_active_port_bitmap( + ia_css_process_t *process, + const vied_nci_dev_dfm_id_t dfm_dev_id, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_dfm_active_port_bitmap(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + parent_state = ia_css_process_group_get_state(parent); + + /* TODO : separate process group start and run from + * process_group_exec_cmd() + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_RUNNING))); + verifexit(state == IA_CSS_PROCESS_READY); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_dev_id <= VIED_NCI_N_DEV_DFM_ID); + process->dfm_active_port_bitmap[dfm_dev_id] = bitmap; +#else + (void)bitmap; + (void)dfm_dev_id; +#endif + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_dfm_active_port_bitmap invalid argument\n"); + } + return retval; +} + +int ia_css_process_clear_dev_chn( + ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_clear_dev_chn(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + + /* We should have a check on NULL != parent but it parent is NULL + * ia_css_process_group_get_state will return + * IA_CSS_N_PROCESS_GROUP_STATES so it will be filtered anyway later. + */ + + /* verifexit(parent != NULL); */ + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) + || (parent_state == IA_CSS_PROCESS_GROUP_STARTED))); + verifexit(state == IA_CSS_PROCESS_READY); + + verifexit(dev_chn_id <= VIED_NCI_N_DEV_CHN_ID); + + process->dev_chn_offset[dev_chn_id] = IA_CSS_PROCESS_INVALID_OFFSET; + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_clear_dev_chn invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_clear_dev_chn failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_clear_all( + ia_css_process_t *process) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + int mem_index; + int dev_chn_index; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_clear_all(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + /* We should have a check on NULL != parent but it parent is NULL + * ia_css_process_group_get_state will return + * IA_CSS_N_PROCESS_GROUP_STATES so it will be filtered anyway later. + */ + + /* verifexit(parent != NULL); */ + + parent_state = ia_css_process_group_get_state(parent); + +/* Resource clear can only be called in excluded states contrary to set */ + verifexit((parent_state != IA_CSS_PROCESS_GROUP_RUNNING) || + (parent_state == IA_CSS_N_PROCESS_GROUP_STATES)); + verifexit((state == IA_CSS_PROCESS_CREATED) || + (state == IA_CSS_PROCESS_READY)); + + for (dev_chn_index = 0; dev_chn_index < VIED_NCI_N_DEV_CHN_ID; + dev_chn_index++) { + process->dev_chn_offset[dev_chn_index] = + IA_CSS_PROCESS_INVALID_OFFSET; + } +/* No difference whether a cell_id has been set or not, clear all */ + for (mem_index = 0; mem_index < VIED_NCI_N_DATA_MEM_TYPE_ID; + mem_index++) { + process->ext_mem_id[mem_index] = VIED_NCI_N_MEM_ID; + process->ext_mem_offset[mem_index] = + IA_CSS_PROCESS_INVALID_OFFSET; + } + for (mem_index = 0; mem_index < VIED_NCI_N_MEM_TYPE_ID; mem_index++) { + process->int_mem_id[mem_index] = VIED_NCI_N_MEM_ID; + process->int_mem_offset[mem_index] = + IA_CSS_PROCESS_INVALID_OFFSET; + } + + ia_css_process_cells_clear(process); + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_clear_all invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_clear_all failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_acquire( + ia_css_process_t *process) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_acquire(): enter:\n"); + + verifexit(process != NULL); + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_acquire invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_acquire failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_release( + ia_css_process_t *process) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_release(): enter:\n"); + + verifexit(process != NULL); + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_t invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_release failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_print(const ia_css_process_t *process, void *fid) +{ + int retval = -1; + int i, dev_chn_index; + uint16_t mem_index; + uint8_t cell_dependency_count, terminal_dependency_count; + vied_nci_cell_ID_t cell_id = ia_css_process_get_cell(process); + + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_print(process %p): enter:\n", process); + + verifexit(process != NULL); + + IA_CSS_TRACE_6(PSYSAPI_DYNAMIC, INFO, + "\tprocess %p, sizeof %d, programID %d, state %d, parent %p, cell %d\n", + process, + (int)ia_css_process_get_size(process), + (int)ia_css_process_get_program_ID(process), + (int)ia_css_process_get_state(process), + (void *)ia_css_process_get_parent(process), + (int)ia_css_process_get_cell(process)); + + for (mem_index = 0; mem_index < (int)VIED_NCI_N_MEM_TYPE_ID; + mem_index++) { + vied_nci_mem_ID_t mem_id = + (vied_nci_mem_ID_t)(process->int_mem_id[mem_index]); + if (cell_id == VIED_NCI_N_CELL_ID) { + verifexit(mem_id == VIED_NCI_N_MEM_ID); + continue; + } + verifexit(((mem_id == vied_nci_cell_get_mem(cell_id, mem_index)) + || (mem_id == VIED_NCI_N_MEM_ID))); + + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "\tinternal index %d, type %d, id %d offset 0x%x\n", + mem_index, + (int)vied_nci_cell_get_mem_type(cell_id, mem_index), + (int)mem_id, + process->int_mem_offset[mem_index]); + } + + for (mem_index = 0; mem_index < (int)VIED_NCI_N_DATA_MEM_TYPE_ID; + mem_index++) { + vied_nci_mem_ID_t mem_id = + (vied_nci_mem_ID_t)(process->ext_mem_id[mem_index]); + /* TODO: in case of an cells_bitmap = [], + * vied_nci_cell_get_mem_type will return a wrong result. + */ + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "\texternal index %d, type %d, id %d offset 0x%x\n", + mem_index, + (int)vied_nci_cell_get_mem_type(cell_id, mem_index), + (int)mem_id, + process->ext_mem_offset[mem_index]); + NOT_USED(mem_id); + } + for (dev_chn_index = 0; dev_chn_index < (int)VIED_NCI_N_DEV_CHN_ID; + dev_chn_index++) { + IA_CSS_TRACE_3(PSYSAPI_DYNAMIC, INFO, + "\tdevice channel index %d, type %d, offset 0x%x\n", + dev_chn_index, + (int)dev_chn_index, + process->dev_chn_offset[dev_chn_index]); + } +#if HAS_DFM + for (dev_chn_index = 0; dev_chn_index < (int)VIED_NCI_N_DEV_DFM_ID; + dev_chn_index++) { + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "\tdfm device index %d, type %d, bitmap 0x%x active_ports_bitmap 0x%x\n", + dev_chn_index, dev_chn_index, + process->dfm_port_bitmap[dev_chn_index], + process->dfm_active_port_bitmap[dev_chn_index]); + } +#endif + + for (i = 0; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "\tcells[%d] = 0x%x\n", + i, ia_css_process_cells_get_cell(process, i)); + } + + cell_dependency_count = + ia_css_process_get_cell_dependency_count(process); + if (cell_dependency_count == 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tcell_dependencies[%d] {};\n", cell_dependency_count); + } else { + vied_nci_resource_id_t cell_dependency; + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tcell_dependencies[%d] {", cell_dependency_count); + for (i = 0; i < (int)cell_dependency_count - 1; i++) { + cell_dependency = + ia_css_process_get_cell_dependency(process, i); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "%4d, ", cell_dependency); + } + cell_dependency = + ia_css_process_get_cell_dependency(process, i); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "%4d}\n", cell_dependency); + (void)cell_dependency; + } + + terminal_dependency_count = + ia_css_process_get_terminal_dependency_count(process); + if (terminal_dependency_count == 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tterminal_dependencies[%d] {};\n", + terminal_dependency_count); + } else { + uint8_t terminal_dependency; + + terminal_dependency_count = + ia_css_process_get_terminal_dependency_count(process); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tterminal_dependencies[%d] {", + terminal_dependency_count); + for (i = 0; i < (int)terminal_dependency_count - 1; i++) { + terminal_dependency = + ia_css_process_get_terminal_dependency(process, i); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "%4d, ", terminal_dependency); + } + terminal_dependency = + ia_css_process_get_terminal_dependency(process, i); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "%4d}\n", terminal_dependency); + (void)terminal_dependency; + } + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_print invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_print failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_set_parent( + ia_css_process_t *process, + ia_css_process_group_t *parent) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_parent(): enter:\n"); + + verifexit(process != NULL); + verifexit(parent != NULL); + + process->parent_offset = (uint16_t) ((char *)parent - (char *)process); + retval = 0; +EXIT: + if (NULL == process || NULL == parent) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_parent invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_parent failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_set_cell_dependency( + const ia_css_process_t *process, + const unsigned int dep_index, + const vied_nci_resource_id_t id) +{ + int retval = -1; + uint8_t *process_dep_ptr; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_cell_dependency(): enter:\n"); + verifexit(process != NULL); + + process_dep_ptr = + (uint8_t *)process + process->cell_dependencies_offset + + dep_index*sizeof(vied_nci_resource_id_t); + + + *process_dep_ptr = id; + retval = 0; +EXIT: + return retval; +} + +int ia_css_process_set_terminal_dependency( + const ia_css_process_t *process, + const unsigned int dep_index, + const vied_nci_resource_id_t id) +{ + int retval = -1; + uint8_t *terminal_dep_ptr; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_terminal_dependency(): enter:\n"); + verifexit(process != NULL); + verifexit(ia_css_process_get_terminal_dependency_count(process) > dep_index); + + terminal_dep_ptr = + (uint8_t *)process + process->terminal_dependencies_offset + + dep_index*sizeof(uint8_t); + + *terminal_dep_ptr = id; + retval = 0; +EXIT: + return retval; +} + +int ia_css_process_cmd( + ia_css_process_t *process, + const ia_css_process_cmd_t cmd) +{ + int retval = -1; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, "ia_css_process_cmd(): enter:\n"); + + verifexit(process != NULL); + + state = ia_css_process_get_state(process); + + verifexit(state != IA_CSS_PROCESS_ERROR); + verifexit(state < IA_CSS_N_PROCESS_STATES); + + switch (cmd) { + case IA_CSS_PROCESS_CMD_NOP: + break; + case IA_CSS_PROCESS_CMD_ACQUIRE: + verifexit(state == IA_CSS_PROCESS_READY); + break; + case IA_CSS_PROCESS_CMD_RELEASE: + verifexit(state == IA_CSS_PROCESS_READY); + break; + case IA_CSS_PROCESS_CMD_START: + verifexit((state == IA_CSS_PROCESS_READY) + || (state == IA_CSS_PROCESS_STOPPED)); + process->state = IA_CSS_PROCESS_STARTED; + break; + case IA_CSS_PROCESS_CMD_LOAD: + verifexit(state == IA_CSS_PROCESS_STARTED); + process->state = IA_CSS_PROCESS_RUNNING; + break; + case IA_CSS_PROCESS_CMD_STOP: + verifexit((state == IA_CSS_PROCESS_RUNNING) + || (state == IA_CSS_PROCESS_SUSPENDED)); + process->state = IA_CSS_PROCESS_STOPPED; + break; + case IA_CSS_PROCESS_CMD_SUSPEND: + verifexit(state == IA_CSS_PROCESS_RUNNING); + process->state = IA_CSS_PROCESS_SUSPENDED; + break; + case IA_CSS_PROCESS_CMD_RESUME: + verifexit(state == IA_CSS_PROCESS_SUSPENDED); + process->state = IA_CSS_PROCESS_RUNNING; + break; + case IA_CSS_N_PROCESS_CMDS: /* Fall through */ + default: + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_cmd invalid cmd (0x%x)\n", cmd); + goto EXIT; + } + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_cmd invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_cmd failed (%i)\n", retval); + } + return retval; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group.c new file mode 100644 index 0000000000000..9d17e8ca5384d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group.c @@ -0,0 +1,886 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_process_group.h" +#include "ia_css_psys_dynamic_storage_class.h" + +/* + * Functions to possibly inline + */ + +#ifndef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_process_group_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +/* + * Functions not to inline + */ + +/* This header is need for cpu memset to 0 +* and process groups are not created in SP +*/ +#if !defined(__VIED_CELL) +#include "cpu_mem_support.h" +#endif + +/* This source file is created with the intention of sharing and +* compiled for host and firmware. Since there is no native 64bit +* data type support for firmware this wouldn't compile for SP +* tile. The part of the file that is not compilable are marked +* with the following __VIED_CELL marker and this comment. Once we +* come up with a solution to address this issue this will be +* removed. +*/ +#if !defined(__VIED_CELL) +static bool ia_css_process_group_is_program_enabled( + const ia_css_program_manifest_t *program_manifest, + ia_css_kernel_bitmap_t enable_bitmap) +{ + ia_css_kernel_bitmap_t program_bitmap = + ia_css_program_manifest_get_kernel_bitmap(program_manifest); + ia_css_program_type_t program_type = + ia_css_program_manifest_get_type(program_manifest); + ia_css_kernel_bitmap_t program_enable_bitmap; + + if (!ia_css_is_kernel_bitmap_intersection_empty(enable_bitmap, + program_bitmap)) { + + if (program_type == IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB || + program_type == IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER || + program_type == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB) { + /* + * EXCLUSIVE_SUB programs are subsets of + * EXCLUSIVE_SUPER so the bits of the enable_bitmap + * that refer to those are those of their + * EXCLUSIVE_SUPER program (on which the depend) and + * not the subset that their own program_bitmap has + */ + if (program_type == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB || + program_type == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB) { + ia_css_kernel_bitmap_t super_program_bitmap; + + const ia_css_program_group_manifest_t * + prog_group_manifest = + ia_css_program_manifest_get_parent(program_manifest); + uint8_t super_prog_idx = + ia_css_program_manifest_get_program_dependency( + program_manifest, 0); + const ia_css_program_manifest_t * + super_program_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + prog_group_manifest, super_prog_idx); + + verifexit(super_program_manifest != NULL); + if (((program_type == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) && + (ia_css_program_manifest_get_type( + super_program_manifest) != + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER)) + || ((program_type == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB) && + (ia_css_program_manifest_get_type( + super_program_manifest) != + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER))) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_is_program_enabled(): Error\n"); + verifexit(0); + } + + super_program_bitmap = + ia_css_program_manifest_get_kernel_bitmap( + super_program_manifest); + program_enable_bitmap = + ia_css_kernel_bitmap_intersection( + enable_bitmap, + super_program_bitmap); + } else { + program_enable_bitmap = + ia_css_kernel_bitmap_intersection( + enable_bitmap, program_bitmap); + } + + if (ia_css_is_kernel_bitmap_equal( + program_enable_bitmap, program_bitmap)) { + return true; + } + } else if (program_type == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER) { + /* + * Virtual super programs are not selectable + * only the virtual sub programs + */ + return false; + } else { + return true; + } + } + +EXIT: + return false; +} + +static bool ia_css_process_group_is_terminal_enabled( + const ia_css_terminal_manifest_t *terminal_manifest, + ia_css_kernel_bitmap_t enable_bitmap) +{ + ia_css_terminal_type_t terminal_type; + + verifjmpexit(terminal_manifest != NULL); + terminal_type = ia_css_terminal_manifest_get_type(terminal_manifest); + + if (ia_css_is_terminal_manifest_data_terminal(terminal_manifest)) { + ia_css_data_terminal_manifest_t *data_term_manifest = + (ia_css_data_terminal_manifest_t *)terminal_manifest; + ia_css_kernel_bitmap_t term_bitmap = + ia_css_data_terminal_manifest_get_kernel_bitmap( + data_term_manifest); + /* + * Terminals depend on a kernel, + * if the kernel is present the program it contains and + * the terminal the program depends on are active + */ + if (!ia_css_is_kernel_bitmap_intersection_empty( + enable_bitmap, term_bitmap)) { + return true; + } + } else if (ia_css_is_terminal_manifest_spatial_parameter_terminal( + terminal_manifest)) { + ia_css_kernel_bitmap_t term_kernel_bitmap = ia_css_kernel_bitmap_clear(); + ia_css_spatial_param_terminal_manifest_t *spatial_term_man = + (ia_css_spatial_param_terminal_manifest_t *) + terminal_manifest; + + term_kernel_bitmap = + ia_css_kernel_bitmap_set( + term_kernel_bitmap, + spatial_term_man->kernel_id); + if (!ia_css_is_kernel_bitmap_intersection_empty( + enable_bitmap, term_kernel_bitmap)) { + return true; + } + + } else if (ia_css_is_terminal_manifest_parameter_terminal( + terminal_manifest) && terminal_type == + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN) { + return true; + + } else if (ia_css_is_terminal_manifest_parameter_terminal( + terminal_manifest) && terminal_type == + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT) { + /* + * For parameter out terminals, we disable the terminals + * if ALL the corresponding kernels are disabled, + * for parameter in terminals we cannot do this; + * even if kernels are disabled, it may be required that + * (HW) parameters must be supplied via the parameter + * in terminal (e.g. bypass bits). + */ + ia_css_kernel_bitmap_t term_kernel_bitmap = ia_css_kernel_bitmap_clear(); + ia_css_param_terminal_manifest_t *param_term_man = + (ia_css_param_terminal_manifest_t *)terminal_manifest; + ia_css_param_manifest_section_desc_t *section_desc; + unsigned int section = 0; + + for (section = 0; section < param_term_man-> + param_manifest_section_desc_count; section++) { + section_desc = + ia_css_param_terminal_manifest_get_prm_sct_desc( + param_term_man, section); + verifjmpexit(section_desc != NULL); + term_kernel_bitmap = ia_css_kernel_bitmap_set( + term_kernel_bitmap, + section_desc->kernel_id); + } + + if (!ia_css_is_kernel_bitmap_intersection_empty( + enable_bitmap, term_kernel_bitmap)) { + return true; + } + } else if (ia_css_is_terminal_manifest_program_terminal( + terminal_manifest)) { + return true; + } else if (ia_css_is_terminal_manifest_program_control_init_terminal( + terminal_manifest)) { + return true; + } +EXIT: + return false; +} + +size_t ia_css_sizeof_process_group( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + size_t size = 0, tmp_size; + int i, error_val = -1; + uint8_t process_count, process_num; + uint8_t terminal_count; + ia_css_kernel_bitmap_t enable_bitmap; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_sizeof_process_group(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + COMPILATION_ERROR_IF( + SIZE_OF_PROCESS_GROUP_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_process_group_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_process_group_t) % sizeof(uint64_t)); + + process_count = + ia_css_process_group_compute_process_count(manifest, param); + terminal_count = + ia_css_process_group_compute_terminal_count(manifest, param); + + verifexit(process_count != 0); + verifexit(terminal_count != 0); + + size += sizeof(ia_css_process_group_t); + + tmp_size = process_count * sizeof(uint16_t); + size += tot_bytes_for_pow2_align(sizeof(uint64_t), tmp_size); + + tmp_size = terminal_count * sizeof(uint16_t); + size += tot_bytes_for_pow2_align(sizeof(uint64_t), tmp_size); + + enable_bitmap = + ia_css_program_group_param_get_kernel_enable_bitmap(param); + process_num = 0; + for (i = 0; i < (int)ia_css_program_group_manifest_get_program_count( + manifest); i++) { + ia_css_program_manifest_t *program_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst(manifest, i); + ia_css_program_param_t *program_param = + ia_css_program_group_param_get_program_param(param, i); + + if (ia_css_process_group_is_program_enabled( + program_manifest, enable_bitmap)) { + verifexit(process_num < process_count); + size += ia_css_sizeof_process( + program_manifest, program_param); + process_num++; + } + } + + verifexit(process_num == process_count); + + for (i = 0; i < (int)ia_css_program_group_manifest_get_terminal_count( + manifest); i++) { + ia_css_terminal_manifest_t *terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst( + manifest, i); + + if (ia_css_process_group_is_terminal_enabled( + terminal_manifest, enable_bitmap)) { + size += ia_css_sizeof_terminal( + terminal_manifest, param); + } + } + + error_val = 0; + +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_sizeof_process_group invalid argument\n"); + } + if (error_val != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_sizeof_process_group ERROR(%d)\n", error_val); + } + return size; +} + +ia_css_process_group_t *ia_css_process_group_create( + void *process_grp_mem, + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + size_t size = ia_css_sizeof_process_group(manifest, param); + int retval = -1; + int ret; + int i; + ia_css_process_group_t *process_group = NULL; + uint8_t process_count, process_num; + uint8_t terminal_count, terminal_num; + uint16_t fragment_count; + char *process_grp_raw_ptr; + uint16_t *process_tab_ptr, *terminal_tab_ptr; + ia_css_kernel_bitmap_t enable_bitmap; + uint8_t manifest_terminal_count; + + IA_CSS_TRACE_3(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create(process_grp_mem %p, manifest %p, group_param %p): enter:\n", + process_grp_mem, manifest, param); + + verifexit(process_grp_mem != NULL); + verifexit(manifest != NULL); + verifexit(param != NULL); + verifexit(ia_css_is_program_group_manifest_valid(manifest)); + + process_group = (ia_css_process_group_t *)process_grp_mem; + ia_css_cpu_mem_set_zero(process_group, size); + process_grp_raw_ptr = (char *) process_group; + + process_group->state = IA_CSS_PROCESS_GROUP_CREATED; + + process_group->protocol_version = + ia_css_program_group_param_get_protocol_version(param); + + fragment_count = ia_css_program_group_param_get_fragment_count(param); + process_count = + ia_css_process_group_compute_process_count(manifest, param); + terminal_count = + ia_css_process_group_compute_terminal_count(manifest, param); + enable_bitmap = + ia_css_program_group_param_get_kernel_enable_bitmap(param); + + process_group->fragment_count = fragment_count; + process_group->process_count = process_count; + process_group->terminal_count = terminal_count; + + process_grp_raw_ptr += sizeof(ia_css_process_group_t); + process_tab_ptr = (uint16_t *) process_grp_raw_ptr; + process_group->processes_offset = + (uint16_t)(process_grp_raw_ptr - (char *)process_group); + + process_grp_raw_ptr += tot_bytes_for_pow2_align( + sizeof(uint64_t), process_count * sizeof(uint16_t)); + terminal_tab_ptr = (uint16_t *) process_grp_raw_ptr; + process_group->terminals_offset = + (uint16_t)(process_grp_raw_ptr - (char *)process_group); + + /* Move raw pointer to the first process */ + process_grp_raw_ptr += tot_bytes_for_pow2_align( + sizeof(uint64_t), terminal_count * sizeof(uint16_t)); + + /* Set default */ + verifexit(ia_css_process_group_set_fragment_limit( + process_group, fragment_count) == 0); + + /* Set process group terminal dependency list */ + /* This list is used during creating the process dependency list */ + manifest_terminal_count = + ia_css_program_group_manifest_get_terminal_count(manifest); + + terminal_num = 0; + for (i = 0; i < (int)manifest_terminal_count; i++) { + ia_css_terminal_manifest_t *t_manifest = + ia_css_program_group_manifest_get_term_mnfst( + manifest, i); + + verifexit(t_manifest != NULL); + if (ia_css_process_group_is_terminal_enabled( + t_manifest, enable_bitmap)) { + ia_css_terminal_t *terminal = NULL; + ia_css_terminal_param_t *terminal_param = + ia_css_program_group_param_get_terminal_param( + param, i); + + verifexit(terminal_param != NULL); + terminal_tab_ptr[terminal_num] = + (uint16_t)(process_grp_raw_ptr - + (char *)process_group); + terminal = ia_css_terminal_create( + process_grp_raw_ptr, t_manifest, + terminal_param, enable_bitmap); + verifexit(terminal != NULL); + verifexit((ia_css_terminal_set_parent( + terminal, process_group) == 0)); + verifexit((ia_css_terminal_set_terminal_manifest_index( + terminal, i) == 0)); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create: terminal_manifest_index %d\n", + i); + + process_grp_raw_ptr += ia_css_terminal_get_size( + terminal); + terminal_num++; + } + } + verifexit(terminal_num == terminal_count); + + process_num = 0; + for (i = 0; i < (int)ia_css_program_group_manifest_get_program_count( + manifest); i++) { + ia_css_process_t *process = NULL; + ia_css_program_manifest_t *program_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, i); + ia_css_program_param_t *program_param = + ia_css_program_group_param_get_program_param(param, i); + unsigned int prog_dep_index, proc_dep_index; + unsigned int term_dep_index, term_index; + + if (ia_css_process_group_is_program_enabled( + program_manifest, enable_bitmap)) { + + verifexit(process_num < process_count); + + process_tab_ptr[process_num] = + (uint16_t)(process_grp_raw_ptr - + (char *)process_group); + process = ia_css_process_create( + process_grp_raw_ptr, + program_manifest, + program_param, + i); + verifexit(process != NULL); + + ia_css_process_set_parent(process, process_group); + if (ia_css_has_program_manifest_fixed_cell( + program_manifest)) { + vied_nci_cell_ID_t cell_id = + ia_css_program_manifest_get_cell_ID( + program_manifest); + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create: cell_id %d\n", + cell_id); + ia_css_process_set_cell(process, cell_id); + } + + process_grp_raw_ptr += ia_css_process_get_size( + process); + /* + * Set process dependencies of process derived + * from program manifest + */ + for (prog_dep_index = 0; prog_dep_index < + ia_css_program_manifest_get_program_dependency_count( + program_manifest); prog_dep_index++) { + uint8_t dep_prog_idx = + ia_css_program_manifest_get_program_dependency( + program_manifest, prog_dep_index); + const ia_css_program_manifest_t * + dep_prg_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, dep_prog_idx); + ia_css_program_ID_t id = + ia_css_program_manifest_get_program_ID( + dep_prg_manifest); + + verifexit(id != 0); + for (proc_dep_index = 0; + proc_dep_index < process_num; + proc_dep_index++) { + ia_css_process_t *dep_process = + ia_css_process_group_get_process( + process_group, + proc_dep_index); + + ia_css_process_set_cell_dependency( + process, + prog_dep_index, 0); + + if (ia_css_process_get_program_ID( + dep_process) == id) { + ia_css_process_set_cell_dependency( + process, + prog_dep_index, + proc_dep_index); + break; + } + } + } + process_num++; + + /* + * Set terminal dependencies of process derived + * from program manifest + */ + for (term_dep_index = 0; term_dep_index < + ia_css_program_manifest_get_terminal_dependency_count( + program_manifest); term_dep_index++) { + uint8_t pm_term_index = + ia_css_program_manifest_get_terminal_dependency + (program_manifest, term_dep_index); + + verifexit(pm_term_index < manifest_terminal_count); + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create(): term_dep_index: %d, pm_term_index: %d\n", + term_dep_index, pm_term_index); + for (term_index = 0; + term_index < terminal_count; + term_index++) { + ia_css_terminal_t *terminal = + ia_css_process_group_get_terminal( + process_group, + term_index); + + if (ia_css_terminal_get_terminal_manifest_index + (terminal) == pm_term_index) { + ia_css_process_set_terminal_dependency( + process, + term_dep_index, + term_index); + IA_CSS_TRACE_3(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create() set_terminal_dependency(process: %d, dep_idx: %d, term_idx: %d)\n", + i, term_dep_index, term_index); + + break; + } + } + } + } + } + verifexit(process_num == process_count); + + process_group->size = + (uint32_t)ia_css_sizeof_process_group(manifest, param); + process_group->ID = + ia_css_program_group_manifest_get_program_group_ID(manifest); + + /* Initialize performance measurement fields to zero */ + process_group->pg_load_start_ts = 0; + process_group->pg_load_cycles = 0; + process_group->pg_init_cycles = 0; + process_group->pg_processing_cycles = 0; + + verifexit(process_group->ID != 0); + + ret = ia_css_process_group_on_create(process_group, manifest, param); + verifexit(ret == 0); + + process_group->state = IA_CSS_PROCESS_GROUP_READY; + retval = 0; + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create(): Created successfully process group ID 0x%x\n", + process_group->ID); + +EXIT: + if (NULL == process_grp_mem || NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_create invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_create failed (%i)\n", retval); + process_group = ia_css_process_group_destroy(process_group); + } + return process_group; +} + +ia_css_process_group_t *ia_css_process_group_destroy( + ia_css_process_group_t *process_group) +{ + if (process_group != NULL) { + ia_css_process_group_on_destroy(process_group); + process_group = NULL; + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_destroy invalid argument\n"); + } + return process_group; +} + +int ia_css_process_group_submit( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_submit(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_SUBMIT); +} + +int ia_css_process_group_start( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_start(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_START); +} + +int ia_css_process_group_stop( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_stop(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_STOP); +} + +int ia_css_process_group_run( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_run(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_RUN); +} + +int ia_css_process_group_suspend( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_suspend(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_SUSPEND); +} + +int ia_css_process_group_resume( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_resume(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_RESUME); +} + +int ia_css_process_group_reset( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_reset(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_RESET); +} + +int ia_css_process_group_abort( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_abort(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_ABORT); +} + +int ia_css_process_group_disown( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_disown(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_DISOWN); +} + +extern uint64_t ia_css_process_group_get_token( + ia_css_process_group_t *process_group) +{ + uint64_t token = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_token(): enter:\n"); + + verifexit(process_group != NULL); + + token = process_group->token; + +EXIT: + if (process_group == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_get_token invalid argument\n"); + } + return token; +} + +int ia_css_process_group_set_token( + ia_css_process_group_t *process_group, + const uint64_t token) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_token(): enter:\n"); + + verifexit(process_group != NULL); + verifexit(token != 0); + + process_group->token = token; + + retval = 0; +EXIT: + if (NULL == process_group || 0 == token) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_set_token invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_token failed (%i)\n", + retval); + } + return retval; +} + +extern uint64_t ia_css_process_group_get_private_token( + ia_css_process_group_t *process_group) +{ + uint64_t token = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_private_token(): enter:\n"); + + verifexit(process_group != NULL); + + token = process_group->private_token; + +EXIT: + if (process_group == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_get_private_token invalid argument\n"); + } + return token; +} + +int ia_css_process_group_set_private_token( + ia_css_process_group_t *process_group, + const uint64_t token) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_private_token(): enter:\n"); + + verifexit(process_group != NULL); + verifexit(token != 0); + + process_group->private_token = token; + + retval = 0; +EXIT: + if (NULL == process_group || 0 == token) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_set_private_token invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_private_token failed (%i)\n", + retval); + } + return retval; +} + +uint8_t ia_css_process_group_compute_process_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + uint8_t process_count = 0; + ia_css_kernel_bitmap_t total_bitmap; + ia_css_kernel_bitmap_t enable_bitmap; + int i; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_compute_process_count(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + total_bitmap = + ia_css_program_group_manifest_get_kernel_bitmap(manifest); + enable_bitmap = + ia_css_program_group_param_get_kernel_enable_bitmap(param); + + verifexit(ia_css_is_program_group_manifest_valid(manifest)); + verifexit(ia_css_is_kernel_bitmap_subset(total_bitmap, enable_bitmap)); + verifexit(!ia_css_is_kernel_bitmap_empty(enable_bitmap)); + + for (i = 0; i < + (int)ia_css_program_group_manifest_get_program_count(manifest); + i++) { + ia_css_program_manifest_t *program_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, i); + ia_css_kernel_bitmap_t program_bitmap = + ia_css_program_manifest_get_kernel_bitmap( + program_manifest); + /* + * Programs can be orthogonal, + * a mutually exclusive subset, + * or a concurrent subset + */ + if (!ia_css_is_kernel_bitmap_intersection_empty(enable_bitmap, + program_bitmap)) { + ia_css_program_type_t program_type = + ia_css_program_manifest_get_type( + program_manifest); + /* + * An exclusive subnode < exclusive supernode, + * so simply don't count it + */ + if (program_type != + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB && + program_type != + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB) { + process_count++; + } + } + } + +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_compute_process_count invalid argument\n"); + } + return process_count; +} + +uint8_t ia_css_process_group_compute_terminal_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + uint8_t terminal_count = 0; + ia_css_kernel_bitmap_t total_bitmap, enable_bitmap; + int i; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_compute_terminal_count(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + total_bitmap = + ia_css_program_group_manifest_get_kernel_bitmap(manifest); + enable_bitmap = + ia_css_program_group_param_get_kernel_enable_bitmap(param); + + verifexit(ia_css_is_program_group_manifest_valid(manifest)); + verifexit(ia_css_is_kernel_bitmap_subset(total_bitmap, enable_bitmap)); + verifexit(!ia_css_is_kernel_bitmap_empty(enable_bitmap)); + + for (i = 0; i < + (int)ia_css_program_group_manifest_get_terminal_count( + manifest); i++) { + ia_css_terminal_manifest_t *tmanifest = + ia_css_program_group_manifest_get_term_mnfst( + manifest, i); + + if (ia_css_process_group_is_terminal_enabled( + tmanifest, enable_bitmap)) { + terminal_count++; + } + } + +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_compute_terminal_count invalid argument\n"); + } + return terminal_count; +} +#endif /* !defined(__VIED_CELL) */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group_impl.h new file mode 100644 index 0000000000000..0f1760f2873dc --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group_impl.h @@ -0,0 +1,1538 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_IMPL_H +#define __IA_CSS_PSYS_PROCESS_GROUP_IMPL_H + +#include +#include +#include "ia_css_psys_process_group_cmd_impl.h" +#include +#include +#include +#include +#include +#include +#include "ia_css_terminal_manifest_types.h" + +#include "ia_css_rbm.h" + +#include /* ia_css_kernel_bitmap_t */ + +#include +#include +#include "ia_css_rbm_manifest_types.h" +#include +#include +#include + +#include "ia_css_psys_dynamic_trace.h" + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint16_t ia_css_process_group_get_fragment_limit( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint16_t fragment_limit = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_fragment_limit(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + fragment_limit = process_group->fragment_limit; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_limit invalid argument\n"); + } + return fragment_limit; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_fragment_limit( + ia_css_process_group_t *process_group, + const uint16_t fragment_limit) +{ + DECLARE_ERRVAL + int retval = -1; + uint16_t fragment_state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_fragment_limit(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + retval = ia_css_process_group_get_fragment_state(process_group, + &fragment_state); + + verifexitval(retval == 0, EINVAL); + verifexitval(fragment_limit > fragment_state, EINVAL); + verifexitval(fragment_limit <= ia_css_process_group_get_fragment_count( + process_group), EINVAL); + + process_group->fragment_limit = fragment_limit; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_limit invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_limit failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_clear_fragment_limit( + ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_clear_fragment_limit(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + process_group->fragment_limit = 0; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_clear_fragment_limit invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_clear_fragment_limit failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_attach_buffer( + ia_css_process_group_t *process_group, + vied_vaddress_t buffer, + const ia_css_buffer_state_t buffer_state, + const unsigned int terminal_index) +{ + DECLARE_ERRVAL + int retval = -1; + ia_css_terminal_t *terminal = NULL; + + NOT_USED(buffer_state); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_attach_buffer(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + terminal = ia_css_process_group_get_terminal( + process_group, terminal_index); + + verifexitval(terminal != NULL, EINVAL); + verifexitval(ia_css_process_group_get_state(process_group) == + IA_CSS_PROCESS_GROUP_READY, EINVAL); + verifexitval(process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_LEGACY || + process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_PPG, EINVAL); + + if (process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_LEGACY) { + /* + * Legacy flow: + * Terminal address is part of the process group structure + */ + retval = ia_css_terminal_set_buffer( + terminal, buffer); + } else if (process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_PPG) { + /* + * PPG flow: + * Terminal address is part of external buffer set structure + */ + retval = ia_css_terminal_set_terminal_index( + terminal, terminal_index); + } + verifexitval(retval == 0, EFAULT); + + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "\tTerminal %p has buffer 0x%x\n", terminal, buffer); + + if (ia_css_is_terminal_data_terminal(terminal) == true) { + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + verifexitval(frame != NULL, EINVAL); + + retval = ia_css_frame_set_buffer_state(frame, buffer_state); + verifexitval(retval == 0, EINVAL); + } + + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_attach_buffer invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_attach_buffer failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_vaddress_t ia_css_process_group_detach_buffer( + ia_css_process_group_t *process_group, + const unsigned int terminal_index) +{ + DECLARE_ERRVAL + int retval = -1; + vied_vaddress_t buffer = VIED_NULL; + + ia_css_terminal_t *terminal = NULL; + ia_css_process_group_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_detach_buffer(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + terminal = + ia_css_process_group_get_terminal( + process_group, terminal_index); + state = ia_css_process_group_get_state(process_group); + + verifexitval(terminal != NULL, EINVAL); + verifexitval(state == IA_CSS_PROCESS_GROUP_READY, EINVAL); + + buffer = ia_css_terminal_get_buffer(terminal); + + if (ia_css_is_terminal_data_terminal(terminal) == true) { + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + verifexitval(frame != NULL, EINVAL); + + retval = ia_css_frame_set_buffer_state(frame, IA_CSS_BUFFER_NULL); + verifexitval(retval == 0, EINVAL); + } + ia_css_terminal_set_buffer(terminal, VIED_NULL); + + retval = 0; +EXIT: + /* + * buffer pointer will appear on output, + * regardless of subsequent fails to avoid memory leaks + */ + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_detach_buffer invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_detach_buffer failed (%i)\n", + retval); + } + return buffer; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_attach_stream( + ia_css_process_group_t *process_group, + uint32_t stream, + const ia_css_buffer_state_t buffer_state, + const unsigned int terminal_index) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_attach_stream(): enter:\n"); + + NOT_USED(process_group); + NOT_USED(stream); + NOT_USED(buffer_state); + NOT_USED(terminal_index); + + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_attach_stream failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_detach_stream( + ia_css_process_group_t *process_group, + const unsigned int terminal_index) +{ + int retval = -1; + uint32_t stream = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_detach_stream(): enter:\n"); + + NOT_USED(process_group); + NOT_USED(terminal_index); + + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_detach_stream failed (%i)\n", + retval); + } + return stream; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_barrier( + ia_css_process_group_t *process_group, + const vied_nci_barrier_ID_t barrier_index) +{ + DECLARE_ERRVAL + int retval = -1; + vied_nci_resource_bitmap_t bit_mask; + vied_nci_resource_bitmap_t resource_bitmap; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_barrier(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + resource_bitmap = + ia_css_process_group_get_resource_bitmap(process_group); + + bit_mask = vied_nci_barrier_bit_mask(barrier_index); + + verifexitval(bit_mask != 0, EINVAL); + verifexitval(vied_nci_is_bitmap_clear(bit_mask, resource_bitmap), EINVAL); + + resource_bitmap = vied_nci_bitmap_set(resource_bitmap, bit_mask); + + retval = + ia_css_process_group_set_resource_bitmap( + process_group, resource_bitmap); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_barrier invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_barrier failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_clear_barrier( + ia_css_process_group_t *process_group, + const vied_nci_barrier_ID_t barrier_index) +{ + DECLARE_ERRVAL + int retval = -1; + vied_nci_resource_bitmap_t bit_mask, resource_bitmap; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_clear_barrier(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + resource_bitmap = + ia_css_process_group_get_resource_bitmap(process_group); + + bit_mask = vied_nci_barrier_bit_mask(barrier_index); + + verifexitval(bit_mask != 0, EINVAL); + verifexitval(vied_nci_is_bitmap_set(bit_mask, resource_bitmap), EINVAL); + + resource_bitmap = vied_nci_bitmap_clear(resource_bitmap, bit_mask); + + retval = + ia_css_process_group_set_resource_bitmap( + process_group, resource_bitmap); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_clear_barrier invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_clear_barrier failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_print( + const ia_css_process_group_t *process_group, + void *fid) +{ + DECLARE_ERRVAL + int retval = -1; + int i; + + uint8_t process_count; + uint8_t terminal_count; + vied_vaddress_t ipu_vaddress = VIED_NULL; + ia_css_rbm_t routing_bitmap; + + NOT_USED(fid); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_print(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + retval = ia_css_process_group_get_ipu_vaddress(process_group, &ipu_vaddress); + verifexitval(retval == 0, EINVAL); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "=============== Process group print start ===============\n"); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tprocess_group cpu address = %p\n", process_group); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tipu_virtual_address = %#x\n", ipu_vaddress); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tsizeof(process_group) = %d\n", + (int)ia_css_process_group_get_size(process_group)); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tfragment_count = %d\n", + (int)ia_css_process_group_get_fragment_count(process_group)); + + routing_bitmap = *ia_css_process_group_get_routing_bitmap(process_group); + for (i = 0; i < (int)IA_CSS_RBM_NOF_ELEMS; i++) { + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "\trouting_bitmap[index = %d] = 0x%X\n", + i, (int)routing_bitmap.data[i]); + } + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tprogram_group(process_group) = %d\n", + (int)ia_css_process_group_get_program_group_ID(process_group)); + process_count = ia_css_process_group_get_process_count(process_group); + terminal_count = + ia_css_process_group_get_terminal_count(process_group); + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\t%d processes\n", (int)process_count); + for (i = 0; i < (int)process_count; i++) { + ia_css_process_t *process = + ia_css_process_group_get_process(process_group, i); + + retval = ia_css_process_print(process, fid); + verifjmpexit(retval == 0); + } + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\t%d terminals\n", (int)terminal_count); + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_t *terminal = + ia_css_process_group_get_terminal(process_group, i); + + retval = ia_css_terminal_print(terminal, fid); + verifjmpexit(retval == 0); + } + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "=============== Process group print end ===============\n"); + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_print invalid argument\n"); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_process_group_valid( + const ia_css_process_group_t *process_group, + const ia_css_program_group_manifest_t *pg_manifest, + const ia_css_program_group_param_t *param) +{ + DECLARE_ERRVAL + bool invalid_flag = false; + uint8_t proc_idx; + uint8_t prog_idx; + uint8_t proc_term_idx; + uint8_t process_count; + uint8_t program_count; + uint8_t terminal_count; + uint8_t man_terminal_count; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_process_group_valid(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + verifexitval(pg_manifest != NULL, EFAULT); + NOT_USED(param); + + process_count = process_group->process_count; + terminal_count = process_group->terminal_count; + program_count = + ia_css_program_group_manifest_get_program_count(pg_manifest); + man_terminal_count = + ia_css_program_group_manifest_get_terminal_count(pg_manifest); + + /* Validate process group */ + invalid_flag = invalid_flag || + !(program_count >= process_count) || + !(man_terminal_count >= terminal_count) || + !(process_group->size > process_group->processes_offset) || + !(process_group->size > process_group->terminals_offset); + + /* Validate processes */ + for (proc_idx = 0; proc_idx < process_count; proc_idx++) { + const ia_css_process_t *process; + ia_css_program_ID_t prog_id; + bool no_match_found = true; + + process = ia_css_process_group_get_process( + process_group, proc_idx); + verifexitval(NULL != process, EFAULT); + prog_id = ia_css_process_get_program_ID(process); + for (prog_idx = 0; prog_idx < program_count; prog_idx++) { + ia_css_program_manifest_t *p_manifest = NULL; + + p_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + pg_manifest, prog_idx); + if (prog_id == + ia_css_program_manifest_get_program_ID( + p_manifest)) { + invalid_flag = invalid_flag || + !ia_css_is_process_valid( + process, p_manifest); + no_match_found = false; + break; + } + } + invalid_flag = invalid_flag || no_match_found; + } + + /* Validate terminals */ + for (proc_term_idx = 0; proc_term_idx < terminal_count; + proc_term_idx++) { + int man_term_idx; + const ia_css_terminal_t *terminal; + const ia_css_terminal_manifest_t *terminal_manifest; + + terminal = + ia_css_process_group_get_terminal( + process_group, proc_term_idx); + verifexitval(NULL != terminal, EFAULT); + man_term_idx = + ia_css_terminal_get_terminal_manifest_index(terminal); + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst( + pg_manifest, man_term_idx); + invalid_flag = invalid_flag || + !ia_css_is_terminal_valid(terminal, terminal_manifest); + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_process_group_valid() invalid argument\n"); + return false; + } else { + return (!invalid_flag); + } +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_can_process_group_submit( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + int i; + bool can_submit = false; + int retval = -1; + uint8_t terminal_count = + ia_css_process_group_get_terminal_count(process_group); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_can_process_group_submit(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_t *terminal = + ia_css_process_group_get_terminal(process_group, i); + vied_vaddress_t buffer; + ia_css_buffer_state_t buffer_state; + + verifexitval(terminal != NULL, EINVAL); + + if (process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_LEGACY) { + /* + * For legacy pg flow, buffer addresses are contained inside + * the process group structure, so these need to be validated + * on process group submission. + */ + buffer = ia_css_terminal_get_buffer(terminal); + IA_CSS_TRACE_3(PSYSAPI_DYNAMIC, INFO, + "\tH: Terminal number(%d) is %p having buffer 0x%x\n", + i, terminal, buffer); + } + + /* buffer_state is applicable only for data terminals*/ + if (ia_css_is_terminal_data_terminal(terminal) == true) { + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + + verifexitval(frame != NULL, EINVAL); + buffer_state = ia_css_frame_get_buffer_state(frame); + if ((buffer_state == IA_CSS_BUFFER_NULL) || + (buffer_state == IA_CSS_N_BUFFER_STATES)) { + break; + } + } else if ( + (ia_css_is_terminal_parameter_terminal(terminal) + != true) && + (ia_css_is_terminal_program_terminal(terminal) + != true) && + (ia_css_is_terminal_program_control_init_terminal(terminal) + != true) && + (ia_css_is_terminal_spatial_parameter_terminal( + terminal) != true)) { + /* neither data nor parameter terminal, so error.*/ + break; + } + + } + /* Only true if no check failed */ + can_submit = (i == terminal_count); + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_process_group_submit invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_process_group_submit failed (%i)\n", + retval); + } + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_can_process_group_submit(): leave:\n"); + return can_submit; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_can_enqueue_buffer_set( + const ia_css_process_group_t *process_group, + const ia_css_buffer_set_t *buffer_set) +{ + DECLARE_ERRVAL + int i; + bool can_enqueue = false; + int retval = -1; + uint8_t terminal_count; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_can_enqueue_buffer_set(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + verifexitval(buffer_set != NULL, EFAULT); + + terminal_count = + ia_css_process_group_get_terminal_count(process_group); + + /* + * For ppg flow, buffer addresses are contained in the + * external buffer set structure, so these need to be + * validated before enqueueing. + */ + verifexitval(process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_PPG, EFAULT); + + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_t *terminal = + ia_css_process_group_get_terminal(process_group, i); + vied_vaddress_t buffer; + ia_css_buffer_state_t buffer_state; + + verifexitval(terminal != NULL, EINVAL); + + buffer = ia_css_buffer_set_get_buffer(buffer_set, terminal); + IA_CSS_TRACE_3(PSYSAPI_DYNAMIC, INFO, + "\tH: Terminal number(%d) is %p having buffer 0x%x\n", + i, terminal, buffer); + + /* buffer_state is applicable only for data terminals*/ + if (ia_css_is_terminal_data_terminal(terminal) == true) { + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + + verifexitval(frame != NULL, EINVAL); + buffer_state = ia_css_frame_get_buffer_state(frame); + if ((buffer_state == IA_CSS_BUFFER_NULL) || + (buffer_state == IA_CSS_N_BUFFER_STATES)) { + break; + } + } else if ( + (ia_css_is_terminal_parameter_terminal(terminal) + != true) && + (ia_css_is_terminal_program_terminal(terminal) + != true) && + (ia_css_is_terminal_program_control_init_terminal(terminal) + != true) && + (ia_css_is_terminal_spatial_parameter_terminal( + terminal) != true)) { + /* neither data nor parameter terminal, so error.*/ + break; + } + } + /* Only true if no check failed */ + can_enqueue = (i == terminal_count); + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_enqueue_buffer_set invalid argument\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_enqueue_buffer_set failed (%i)\n", + retval); + } + return can_enqueue; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_can_process_group_start( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + int i; + bool can_start = false; + int retval = -1; + uint8_t terminal_count; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_can_process_group_start(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + terminal_count = + ia_css_process_group_get_terminal_count(process_group); + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_t *terminal = + ia_css_process_group_get_terminal(process_group, i); + ia_css_buffer_state_t buffer_state; + bool ok = false; + + verifexitval(terminal != NULL, EINVAL); + if (ia_css_is_terminal_data_terminal(terminal) == true) { + /* + * buffer_state is applicable only for data terminals + */ + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + bool is_input = ia_css_is_terminal_input(terminal); + /* + * check for NULL here. + * then invoke next 2 statements + */ + verifexitval(frame != NULL, EINVAL); + IA_CSS_TRACE_5(PSYSAPI_DYNAMIC, VERBOSE, + "\tTerminal %d: buffer_state %u, access_type %u, data_bytes %u, data %u\n", + i, frame->buffer_state, frame->access_type, + frame->data_bytes, frame->data); + buffer_state = ia_css_frame_get_buffer_state(frame); + + ok = ((is_input && + (buffer_state == IA_CSS_BUFFER_FULL)) || + (!is_input && (buffer_state == + IA_CSS_BUFFER_EMPTY))); + + } else if (ia_css_is_terminal_parameter_terminal(terminal) == + true) { + /* + * FIXME: + * is there any pre-requisite for param_terminal? + */ + ok = true; + } else if (ia_css_is_terminal_program_terminal(terminal) == + true) { + ok = true; + } else if (ia_css_is_terminal_program_control_init_terminal(terminal) == + true) { + ok = true; + } else if (ia_css_is_terminal_spatial_parameter_terminal( + terminal) == true) { + ok = true; + } else { + /* neither data nor parameter terminal, so error.*/ + break; + } + + if (!ok) + break; + } + /* Only true if no check failed */ + can_start = (i == terminal_count); + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_process_group_submit invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_process_group_start failed (%i)\n", + retval); + } + return can_start; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +size_t ia_css_process_group_get_size( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_size(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + size = process_group->size; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_size invalid argument\n"); + } + return size; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_group_state_t ia_css_process_group_get_state( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + ia_css_process_group_state_t state = IA_CSS_N_PROCESS_GROUP_STATES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_state(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + state = process_group->state; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_state invalid argument\n"); + } + return state; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +const ia_css_rbm_t *ia_css_process_group_get_routing_bitmap( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + const ia_css_rbm_t *rbm = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_routing_bitmap(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + rbm = &(process_group->routing_bitmap); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_routing_bitmap invalid argument\n"); + } + return rbm; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint16_t ia_css_process_group_get_fragment_count( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint16_t fragment_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_fragment_count(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + fragment_count = process_group->fragment_count; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_count invalid argument\n"); + } + return fragment_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_group_get_process_count( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint8_t process_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_process_count(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + process_count = process_group->process_count; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_process_count invalid argument\n"); + } + return process_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_group_get_terminal_count( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint8_t terminal_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_terminal_count(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + terminal_count = process_group->terminal_count; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_terminal_count invalid argument\n"); + } + return terminal_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_get_pg_load_start_ts( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint32_t pg_load_start_ts = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_pg_load_start_ts(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + pg_load_start_ts = process_group->pg_load_start_ts; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_pg_load_start_ts invalid argument\n"); + } + return pg_load_start_ts; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_get_pg_load_cycles( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint32_t pg_load_cycles = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_pg_load_cycles(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + pg_load_cycles = process_group->pg_load_cycles; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_pg_load_cycles invalid argument\n"); + } + return pg_load_cycles; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_get_pg_init_cycles( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint32_t pg_init_cycles = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_pg_init_cycles(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + pg_init_cycles = process_group->pg_init_cycles; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_pg_init_cycles invalid argument\n"); + } + return pg_init_cycles; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_get_pg_processing_cycles( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint32_t pg_processing_cycles = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_pg_processing_cycles(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + pg_processing_cycles = process_group->pg_processing_cycles; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_pg_processing_cycles invalid argument\n"); + } + return pg_processing_cycles; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_terminal_t *ia_css_process_group_get_terminal_from_type( + const ia_css_process_group_t *process_group, + const ia_css_terminal_type_t terminal_type) +{ + unsigned int proc_cnt; + ia_css_terminal_t *terminal = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_terminal_from_type(): enter:\n"); + + for (proc_cnt = 0; proc_cnt < (unsigned int)ia_css_process_group_get_terminal_count(process_group); proc_cnt++) { + terminal = ia_css_process_group_get_terminal(process_group, proc_cnt); + if (terminal == NULL) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_terminal_from_type() Failed to get terminal %d", proc_cnt); + goto EXIT; + } + if (ia_css_terminal_get_type(terminal) == terminal_type) { + return terminal; + } + terminal = NULL; /* If not the expected type, return NULL */ + } +EXIT: + return terminal; +} + +/* Returns the terminal or NULL if it was not found + For some of those maybe valid to not exist at all in the process group */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +const ia_css_terminal_t *ia_css_process_group_get_single_instance_terminal( + const ia_css_process_group_t *process_group, + ia_css_terminal_type_t term_type) +{ + int i, term_count; + + assert(process_group != NULL); + + /* Those below have at most one instance per process group */ + assert(term_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN || + term_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT || + term_type == IA_CSS_TERMINAL_TYPE_PROGRAM || + term_type == IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT); + + term_count = ia_css_process_group_get_terminal_count(process_group); + + for (i = 0; i < term_count; i++) { + const ia_css_terminal_t *terminal = ia_css_process_group_get_terminal(process_group, i); + + if (ia_css_terminal_get_type(terminal) == term_type) { + /* Only one parameter terminal per process group */ + return terminal; + } + } + + return NULL; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_terminal_t *ia_css_process_group_get_terminal( + const ia_css_process_group_t *process_grp, + const unsigned int terminal_num) +{ + DECLARE_ERRVAL + ia_css_terminal_t *terminal_ptr = NULL; + uint16_t *terminal_offset_table; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_terminal(): enter:\n"); + + verifexitval(process_grp != NULL, EFAULT); + verifexitval(terminal_num < process_grp->terminal_count, EINVAL); + + terminal_offset_table = + (uint16_t *)((char *)process_grp + + process_grp->terminals_offset); + terminal_ptr = + (ia_css_terminal_t *)((char *)process_grp + + terminal_offset_table[terminal_num]); + + verifexitval(terminal_ptr != NULL, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_terminal invalid argument\n"); + } + return terminal_ptr; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_t *ia_css_process_group_get_process( + const ia_css_process_group_t *process_grp, + const unsigned int process_num) +{ + DECLARE_ERRVAL + ia_css_process_t *process_ptr = NULL; + uint16_t *process_offset_table; + + verifexitval(process_grp != NULL, EFAULT); + verifexitval(process_num < process_grp->process_count, EINVAL); + + process_offset_table = + (uint16_t *)((char *)process_grp + + process_grp->processes_offset); + process_ptr = + (ia_css_process_t *)((char *)process_grp + + process_offset_table[process_num]); + + verifexitval(process_ptr != NULL, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_process invalid argument\n"); + } + return process_ptr; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_program_group_ID_t ia_css_process_group_get_program_group_ID( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + ia_css_program_group_ID_t id = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_program_group_ID(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + id = process_group->ID; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_program_group_ID invalid argument\n"); + } + return id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t ia_css_process_group_get_resource_bitmap( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t resource_bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_resource_bitmap(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + resource_bitmap = process_group->resource_bitmap; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_resource_bitmap invalid argument\n"); + } + return resource_bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_resource_bitmap( + ia_css_process_group_t *process_group, + const vied_nci_resource_bitmap_t resource_bitmap) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_resource_bitmap(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + process_group->resource_bitmap = resource_bitmap; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_resource_bitmap invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_resource_bitmap failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_routing_bitmap( + ia_css_process_group_t *process_group, + const ia_css_rbm_t rbm) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_routing_bitmap(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + process_group->routing_bitmap = rbm; + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_routing_bitmap invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_routing_bitmap failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_compute_cycle_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + DECLARE_ERRVAL + uint32_t cycle_count = 0; + + NOT_USED(manifest); + NOT_USED(param); + + verifexitval(manifest != NULL, EFAULT); + verifexitval(param != NULL, EFAULT); + + cycle_count = 1; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_compute_cycle_count invalid argument\n"); + } + return cycle_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_fragment_state( + ia_css_process_group_t *process_group, + uint16_t fragment_state) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_set_fragment_state(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + verifexitval(fragment_state <= ia_css_process_group_get_fragment_count( + process_group), EINVAL); + + process_group->fragment_state = fragment_state; + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_fragment_state invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_fragment_state failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_get_fragment_state( + const ia_css_process_group_t *process_group, + uint16_t *fragment_state) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_fragment_state(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + verifexitval(fragment_state != NULL, EFAULT); + + *fragment_state = process_group->fragment_state; + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_state invalid argument\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_state failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_get_ipu_vaddress( + const ia_css_process_group_t *process_group, + vied_vaddress_t *ipu_vaddress) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_ipu_vaddress(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + verifexitval(ipu_vaddress != NULL, EFAULT); + + *ipu_vaddress = process_group->ipu_virtual_address; + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_ipu_vaddress invalid argument\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_ipu_vaddress failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_ipu_vaddress( + ia_css_process_group_t *process_group, + vied_vaddress_t ipu_vaddress) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_ipu_vaddress(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + process_group->ipu_virtual_address = ipu_vaddress; + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_ipu_vaddress invalid argument\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_ipu_vaddress failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_group_get_protocol_version( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint8_t protocol_version = IA_CSS_PROCESS_GROUP_N_PROTOCOLS; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_protocol_version(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + protocol_version = process_group->protocol_version; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_protocol_version invalid argument\n"); + } + return protocol_version; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_group_get_base_queue_id( + ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint8_t queue_id = IA_CSS_N_PSYS_CMD_QUEUE_ID; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_base_queue_id(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + queue_id = process_group->base_queue_id; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_base_queue_id invalid argument\n"); + } + return queue_id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_base_queue_id( + ia_css_process_group_t *process_group, + uint8_t queue_id) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_base_queue_id(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + process_group->base_queue_id = queue_id; + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_base_queue_id invalid argument\n"); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_group_get_num_queues( + ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint8_t num_queues = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_num_queues(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + num_queues = process_group->num_queues; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_num_queues invalid argument\n"); + } + return num_queues; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_num_queues( + ia_css_process_group_t *process_group, + uint8_t num_queues) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_num_queues(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + process_group->num_queues = num_queues; + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_num_queues invalid argument\n"); + } + return retval; +} + + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_process_group_has_vp(const ia_css_process_group_t *process_group) +{ + bool has_vp = false; + uint32_t i; + + uint8_t process_count = ia_css_process_group_get_process_count(process_group); + + for (i = 0; i < process_count; i++) { + ia_css_process_t *process; + vied_nci_cell_ID_t cell_id; + + process = ia_css_process_group_get_process(process_group, i); + cell_id = ia_css_process_get_cell(process); + + if (vied_nci_cell_get_type(cell_id) == VIED_NCI_VP_TYPE_ID) { + has_vp = true; + break; + } + } + + return has_vp; +} + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_impl.h new file mode 100644 index 0000000000000..e9a3ef6c6f3c6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_impl.h @@ -0,0 +1,638 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_IMPL_H +#define __IA_CSS_PSYS_PROCESS_IMPL_H + +#include + +#include +#include + +#include +#include +#include + +#include + +#include "ia_css_psys_dynamic_trace.h" +#include "ia_css_psys_process_private_types.h" + +/** Function only to be used in ia_css_psys_process_impl.h and ia_css_psys_process.h */ +STORAGE_CLASS_INLINE vied_nci_cell_ID_t ia_css_process_cells_get_cell(const ia_css_process_t *process, int index) +{ + assert(index < IA_CSS_PROCESS_MAX_CELLS); + if (index >= IA_CSS_PROCESS_MAX_CELLS) { + return VIED_NCI_N_CELL_ID; + } +#if IA_CSS_PROCESS_MAX_CELLS == 1 + return process->cell_id; +#else + return process->cells[index]; +#endif +} + +/** Function only to be used in ia_css_psys_process_impl.h and ia_css_psys_process.h */ +STORAGE_CLASS_INLINE void ia_css_process_cells_set_cell(ia_css_process_t *process, int index, vied_nci_cell_ID_t cell_id) +{ + assert(index < IA_CSS_PROCESS_MAX_CELLS); + if (index >= IA_CSS_PROCESS_MAX_CELLS) { + return; + } +#if IA_CSS_PROCESS_MAX_CELLS == 1 + process->cell_id = cell_id; +#else + process->cells[index] = cell_id; +#endif +} + +/** Function only to be used in ia_css_psys_process_impl.h and ia_css_psys_process */ +STORAGE_CLASS_INLINE void ia_css_process_cells_clear(ia_css_process_t *process) +{ + int i; + + for (i = 0; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + ia_css_process_cells_set_cell(process, i, VIED_NCI_N_CELL_ID); + } +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_cell_ID_t ia_css_process_get_cell( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + vied_nci_cell_ID_t cell_id = VIED_NCI_N_CELL_ID; + int i = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_cell(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + +#if IA_CSS_PROCESS_MAX_CELLS > 1 + for (i = 1; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + assert(ia_css_process_cells_get_cell(process, i) == VIED_NCI_N_CELL_ID); +#ifdef __HIVECC +#pragma hivecc unroll +#endif + } +#else + (void)i; +#endif + cell_id = ia_css_process_cells_get_cell(process, 0); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_cell invalid argument\n"); + } + return cell_id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_mem_ID_t ia_css_process_get_ext_mem_id( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type) +{ + DECLARE_ERRVAL + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_ext_mem(): enter:\n"); + + verifexitval(process != NULL && mem_type < VIED_NCI_N_DATA_MEM_TYPE_ID, EFAULT); + +EXIT: + if (!noerror()) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_ext_mem invalid argument\n"); + return IA_CSS_PROCESS_INVALID_OFFSET; + } + return process->ext_mem_id[mem_type]; +} + + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_get_program_idx( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_program_idx(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_program_idx invalid argument\n"); + return IA_CSS_PROCESS_INVALID_PROGRAM_IDX; + } + return process->program_idx; +} + + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_size_t ia_css_process_get_dev_chn( + const ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id) +{ + DECLARE_ERRVAL + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_dev_chn(): enter:\n"); + + verifexitval(process != NULL && dev_chn_id < VIED_NCI_N_DEV_CHN_ID, EFAULT); + +EXIT: + if (!noerror()) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_dev_chn(): invalid arguments\n"); + return IA_CSS_PROCESS_INVALID_OFFSET; + } + return process->dev_chn_offset[dev_chn_id]; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_size_t ia_css_process_get_int_mem_offset( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_id) +{ + DECLARE_ERRVAL + vied_nci_resource_size_t int_mem_offset = IA_CSS_PROCESS_INVALID_OFFSET; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_int_mem_offset(): enter:\n"); + + verifexitval(process != NULL && mem_id < VIED_NCI_N_MEM_TYPE_ID, EFAULT); + +EXIT: + if (noerror()) { + int_mem_offset = process->int_mem_offset[mem_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_int_mem_offset invalid argument\n"); + } + + return int_mem_offset; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_size_t ia_css_process_get_ext_mem_offset( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id) +{ + DECLARE_ERRVAL + vied_nci_resource_size_t ext_mem_offset = IA_CSS_PROCESS_INVALID_OFFSET; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_ext_mem_offset(): enter:\n"); + + verifexitval(process != NULL && mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID, EFAULT); + +EXIT: + if (noerror()) { + ext_mem_offset = process->ext_mem_offset[mem_type_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_ext_mem_offset invalid argument\n"); + } + + return ext_mem_offset; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +size_t ia_css_process_get_size( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_size(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + +EXIT: + if (noerror()) { + size = process->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_size invalid argument\n"); + } + + return size; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_state_t ia_css_process_get_state( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + ia_css_process_state_t state = IA_CSS_N_PROCESS_STATES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_state(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + +EXIT: + if (noerror()) { + state = process->state; + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_state invalid argument\n"); + } + + return state; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_set_state( + ia_css_process_t *process, + ia_css_process_state_t state) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_state(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + + process->state = state; + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_state invalid argument\n"); + } + + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_get_cell_dependency_count( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + uint8_t cell_dependency_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_cell_dependency_count(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + cell_dependency_count = process->cell_dependency_count; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_cell_dependency_count invalid argument\n"); + } + return cell_dependency_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_get_terminal_dependency_count( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + uint8_t terminal_dependency_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_terminal_dependency_count(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + terminal_dependency_count = process->terminal_dependency_count; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_terminal_dependency_count invalid argument process\n"); + } + return terminal_dependency_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_group_t *ia_css_process_get_parent( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + ia_css_process_group_t *parent = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_parent(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + + parent = + (ia_css_process_group_t *) ((char *)process + process->parent_offset); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_parent invalid argument process\n"); + } + return parent; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_program_ID_t ia_css_process_get_program_ID( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + ia_css_program_ID_t id = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_program_ID(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + + id = process->ID; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_program_ID invalid argument process\n"); + } + return id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_id_t ia_css_process_get_cell_dependency( + const ia_css_process_t *process, + const unsigned int cell_num) +{ + DECLARE_ERRVAL + vied_nci_resource_id_t cell_dependency = + IA_CSS_PROCESS_INVALID_DEPENDENCY; + vied_nci_resource_id_t *cell_dep_ptr = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_cell_dependency(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + verifexitval(cell_num < process->cell_dependency_count, EFAULT); + + cell_dep_ptr = + (vied_nci_resource_id_t *) + ((char *)process + process->cell_dependencies_offset); + cell_dependency = *(cell_dep_ptr + cell_num); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_cell_dependency invalid argument\n"); + } + return cell_dependency; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_get_terminal_dependency( + const ia_css_process_t *process, + const unsigned int terminal_num) +{ + DECLARE_ERRVAL + uint8_t *ter_dep_ptr = NULL; + uint8_t ter_dep = IA_CSS_PROCESS_INVALID_DEPENDENCY; + + verifexitval(process != NULL, EFAULT); + verifexitval(terminal_num < process->terminal_dependency_count, EFAULT); + + ter_dep_ptr = (uint8_t *) ((char *)process + + process->terminal_dependencies_offset); + + ter_dep = *(ter_dep_ptr + terminal_num); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_terminal_dependency invalid argument\n"); + } + return ter_dep; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_kernel_bitmap_t ia_css_process_get_kernel_bitmap( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + ia_css_kernel_bitmap_t bitmap = ia_css_kernel_bitmap_clear(); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_kernel_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + + bitmap = process->kernel_bitmap; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_kernel_bitmap invalid argument process\n"); + } + return bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t ia_css_process_get_cells_bitmap( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t bitmap = 0; + vied_nci_cell_ID_t cell_id; + int i = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_cell_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + + for (i = 0; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + cell_id = ia_css_process_cells_get_cell(process, i); + if (cell_id != VIED_NCI_N_CELL_ID) { + bitmap |= (1 << cell_id); + } +#ifdef __HIVECC +#pragma hivecc unroll +#endif + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_cells_bitmap invalid argument process\n"); + } + + return bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t *ia_css_process_get_dfm_port_bitmap_ptr( + ia_css_process_t *process) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t *p_bitmap = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_dfm_port_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + p_bitmap = &process->dfm_port_bitmap[0]; +#else + p_bitmap = NULL; +#endif +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_dfm_port_bitmap invalid argument process\n"); + } + + return p_bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t *ia_css_process_get_dfm_active_port_bitmap_ptr( + ia_css_process_t *process) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t *p_bitmap = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_dfm_port_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + p_bitmap = &process->dfm_active_port_bitmap[0]; +#else + p_bitmap = NULL; +#endif +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_dfm_port_bitmap invalid argument process\n"); + } + + return p_bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t ia_css_process_get_dfm_port_bitmap( + const ia_css_process_t *process, + vied_nci_dev_dfm_id_t dfm_res_id) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_dfm_port_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexitval(dfm_res_id < VIED_NCI_N_DEV_DFM_ID, EFAULT); + bitmap = process->dfm_port_bitmap[dfm_res_id]; +#else + bitmap = 0; + (void)dfm_res_id; +#endif +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_dfm_port_bitmap invalid argument process\n"); + } + + return bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t ia_css_process_get_dfm_active_port_bitmap( + const ia_css_process_t *process, + vied_nci_dev_dfm_id_t dfm_res_id) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_dfm_active_port_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexitval(dfm_res_id < VIED_NCI_N_DEV_DFM_ID, EFAULT); + bitmap = process->dfm_active_port_bitmap[dfm_res_id]; +#else + bitmap = 0; + (void)dfm_res_id; +#endif +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_dfm_active_port_bitmap invalid argument process\n"); + } + return bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_process_valid( + const ia_css_process_t *process, + const ia_css_program_manifest_t *p_manifest) +{ + DECLARE_ERRVAL + bool invalid_flag = false; + ia_css_program_ID_t prog_id; + ia_css_kernel_bitmap_t prog_kernel_bitmap; + + verifexitval(NULL != process, EFAULT); + verifexitval(NULL != p_manifest, EFAULT); + + prog_id = ia_css_process_get_program_ID(process); + verifjmpexit(prog_id == + ia_css_program_manifest_get_program_ID(p_manifest)); + + prog_kernel_bitmap = + ia_css_program_manifest_get_kernel_bitmap(p_manifest); + + invalid_flag = (process->size <= process->cell_dependencies_offset) || + (process->size <= process->terminal_dependencies_offset) || + !ia_css_is_kernel_bitmap_subset(prog_kernel_bitmap, + process->kernel_bitmap); + + if (ia_css_has_program_manifest_fixed_cell(p_manifest)) { + vied_nci_cell_ID_t cell_id; + + cell_id = ia_css_program_manifest_get_cell_ID(p_manifest); + invalid_flag = invalid_flag || + (cell_id != (vied_nci_cell_ID_t)(ia_css_process_get_cell(process))); + } + invalid_flag = invalid_flag || + ((process->cell_dependency_count + + process->terminal_dependency_count) == 0) || + (process->cell_dependency_count != + ia_css_program_manifest_get_program_dependency_count(p_manifest)) || + (process->terminal_dependency_count != + ia_css_program_manifest_get_terminal_dependency_count(p_manifest)); + + /* TODO: to be removed once all PGs pass validation */ + if (invalid_flag == true) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_is_process_valid(): false\n"); + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_process_valid() invalid argument\n"); + return false; + } else { + return (!invalid_flag); + } +} + +#endif /* __IA_CSS_PSYS_PROCESS_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_private_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_private_types.h new file mode 100644 index 0000000000000..ae0affde97187 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_private_types.h @@ -0,0 +1,87 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_PRIVATE_TYPES_H +#define __IA_CSS_PSYS_PROCESS_PRIVATE_TYPES_H + +#include "ia_css_psys_process_types.h" +#include "vied_nci_psys_resource_model.h" + +#define N_UINT32_IN_PROCESS_STRUCT 2 +#define N_UINT16_IN_PROCESS_STRUCT 3 +#define N_UINT8_IN_PROCESS_STRUCT 2 + +#define SIZE_OF_PROCESS_STRUCT_BITS \ + (IA_CSS_KERNEL_BITMAP_BITS \ + + (N_UINT32_IN_PROCESS_STRUCT * 32) \ + + IA_CSS_PROGRAM_ID_BITS \ + + (VIED_NCI_RESOURCE_BITMAP_BITS * VIED_NCI_N_DEV_DFM_ID) \ + + (VIED_NCI_RESOURCE_BITMAP_BITS * VIED_NCI_N_DEV_DFM_ID) \ + + IA_CSS_PROCESS_STATE_BITS \ + + (N_UINT16_IN_PROCESS_STRUCT * 16) \ + + (VIED_NCI_N_MEM_TYPE_ID * VIED_NCI_RESOURCE_SIZE_BITS) \ + + (VIED_NCI_N_DATA_MEM_TYPE_ID * VIED_NCI_RESOURCE_SIZE_BITS) \ + + (VIED_NCI_N_DEV_CHN_ID * VIED_NCI_RESOURCE_SIZE_BITS) \ + + (IA_CSS_PROCESS_MAX_CELLS * VIED_NCI_RESOURCE_ID_BITS) \ + + (VIED_NCI_N_MEM_TYPE_ID * VIED_NCI_RESOURCE_ID_BITS) \ + + (VIED_NCI_N_DATA_MEM_TYPE_ID * VIED_NCI_RESOURCE_ID_BITS) \ + + (N_UINT8_IN_PROCESS_STRUCT * 8) \ + + (N_PADDING_UINT8_IN_PROCESS_STRUCT * 8)) + +struct ia_css_process_s { + /**< Indicate which kernels lead to this process being used */ + ia_css_kernel_bitmap_t kernel_bitmap; + uint32_t size; /**< Size of this structure */ + ia_css_program_ID_t ID; /**< Referal ID to a specific program FW */ + uint32_t program_idx; /**< Program Index into the PG manifest */ +#if (VIED_NCI_N_DEV_DFM_ID > 0) + /**< DFM port allocated to this process */ + vied_nci_resource_bitmap_t dfm_port_bitmap[VIED_NCI_N_DEV_DFM_ID]; + /**< Active DFM ports which need a kick */ + vied_nci_resource_bitmap_t dfm_active_port_bitmap[VIED_NCI_N_DEV_DFM_ID]; +#endif + /**< State of the process FSM dependent on the parent FSM */ + ia_css_process_state_t state; + int16_t parent_offset; /**< Reference to the process group */ + /**< Array[dependency_count] of ID's of the cells that provide input */ + uint16_t cell_dependencies_offset; + /**< Array[terminal_dependency_count] of indices of connected terminals */ + uint16_t terminal_dependencies_offset; + /**< (internal) Memory allocation offset given to this process */ + vied_nci_resource_size_t int_mem_offset[VIED_NCI_N_MEM_TYPE_ID]; + /**< (external) Memory allocation offset given to this process */ + vied_nci_resource_size_t ext_mem_offset[VIED_NCI_N_DATA_MEM_TYPE_ID]; + /**< Device channel allocation offset given to this process */ + vied_nci_resource_size_t dev_chn_offset[VIED_NCI_N_DEV_CHN_ID]; + /**< Cells (VP, ACB) allocated for the process*/ +#if IA_CSS_PROCESS_MAX_CELLS == 1 + vied_nci_resource_id_t cell_id; +#else + vied_nci_resource_id_t cells[IA_CSS_PROCESS_MAX_CELLS]; +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ + /**< (internal) Memory ID; This is redundant, derived from cell_id */ + vied_nci_resource_id_t int_mem_id[VIED_NCI_N_MEM_TYPE_ID]; + /**< (external) Memory ID */ + vied_nci_resource_id_t ext_mem_id[VIED_NCI_N_DATA_MEM_TYPE_ID]; + /**< Number of processes (mapped on cells) this process depends on */ + uint8_t cell_dependency_count; + /**< Number of terminals this process depends on */ + uint8_t terminal_dependency_count; + /**< Padding bytes for 64bit alignment*/ +#if (N_PADDING_UINT8_IN_PROCESS_STRUCT > 0) + uint8_t padding[N_PADDING_UINT8_IN_PROCESS_STRUCT]; +#endif /*(N_PADDING_UINT8_IN_PROCESS_STRUCT > 0)*/ +}; + +#endif /* __IA_CSS_PSYS_PROCESS_PRIVATE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal.c new file mode 100644 index 0000000000000..632d6134b1471 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal.c @@ -0,0 +1,604 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_dynamic_storage_class.h" +#include "ia_css_psys_terminal_private_types.h" +#include "ia_css_terminal_types.h" + +/* + * Functions to possibly inline + */ + +#ifndef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_terminal_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +STORAGE_CLASS_INLINE void __terminal_dummy_check_alignment(void) +{ + COMPILATION_ERROR_IF( + SIZE_OF_PARAM_TERMINAL_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_param_terminal_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_param_terminal_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PARAM_SEC_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_param_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_param_section_desc_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_SPATIAL_PARAM_TERM_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_spatial_param_terminal_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_spatial_param_terminal_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAME_GRID_PARAM_SEC_STRUCT_BITS != + (CHAR_BIT * sizeof( + ia_css_frame_grid_param_section_desc_t))); + + COMPILATION_ERROR_IF(0 != sizeof( + ia_css_frame_grid_param_section_desc_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAG_GRID_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_fragment_grid_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_fragment_grid_desc_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_SLICED_PARAM_TERM_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_sliced_param_terminal_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_sliced_param_terminal_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAGMENT_SLICE_DESC_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_fragment_slice_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_fragment_slice_desc_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_SLICE_PARAM_SECTION_DESC_STRUCT_BITS != + (CHAR_BIT * sizeof( + ia_css_slice_param_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_slice_param_section_desc_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_TERM_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_program_terminal_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_terminal_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAG_SEQ_INFO_STRUCT_BITS != + (CHAR_BIT * sizeof( + ia_css_kernel_fragment_sequencer_info_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_kernel_fragment_sequencer_info_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAG_SEQ_COMMANDS_STRUCT_BITS != + (CHAR_BIT * sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_kernel_fragment_sequencer_command_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAG_PARAM_SEC_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_fragment_param_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_fragment_param_section_desc_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_CONTROL_INIT_LOAD_SECTION_DESC_STRUCT_BITS != + (CHAR_BIT * + sizeof(ia_css_program_control_init_load_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_control_init_load_section_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_CONTROL_INIT_CONNECT_SECTION_DESC_STRUCT_BITS != + (CHAR_BIT * + sizeof(ia_css_program_control_init_connect_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_control_init_connect_section_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROGRAM_DESC_CONTROL_INFO_STRUCT_BITS != + (CHAR_BIT * + sizeof(struct ia_css_program_desc_control_info_s))); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_CONTROL_INIT_PROG_DESC_STRUCT_BITS != + (CHAR_BIT * + sizeof(ia_css_program_control_init_program_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_control_init_program_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_CONTROL_INIT_TERM_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_program_control_init_terminal_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_control_init_terminal_t) % + sizeof(uint64_t)); +} + +/* + * Functions not to inline + */ + +/* + * This source file is created with the intention of sharing and + * compiled for host and firmware. Since there is no native 64bit + * data type support for firmware this wouldn't compile for SP + * tile. The part of the file that is not compilable are marked + * with the following __VIED_CELL marker and this comment. Once we + * come up with a solution to address this issue this will be + * removed. + */ +#if !defined(__VIED_CELL) +size_t ia_css_sizeof_terminal( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + size_t size = 0; + uint16_t fragment_count = + ia_css_program_group_param_get_fragment_count(param); + + COMPILATION_ERROR_IF( + SIZE_OF_DATA_TERMINAL_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_data_terminal_t))); + + COMPILATION_ERROR_IF( + 0 != sizeof(ia_css_data_terminal_t)%sizeof(uint64_t)); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_sizeof_terminal(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + if (ia_css_is_terminal_manifest_parameter_terminal(manifest)) { + const ia_css_param_terminal_manifest_t *param_term_man = + (const ia_css_param_terminal_manifest_t *)manifest; + if (ia_css_terminal_manifest_get_type(manifest) == + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN) { + size = ia_css_param_in_terminal_get_descriptor_size( + param_term_man->param_manifest_section_desc_count); + } else if (ia_css_terminal_manifest_get_type(manifest) == + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT) { + size = ia_css_param_out_terminal_get_descriptor_size( + param_term_man->param_manifest_section_desc_count, + fragment_count); + } else { + assert(NULL == "Invalid parameter terminal type"); + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_sizeof_terminal(): Invalid parameter terminal type:\n"); + verifjmpexit(0); + } + } else if (ia_css_is_terminal_manifest_data_terminal(manifest)) { + size += sizeof(ia_css_data_terminal_t); + size += fragment_count * sizeof(ia_css_fragment_descriptor_t); + } else if (ia_css_is_terminal_manifest_program_terminal(manifest)) { + ia_css_program_terminal_manifest_t *prog_term_man = + (ia_css_program_terminal_manifest_t *)manifest; + + size = ia_css_program_terminal_get_descriptor_size( + fragment_count, + prog_term_man-> + fragment_param_manifest_section_desc_count, + prog_term_man-> + kernel_fragment_sequencer_info_manifest_info_count, + (fragment_count * prog_term_man-> + max_kernel_fragment_sequencer_command_desc)); + } else if (ia_css_is_terminal_manifest_spatial_parameter_terminal( + manifest)) { + ia_css_spatial_param_terminal_manifest_t *spatial_param_term = + (ia_css_spatial_param_terminal_manifest_t *)manifest; + size = ia_css_spatial_param_terminal_get_descriptor_size( + spatial_param_term-> + frame_grid_param_manifest_section_desc_count, + fragment_count); + } else if (ia_css_is_terminal_manifest_program_control_init_terminal( + manifest)) { + ia_css_program_control_init_terminal_manifest_t *progctrlinit_term_man = + (ia_css_program_control_init_terminal_manifest_t *)manifest; + + size = ia_css_program_control_init_terminal_get_descriptor_size( + progctrlinit_term_man); + } +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_sizeof_terminal invalid argument\n"); + } + return size; +} + +ia_css_terminal_t *ia_css_terminal_create( + void *raw_mem, + const ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_param_t *terminal_param, + ia_css_kernel_bitmap_t enable_bitmap) +{ + char *terminal_raw_ptr; + ia_css_terminal_t *terminal = NULL; + uint16_t fragment_count; + int i, j; + int retval = -1; + ia_css_program_group_param_t *param; + + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "ia_css_terminal_create(manifest %p, terminal_param %p): enter:\n", + manifest, terminal_param); + + param = ia_css_terminal_param_get_parent(terminal_param); + fragment_count = ia_css_program_group_param_get_fragment_count(param); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + terminal_raw_ptr = (char *) raw_mem; + + terminal = (ia_css_terminal_t *) terminal_raw_ptr; + verifexit(terminal != NULL); + + terminal->size = (uint16_t)ia_css_sizeof_terminal(manifest, param); + verifexit(ia_css_terminal_set_type( + terminal, ia_css_terminal_manifest_get_type(manifest)) == 0); + + terminal->ID = ia_css_terminal_manifest_get_ID(manifest); + + verifexit(ia_css_terminal_set_buffer(terminal, + VIED_NULL) == 0); + + if (ia_css_is_terminal_manifest_data_terminal(manifest) == true) { + ia_css_data_terminal_t *dterminal = + (ia_css_data_terminal_t *)terminal; + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame(dterminal); + ia_css_kernel_bitmap_t intersection = + ia_css_kernel_bitmap_intersection(enable_bitmap, + ia_css_data_terminal_manifest_get_kernel_bitmap( + (const ia_css_data_terminal_manifest_t *)manifest)); + + verifexit(frame != NULL); + verifexit(ia_css_frame_set_buffer_state( + frame, IA_CSS_BUFFER_NULL) == 0); + verifexit(ia_css_is_kernel_bitmap_onehot(intersection) == + true); + + terminal_raw_ptr += sizeof(ia_css_data_terminal_t); + dterminal->fragment_descriptor_offset = + (uint16_t) (terminal_raw_ptr - (char *)terminal); + + dterminal->kernel_id = 0; + while (!ia_css_is_kernel_bitmap_empty(intersection)) { + intersection = ia_css_kernel_bitmap_shift( + intersection); + dterminal->kernel_id++; + } + assert(dterminal->kernel_id > 0); + dterminal->kernel_id -= 1; + + /* some terminal and fragment initialization */ + dterminal->frame_descriptor.frame_format_type = + terminal_param->frame_format_type; + for (i = 0; i < IA_CSS_N_DATA_DIMENSION; i++) { + dterminal->frame_descriptor.dimension[i] = + terminal_param->dimensions[i]; + } + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION] = + terminal_param->stride; + dterminal->frame_descriptor.bpp = terminal_param->bpp; + dterminal->frame_descriptor.bpe = terminal_param->bpe; + switch (dterminal->frame_descriptor.frame_format_type) { + case IA_CSS_DATA_FORMAT_UYVY: + case IA_CSS_DATA_FORMAT_YUYV: + case IA_CSS_DATA_FORMAT_Y800: + case IA_CSS_DATA_FORMAT_RGB565: + case IA_CSS_DATA_FORMAT_RGBA888: + case IA_CSS_DATA_FORMAT_BAYER_GRBG: + case IA_CSS_DATA_FORMAT_BAYER_RGGB: + case IA_CSS_DATA_FORMAT_BAYER_BGGR: + case IA_CSS_DATA_FORMAT_BAYER_GBRG: + case IA_CSS_DATA_FORMAT_RAW: + case IA_CSS_DATA_FORMAT_RAW_PACKED: + case IA_CSS_DATA_FORMAT_YYUVYY_VECTORIZED: + case IA_CSS_DATA_FORMAT_PAF: + dterminal->frame_descriptor.plane_count = 1; + dterminal->frame_descriptor.plane_offsets[0] = 0; + break; + case IA_CSS_DATA_FORMAT_NV12: + case IA_CSS_DATA_FORMAT_NV21: + case IA_CSS_DATA_FORMAT_NV16: + case IA_CSS_DATA_FORMAT_NV61: + dterminal->frame_descriptor.plane_count = 2; + dterminal->frame_descriptor.plane_offsets[0] = 0; + dterminal->frame_descriptor.plane_offsets[1] = + dterminal->frame_descriptor.plane_offsets[0] + + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION] * + dterminal->frame_descriptor.dimension[IA_CSS_ROW_DIMENSION]; + break; + case IA_CSS_DATA_FORMAT_YUV444: + case IA_CSS_DATA_FORMAT_RGB888: + case IA_CSS_DATA_FORMAT_YUV420_VECTORIZED: + dterminal->frame_descriptor.plane_count = 3; + dterminal->frame_descriptor.plane_offsets[0] = 0; + dterminal->frame_descriptor.plane_offsets[1] = + dterminal->frame_descriptor.plane_offsets[0] + + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION] * + dterminal->frame_descriptor.dimension[IA_CSS_ROW_DIMENSION]; + dterminal->frame_descriptor.plane_offsets[2] = + dterminal->frame_descriptor.plane_offsets[1] + + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION] * + dterminal->frame_descriptor.dimension[IA_CSS_ROW_DIMENSION]; + break; + case IA_CSS_DATA_FORMAT_YUV420: + dterminal->frame_descriptor.plane_count = 3; + dterminal->frame_descriptor.plane_offsets[0] = 0; + dterminal->frame_descriptor.plane_offsets[1] = + dterminal->frame_descriptor.plane_offsets[0] + + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION] * + dterminal->frame_descriptor.dimension[IA_CSS_ROW_DIMENSION]; + dterminal->frame_descriptor.plane_offsets[2] = + dterminal->frame_descriptor.plane_offsets[1] + + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION]/2 * + dterminal->frame_descriptor.dimension[IA_CSS_ROW_DIMENSION]/2; + break; + default: + /* Unset, resulting in potential terminal connect issues */ + dterminal->frame_descriptor.plane_count = 1; + dterminal->frame_descriptor.plane_offsets[0] = 0; + break; + } + /* + * Initial solution for single fragment initialization + * TODO: + * where to get the fragment description params from??? + */ + if (fragment_count > 0) { + ia_css_fragment_descriptor_t *fragment_descriptor = + (ia_css_fragment_descriptor_t *) + terminal_raw_ptr; + + fragment_descriptor->index[IA_CSS_COL_DIMENSION] = + terminal_param->index[IA_CSS_COL_DIMENSION]; + fragment_descriptor->index[IA_CSS_ROW_DIMENSION] = + terminal_param->index[IA_CSS_ROW_DIMENSION]; + fragment_descriptor->offset[0] = + terminal_param->offset; + for (i = 0; i < IA_CSS_N_DATA_DIMENSION; i++) { + fragment_descriptor->dimension[i] = + terminal_param->fragment_dimensions[i]; + } + } + /* end fragment stuff */ + } else if (ia_css_is_terminal_manifest_parameter_terminal(manifest) == + true) { + ia_css_param_terminal_t *pterminal = + (ia_css_param_terminal_t *)terminal; + uint16_t section_count = + ((const ia_css_param_terminal_manifest_t *)manifest)-> + param_manifest_section_desc_count; + size_t curr_offset = 0; + + pterminal->param_section_desc_offset = + sizeof(ia_css_param_terminal_t); + + for (i = 0; i < section_count; i++) { + ia_css_param_section_desc_t *section = + ia_css_param_in_terminal_get_param_section_desc( + pterminal, i); + const ia_css_param_manifest_section_desc_t * + man_section = + ia_css_param_terminal_manifest_get_prm_sct_desc( + (const ia_css_param_terminal_manifest_t *)manifest, i); + + verifjmpexit(man_section != NULL); + verifjmpexit(section != NULL); + + section->mem_size = man_section->max_mem_size; + section->mem_offset = curr_offset; + curr_offset += man_section->max_mem_size; + } + } else if (ia_css_is_terminal_manifest_program_terminal(manifest) == + true && + ia_css_terminal_manifest_get_type(manifest) == + IA_CSS_TERMINAL_TYPE_PROGRAM) { /* for program terminal */ + ia_css_program_terminal_t *prog_terminal = + (ia_css_program_terminal_t *)terminal; + const ia_css_program_terminal_manifest_t *prog_terminal_man = + (const ia_css_program_terminal_manifest_t *)manifest; + ia_css_kernel_fragment_sequencer_info_desc_t + *sequencer_info_desc_base = NULL; + uint16_t section_count = prog_terminal_man-> + fragment_param_manifest_section_desc_count; + uint16_t manifest_info_count = + prog_terminal_man-> + kernel_fragment_sequencer_info_manifest_info_count; + /* information needs to come from user or manifest once + * the size sizeof function is updated. + */ + uint16_t nof_command_objs = 0; + size_t curr_offset = 0; + + prog_terminal->kernel_fragment_sequencer_info_desc_offset = + sizeof(ia_css_program_terminal_t); + prog_terminal->fragment_param_section_desc_offset = + prog_terminal-> + kernel_fragment_sequencer_info_desc_offset + + (fragment_count * manifest_info_count * + sizeof(ia_css_kernel_fragment_sequencer_info_desc_t)) + + (nof_command_objs * + sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t)); + + NOT_USED(sequencer_info_desc_base); + for (i = 0; i < fragment_count; i++) { + for (j = 0; j < section_count; j++) { + ia_css_fragment_param_section_desc_t *section = + ia_css_program_terminal_get_frgmnt_prm_sct_desc( + prog_terminal, i, j, section_count); + const ia_css_fragment_param_manifest_section_desc_t * + man_section = +ia_css_program_terminal_manifest_get_frgmnt_prm_sct_desc + (prog_terminal_man, j); + + verifjmpexit(man_section != NULL); + verifjmpexit(section != NULL); + + section->mem_size = man_section->max_mem_size; + section->mem_offset = curr_offset; + curr_offset += man_section->max_mem_size; + } + + sequencer_info_desc_base = + ia_css_program_terminal_get_kernel_frgmnt_seq_info_desc( + prog_terminal, i, 0, + manifest_info_count); + + /* + * This offset cannot be initialized properly + * since the number of commands in every sequencer + * is not known at this point + */ + /*for (j = 0; j < manifest_info_count; j++) { + sequencer_info_desc_base[j]. + command_desc_offset = + prog_terminal-> + kernel_fragment_sequencer_info_desc_offset + + (manifest_info_count * + sizeof( + ia_css_kernel_fragment_sequencer_info_desc_t) + + (nof_command_objs * + sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t + )); + }*/ + } + } else if (ia_css_is_terminal_manifest_spatial_parameter_terminal( + manifest) == true) { + ia_css_spatial_param_terminal_t *spatial_param_terminal = + (ia_css_spatial_param_terminal_t *)terminal; + ia_css_spatial_param_terminal_manifest_t * + spatia_param_terminal_man = + (ia_css_spatial_param_terminal_manifest_t *)manifest; + + /* Initialize the spatial terminal structure */ + spatial_param_terminal->fragment_grid_desc_offset = + sizeof(ia_css_spatial_param_terminal_t); + spatial_param_terminal->frame_grid_param_section_desc_offset = + spatial_param_terminal->fragment_grid_desc_offset + + (fragment_count * sizeof(ia_css_fragment_grid_desc_t)); + spatial_param_terminal->kernel_id = + spatia_param_terminal_man->kernel_id; + } else if (ia_css_is_terminal_manifest_sliced_terminal(manifest) == + true) { + ia_css_sliced_param_terminal_t *sliced_param_terminal = + (ia_css_sliced_param_terminal_t *)terminal; + ia_css_sliced_param_terminal_manifest_t + *sliced_param_terminal_man = + (ia_css_sliced_param_terminal_manifest_t *)manifest; + + /* Initialize the sliced terminal structure */ + sliced_param_terminal->fragment_slice_desc_offset = + sizeof(ia_css_sliced_param_terminal_t); + sliced_param_terminal->kernel_id = + sliced_param_terminal_man->kernel_id; + } else if (ia_css_is_terminal_manifest_program_control_init_terminal( + manifest) == true) { + verifjmpexit(ia_css_program_control_init_terminal_init( + (ia_css_program_control_init_terminal_t *) + terminal, + (const ia_css_program_control_init_terminal_manifest_t *) + manifest) == 0); + } else { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_create failed, not a data or param terminal. Returning (%i)\n", + EFAULT); + goto EXIT; + } + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_terminal_create(): Created successfully terminal %p\n", + terminal); + + retval = 0; +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_terminal_create invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_create failed (%i)\n", retval); + terminal = ia_css_terminal_destroy(terminal); + } + return terminal; +} + +ia_css_terminal_t *ia_css_terminal_destroy( + ia_css_terminal_t *terminal) +{ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_terminal_destroy(terminal %p): enter:\n", terminal); + return terminal; +} + +uint16_t ia_css_param_terminal_compute_section_count( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param) /* Delete 2nd argument*/ +{ + uint16_t section_count = 0; + + NOT_USED(param); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_param_terminal_compute_section_count(): enter:\n"); + + verifexit(manifest != NULL); + section_count = ((const ia_css_param_terminal_manifest_t *)manifest)-> + param_manifest_section_desc_count; +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_param_terminal_compute_section_count: invalid argument\n"); + } + return section_count; +} +#endif /* !defined(__VIED_CELL) */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_impl.h new file mode 100644 index 0000000000000..b65813b40266c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_impl.h @@ -0,0 +1,1867 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_IMPL_H +#define __IA_CSS_PSYS_TERMINAL_IMPL_H + +#include + +#include +#include + +#include +#include + +#include + + +#include +#include /* for verifexit, verifjmpexit */ +#include /* for COMPILATION_ERROR_IF */ +#include /* for NOT_USED */ +#include "ia_css_psys_terminal_private_types.h" +#include "ia_css_terminal_manifest_types.h" +#include "ia_css_psys_dynamic_trace.h" +#include "ia_css_psys_manifest_types.h" +#include "ia_css_psys_program_group_private.h" +#include "ia_css_terminal_types.h" + +STORAGE_CLASS_INLINE int ia_css_data_terminal_print(const ia_css_terminal_t *terminal, + void *fid) +{ + + DECLARE_ERRVAL + int retval = -1; + int i; + ia_css_data_terminal_t *dterminal = (ia_css_data_terminal_t *)terminal; + uint16_t fragment_count = + ia_css_data_terminal_get_fragment_count(dterminal); + verifexitval(fragment_count != 0, EINVAL); + + retval = ia_css_frame_descriptor_print( + ia_css_data_terminal_get_frame_descriptor(dterminal), + fid); + verifexitval(retval == 0, EINVAL); + + retval = ia_css_frame_print( + ia_css_data_terminal_get_frame(dterminal), fid); + verifexitval(retval == 0, EINVAL); + + for (i = 0; i < (int)fragment_count; i++) { + retval = ia_css_fragment_descriptor_print( + ia_css_data_terminal_get_fragment_descriptor( + dterminal, i), fid); + verifexitval(retval == 0, EINVAL); + } + + retval = 0; +EXIT: + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_print failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_print( + const ia_css_terminal_t *terminal, + void *fid) +{ + DECLARE_ERRVAL + int retval = -1; + ia_css_terminal_type_t term_type = ia_css_terminal_get_type(terminal); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_terminal_print(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "\tTerminal %p sizeof %d, typeof %d, parent %p\n", + terminal, + (int)ia_css_terminal_get_size(terminal), + (int)ia_css_terminal_get_type(terminal), + (void *)ia_css_terminal_get_parent(terminal)); + + switch (term_type) { + case IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT: + ia_css_program_control_init_terminal_print( + (ia_css_program_control_init_terminal_t *)terminal); + break; + case IA_CSS_TERMINAL_TYPE_DATA_IN: + case IA_CSS_TERMINAL_TYPE_DATA_OUT: + ia_css_data_terminal_print(terminal, fid); + break; + default: + /* other terminal prints are currently not supported */ + break; + } + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_print invalid argument terminal\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_print failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_input( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + bool is_input = false; + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_input(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + terminal_type = ia_css_terminal_get_type(terminal); + + switch (terminal_type) { + case IA_CSS_TERMINAL_TYPE_DATA_IN: /* Fall through */ + case IA_CSS_TERMINAL_TYPE_STATE_IN: /* Fall through */ + case IA_CSS_TERMINAL_TYPE_PARAM_STREAM: /* Fall through */ + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN: + case IA_CSS_TERMINAL_TYPE_PROGRAM: + case IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT: + is_input = true; + break; + case IA_CSS_TERMINAL_TYPE_DATA_OUT: /* Fall through */ + case IA_CSS_TERMINAL_TYPE_STATE_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + is_input = false; + break; + default: + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_input: Unknown terminal type (%d)\n", + terminal_type); + goto EXIT; + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_input invalid argument\n"); + } + return is_input; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +size_t ia_css_terminal_get_size( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_size(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + size = terminal->size; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_size invalid argument\n"); + } + return size; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_terminal_type_t ia_css_terminal_get_type( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_type(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + terminal_type = terminal->terminal_type; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_type invalid argument\n"); + } + return terminal_type; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_type( + ia_css_terminal_t *terminal, + const ia_css_terminal_type_t terminal_type) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_set_type(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + terminal->terminal_type = terminal_type; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_type invalid argument terminal\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_type failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint16_t ia_css_terminal_get_terminal_manifest_index( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + uint16_t terminal_manifest_index; + + terminal_manifest_index = 0xffff; + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_terminal_manifest_index(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + terminal_manifest_index = terminal->tm_index; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_terminal_manifest_index: invalid argument\n"); + } + return terminal_manifest_index; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_terminal_manifest_index( + ia_css_terminal_t *terminal, + const uint16_t terminal_manifest_index) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_set_terminal_manifest_index(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + terminal->tm_index = terminal_manifest_index; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_terminal_manifest_index: invalid argument terminal\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_terminal_manifest_index: failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_terminal_ID_t ia_css_terminal_get_ID( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_ID_t retval = IA_CSS_TERMINAL_INVALID_ID; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_ID(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + retval = terminal->ID; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_ID invalid argument\n"); + retval = 0; + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_data_terminal_get_kernel_id( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + uint8_t retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_kernel_id(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + retval = dterminal->kernel_id; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_kernel_id: invalid argument\n"); + retval = 0; + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_connection_type_t ia_css_data_terminal_get_connection_type( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + ia_css_connection_type_t connection_type = IA_CSS_N_CONNECTION_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_connection_type(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + connection_type = dterminal->connection_type; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_connection_type: invalid argument\n"); + } + return connection_type; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_data_terminal_get_link_id( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + uint8_t link_id = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_link_id(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + link_id = dterminal->link_id; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_link_id: invalid argument\n"); + } + return link_id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_data_terminal_set_link_id( + ia_css_data_terminal_t *dterminal, + const uint8_t link_id) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_set_link_id(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + dterminal->link_id = link_id; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_set_link_id: invalid argument terminal\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_set_link_id: failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_data_terminal_set_connection_type( + ia_css_data_terminal_t *dterminal, + const ia_css_connection_type_t connection_type) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_set_connection_type(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + dterminal->connection_type = connection_type; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_set_connection_type: invalid argument dterminal\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_set_connection_type failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_group_t *ia_css_terminal_get_parent( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_process_group_t *parent = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_parent(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + parent = (ia_css_process_group_t *) ((char *)terminal + + terminal->parent_offset); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_parent invalid argument\n"); + } + return parent; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_parent( + ia_css_terminal_t *terminal, + ia_css_process_group_t *parent) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_set_parent(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + verifexitval(parent != NULL, EFAULT); + + terminal->parent_offset = (uint16_t) ((char *)parent - + (char *)terminal); + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_parent invalid argument\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_parent failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_frame_t *ia_css_data_terminal_get_frame( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + ia_css_frame_t *frame = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_frame(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + frame = (ia_css_frame_t *)(&(dterminal->frame)); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_frame invalid argument\n"); + } + return frame; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_frame_descriptor_t *ia_css_data_terminal_get_frame_descriptor( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + ia_css_frame_descriptor_t *frame_descriptor = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_frame_descriptor(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + frame_descriptor = + (ia_css_frame_descriptor_t *)(&(dterminal->frame_descriptor)); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_frame_descriptor: invalid argument\n"); + } + return frame_descriptor; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_fragment_descriptor_t *ia_css_data_terminal_get_fragment_descriptor( + const ia_css_data_terminal_t *dterminal, + const unsigned int fragment_index) +{ + DECLARE_ERRVAL + ia_css_fragment_descriptor_t *fragment_descriptor = NULL; + uint16_t fragment_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_frame_descriptor(): enter:\n"); + + fragment_count = ia_css_data_terminal_get_fragment_count(dterminal); + + verifexitval(dterminal != NULL, EFAULT); + verifexitval(fragment_count != 0, EINVAL); + verifexitval(fragment_index < fragment_count, EINVAL); + + fragment_descriptor = (ia_css_fragment_descriptor_t *) + ((char *)dterminal + dterminal->fragment_descriptor_offset); + + fragment_descriptor += fragment_index; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_frame_descriptor: invalid argument\n"); + } + return fragment_descriptor; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint16_t ia_css_data_terminal_get_fragment_count( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + ia_css_process_group_t *parent; + uint16_t fragment_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_fragment_count(): enter:\n"); + + parent = ia_css_terminal_get_parent((ia_css_terminal_t *)dterminal); + + verifexitval(dterminal != NULL, EFAULT); + verifexitval(parent != NULL, EFAULT); + + fragment_count = ia_css_process_group_get_fragment_count(parent); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_fragment_count: invalid argument\n"); + } + return fragment_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_parameter_terminal( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_parameter_terminal(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + /* will return an error value on error */ + terminal_type = ia_css_terminal_get_type(terminal); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_parameter_terminal: invalid argument\n"); + } + return (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT); +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_data_terminal( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_data_terminal(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + /* will return an error value on error */ + terminal_type = ia_css_terminal_get_type(terminal); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_data_terminal invalid argument\n"); + } + return (terminal_type == IA_CSS_TERMINAL_TYPE_DATA_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_DATA_OUT); +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_program_terminal( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_program_terminal(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + /* will return an error value on error */ + terminal_type = ia_css_terminal_get_type(terminal); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_program_terminal: invalid argument\n"); + } + return (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM); +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_program_control_init_terminal( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_program_control_init_terminal(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + /* will return an error value on error */ + terminal_type = ia_css_terminal_get_type(terminal); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_program_control_init_terminal: invalid argument\n"); + } + return (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT); +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_spatial_parameter_terminal( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_spatial_parameter_terminal(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + /* will return an error value on error */ + terminal_type = ia_css_terminal_get_type(terminal); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_spatial_param_terminal: invalid argument\n"); + } + return (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT); +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_data_terminal_compute_plane_count( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + DECLARE_ERRVAL + uint8_t plane_count = 1; + + NOT_USED(manifest); + NOT_USED(param); + + verifexitval(manifest != NULL, EFAULT); + verifexitval(param != NULL, EFAULT); + /* TODO: Implementation Missing*/ + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_compute_plane_count(): enter:\n"); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_compute_plane_count: invalid argument\n"); + } + return plane_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_vaddress_t ia_css_terminal_get_buffer( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + vied_vaddress_t buffer = VIED_NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_buffer(): enter:\n"); + + if (ia_css_is_terminal_data_terminal(terminal)) { + ia_css_frame_t *frame = ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + + verifexitval(frame != NULL, EFAULT); + buffer = ia_css_frame_get_buffer(frame); + } else if (ia_css_is_terminal_parameter_terminal(terminal)) { + const ia_css_param_terminal_t *param_terminal = + (const ia_css_param_terminal_t *)terminal; + + buffer = param_terminal->param_payload.buffer; + } else if (ia_css_is_terminal_program_terminal(terminal)) { + const ia_css_program_terminal_t *program_terminal = + (const ia_css_program_terminal_t *)terminal; + + buffer = program_terminal->param_payload.buffer; + } else if (ia_css_is_terminal_program_control_init_terminal(terminal)) { + const ia_css_program_control_init_terminal_t *program_ctrl_init_terminal = + (const ia_css_program_control_init_terminal_t *)terminal; + + buffer = program_ctrl_init_terminal->param_payload.buffer; + } else if (ia_css_is_terminal_spatial_parameter_terminal(terminal)) { + const ia_css_spatial_param_terminal_t *spatial_terminal = + (const ia_css_spatial_param_terminal_t *)terminal; + + buffer = spatial_terminal->param_payload.buffer; + } +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_buffer: invalid argument terminal\n"); + } + return buffer; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_buffer( + ia_css_terminal_t *terminal, + vied_vaddress_t buffer) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_set_buffer(): enter:\n"); + + if (ia_css_is_terminal_data_terminal(terminal) == true) { + /* Currently using Frames inside data terminal , + * TODO: start directly using data. + */ + ia_css_data_terminal_t *dterminal = + (ia_css_data_terminal_t *)terminal; + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame(dterminal); + + verifexitval(frame != NULL, EFAULT); + retval = ia_css_frame_set_buffer(frame, buffer); + verifexitval(retval == 0, EINVAL); + } else if (ia_css_is_terminal_parameter_terminal(terminal) == true) { + ia_css_param_terminal_t *pterminal = + (ia_css_param_terminal_t *)terminal; + + pterminal->param_payload.buffer = buffer; + retval = 0; + } else if (ia_css_is_terminal_program_terminal(terminal) == true) { + ia_css_program_terminal_t *pterminal = + (ia_css_program_terminal_t *)terminal; + + pterminal->param_payload.buffer = buffer; + retval = 0; + } else if (ia_css_is_terminal_program_control_init_terminal(terminal) == true) { + ia_css_program_control_init_terminal_t *pterminal = + (ia_css_program_control_init_terminal_t *)terminal; + + pterminal->param_payload.buffer = buffer; + retval = 0; + } else if (ia_css_is_terminal_spatial_parameter_terminal(terminal) == + true) { + ia_css_spatial_param_terminal_t *pterminal = + (ia_css_spatial_param_terminal_t *)terminal; + + pterminal->param_payload.buffer = buffer; + retval = 0; + } else { + return retval; + } + + retval = 0; +EXIT: + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_buffer failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_get_terminal_index( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + int terminal_index = -1; + + verifexitval(terminal != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_terminal_index(): enter:\n"); + + if (ia_css_is_terminal_data_terminal(terminal)) { + ia_css_frame_t *frame = ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + + verifexitval(frame != NULL, EFAULT); + terminal_index = ia_css_frame_get_data_index(frame); + } else { + if (ia_css_is_terminal_parameter_terminal(terminal)) { + const ia_css_param_terminal_t *param_terminal = + (const ia_css_param_terminal_t *)terminal; + + terminal_index = param_terminal->param_payload.terminal_index; + } else if (ia_css_is_terminal_program_terminal(terminal)) { + const ia_css_program_terminal_t *program_terminal = + (const ia_css_program_terminal_t *)terminal; + + terminal_index = program_terminal->param_payload.terminal_index; + } else if (ia_css_is_terminal_program_control_init_terminal(terminal)) { + const ia_css_program_control_init_terminal_t *program_ctrl_init_terminal = + (const ia_css_program_control_init_terminal_t *)terminal; + + terminal_index = program_ctrl_init_terminal->param_payload.terminal_index; + } else if (ia_css_is_terminal_spatial_parameter_terminal(terminal)) { + const ia_css_spatial_param_terminal_t *spatial_terminal = + (const ia_css_spatial_param_terminal_t *)terminal; + + terminal_index = spatial_terminal->param_payload.terminal_index; + } else { + verifjmpexit(0); + } + } +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_terminal_index: invalid argument\n"); + } + return terminal_index; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_terminal_index( + ia_css_terminal_t *terminal, + unsigned int terminal_index) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_set_terminal_index(): enter:\n"); + + if (ia_css_is_terminal_data_terminal(terminal) == true) { + /* Currently using Frames inside data terminal , + * TODO: start directly using data. + */ + ia_css_data_terminal_t *dterminal = + (ia_css_data_terminal_t *)terminal; + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame(dterminal); + + verifexitval(frame != NULL, EFAULT); + retval = ia_css_frame_set_data_index(frame, terminal_index); + verifexitval(retval == 0, EINVAL); + } else { + if (ia_css_is_terminal_parameter_terminal(terminal) == true) { + ia_css_param_terminal_t *pterminal = + (ia_css_param_terminal_t *)terminal; + + pterminal->param_payload.terminal_index = terminal_index; + retval = 0; + } else if (ia_css_is_terminal_program_terminal(terminal) == true) { + ia_css_program_terminal_t *pterminal = + (ia_css_program_terminal_t *)terminal; + + pterminal->param_payload.terminal_index = terminal_index; + retval = 0; + } else if (ia_css_is_terminal_program_control_init_terminal(terminal) + == true) { + ia_css_program_control_init_terminal_t *pterminal = + (ia_css_program_control_init_terminal_t *)terminal; + + pterminal->param_payload.terminal_index = terminal_index; + retval = 0; + } else if (ia_css_is_terminal_spatial_parameter_terminal(terminal) == + true) { + ia_css_spatial_param_terminal_t *pterminal = + (ia_css_spatial_param_terminal_t *)terminal; + + pterminal->param_payload.terminal_index = terminal_index; + retval = 0; + } else { + return retval; + } + } + + retval = 0; +EXIT: + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_terminal_index failed (%i)\n", + retval); + } + return retval; +} + +STORAGE_CLASS_INLINE bool ia_css_is_data_terminal_valid( + const ia_css_terminal_t *terminal, + const ia_css_terminal_manifest_t *terminal_manifest, + const uint16_t nof_fragments) +{ + DECLARE_ERRVAL + bool invalid_flag = false; + + const ia_css_data_terminal_t *dterminal = + (ia_css_data_terminal_t *)terminal; + const ia_css_data_terminal_manifest_t *dt_manifest = + (ia_css_data_terminal_manifest_t *)terminal_manifest; + const ia_css_frame_descriptor_t *frame_descriptor; + ia_css_frame_format_bitmap_t man_frame_format_bitmap; + ia_css_frame_format_bitmap_t proc_frame_format_bitmap; + uint16_t max_value[IA_CSS_N_DATA_DIMENSION]; + uint16_t min_value[IA_CSS_N_DATA_DIMENSION]; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_data_terminal_valid enter\n"); + + frame_descriptor = + ia_css_data_terminal_get_frame_descriptor(dterminal); + verifexitval(frame_descriptor != NULL, EFAULT); + man_frame_format_bitmap = + ia_css_data_terminal_manifest_get_frame_format_bitmap( + dt_manifest); + proc_frame_format_bitmap = + ia_css_frame_format_bit_mask( + frame_descriptor->frame_format_type); + /* + * TODO: Replace by 'validation of frame format type'. + * Currently frame format type is not correctly set by manifest, + * waiting for HSD 1804260604 + */ + if (man_frame_format_bitmap > 0) { + if ((man_frame_format_bitmap & + proc_frame_format_bitmap) == 0) { + uint32_t *bitmap_arr = + (uint32_t *)&man_frame_format_bitmap; + + NOT_USED(bitmap_arr); + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Frame format type not defined in manifest\n"); + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + " man bitmap_arr[]: %d,%d\n", + bitmap_arr[1], bitmap_arr[0]); + bitmap_arr = (uint32_t *)&proc_frame_format_bitmap; + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + " proc bitmap_arr[]: %d,%d\n", + bitmap_arr[1], bitmap_arr[0]); + } + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Frame format bitmap not defined in manifest\n"); + } + ia_css_data_terminal_manifest_get_min_size(dt_manifest, min_value); + /* + * TODO: Replace by validation of Minimal frame column dimensions. + * Currently not correctly set by manifest yet, + * waiting for HSD 1804260604 + */ + if ((frame_descriptor->dimension[IA_CSS_COL_DIMENSION] < + min_value[IA_CSS_COL_DIMENSION])) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Minimal frame column dimensions not set correctly (by manifest)\n"); + } + /* + * TODO: Replace by validation of Minimal frame row dimensions. + * Currently not correctly set by manifest yet, + * waiting for HSD 1804260604 + */ + if (frame_descriptor->dimension[IA_CSS_ROW_DIMENSION] < + min_value[IA_CSS_ROW_DIMENSION]) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Minimal frame row dimensions not set correctly (by manifest)\n"); + } + + ia_css_data_terminal_manifest_get_max_size(dt_manifest, max_value); + /* + * TODO: Replace by validation of Maximal frame column dimensions. + * Currently not correctly set by manifest yet, + * waiting for HSD 1804260604 + */ + if (frame_descriptor->dimension[IA_CSS_COL_DIMENSION] > + max_value[IA_CSS_COL_DIMENSION]) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Maximal frame column dimensions not set correctly (by manifest)\n"); + } + /* + * TODO: Replace by validation of Maximal frame row dimensions. + * Currently not correctly set by manifest yet, + * waiting for HSD 1804260604 + */ + if (frame_descriptor->dimension[IA_CSS_ROW_DIMENSION] > + max_value[IA_CSS_ROW_DIMENSION]) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Maximal frame row dimensions not set correctly (by manifest)\n"); + } + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, VERBOSE, "min_value: [%d,%d]\n", + min_value[IA_CSS_COL_DIMENSION], + min_value[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, VERBOSE, "max_value: [%d,%d]\n", + max_value[IA_CSS_COL_DIMENSION], + max_value[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, VERBOSE, "frame dim: [%d,%d]\n", + frame_descriptor->dimension[IA_CSS_COL_DIMENSION], + frame_descriptor->dimension[IA_CSS_ROW_DIMENSION]); + /* + * TODO: Add validation of fragment dimensions. + * Currently not set by manifest yet, waiting for HSD 1804260604 + */ + NOT_USED(nof_fragments); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_data_terminal_valid() invalid argument\n"); + return false; + } else { + return (!invalid_flag); + } +} + +STORAGE_CLASS_INLINE void ia_css_program_terminal_seq_info_print( + const ia_css_kernel_fragment_sequencer_info_manifest_desc_t + *man_seq_info_desc, + const ia_css_kernel_fragment_sequencer_info_desc_t + *term_seq_info_desc) +{ + NOT_USED(man_seq_info_desc); + NOT_USED(term_seq_info_desc); + + /* slice dimension column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_slice_dimension: %d\n", + term_seq_info_desc-> + fragment_grid_slice_dimension[IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_slice_dimension: %d\n", + man_seq_info_desc-> + max_fragment_grid_slice_dimension[IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_slice_dimension: %d\n", + man_seq_info_desc-> + min_fragment_grid_slice_dimension[IA_CSS_COL_DIMENSION]); + + /* slice dimension row */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_slice_dimension: %d\n", + term_seq_info_desc-> + fragment_grid_slice_dimension[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_slice_dimension: %d\n", + man_seq_info_desc-> + max_fragment_grid_slice_dimension[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_slice_dimension: %d\n", + man_seq_info_desc-> + min_fragment_grid_slice_dimension[IA_CSS_ROW_DIMENSION]); + + /* slice count column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_slice_count: %d\n", + term_seq_info_desc-> + fragment_grid_slice_count[IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_slice_count: %d\n", + man_seq_info_desc-> + max_fragment_grid_slice_count[IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_slice_count: %d\n", + man_seq_info_desc-> + min_fragment_grid_slice_count[IA_CSS_COL_DIMENSION]); + + /* slice count row */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_slice_count: %d\n", + term_seq_info_desc-> + fragment_grid_slice_count[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_slice_count: %d\n", + man_seq_info_desc-> + max_fragment_grid_slice_count[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_slice_count: %d\n", + man_seq_info_desc-> + min_fragment_grid_slice_count[IA_CSS_ROW_DIMENSION]); + + /* decimation factor column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_point_decimation_factor: %d\n", + term_seq_info_desc-> + fragment_grid_point_decimation_factor[IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_point_decimation_factor: %d\n", + man_seq_info_desc-> + max_fragment_grid_point_decimation_factor[IA_CSS_COL_DIMENSION] + ); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_point_decimation_factor: %d\n", + man_seq_info_desc-> + min_fragment_grid_point_decimation_factor[IA_CSS_COL_DIMENSION] + ); + + /* decimation factor row */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_point_decimation_factor: %d\n", + term_seq_info_desc-> + fragment_grid_point_decimation_factor[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_point_decimation_factor: %d\n", + man_seq_info_desc-> + max_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_point_decimation_factor: %d\n", + man_seq_info_desc-> + min_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + + /* index column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_overlay_pixel_topleft_index: %d\n", + term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_overlay_pixel_topleft_index: %d\n", + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_overlay_pixel_topleft_index: %d\n", + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION]); + + /* index row */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_overlay_pixel_topleft_index: %d\n", + term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_overlay_pixel_topleft_index: %d\n", + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_overlay_pixel_topleft_index: %d\n", + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + + /* dimension column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_overlay_pixel_dimension: %d\n", + term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_overlay_pixel_dimension: %d\n", + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_overlay_pixel_dimension: %d\n", + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION]); + + /* dimension column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_overlay_pixel_dimension: %d\n", + term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_overlay_pixel_dimension: %d\n", + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_overlay_pixel_dimension: %d\n", + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); +} + +STORAGE_CLASS_INLINE bool ia_css_is_program_terminal_valid( + const ia_css_terminal_t *terminal, + const ia_css_terminal_manifest_t *terminal_manifest, + const uint16_t nof_fragments) +{ + DECLARE_ERRVAL + bool invalid_flag = false; + uint16_t frag_idx; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_program_terminal_valid enter\n"); + + for (frag_idx = 0; frag_idx < nof_fragments; frag_idx++) { + uint16_t frag_seq_info_count, seq_idx; + const ia_css_program_terminal_t *prog_term; + const ia_css_program_terminal_manifest_t *prog_term_man; + + prog_term = (const ia_css_program_terminal_t *)terminal; + prog_term_man = + (const ia_css_program_terminal_manifest_t *) + terminal_manifest; + frag_seq_info_count = + prog_term_man-> + kernel_fragment_sequencer_info_manifest_info_count; + + for (seq_idx = 0; seq_idx < frag_seq_info_count; seq_idx++) { + const ia_css_kernel_fragment_sequencer_info_desc_t + *term_seq_info_desc; + const + ia_css_kernel_fragment_sequencer_info_manifest_desc_t * + man_seq_info_desc; + + term_seq_info_desc = + ia_css_program_terminal_get_kernel_frgmnt_seq_info_desc( + prog_term, frag_idx, seq_idx, + frag_seq_info_count); + verifexitval(term_seq_info_desc != NULL, EFAULT); + man_seq_info_desc = + ia_css_program_terminal_manifest_get_kernel_frgmnt_seq_info_desc + (prog_term_man, seq_idx); + verifexitval(man_seq_info_desc != NULL, EFAULT); + + ia_css_program_terminal_seq_info_print( + man_seq_info_desc, term_seq_info_desc); + /* slice dimension column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION]); + + /* slice dimension row */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION]); + + /* slice count column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION]); + + /* slice count row */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION]); + + /* decimation factor column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION]); + + /* decimation factor row */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + + /* index column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION]); + + /* index row */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + + /* dimension column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION]); + + /* dimension column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + } + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_program_terminal_valid() invalid argument\n"); + return false; + } + if (invalid_flag == true) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_is_program_terminal_valid(): validation failed\n"); + /* TODO: program terminal parameters not correctly defined, + * disable validation result until issues has been solved + */ + return true; + } + return (!invalid_flag); +} + +STORAGE_CLASS_INLINE bool ia_css_is_sliced_terminal_valid( + const ia_css_terminal_t *terminal, + const ia_css_terminal_manifest_t *terminal_manifest, + const uint16_t nof_fragments) +{ + DECLARE_ERRVAL + bool invalid_flag = false; + uint16_t frag_idx; + + uint16_t slice_idx, section_idx; + + const ia_css_sliced_param_terminal_t *sliced_term = + (const ia_css_sliced_param_terminal_t *)terminal; + const ia_css_sliced_param_terminal_manifest_t *sliced_term_man = + (const ia_css_sliced_param_terminal_manifest_t *) + terminal_manifest; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_sliced_terminal_valid enter\n"); + + for (frag_idx = 0; frag_idx < nof_fragments; frag_idx++) { + const ia_css_fragment_slice_desc_t *fragment_slice_desc = + ia_css_sliced_param_terminal_get_fragment_slice_desc( + sliced_term, frag_idx); + + verifexitval(fragment_slice_desc != NULL, EFAULT); + + for (slice_idx = 0; + slice_idx < fragment_slice_desc->slice_count; + slice_idx++) { + for (section_idx = 0; + section_idx < + sliced_term_man->sliced_param_section_count; + section_idx++) { + const + ia_css_sliced_param_manifest_section_desc_t * + slice_man_section_desc; + const ia_css_slice_param_section_desc_t * + slice_section_desc; + + slice_man_section_desc = + ia_css_sliced_param_terminal_manifest_get_sliced_prm_sct_desc( + sliced_term_man, section_idx); + slice_section_desc = + ia_css_sliced_param_terminal_get_slice_param_section_desc( + sliced_term, frag_idx, + slice_idx, section_idx, + sliced_term_man-> + sliced_param_section_count); + verifexitval(slice_man_section_desc != NULL, EFAULT); + verifexitval(slice_section_desc != NULL, EFAULT); + + invalid_flag = invalid_flag || + (slice_section_desc->mem_size > + slice_man_section_desc->max_mem_size); + } + } + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_sliced_terminal_valid() invalid argument\n"); + return false; + } else { + return (!invalid_flag); + } + +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_valid( + const ia_css_terminal_t *terminal, + const ia_css_terminal_manifest_t *terminal_manifest) +{ + DECLARE_ERRVAL + bool is_valid = false; + uint16_t nof_fragments; + ia_css_terminal_type_t terminal_type = IA_CSS_TERMINAL_INVALID_ID; + + verifexitval(NULL != terminal, EFAULT); + verifexitval(NULL != terminal_manifest, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_valid enter\n"); + + nof_fragments = ia_css_data_terminal_get_fragment_count( + (const ia_css_data_terminal_t *)terminal); + terminal_type = ia_css_terminal_get_type(terminal); + + switch (terminal_type) { + case IA_CSS_TERMINAL_TYPE_DATA_IN: + case IA_CSS_TERMINAL_TYPE_DATA_OUT: + is_valid = ia_css_is_data_terminal_valid(terminal, + terminal_manifest, nof_fragments); + break; + case IA_CSS_TERMINAL_TYPE_PROGRAM: + is_valid = ia_css_is_program_terminal_valid(terminal, + terminal_manifest, nof_fragments); + break; + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + case IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT: + /* Nothing to be validated for cached and spatial + * parameters, return valid + */ + is_valid = true; + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT: + is_valid = ia_css_is_sliced_terminal_valid(terminal, + terminal_manifest, nof_fragments); + break; + default: + /* Terminal type unknown, return invalid */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, WARNING, + "ia_css_is_terminal_valid() Terminal type %x unknown\n", + (int)terminal_type); + is_valid = false; + break; + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_valid() invalid argument\n"); + return false; + } + /* TODO: to be removed once all PGs pass validation */ + if (is_valid == false) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_is_terminal_valid(): type: %d validation failed\n", + terminal_type); + } + return is_valid; +} + +/* ================= Program Control Init Terminal - START ================= */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int +ia_css_program_control_init_terminal_init( + ia_css_program_control_init_terminal_t *terminal, + const ia_css_program_control_init_terminal_manifest_t *manifest) +{ + int retval = -1; + unsigned int i; + unsigned int base_load_sec; + unsigned int base_connect_sec; + unsigned int load_index = 0; + unsigned int connect_index = 0; + unsigned int load_section_count = 0; + unsigned int connect_section_count = 0; + + ia_css_program_control_init_manifest_program_desc_t *man_progs; + + verifjmpexit(terminal != NULL); + + man_progs = + ia_css_program_control_init_terminal_manifest_get_program_desc(manifest, 0); + verifjmpexit(man_progs != NULL); + + for (i = 0; i < manifest->program_count; i++) { + load_section_count += man_progs[i].load_section_count; + connect_section_count += man_progs[i].connect_section_count; + } + + terminal->program_count = manifest->program_count; + terminal->program_section_desc_offset = + sizeof(ia_css_program_control_init_terminal_t); + + base_load_sec = /* base_load_sec relative to first program */ + terminal->program_count * + sizeof(ia_css_program_control_init_program_desc_t); + + base_connect_sec = base_load_sec + + load_section_count * + sizeof(ia_css_program_control_init_load_section_desc_t); + + for (i = 0; i < terminal->program_count; i++) { + ia_css_program_control_init_program_desc_t *prog; + + prog = ia_css_program_control_init_terminal_get_program_desc( + terminal, i); + verifjmpexit(prog != NULL); + + prog->load_section_count = man_progs[i].load_section_count; + prog->connect_section_count = man_progs[i].connect_section_count; + + prog->load_section_desc_offset = + base_load_sec + + load_index * + sizeof(ia_css_program_control_init_load_section_desc_t) - + i * sizeof(ia_css_program_control_init_program_desc_t); + prog->connect_section_desc_offset = + base_connect_sec + + connect_index * + sizeof(ia_css_program_control_init_connect_section_desc_t) - + i * sizeof(ia_css_program_control_init_program_desc_t); + + load_index += man_progs[i].load_section_count; + connect_index += man_progs[i].connect_section_count; + } + retval = 0; +EXIT: + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +unsigned int +ia_css_program_control_init_terminal_get_descriptor_size( + const ia_css_program_control_init_terminal_manifest_t *manifest) +{ + unsigned int i; + unsigned int size = 0; + unsigned int load_section_count = 0; + unsigned int connect_section_count = 0; + ia_css_program_control_init_manifest_program_desc_t *man_progs; + + verifjmpexit(manifest != NULL); + + man_progs = + ia_css_program_control_init_terminal_manifest_get_program_desc( + manifest, 0); + verifjmpexit(man_progs != NULL); + + for (i = 0; i < manifest->program_count; i++) { + load_section_count += man_progs[i].load_section_count; + connect_section_count += man_progs[i].connect_section_count; + } + + size = sizeof(ia_css_program_control_init_terminal_t) + + manifest->program_count * + sizeof(struct ia_css_program_control_init_program_desc_s) + + load_section_count * + sizeof(struct ia_css_program_control_init_load_section_desc_s) + + connect_section_count * + sizeof(struct ia_css_program_control_init_connect_section_desc_s); +EXIT: + return size; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +void ia_css_program_control_init_terminal_print( + const ia_css_program_control_init_terminal_t *terminal) +{ + unsigned int prog_idx, sec_idx; + ia_css_program_control_init_program_desc_t *prog; + ia_css_program_control_init_load_section_desc_t *load_sec; + ia_css_program_control_init_connect_section_desc_t *connect_sec; + + verifjmpexit(terminal != NULL); + + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "program_count: %d, payload_fragment_stride: %d\n", + terminal->program_count, + terminal->payload_fragment_stride); + + for (prog_idx = 0; prog_idx < terminal->program_count; prog_idx++) { + prog = ia_css_program_control_init_terminal_get_program_desc( + terminal, prog_idx); + verifjmpexit(prog != NULL); + + for (sec_idx = 0; sec_idx < prog->load_section_count; sec_idx++) { + load_sec = + ia_css_program_control_init_terminal_get_load_section_desc( + prog, sec_idx); + verifjmpexit(load_sec != NULL); + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "load_section>> device_descriptor_id: 0x%x, mem_offset: %d, mem_size: %d, mode_bitmask: %x\n", + load_sec->device_descriptor_id.data, + load_sec->mem_offset, + load_sec->mem_size, + load_sec->mode_bitmask); + } + for (sec_idx = 0; sec_idx < prog->connect_section_count; sec_idx++) { + connect_sec = + ia_css_program_control_init_terminal_get_connect_section_desc( + prog, sec_idx); + verifjmpexit(connect_sec != NULL); + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "connect_section>> device_descriptor_id: 0x%x, connect_terminal_ID: %d, connect_section_idx: %d, mode_bitmask: %x\n", + connect_sec->device_descriptor_id.data, + connect_sec->connect_terminal_ID, + connect_sec->connect_section_idx, + connect_sec->mode_bitmask); + } + } +EXIT: + return; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_program_control_init_program_desc_t * +ia_css_program_control_init_terminal_get_program_desc( + const ia_css_program_control_init_terminal_t *prog_ctrl_init_terminal, + const unsigned int program_index) +{ + ia_css_program_control_init_program_desc_t *program_desc_base; + ia_css_program_control_init_program_desc_t *program_desc = NULL; + + verifjmpexit(prog_ctrl_init_terminal != NULL); + verifjmpexit(program_index < prog_ctrl_init_terminal->program_count); + + program_desc_base = (ia_css_program_control_init_program_desc_t *) + (((const char *)prog_ctrl_init_terminal) + + prog_ctrl_init_terminal->program_section_desc_offset); + program_desc = &(program_desc_base[program_index]); + +EXIT: + return program_desc; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_id_t ia_css_program_control_init_terminal_get_process_id( + const ia_css_program_control_init_program_desc_t *program_desc) +{ + ia_css_process_id_t process_id = 0; + + verifjmpexit(program_desc != NULL); + + process_id = program_desc->control_info.process_id; + +EXIT: + return process_id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_program_control_init_terminal_get_num_done_events( + const ia_css_program_control_init_program_desc_t *program_desc) +{ + uint8_t num_done_events = 0; + + verifjmpexit(program_desc != NULL); + + num_done_events = program_desc->control_info.num_done_events; + +EXIT: + return num_done_events; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +void ia_css_program_control_init_terminal_set_control_info( + ia_css_program_control_init_program_desc_t *program_desc, + ia_css_process_id_t process_id, + uint8_t num_done_events) +{ + verifjmpexit(program_desc != NULL); + + program_desc->control_info.process_id = process_id; + program_desc->control_info.num_done_events = num_done_events; + +EXIT: + return; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_program_control_init_load_section_desc_t * +ia_css_program_control_init_terminal_get_load_section_desc( + const ia_css_program_control_init_program_desc_t *program_desc, + const unsigned int load_section_index) +{ + ia_css_program_control_init_load_section_desc_t *load_section_desc_base; + ia_css_program_control_init_load_section_desc_t *load_section_desc = NULL; + + verifjmpexit(program_desc != NULL); + verifjmpexit(load_section_index < program_desc->load_section_count); + + load_section_desc_base = (ia_css_program_control_init_load_section_desc_t *) + (((const char *)program_desc) + + program_desc->load_section_desc_offset); + load_section_desc = &(load_section_desc_base[load_section_index]); + +EXIT: + return load_section_desc; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_program_control_init_connect_section_desc_t * +ia_css_program_control_init_terminal_get_connect_section_desc( + const ia_css_program_control_init_program_desc_t *program_desc, + const unsigned int connect_section_index) +{ + ia_css_program_control_init_connect_section_desc_t *connect_sec_desc_base; + ia_css_program_control_init_connect_section_desc_t *connect_sec_desc = NULL; + + verifjmpexit(program_desc != NULL); + verifjmpexit(connect_section_index < program_desc->connect_section_count); + + connect_sec_desc_base = + (ia_css_program_control_init_connect_section_desc_t *) + (((const char *)program_desc) + + program_desc->connect_section_desc_offset); + connect_sec_desc = &(connect_sec_desc_base[connect_section_index]); + +EXIT: + return connect_sec_desc; +} + +/* ================= Program Control Init Terminal - END ================= */ + +#endif /* __IA_CSS_PSYS_TERMINAL_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_private_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_private_types.h new file mode 100644 index 0000000000000..a815fdfb8eaf5 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_private_types.h @@ -0,0 +1,186 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_PRIVATE_TYPES_H +#define __IA_CSS_PSYS_TERMINAL_PRIVATE_TYPES_H + +#include "ia_css_terminal_types.h" +#include "ia_css_program_group_data.h" +#include "ia_css_psys_manifest_types.h" + +#define N_UINT16_IN_DATA_TERMINAL_STRUCT 1 +#define N_UINT8_IN_DATA_TERMINAL_STRUCT 3 +#define N_PADDING_UINT8_IN_DATA_TERMINAL_STRUCT 3 + +/* ========================= Data terminal - START ========================= */ + +#define SIZE_OF_DATA_TERMINAL_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_FRAME_DESCRIPTOR_STRUCT_BITS \ + + IA_CSS_FRAME_STRUCT_BITS \ + + IA_CSS_STREAM_STRUCT_BITS \ + + IA_CSS_UINT32_T_BITS \ + + IA_CSS_CONNECTION_TYPE_BITS \ + + (N_UINT16_IN_DATA_TERMINAL_STRUCT * 16) \ + + (N_UINT8_IN_DATA_TERMINAL_STRUCT * 8) \ + + (N_PADDING_UINT8_IN_DATA_TERMINAL_STRUCT * 8)) + +/* + * The (data) terminal can be attached to a buffer or a stream. + * The stream interface is not necessarily limited to strict in-order access. + * For a stream the restriction is that contrary to a buffer it cannot be + * addressed directly, i.e. it behaves as a port, + * but it may support stream_pos() and/or seek() operations + */ +struct ia_css_data_terminal_s { + /**< Data terminal base */ + ia_css_terminal_t base; + /**< Properties of the data attached to the terminal */ + ia_css_frame_descriptor_t frame_descriptor; + /**< Data buffer handle attached to the terminal */ + ia_css_frame_t frame; + /**< (exclusive) Data stream handle attached to the terminal + * if the data is sourced over a device port + */ + ia_css_stream_t stream; + /**< Reserved */ + uint32_t reserved; + /**< Connection {buffer, stream, ...} */ + ia_css_connection_type_t connection_type; + /**< Array[fragment_count] (fragment_count being equal for all + * terminals in a subgraph) of fragment descriptors + */ + uint16_t fragment_descriptor_offset; + /**< Kernel id where this terminal is connected to */ + uint8_t kernel_id; + /**< Indicate to which subgraph this terminal belongs + * for common constraints + */ + uint8_t subgraph_id; + /* Link ID of the data terminal */ + uint8_t link_id; + /**< Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_DATA_TERMINAL_STRUCT]; +}; +/* ========================== Data terminal - END ========================== */ + +/* ================= Program Control Init Terminal - START ================= */ +#define SIZE_OF_PROG_CONTROL_INIT_LOAD_SECTION_DESC_STRUCT_BITS \ + (DEVICE_DESCRIPTOR_ID_BITS \ + + (3 * IA_CSS_UINT32_T_BITS) \ + ) +struct ia_css_program_control_init_load_section_desc_s { + /* Offset of the parameter allocation in memory */ + uint32_t mem_offset; + /* Memory allocation size needs of this parameter */ + uint32_t mem_size; + /* Device descriptor */ + device_descriptor_id_t device_descriptor_id; /* 32 bits */ + /* (Applicable to) mode bitmask */ + uint32_t mode_bitmask; +}; + +#define MODE_BITMASK_MEMORY (1u << IA_CSS_CONNECTION_MEMORY) +#define MODE_BITMASK_MEMORY_STREAM (1u << IA_CSS_CONNECTION_MEMORY_STREAM) +#define MODE_BITMASK_STREAM (1u << IA_CSS_CONNECTION_STREAM) +#define MODE_BITMASK_DONT_CARE (MODE_BITMASK_MEMORY | MODE_BITMASK_MEMORY_STREAM | MODE_BITMASK_STREAM) + +#define N_PADDING_UINT8_IN_PROG_CTRL_INIT_CONNECT_SECT_STRUCT (5) +#define SIZE_OF_PROG_CONTROL_INIT_CONNECT_SECTION_DESC_STRUCT_BITS \ + (DEVICE_DESCRIPTOR_ID_BITS \ + + (1 * IA_CSS_UINT32_T_BITS) \ + + (1 * IA_CSS_UINT16_T_BITS) \ + + IA_CSS_TERMINAL_ID_BITS \ + + (N_PADDING_UINT8_IN_PROG_CTRL_INIT_CONNECT_SECT_STRUCT * \ + IA_CSS_UINT8_T_BITS) \ + ) +struct ia_css_program_control_init_connect_section_desc_s { + /* Device descriptor */ + device_descriptor_id_t device_descriptor_id; /* 32 bits */ + /* (Applicable to) mode bitmask */ + uint32_t mode_bitmask; + /* Connected terminal section (plane) index */ + uint16_t connect_section_idx; + /* Absolute referral ID for the connected terminal */ + ia_css_terminal_ID_t connect_terminal_ID; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PROG_CTRL_INIT_CONNECT_SECT_STRUCT]; +}; + +#define N_PADDING_UINT8_IN_PROG_DESC_CONTROL_INFO (1) +#define N_PADDING_UINT8_IN_PROG_CTRL_INIT_PROGRAM_DESC_STRUCT (4) +#define SIZE_OF_PROGRAM_DESC_CONTROL_INFO_STRUCT_BITS \ + ((1 * IA_CSS_UINT16_T_BITS) \ + + (1 * IA_CSS_UINT8_T_BITS) \ + + (N_PADDING_UINT8_IN_PROG_DESC_CONTROL_INFO * IA_CSS_UINT8_T_BITS)) + +#define SIZE_OF_PROG_CONTROL_INIT_PROG_DESC_STRUCT_BITS \ + ((4 * IA_CSS_UINT16_T_BITS) \ + + (SIZE_OF_PROGRAM_DESC_CONTROL_INFO_STRUCT_BITS) \ + + (N_PADDING_UINT8_IN_PROG_CTRL_INIT_PROGRAM_DESC_STRUCT * \ + IA_CSS_UINT8_T_BITS)) + +struct ia_css_program_desc_control_info_s { + /* 12-bit process identifier */ + ia_css_process_id_t process_id; + /* number of done acks required to close the process */ + uint8_t num_done_events; + uint8_t padding[N_PADDING_UINT8_IN_PROG_DESC_CONTROL_INFO]; +}; + +struct ia_css_program_control_init_program_desc_s { + /* Number of load sections in this program */ + uint16_t load_section_count; + /* Points to variable size array of + * ia_css_program_control_init_load_section_desc_s + * in relation to its program_desc + */ + uint16_t load_section_desc_offset; + /* Number of connect sections in this program */ + uint16_t connect_section_count; + /* Points to variable size array of + * ia_css_program_control_init_connect_section_desc_s + * in relation to its program_desc + */ + uint16_t connect_section_desc_offset; + struct ia_css_program_desc_control_info_s control_info; + /* align to 64 bits */ + uint8_t padding[N_PADDING_UINT8_IN_PROG_CTRL_INIT_PROGRAM_DESC_STRUCT]; +}; + +#define SIZE_OF_PROG_CONTROL_INIT_TERM_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + + (1 * IA_CSS_UINT32_T_BITS) \ + + (2 * IA_CSS_UINT16_T_BITS) \ + ) +struct ia_css_program_control_init_terminal_s { + /* Parameter terminal base */ + ia_css_terminal_t base; + /* Parameter buffer handle attached to the terminal */ + ia_css_param_payload_t param_payload; + /* Fragment stride for the payload, used to find the base + * of the payload for a given fragment + */ + uint32_t payload_fragment_stride; + /* Points to the variable array of + * ia_css_program_control_init_program_desc_s + */ + uint16_t program_section_desc_offset; + /* Number of instantiated programs in program group (processes) */ + uint16_t program_count; +}; +/* ================= Program Control Init Terminal - END ================= */ + +#endif /* __IA_CSS_PSYS_TERMINAL_PRIVATE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi.h new file mode 100644 index 0000000000000..4c8fd33b331ca --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi.h @@ -0,0 +1,23 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYSAPI_H +#define __IA_CSS_PSYSAPI_H + +#include +#include +#include +#include + +#endif /* __IA_CSS_PSYSAPI_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_fw_version.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_fw_version.h new file mode 100644 index 0000000000000..5658a2988a08d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_fw_version.h @@ -0,0 +1,33 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_PSYSAPI_FW_VERSION_H +#define __IA_CSS_PSYSAPI_FW_VERSION_H + +/* PSYSAPI FW VERSION is taken from Makefile for FW tests */ +#define BXT_FW_RELEASE_VERSION PSYS_FIRMWARE_VERSION + +enum ia_css_process_group_protocol_version { + /* + * Legacy protocol + */ + IA_CSS_PROCESS_GROUP_PROTOCOL_LEGACY = 0, + /* + * Persistent process group support protocol + */ + IA_CSS_PROCESS_GROUP_PROTOCOL_PPG, + IA_CSS_PROCESS_GROUP_N_PROTOCOLS +}; + +#endif /* __IA_CSS_PSYSAPI_FW_VERSION_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_trace.h new file mode 100644 index 0000000000000..e35ec24c77b36 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_trace.h @@ -0,0 +1,78 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYSAPI_TRACE_H +#define __IA_CSS_PSYSAPI_TRACE_H + +#include "ia_css_trace.h" + +#define PSYSAPI_TRACE_LOG_LEVEL_OFF 0 +#define PSYSAPI_TRACE_LOG_LEVEL_NORMAL 1 +#define PSYSAPI_TRACE_LOG_LEVEL_DEBUG 2 + +/* PSYSAPI and all the submodules in PSYSAPI will have the default tracing + * level set to the PSYSAPI_TRACE_CONFIG level. If not defined in the + * psysapi.mk fill it will be set by default to no trace + * (PSYSAPI_TRACE_LOG_LEVEL_OFF) + */ +#define PSYSAPI_TRACE_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +#if !defined(PSYSAPI_TRACE_CONFIG) + #define PSYSAPI_TRACE_CONFIG PSYSAPI_TRACE_CONFIG_DEFAULT +#endif + +/* Module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_TRACE_CONFIG)) + /* Module specific trace setting */ + #if PSYSAPI_TRACE_CONFIG == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_TRACE_CONFIG == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_TRACE_CONFIG == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_TRACE_CONFIG Tracing level defined" + #endif +#else + #error "PSYSAPI_TRACE_CONFIG not defined" +#endif + +/* Overriding submodules in PSYSAPI with a specific tracing level */ +/* #define PSYSAPI_DYNAMIC_TRACING_OVERRIDE TRACE_LOG_LEVEL_VERBOSE */ + +#endif /* __IA_CSS_PSYSAPI_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_kernel_bitmap.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_kernel_bitmap.h new file mode 100644 index 0000000000000..3fec775eb019d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_kernel_bitmap.h @@ -0,0 +1,223 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_KERNEL_BITMAP_H +#define __IA_CSS_KERNEL_BITMAP_H + +/*! \file */ + +/** @file ia_css_kernel_bitmap.h + * + * The types and operations to make logic decisions given kernel bitmaps + * "ia_css_kernel_bitmap_t" can be larger than native types + */ + +#include +#include "vied_nci_psys_resource_model.h" + +#define IA_CSS_KERNEL_BITMAP_BITS 64 +#define IA_CSS_KERNEL_BITMAP_ELEM_TYPE uint32_t +#define IA_CSS_KERNEL_BITMAP_ELEM_BITS \ + (sizeof(IA_CSS_KERNEL_BITMAP_ELEM_TYPE)*8) +#define IA_CSS_KERNEL_BITMAP_NOF_ELEMS \ + ((IA_CSS_KERNEL_BITMAP_BITS) / (IA_CSS_KERNEL_BITMAP_ELEM_BITS)) + +/** An element is a 32 bit unsigned integer. 64 bit integers might cause + * problems in the compiler. + */ +typedef struct { + IA_CSS_KERNEL_BITMAP_ELEM_TYPE data[IA_CSS_KERNEL_BITMAP_NOF_ELEMS]; +} ia_css_kernel_bitmap_elems_t; + +/** Users should make no assumption about the actual type of + * ia_css_kernel_bitmap_t. + * Users should use IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS in + * case they erroneously assume that this type is uint64_t and they + * cannot change their implementation. + */ +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS +typedef ia_css_kernel_bitmap_elems_t ia_css_kernel_bitmap_t; +#else +typedef uint64_t ia_css_kernel_bitmap_t; +#if IA_CSS_KERNEL_BITMAP_BITS > 64 +#error IA_CSS_KERNEL_BITMAP_BITS > 64 not supported \ + with IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS +#endif +#endif + +/*! Print the bits of a kernel bitmap + + @return < 0 on error + */ +extern int ia_css_kernel_bitmap_print( + const ia_css_kernel_bitmap_t bitmap, + void *fid); + +/*! Create an empty kernel bitmap + + @return bitmap = 0 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_clear(void); + +/*! Creates the complement of a kernel bitmap + * @param bitmap[in] kernel bitmap + * @return ~bitmap + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_complement( + const ia_css_kernel_bitmap_t bitmap); + +/*! Create the union of two kernel bitmaps + + @param bitmap0[in] kernel bitmap 0 + @param bitmap1[in] kernel bitmap 1 + + @return bitmap0 | bitmap1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_union( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1); + +/*! Create the intersection of two kernel bitmaps + + @param bitmap0[in] kernel bitmap 0 + @param bitmap1[in] kernel bitmap 1 + + @return bitmap0 & bitmap1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_intersection( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1); + +/*! Check if the kernel bitmaps is empty + + @param bitmap[in] kernel bitmap + + @return bitmap == 0 + */ +extern bool ia_css_is_kernel_bitmap_empty( + const ia_css_kernel_bitmap_t bitmap); + +/*! Check if the intersection of two kernel bitmaps is empty + + @param bitmap0[in] kernel bitmap 0 + @param bitmap1[in] kernel bitmap 1 + + @return (bitmap0 & bitmap1) == 0 + */ +extern bool ia_css_is_kernel_bitmap_intersection_empty( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1); + +/*! Check if the second kernel bitmap is a subset of the first (or equal) + + @param bitmap0[in] kernel bitmap 0 + @param bitmap1[in] kernel bitmap 1 + + Note: An empty set is always a subset, this function + returns true if bitmap 1 is empty + + @return (bitmap0 & bitmap1) == bitmap1 + */ +extern bool ia_css_is_kernel_bitmap_subset( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1); + +/*! Check if the kernel bitmaps are equal + + @param bitmap0[in] kernel bitmap 0 + @param bitmap1[in] kernel bitmap 1 + + @return bitmap0 == bitmap1 + */ +extern bool ia_css_is_kernel_bitmap_equal( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1); + +/*! Right shift kernel bitmap + + @param bitmap0[in] kernel bitmap 0 + + @return bitmap0 >> 1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_shift( + const ia_css_kernel_bitmap_t bitmap); + +/*! Check if the kernel bitmaps contains only a single element + + @param bitmap[in] kernel bitmap + + @return weight(bitmap) == 1 + */ +extern bool ia_css_is_kernel_bitmap_onehot( + const ia_css_kernel_bitmap_t bitmap); + +/*! Checks whether a specific kernel bit is set + * @return bitmap[index] == 1 + */ +extern int ia_css_is_kernel_bitmap_set( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index); + +/*! Create the union of a kernel bitmap with a onehot bitmap + * with a bit set at index + + @return bitmap[index] |= 1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_set( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index); + +/*! Creates kernel bitmap using a uint64 value. + * @return bitmap with the same bits set as in value (provided that width of bitmap is sufficient). + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_create_from_uint64( + const uint64_t value); + +/*! Converts an ia_css_kernel_bitmap_t type to uint64_t. Note that if + * ia_css_kernel_bitmap_t contains more then 64 bits, only the lowest 64 bits + * are returned. + * @return uint64_t representation of value +*/ +extern uint64_t ia_css_kernel_bitmap_to_uint64( + const ia_css_kernel_bitmap_t value); + +/*! Creates a kernel bitmap with the bit at index 'index' removed. + * @return ~(1 << index) & bitmap + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_unset( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index); + +/*! Set a previously clear field of a kernel bitmap at index + + @return if bitmap[index] == 0, bitmap[index] -> 1, else 0 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_set_unique( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index); + +/*! Create a onehot kernel bitmap with a bit set at index + + @return bitmap[index] = 1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bit_mask( + const unsigned int index); + +/*! Create a random bitmap + + @return bitmap[index] = 1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_ran_bitmap(void); + +#endif /* __IA_CSS_KERNEL_BITMAP_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_psys_kernel_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_psys_kernel_trace.h new file mode 100644 index 0000000000000..1ba29c7ab77ec --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_psys_kernel_trace.h @@ -0,0 +1,103 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_KERNEL_TRACE_H +#define __IA_CSS_PSYS_KERNEL_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_KERNEL_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_KERNEL_TRACING_OVERRIDE)) + #define PSYS_KERNEL_TRACE_LEVEL_CONFIG \ + PSYS_KERNEL_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_KERNEL_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_KERNEL_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_KERNEL_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_KERNEL_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_KERNEL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_KERNEL_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_KERNEL_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_KERNEL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_KERNEL_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_KERNEL_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_KERNEL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_KERNEL_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_KERNEL_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_KERNEL_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_KERNEL_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_KERNEL_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_KERNEL_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_KERNEL_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_KERNEL_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/kernel/src/ia_css_kernel_bitmap.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/kernel/src/ia_css_kernel_bitmap.c new file mode 100644 index 0000000000000..7e99217e301e4 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/kernel/src/ia_css_kernel_bitmap.c @@ -0,0 +1,418 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include +#include +#include +#include +#include "ia_css_psys_kernel_trace.h" + +static int ia_css_kernel_bitmap_compute_weight( + const ia_css_kernel_bitmap_t bitmap); + +bool ia_css_is_kernel_bitmap_intersection_empty( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1) +{ + ia_css_kernel_bitmap_t intersection; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_intersection_empty(): enter:\n"); + + intersection = ia_css_kernel_bitmap_intersection(bitmap0, bitmap1); + return ia_css_is_kernel_bitmap_empty(intersection); +} + +bool ia_css_is_kernel_bitmap_empty( + const ia_css_kernel_bitmap_t bitmap) +{ + unsigned int i; + bool is_empty = true; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_empty(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + is_empty &= bitmap.data[i] == 0; + } +#else + NOT_USED(i); + is_empty = (bitmap == 0); +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return is_empty; +} + +bool ia_css_is_kernel_bitmap_equal( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1) +{ + unsigned int i; + bool is_equal = true; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_equal(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + is_equal = is_equal && (bitmap0.data[i] == bitmap1.data[i]); + } +#else + NOT_USED(i); + is_equal = (bitmap0 == bitmap1); +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return is_equal; +} + +bool ia_css_is_kernel_bitmap_onehot( + const ia_css_kernel_bitmap_t bitmap) +{ + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_onehot(): enter:\n"); + return ia_css_kernel_bitmap_compute_weight(bitmap) == 1; +} + +bool ia_css_is_kernel_bitmap_subset( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1) +{ + ia_css_kernel_bitmap_t intersection; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_subset(): enter:\n"); + + intersection = ia_css_kernel_bitmap_intersection(bitmap0, bitmap1); + return ia_css_is_kernel_bitmap_equal(intersection, bitmap1); +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_clear(void) +{ + unsigned int i; + ia_css_kernel_bitmap_t bitmap; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_clear(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + bitmap.data[i] = 0; + } +#else + NOT_USED(i); + bitmap = 0; +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return bitmap; +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_complement( + const ia_css_kernel_bitmap_t bitmap) +{ + unsigned int i; + ia_css_kernel_bitmap_t result; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_complement(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + result.data[i] = ~bitmap.data[i]; + } +#else + NOT_USED(i); + result = ~bitmap; +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return result; +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_union( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1) +{ + unsigned int i; + ia_css_kernel_bitmap_t result; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_union(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + result.data[i] = (bitmap0.data[i] | bitmap1.data[i]); + } +#else + NOT_USED(i); + result = (bitmap0 | bitmap1); +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return result; +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_intersection( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1) +{ + unsigned int i; + ia_css_kernel_bitmap_t result; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_intersection(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + result.data[i] = (bitmap0.data[i] & bitmap1.data[i]); + } +#else + NOT_USED(i); + result = (bitmap0 & bitmap1); +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return result; +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_set( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index) +{ + ia_css_kernel_bitmap_t bit_mask; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_set(): enter:\n"); + + bit_mask = ia_css_kernel_bit_mask(index); + return ia_css_kernel_bitmap_union(bitmap, bit_mask); +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_create_from_uint64( + const uint64_t value) +{ + unsigned int i; + ia_css_kernel_bitmap_t result; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_create_from_uint64(): enter:\n"); + +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + result = ia_css_kernel_bitmap_clear(); + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + /* masking is done implictly, the MSB bits of casting will be chopped off */ + result.data[i] = (IA_CSS_KERNEL_BITMAP_ELEM_TYPE) + (value >> (i * IA_CSS_KERNEL_BITMAP_ELEM_BITS)); + } +#if IA_CSS_KERNEL_BITMAP_BITS < 64 + if ((value >> IA_CSS_KERNEL_BITMAP_BITS) != 0) { + IA_CSS_TRACE_0(PSYSAPI_KERNEL, ERROR, + "ia_css_kernel_bitmap_create_from_uint64(): kernel bitmap is not wide enough to encode value\n"); + assert(0); + } +#endif +#else + NOT_USED(i); + result = value; +#endif /* IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS */ + return result; +} + +uint64_t ia_css_kernel_bitmap_to_uint64( + const ia_css_kernel_bitmap_t value) +{ + const unsigned int bits64 = sizeof(uint64_t) * 8; + const unsigned int nof_elems_bits64 = bits64 / IA_CSS_KERNEL_BITMAP_ELEM_BITS; + unsigned int i; + uint64_t res = 0; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_to_uint64(): enter:\n"); + + assert((bits64 % IA_CSS_KERNEL_BITMAP_ELEM_BITS) == 0); + assert(nof_elems_bits64 > 0); + +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < nof_elems_bits64; i++) { + res |= ((uint64_t)(value.data[i]) << (i * IA_CSS_KERNEL_BITMAP_ELEM_BITS)); + } + for (i = nof_elems_bits64; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + assert(value.data[i] == 0); + } + return res; +#else + (void)i; + (void)res; + (void)nof_elems_bits64; + return (uint64_t)value; +#endif /* IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS */ +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_unset( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index) +{ + ia_css_kernel_bitmap_t result; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_unset(): enter:\n"); + + result = ia_css_kernel_bit_mask(index); + result = ia_css_kernel_bitmap_complement(result); + return ia_css_kernel_bitmap_intersection(bitmap, result); +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_set_unique( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index) +{ + ia_css_kernel_bitmap_t ret; + ia_css_kernel_bitmap_t bit_mask; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_set_unique(): enter:\n"); + + ret = ia_css_kernel_bitmap_clear(); + bit_mask = ia_css_kernel_bit_mask(index); + + if (ia_css_is_kernel_bitmap_intersection_empty(bitmap, bit_mask) + && !ia_css_is_kernel_bitmap_empty(bit_mask)) { + ret = ia_css_kernel_bitmap_union(bitmap, bit_mask); + } + return ret; +} + +ia_css_kernel_bitmap_t ia_css_kernel_bit_mask( + const unsigned int index) +{ + unsigned int elem_index; + unsigned int elem_bit_index; + ia_css_kernel_bitmap_t bit_mask = ia_css_kernel_bitmap_clear(); + + /* Assert disabled for staging, because some PGs do not satisfy this condition */ + /* assert(index < IA_CSS_KERNEL_BITMAP_BITS); */ + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bit_mask(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + if (index < IA_CSS_KERNEL_BITMAP_BITS) { + elem_index = index / IA_CSS_KERNEL_BITMAP_ELEM_BITS; + elem_bit_index = index % IA_CSS_KERNEL_BITMAP_ELEM_BITS; + assert(elem_index < IA_CSS_KERNEL_BITMAP_NOF_ELEMS); + + bit_mask.data[elem_index] = 1 << elem_bit_index; + } +#else + NOT_USED(elem_index); + NOT_USED(elem_bit_index); + if (index < IA_CSS_KERNEL_BITMAP_BITS) { + bit_mask = (ia_css_kernel_bitmap_t)1 << index; + } +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return bit_mask; +} + + +static int ia_css_kernel_bitmap_compute_weight( + const ia_css_kernel_bitmap_t bitmap) +{ + ia_css_kernel_bitmap_t loc_bitmap; + int weight = 0; + int i; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_compute_weight(): enter:\n"); + + loc_bitmap = bitmap; + + /* In fact; do not need the iterator "i" */ + for (i = 0; (i < IA_CSS_KERNEL_BITMAP_BITS) && + !ia_css_is_kernel_bitmap_empty(loc_bitmap); i++) { + weight += ia_css_is_kernel_bitmap_set(loc_bitmap, 0); + loc_bitmap = ia_css_kernel_bitmap_shift(loc_bitmap); + } + + return weight; +} + +int ia_css_is_kernel_bitmap_set( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index) +{ + unsigned int elem_index; + unsigned int elem_bit_index; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_set(): enter:\n"); + + /* Assert disabled for staging, because some PGs do not satisfy this condition */ + /* assert(index < IA_CSS_KERNEL_BITMAP_BITS); */ + +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + elem_index = index / IA_CSS_KERNEL_BITMAP_ELEM_BITS; + elem_bit_index = index % IA_CSS_KERNEL_BITMAP_ELEM_BITS; + assert(elem_index < IA_CSS_KERNEL_BITMAP_NOF_ELEMS); + return (((bitmap.data[elem_index] >> elem_bit_index) & 0x1) == 1); +#else + NOT_USED(elem_index); + NOT_USED(elem_bit_index); + return (((bitmap >> index) & 0x1) == 1); +#endif /* IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS */ +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_shift( + const ia_css_kernel_bitmap_t bitmap) +{ + int i; + unsigned int lsb_current_elem = 0; + unsigned int lsb_previous_elem = 0; + ia_css_kernel_bitmap_t loc_bitmap; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_shift(): enter:\n"); + + loc_bitmap = bitmap; + +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = IA_CSS_KERNEL_BITMAP_NOF_ELEMS - 1; i >= 0; i--) { + lsb_current_elem = bitmap.data[i] & 0x01; + loc_bitmap.data[i] >>= 1; + loc_bitmap.data[i] |= (lsb_previous_elem << (IA_CSS_KERNEL_BITMAP_ELEM_BITS - 1)); + lsb_previous_elem = lsb_current_elem; + } +#else + NOT_USED(i); + NOT_USED(lsb_current_elem); + NOT_USED(lsb_previous_elem); + loc_bitmap >>= 1; +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return loc_bitmap; +} + +int ia_css_kernel_bitmap_print( + const ia_css_kernel_bitmap_t bitmap, + void *fid) +{ + int retval = -1; + int bit; + unsigned int bit_index = 0; + ia_css_kernel_bitmap_t loc_bitmap; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, INFO, + "ia_css_kernel_bitmap_print(): enter:\n"); + + NOT_USED(fid); + NOT_USED(bit); + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, INFO, "kernel bitmap {\n"); + + loc_bitmap = bitmap; + + for (bit_index = 0; (bit_index < IA_CSS_KERNEL_BITMAP_BITS) && + !ia_css_is_kernel_bitmap_empty(loc_bitmap); bit_index++) { + + bit = ia_css_is_kernel_bitmap_set(loc_bitmap, 0); + loc_bitmap = ia_css_kernel_bitmap_shift(loc_bitmap); + IA_CSS_TRACE_2(PSYSAPI_KERNEL, INFO, "\t%d\t = %d\n", bit_index, bit); + } + IA_CSS_TRACE_0(PSYSAPI_KERNEL, INFO, "}\n"); + + retval = 0; + return retval; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.h new file mode 100644 index 0000000000000..485dd63e5a861 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.h @@ -0,0 +1,293 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_PARAM_H +#define __IA_CSS_PROGRAM_GROUP_PARAM_H + +/*! \file */ + +/** @file ia_css_program_group_param.h + * + * Define the methods on the program group parameter object that are not part + * of a single interface + */ +#include + +#include + +#include /* ia_css_kernel_bitmap_t */ + +#include + +/*! Get the stored size of the program group parameter object + + @param param[in] program group parameter object + + @return size, 0 on error + */ +extern size_t ia_css_program_group_param_get_size( + const ia_css_program_group_param_t *param); + +/*! initialize program_group_param + + @param blob[in] program group parameter object + @param program_count[in] number of terminals. + @param terminal_count[in] number of terminals. + @param fragment_count[in] number of terminals. + + @return 0 if success, else failure. + */ +extern int ia_css_program_group_param_init( + ia_css_program_group_param_t *blob, + const uint8_t program_count, + const uint8_t terminal_count, + const uint16_t fragment_count, + const enum ia_css_frame_format_type *frame_format_types); +/*! Get the program parameter object from a program group parameter object + + @param program_group_param[in] program group parameter object + @param i[in] program parameter index + + @return program parameter pointer, NULL on error + */ +extern ia_css_program_param_t *ia_css_program_group_param_get_program_param( + const ia_css_program_group_param_t *param, + const int i); + +/*! Get the terminal parameter object from a program group parameter object + + @param program_group_param[in] program group parameter object + @param i[in] terminal parameter index + + @return terminal parameter pointer, NULL on error + */ +extern ia_css_terminal_param_t *ia_css_program_group_param_get_terminal_param( + const ia_css_program_group_param_t *param, + const int i); + +/*! Get the fragment count from a program group parameter object + + @param program_group_param[in] program group parameter object + + @return fragment count, 0 on error + */ +extern uint16_t ia_css_program_group_param_get_fragment_count( + const ia_css_program_group_param_t *param); + +/*! Get the program count from a program group parameter object + + @param program_group_param[in] program group parameter object + + @return program count, 0 on error + */ +extern uint8_t ia_css_program_group_param_get_program_count( + const ia_css_program_group_param_t *param); + +/*! Get the terminal count from a program group parameter object + + @param program_group_param[in] program group parameter object + + @return terminal count, 0 on error + */ +extern uint8_t ia_css_program_group_param_get_terminal_count( + const ia_css_program_group_param_t *param); + +/*! Set the protocol version in a program group parameter object + + @param program_group_param[in] program group parameter object + @param protocol_version[in] protocol version + + @return nonzero on error +*/ +extern int +ia_css_program_group_param_set_protocol_version( + ia_css_program_group_param_t *param, + uint8_t protocol_version); + +/*! Get the protocol version from a program group parameter object + + @param program_group_param[in] program group parameter object + + @return protocol version +*/ +extern uint8_t +ia_css_program_group_param_get_protocol_version( + const ia_css_program_group_param_t *param); + +/*! Set the kernel enable bitmap from a program group parameter object + + @param param[in] program group parameter object + @param bitmap[in] kernel enable bitmap + + @return non-zero on error + */ +extern int ia_css_program_group_param_set_kernel_enable_bitmap( + ia_css_program_group_param_t *param, + const ia_css_kernel_bitmap_t bitmap); + +/*! Get the kernel enable bitmap from a program group parameter object + + @param program_group_param[in] program group parameter object + + @return kernel enable bitmap, 0 on error +*/ +extern ia_css_kernel_bitmap_t +ia_css_program_group_param_get_kernel_enable_bitmap( + const ia_css_program_group_param_t *param); + +/*! Get the stored size of the program parameter object + + @param param[in] program parameter object + + @return size, 0 on error + */ +extern size_t ia_css_program_param_get_size( + const ia_css_program_param_t *param); + +/*! Set the kernel enable bitmap from a program parameter object + + @param program_param[in] program parameter object + @param bitmap[in] kernel enable bitmap + + @return non-zero on error + */ +extern int ia_css_program_param_set_kernel_enable_bitmap( + ia_css_program_param_t *program_param, + const ia_css_kernel_bitmap_t bitmap); + +/*! Get the kernel enable bitmap from a program parameter object + + @param program_param[in] program parameter object + + Note: This function returns in fact the kernel enable of the program group + parameters + + @return kernel enable bitmap, 0 on error + */ +extern ia_css_kernel_bitmap_t ia_css_program_param_get_kernel_enable_bitmap( + const ia_css_program_param_t *param); + +/*! Get the stored size of the terminal parameter object + + @param param[in] terminal parameter object + + @return size, 0 on error + */ +extern size_t ia_css_terminal_param_get_size( + const ia_css_terminal_param_t *param); + +/*! Get the kernel enable bitmap from a terminal parameter object + + @param terminal_param[in] terminal parameter object + + Note: This function returns in fact the kernel enable of the program group + parameters + + @return kernel enable bitmap, 0 on error + */ +extern ia_css_kernel_bitmap_t ia_css_terminal_param_get_kernel_enable_bitmap( + const ia_css_terminal_param_t *param); + +/*! Get the parent object for this terminal param. + + @param terminal_param[in] terminal parameter object + + @return parent program group param object + */ +extern ia_css_program_group_param_t *ia_css_terminal_param_get_parent( + const ia_css_terminal_param_t *param); + +/*! Get the data format type associated with the terminal. + + @param terminal_param[in] terminal parameter object + + @return data format type (ia_css_data_format_type_t) + */ +extern ia_css_frame_format_type_t ia_css_terminal_param_get_frame_format_type( + const ia_css_terminal_param_t *terminal_param); + +/*! Set the data format type associated with the terminal. + + @param terminal_param[in] terminal parameter object + @param data_format_type[in] data format type + + @return non-zero on error. + */ +extern int ia_css_terminal_param_set_frame_format_type( + ia_css_terminal_param_t *terminal_param, + const ia_css_frame_format_type_t data_format_type); + +/*! Get bits per pixel on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + + @return bits per pixel + */ +extern uint8_t ia_css_terminal_param_get_bpp( + const ia_css_terminal_param_t *terminal_param); + +/*! Set bits per pixel on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + @param bpp[in] bits per pixel + + @return non-zero on error. + */ +extern int ia_css_terminal_param_set_bpp( + ia_css_terminal_param_t *terminal_param, + const uint8_t bpp); + +/*! Get dimensions on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + @param dimensions[out] dimension array + + @return non-zero on error. + */ +extern int ia_css_terminal_param_get_dimensions( + const ia_css_terminal_param_t *terminal_param, + uint16_t dimensions[IA_CSS_N_DATA_DIMENSION]); + +/*! Set dimensions on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + @param dimensions[in] dimension array + + @return non-zero on error. + */ +extern int ia_css_terminal_param_set_dimensions( + ia_css_terminal_param_t *terminal_param, + const uint16_t dimensions[IA_CSS_N_DATA_DIMENSION]); + +/*! Get stride on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + + @return stride of the frame to be attached. + */ +extern uint32_t ia_css_terminal_param_get_stride( + const ia_css_terminal_param_t *terminal_param); + +/*! Set stride on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + @param stride[in] stride + + @return non-zero on error. + */ +extern int ia_css_terminal_param_set_stride( + ia_css_terminal_param_t *terminal_param, + const uint32_t stride); + +#endif /* __IA_CSS_PROGRAM_GROUP_PARAM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.sim.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.sim.h new file mode 100644 index 0000000000000..7821f8147a1a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.sim.h @@ -0,0 +1,153 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_PARAM_SIM_H +#define __IA_CSS_PROGRAM_GROUP_PARAM_SIM_H + +/*! \file */ + +/** @file ia_css_program_group_param.sim.h + * + * Define the methods on the program group parameter object: Simulation only + */ +#include + +#include + +#include + +/* Simulation */ + +/*! Create a program group parameter object from specification + + @param specification[in] specification (index) + @param manifest[in] program group manifest + + @return NULL on error + */ +extern ia_css_program_group_param_t *ia_css_program_group_param_create( + const unsigned int specification, + const ia_css_program_group_manifest_t *manifest); + +/*! Destroy the program group parameter object + + @param program_group_param[in] program group parameter object + + @return NULL + */ +extern ia_css_program_group_param_t *ia_css_program_group_param_destroy( + ia_css_program_group_param_t *param); + +/*! Compute the size of storage required for allocating + * the program group parameter object + + @param program_count[in] Number of programs in the process group + @param terminal_count[in] Number of terminals on the process group + @param fragment_count[in] Number of fragments on the terminals of + the process group + + @return 0 on error + */ +size_t ia_css_sizeof_program_group_param( + const uint8_t program_count, + const uint8_t terminal_count, + const uint16_t fragment_count); + +/*! Allocate (the store of) a program group parameter object + + @param program_count[in] Number of programs in the process group + @param terminal_count[in] Number of terminals on the process group + @param fragment_count[in] Number of fragments on the terminals of + the process group + + @return program group parameter pointer, NULL on error + */ +extern ia_css_program_group_param_t *ia_css_program_group_param_alloc( + const uint8_t program_count, + const uint8_t terminal_count, + const uint16_t fragment_count); + +/*! Free (the store of) a program group parameter object + + @param program_group_param[in] program group parameter object + + @return NULL + */ +extern ia_css_program_group_param_t *ia_css_program_group_param_free( + ia_css_program_group_param_t *param); + +/*! Print the program group parameter object to file/stream + + @param param[in] program group parameter object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_program_group_param_print( + const ia_css_program_group_param_t *param, + void *fid); + +/*! Allocate (the store of) a program parameter object + + @return program parameter pointer, NULL on error + */ +extern ia_css_program_param_t *ia_css_program_param_alloc(void); + +/*! Free (the store of) a program parameter object + + @param param[in] program parameter object + + @return NULL + */ +extern ia_css_program_param_t *ia_css_program_param_free( + ia_css_program_param_t *param); + +/*! Print the program parameter object to file/stream + + @param param[in] program parameter object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_program_param_print( + const ia_css_program_param_t *param, + void *fid); + +/*! Allocate (the store of) a terminal parameter object + + @return terminal parameter pointer, NULL on error + */ +extern ia_css_terminal_param_t *ia_css_terminal_param_alloc(void); + +/*! Free (the store of) a terminal parameter object + + @param param[in] terminal parameter object + + @return NULL + */ +extern ia_css_terminal_param_t *ia_css_terminal_param_free( + ia_css_terminal_param_t *param); + +/*! Print the terminal parameter object to file/stream + + @param param[in] terminal parameter object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_terminal_param_print( + const ia_css_terminal_param_t *param, + void *fid); + +#endif /* __IA_CSS_PROGRAM_GROUP_PARAM_SIM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param_types.h new file mode 100644 index 0000000000000..34f57584a227f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param_types.h @@ -0,0 +1,64 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_PARAM_TYPES_H +#define __IA_CSS_PROGRAM_GROUP_PARAM_TYPES_H + +/*! \file */ + +/** @file ia_css_program_group_param_types.h + * + * Define the parameter objects that are necessary to create the process + * groups i.e. enable parameters and parameters to set-up frame descriptors + */ + +#include +#include /* ia_css_kernel_bitmap_t */ +#include + +#include +/*! make this public so that driver can populate, + * size, bpp, dimensions for all terminals. + * + * Currently one API is provided to get frame_format_type. + * + * frame_format_type is set during ia_css_terminal_param_init(). + * Value for that is const and binary specific. + */ +struct ia_css_terminal_param_s { + uint32_t size; /**< Size of this structure */ + /**< Indicates if this is a generic type or inbuild + * with variable size descriptor + */ + ia_css_frame_format_type_t frame_format_type; + /**< offset to add to reach parent. This is negative value.*/ + int32_t parent_offset; + uint16_t dimensions[IA_CSS_N_DATA_DIMENSION];/**< Logical dimensions */ + /**< Mapping to the index field of the terminal descriptor */ + uint16_t index[IA_CSS_N_DATA_DIMENSION]; + /**< Logical fragment dimension, + * TODO: fragment dimensions can be different per fragment + */ + uint16_t fragment_dimensions[IA_CSS_N_DATA_DIMENSION]; + uint32_t stride;/**< Stride of a frame */ + uint16_t offset;/**< Offset in bytes to first fragment */ + uint8_t bpp; /**< Bits per pixel */ + uint8_t bpe; /**< Bits per element */ +}; + +typedef struct ia_css_program_group_param_s ia_css_program_group_param_t; +typedef struct ia_css_program_param_s ia_css_program_param_t; +typedef struct ia_css_terminal_param_s ia_css_terminal_param_t; + +#endif /* __IA_CSS_PROGRAM_GROUP_PARAM_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_psys_param_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_psys_param_trace.h new file mode 100644 index 0000000000000..f59dfbf165e4d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/interface/ia_css_psys_param_trace.h @@ -0,0 +1,102 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PARAM_TRACE_H +#define __IA_CSS_PSYS_PARAM_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_PARAM_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_PARAM_TRACING_OVERRIDE)) + #define PSYS_PARAM_TRACE_LEVEL_CONFIG PSYS_PARAM_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_PARAM_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_PARAM_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_PARAM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_PARAM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_PARAM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_PARAM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_PARAM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_PARAM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_PARAM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_PARAM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_PARAM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_PARAM_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_PARAM_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_PARAM_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_PARAM_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_PARAM_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_PARAM_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_PARAM_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_PARAM_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param.c new file mode 100644 index 0000000000000..e6fe2bfa8a7be --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param.c @@ -0,0 +1,771 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ia_css_psys_param_trace.h" + +static int +ia_css_terminal_param_init(ia_css_terminal_param_t *terminal_param, + uint32_t offset, + enum ia_css_frame_format_type frame_format_type); + +static int +ia_css_program_param_init(ia_css_program_param_t *program_param, + int32_t offset); + +size_t ia_css_sizeof_program_group_param( + const uint8_t program_count, + const uint8_t terminal_count, + const uint16_t fragment_count) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_sizeof_program_group_param(): enter:\n"); + + verifexit(program_count != 0); + verifexit(terminal_count != 0); + verifexit(fragment_count != 0); + + size += sizeof(ia_css_program_group_param_t); + size += program_count * fragment_count * sizeof(ia_css_program_param_t); + size += terminal_count * sizeof(ia_css_terminal_param_t); +EXIT: + if (0 == program_count || 0 == terminal_count || 0 == fragment_count) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_sizeof_program_group_param invalid argument\n"); + } + return size; +} + +size_t ia_css_program_group_param_get_size( + const ia_css_program_group_param_t *program_group_param) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_size(): enter:\n"); + + if (program_group_param != NULL) { + size = program_group_param->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_size invalid argument\n"); + } + return size; +} + +size_t ia_css_program_param_get_size( + const ia_css_program_param_t *param) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_param_get_size(): enter:\n"); + + if (param != NULL) { + size = param->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_param_get_size invalid argument\n"); + } + return size; +} + +ia_css_program_param_t *ia_css_program_group_param_get_program_param( + const ia_css_program_group_param_t *param, + const int i) +{ + ia_css_program_param_t *program_param = NULL; + ia_css_program_param_t *program_param_base; + int program_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_program_param(): enter:\n"); + + verifexit(param != NULL); + + program_count = + (int)ia_css_program_group_param_get_program_count(param); + + verifexit(i < program_count); + + program_param_base = (ia_css_program_param_t *) + (((char *)param) + param->program_param_offset); + + program_param = &program_param_base[i]; + +EXIT: + if (NULL == param || i >= program_count) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_program_param invalid argument\n"); + } + return program_param; +} + +size_t ia_css_terminal_param_get_size( + const ia_css_terminal_param_t *param) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_size(): enter:\n"); + + if (param != NULL) { + size = param->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_terminal_param_get_size invalid argument\n"); + } + + return size; +} + +ia_css_terminal_param_t *ia_css_program_group_param_get_terminal_param( + const ia_css_program_group_param_t *param, + const int i) +{ + ia_css_terminal_param_t *terminal_param = NULL; + ia_css_terminal_param_t *terminal_param_base; + int program_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_terminal_param(): enter:\n"); + + verifexit(param != NULL); + + program_count = + (int)ia_css_program_group_param_get_terminal_count(param); + + verifexit(i < program_count); + + terminal_param_base = (ia_css_terminal_param_t *) + (((char *)param) + param->terminal_param_offset); + terminal_param = &terminal_param_base[i]; +EXIT: + if (NULL == param || i >= program_count) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_terminal_param invalid argument\n"); + } + return terminal_param; +} + +uint8_t ia_css_program_group_param_get_program_count( + const ia_css_program_group_param_t *param) +{ + uint8_t program_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_program_count(): enter:\n"); + + if (param != NULL) { + program_count = param->program_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_program_count invalid argument\n"); + } + return program_count; +} + +uint8_t ia_css_program_group_param_get_terminal_count( + const ia_css_program_group_param_t *param) +{ + uint8_t terminal_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_terminal_count(): enter:\n"); + + if (param != NULL) { + terminal_count = param->terminal_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_terminal_count invalid argument\n"); + } + return terminal_count; +} + +uint16_t ia_css_program_group_param_get_fragment_count( + const ia_css_program_group_param_t *param) +{ + uint8_t fragment_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_fragment_count(): enter:\n"); + + if (param != NULL) { + fragment_count = (uint8_t)param->fragment_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_fragment_count invalid argument\n"); + } + return fragment_count; +} + +int ia_css_program_group_param_set_protocol_version( + ia_css_program_group_param_t *param, + uint8_t protocol_version) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_set_protocol_version(): enter:\n"); + + if (param != NULL) { + param->protocol_version = protocol_version; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_group_param_set_protocol_version failed (%i)\n", + retval); + } + return retval; +} + +uint8_t ia_css_program_group_param_get_protocol_version( + const ia_css_program_group_param_t *param) +{ + uint8_t protocol_version = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_protocol_version(): enter:\n"); + + if (param != NULL) { + protocol_version = param->protocol_version; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_protocol_version invalid argument\n"); + } + return protocol_version; +} + +int ia_css_program_group_param_set_kernel_enable_bitmap( + ia_css_program_group_param_t *param, + const ia_css_kernel_bitmap_t bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_set_kernel_enable_bitmap(): enter:\n"); + + if (param != NULL) { + param->kernel_enable_bitmap = bitmap; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_group_param_set_kernel_enable_bitmap failed (%i)\n", + retval); + } + return retval; +} + +ia_css_kernel_bitmap_t ia_css_program_group_param_get_kernel_enable_bitmap( + const ia_css_program_group_param_t *param) +{ + ia_css_kernel_bitmap_t bitmap = ia_css_kernel_bitmap_clear(); + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_kernel_enable_bitmap(): enter:\n"); + + if (param != NULL) { + bitmap = param->kernel_enable_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_kernel_enable_bitmap invalid argument\n"); + } + return bitmap; +} + +int ia_css_program_param_set_kernel_enable_bitmap( + ia_css_program_param_t *program_param, + const ia_css_kernel_bitmap_t bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_param_set_kernel_enable_bitmap(): enter:\n"); + + if (program_param != NULL) { + program_param->kernel_enable_bitmap = bitmap; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_param_set_kernel_enable_bitmap failed (%i)\n", + retval); + } + return retval; +} + +ia_css_kernel_bitmap_t ia_css_program_param_get_kernel_enable_bitmap( + const ia_css_program_param_t *program_param) +{ + ia_css_kernel_bitmap_t bitmap = ia_css_kernel_bitmap_clear(); + char *base; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_param_get_kernel_enable_bitmap(): enter:\n"); + + verifexit(program_param != NULL); + verifexit(program_param->parent_offset != 0); + + base = (char *)((char *)program_param + program_param->parent_offset); + bitmap = ((ia_css_program_group_param_t *)base)->kernel_enable_bitmap; +EXIT: + if (NULL == program_param || 0 == program_param->parent_offset) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_param_get_kernel_enable_bitmap invalid argument\n"); + } + return bitmap; +} + +ia_css_kernel_bitmap_t ia_css_terminal_param_get_kernel_enable_bitmap( + const ia_css_terminal_param_t *param) +{ + ia_css_kernel_bitmap_t bitmap = ia_css_kernel_bitmap_clear(); + char *base; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_kernel_enable_bitmap(): enter:\n"); + + verifexit(param != NULL); + verifexit(param->parent_offset != 0); + + base = (char *)((char *)param + param->parent_offset); + bitmap = ((ia_css_program_group_param_t *)base)->kernel_enable_bitmap; +EXIT: + if (NULL == param || 0 == param->parent_offset) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_terminal_param_get_kernel_enable_bitmap invalid argument\n"); + } + return bitmap; +} + +ia_css_frame_format_type_t ia_css_terminal_param_get_frame_format_type( + const ia_css_terminal_param_t *param) +{ + ia_css_frame_format_type_t ft = IA_CSS_N_FRAME_FORMAT_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_frame_format_type(): enter:\n"); + + verifexit(param != NULL); + + ft = param->frame_format_type; +EXIT: + if (param == NULL) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_terminal_param_get_frame_format_type invalid argument\n"); + } + return ft; +} + +int ia_css_terminal_param_set_frame_format_type( + ia_css_terminal_param_t *param, + const ia_css_frame_format_type_t data_format_type) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_set_frame_format_type(): enter:\n"); + + if (param != NULL) { + param->frame_format_type = data_format_type; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_set_frame_format_type failed (%i)\n", + retval); + } + return retval; +} + +uint8_t ia_css_terminal_param_get_bpp( + const ia_css_terminal_param_t *param) +{ + uint8_t bpp = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_bpp(): enter:\n"); + + verifexit(param != NULL); + + bpp = param->bpp; + +EXIT: + if (param == NULL) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_terminal_param_get_bpp invalid argument\n"); + } + return bpp; +} + +int ia_css_terminal_param_set_bpp( + ia_css_terminal_param_t *param, + const uint8_t bpp) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_set_bpp(): enter:\n"); + + if (param != NULL) { + param->bpp = bpp; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_set_bpp failed (%i)\n", retval); + } + return retval; +} + +int ia_css_terminal_param_get_dimensions( + const ia_css_terminal_param_t *param, + uint16_t dimensions[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_dimensions(): enter:\n"); + + if (param != NULL) { + dimensions[IA_CSS_COL_DIMENSION] = + param->dimensions[IA_CSS_COL_DIMENSION]; + dimensions[IA_CSS_ROW_DIMENSION] = + param->dimensions[IA_CSS_ROW_DIMENSION]; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_get_dimensions failed (%i)\n", retval); + } + return retval; +} + +int ia_css_terminal_param_set_dimensions( + ia_css_terminal_param_t *param, + const uint16_t dimensions[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_set_dimensions(): enter:\n"); + + if (param != NULL) { + param->dimensions[IA_CSS_COL_DIMENSION] = + dimensions[IA_CSS_COL_DIMENSION]; + param->dimensions[IA_CSS_ROW_DIMENSION] = + dimensions[IA_CSS_ROW_DIMENSION]; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_set_dimensions failed (%i)\n", retval); + } + return retval; +} + +int ia_css_terminal_param_set_stride( + ia_css_terminal_param_t *param, + const uint32_t stride) +{ + int retval = -1; + + verifexit(param != NULL); + param->stride = stride; + retval = 0; + +EXIT: + return retval; +} + +uint32_t ia_css_terminal_param_get_stride( + const ia_css_terminal_param_t *param) +{ + uint32_t stride = 0; + + verifexit(param != NULL); + stride = param->stride; + +EXIT: + return stride; +} + + +static int ia_css_program_param_init( + ia_css_program_param_t *program_param, + int32_t offset) +{ + int retval = -1; + + COMPILATION_ERROR_IF( + SIZE_OF_PROGRAM_PARAM_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_program_param_t))); + verifexit(program_param != NULL); + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_program_param_init(): enter:\n"); + + program_param->size = sizeof(ia_css_program_param_t); + /* parent is at negative offset from current program.*/ + program_param->parent_offset = -offset; + /*TODO: Kernel_bitmap setting. ?*/ + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_param_init failed (%i)\n", retval); + } + return retval; +} + +static int +ia_css_terminal_param_init(ia_css_terminal_param_t *terminal_param, + uint32_t offset, + enum ia_css_frame_format_type frame_format_type) +{ + int retval = -1; + + COMPILATION_ERROR_IF( + SIZE_OF_TERMINAL_PARAM_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_terminal_param_t))); + verifexit(terminal_param != NULL); + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_terminal_param_init(): enter:\n"); + + terminal_param->size = sizeof(ia_css_terminal_param_t); + /* parent is at negative offset from current program.*/ + terminal_param->parent_offset = -((int32_t)offset); + /*TODO: Kernel_bitmap setting. ?*/ + terminal_param->frame_format_type = frame_format_type; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_init failed (%i)\n", retval); + } + return retval; +} + +ia_css_program_group_param_t * +ia_css_terminal_param_get_parent( + const ia_css_terminal_param_t *param) +{ + ia_css_program_group_param_t *parent = NULL; + char *base; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_parent(): enter:\n"); + + verifexit(param != NULL); + + base = (char *)((char *)param + param->parent_offset); + + parent = (ia_css_program_group_param_t *)(base); +EXIT: + if (param == NULL) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_terminal_param_get_parent invalid argument\n"); + } + return parent; +} + +int ia_css_program_group_param_init( + ia_css_program_group_param_t *blob, + const uint8_t program_count, + const uint8_t terminal_count, + const uint16_t fragment_count, + const enum ia_css_frame_format_type *frame_format_types) +{ + int i = 0; + char *param_base; + uint32_t offset; + int retval = -1; + + COMPILATION_ERROR_IF( + SIZE_OF_PROGRAM_GROUP_PARAM_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_program_group_param_t))); + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_program_group_param_init(): enter:\n"); + + assert(blob != 0); + + verifexit(blob != NULL); + verifexit(frame_format_types != NULL); + + blob->program_count = program_count; + blob->fragment_count = fragment_count; + blob->terminal_count = terminal_count; + blob->program_param_offset = sizeof(ia_css_program_group_param_t); + blob->terminal_param_offset = blob->program_param_offset + + sizeof(ia_css_program_param_t) * program_count; + + param_base = (char *)((char *)blob + blob->program_param_offset); + offset = blob->program_param_offset; + + for (i = 0; i < program_count; i++) { + ia_css_program_param_init( + (ia_css_program_param_t *)param_base, offset); + offset += sizeof(ia_css_program_param_t); + param_base += sizeof(ia_css_program_param_t); + } + + param_base = (char *)((char *)blob + blob->terminal_param_offset); + offset = blob->terminal_param_offset; + + for (i = 0; i < terminal_count; i++) { + ia_css_terminal_param_init( + (ia_css_terminal_param_t *)param_base, + offset, + frame_format_types[i]); + + offset += sizeof(ia_css_terminal_param_t); + param_base += sizeof(ia_css_terminal_param_t); + } + + /* + * For now, set legacy flow by default. This can be removed as soon + * as all hosts/drivers explicitly set the protocol version. + */ + blob->protocol_version = IA_CSS_PROCESS_GROUP_PROTOCOL_LEGACY; + + blob->size = (uint32_t)ia_css_sizeof_program_group_param(program_count, + terminal_count, + fragment_count); + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_group_param_init failed (%i)\n", retval); + } + return retval; +} + +int ia_css_program_group_param_print( + const ia_css_program_group_param_t *param, + void *fid) +{ + int retval = -1; + int i; + uint8_t program_count, terminal_count; + ia_css_kernel_bitmap_t bitmap; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_program_group_param_print(): enter:\n"); + + verifexit(param != NULL); + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, + "sizeof(program_group_param) = %d\n", + (int)ia_css_program_group_param_get_size(param)); + + program_count = ia_css_program_group_param_get_program_count(param); + terminal_count = ia_css_program_group_param_get_terminal_count(param); + + bitmap = ia_css_program_group_param_get_kernel_enable_bitmap(param); + verifexit(ia_css_kernel_bitmap_print(bitmap, fid) == 0); + + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, + "%d program params\n", (int)program_count); + for (i = 0; i < (int)program_count; i++) { + ia_css_program_param_t *program_param = + ia_css_program_group_param_get_program_param(param, i); + + retval = ia_css_program_param_print(program_param, fid); + verifjmpexit(retval == 0); + } + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, "%d terminal params\n", + (int)terminal_count); + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_param_t *terminal_param = + ia_css_program_group_param_get_terminal_param(param, i); + + retval = ia_css_terminal_param_print(terminal_param, fid); + verifjmpexit(retval == 0); + } + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_group_param_print failed (%i)\n", retval); + } + return retval; +} + +int ia_css_terminal_param_print( + const ia_css_terminal_param_t *param, + void *fid) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_terminal_param_print(): enter:\n"); + + verifexit(param != NULL); + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, + "sizeof(terminal_param) = %d\n", + (int)ia_css_terminal_param_get_size(param)); + + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, + "\tframe_format_type = %d\n", param->frame_format_type); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_print failed (%i)\n", retval); + } + return retval; +} + +int ia_css_program_param_print( + const ia_css_program_param_t *param, + void *fid) +{ + int retval = -1; + ia_css_kernel_bitmap_t bitmap; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_program_param_print(): enter:\n"); + + verifexit(param != NULL); + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, "sizeof(program_param) = %d\n", + (int)ia_css_program_param_get_size(param)); + + bitmap = ia_css_program_param_get_kernel_enable_bitmap(param); + verifexit(ia_css_kernel_bitmap_print(bitmap, fid) == 0); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_param_print failed (%i)\n", retval); + } + return retval; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param_private.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param_private.h new file mode 100644 index 0000000000000..6672737e51a14 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param_private.h @@ -0,0 +1,80 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_PARAM_PRIVATE_H +#define __IA_CSS_PROGRAM_GROUP_PARAM_PRIVATE_H + +#include +#include +#include +#include +#include +#include +#include + +#define N_PADDING_UINT8_IN_PROGRAM_GROUP_PARAM_STRUCT 7 +#define SIZE_OF_PROGRAM_GROUP_PARAM_STRUCT_IN_BITS \ + (IA_CSS_KERNEL_BITMAP_BITS \ + + (3 * IA_CSS_UINT32_T_BITS) \ + + IA_CSS_UINT16_T_BITS \ + + (3 * IA_CSS_UINT8_T_BITS) \ + + (N_PADDING_UINT8_IN_PROGRAM_GROUP_PARAM_STRUCT * IA_CSS_UINT8_T_BITS)) + +/* tentative; co-design with ISP algorithm */ +struct ia_css_program_group_param_s { + /* The enable bits for each individual kernel */ + ia_css_kernel_bitmap_t kernel_enable_bitmap; + /* Size of this structure */ + uint32_t size; + uint32_t program_param_offset; + uint32_t terminal_param_offset; + /* Number of (explicit) fragments to use in a frame */ + uint16_t fragment_count; + /* Number of active programs */ + uint8_t program_count; + /* Number of active terminals */ + uint8_t terminal_count; + /* Program group protocol version */ + uint8_t protocol_version; + uint8_t padding[N_PADDING_UINT8_IN_PROGRAM_GROUP_PARAM_STRUCT]; +}; + +#define SIZE_OF_PROGRAM_PARAM_STRUCT_IN_BITS \ + (IA_CSS_KERNEL_BITMAP_BITS \ + + IA_CSS_UINT32_T_BITS \ + + IA_CSS_INT32_T_BITS) + +/* private */ +struct ia_css_program_param_s { + /* What to use this one for ? */ + ia_css_kernel_bitmap_t kernel_enable_bitmap; + /* Size of this structure */ + uint32_t size; + /* offset to add to reach parent. This is negative value.*/ + int32_t parent_offset; +}; + +#define SIZE_OF_TERMINAL_PARAM_STRUCT_IN_BITS \ + (IA_CSS_UINT32_T_BITS \ + + IA_CSS_FRAME_FORMAT_TYPE_BITS \ + + IA_CSS_INT32_T_BITS \ + + (IA_CSS_UINT16_T_BITS * IA_CSS_N_DATA_DIMENSION) \ + + (IA_CSS_UINT16_T_BITS * IA_CSS_N_DATA_DIMENSION) \ + + (IA_CSS_UINT16_T_BITS * IA_CSS_N_DATA_DIMENSION) \ + + IA_CSS_INT32_T_BITS \ + + IA_CSS_UINT16_T_BITS \ + + IA_CSS_UINT8_T_BITS \ + + (IA_CSS_UINT8_T_BITS * 1)) + +#endif /* __IA_CSS_PROGRAM_GROUP_PARAM_PRIVATE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/psys_server_manifest/bxtB0/ia_css_psys_server_manifest.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/psys_server_manifest/bxtB0/ia_css_psys_server_manifest.c new file mode 100644 index 0000000000000..a2dd8cbd1ba1d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/psys_server_manifest/bxtB0/ia_css_psys_server_manifest.c @@ -0,0 +1,50 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_server_manifest.h" + +/** + * Manifest of resources in use by PSYS itself + */ + +const vied_nci_resource_spec_t psys_server_manifest = { + /* internal memory */ + { /* resource id size offset*/ + {VIED_NCI_GMEM_TYPE_ID, 0, 0}, + {VIED_NCI_DMEM_TYPE_ID, VIED_NCI_DMEM0_MAX_SIZE, 0}, + {VIED_NCI_VMEM_TYPE_ID, 0, 0}, + {VIED_NCI_BAMEM_TYPE_ID, 0, 0}, + {VIED_NCI_PMEM_TYPE_ID, 0, 0} + }, + /* external memory */ + { /* resource id size offset*/ + {VIED_NCI_N_MEM_ID, 0, 0}, + {VIED_NCI_N_MEM_ID, 0, 0}, + {VIED_NCI_N_MEM_ID, 0, 0}, + {VIED_NCI_N_MEM_ID, 0, 0}, + }, + /* device channel */ + { /* resource id size offset*/ + {VIED_NCI_DEV_CHN_DMA_EXT0_ID, + PSYS_SERVER_DMA_CHANNEL_SIZE, + PSYS_SERVER_DMA_CHANNEL_OFFSET}, + {VIED_NCI_DEV_CHN_GDC_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_EXT1_READ_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_EXT1_WRITE_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_INTERNAL_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_IPFD_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_ISA_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_FW_ID, 0, 0} + } +}; diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/psys_server_manifest/bxtB0/ia_css_psys_server_manifest.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/psys_server_manifest/bxtB0/ia_css_psys_server_manifest.h new file mode 100644 index 0000000000000..b4c7fbc32d5ba --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/psys_server_manifest/bxtB0/ia_css_psys_server_manifest.h @@ -0,0 +1,29 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_SERVER_MANIFEST_H +#define __IA_CSS_PSYS_SERVER_MANIFEST_H + +#include "vied_nci_psys_resource_model.h" + +/** + * Manifest of resources in use by PSYS itself + */ + +#define PSYS_SERVER_DMA_CHANNEL_SIZE 2 +#define PSYS_SERVER_DMA_CHANNEL_OFFSET 28 + +extern const vied_nci_resource_spec_t psys_server_manifest; + +#endif /* __IA_CSS_PSYS_SERVER_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/psysapi.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/psysapi.mk new file mode 100644 index 0000000000000..e1977cbe2ca2a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/psysapi.mk @@ -0,0 +1,122 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PSYSAPI +# +ifdef _H_PSYSAPI_MK +$(error ERROR: psysapi.mk included multiple times, please check makefile) +else +_H_PSYSAPI_MK=1 +endif + +include $(MODULES_DIR)/config/psys/subsystem_$(IPU_SYSVER).mk + +PSYSAPI_DIR = $${MODULES_DIR}/psysapi + +PSYSAPI_PROCESS_HOST_FILES = $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_process.c +PSYSAPI_PROCESS_HOST_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_process_group.c +PSYSAPI_PROCESS_HOST_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_buffer_set.c +PSYSAPI_PROCESS_HOST_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_terminal.c +PSYSAPI_PROCESS_HOST_FILES += $(PSYSAPI_DIR)/param/src/ia_css_program_group_param.c + +# Use PSYS_MANIFEST_HOST_FILES when only accessing manifest functions +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_program_group_manifest.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_program_manifest.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_terminal_manifest.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/sim/src/vied_nci_psys_system.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/kernel/src/ia_css_kernel_bitmap.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/data/src/ia_css_program_group_data.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/vied_nci_psys_resource_model.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/psys_server_manifest/$(PSYS_SERVER_MANIFEST_VERSION)/ia_css_psys_server_manifest.c + +# Use only kernel bitmap functionality from PSYS API +PSYSAPI_KERNEL_BITMAP_FILES += $(PSYSAPI_DIR)/kernel/src/ia_css_kernel_bitmap.c +PSYSAPI_KERNEL_BITMAP_CPPFLAGS += -I$(PSYSAPI_DIR)/kernel/interface +PSYSAPI_KERNEL_BITMAP_CPPFLAGS += -I$(PSYSAPI_DIR)/interface + +# Use PSYSAPI_HOST_FILES when program and process group are both needed +PSYSAPI_HOST_FILES = $(PSYSAPI_PROCESS_HOST_FILES) $(PSYSAPI_MANIFEST_HOST_FILES) + +# Use PSYSAPI_PROCESS_GROUP_HOST_FILES when program and process group are both needed but there is no +# implementation (yet) of the user customization functions defined in ia_css_psys_process_group_cmd_impl.h. +# Dummy implementations are provided in $(PSYSAPI_DIR)/sim/src/ia_css_psys_process_group_cmd_impl.c +PSYSAPI_PROCESS_GROUP_HOST_FILES = $(PSYSAPI_HOST_FILES) +PSYSAPI_PROCESS_GROUP_HOST_FILES += $(PSYSAPI_DIR)/sim/src/ia_css_psys_process_group_cmd_impl.c + +# for now disabled, implementation for now provided by psys api impl +#PSYSAPI_HOST_FILES += $(PSYSAPI_DIR)/device/src/ia_css_psys_device.c + +PSYSAPI_HOST_CPPFLAGS = -I$(PSYSAPI_DIR)/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/device/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/device/interface/$(IPU_SYSVER) +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/dynamic/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/dynamic/src +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/data/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/data/src +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/static/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/static/src +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/kernel/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/param/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/param/src +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/sim/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/sim/src +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION) +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/private +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/psys_server_manifest/$(PSYS_SERVER_MANIFEST_VERSION) + +PSYSAPI_FW_CPPFLAGS = $(PSYSAPI_HOST_CPPFLAGS) +PSYSAPI_FW_CPPFLAGS += -I$(PSYSAPI_DIR)/static/interface +PSYSAPI_FW_CPPFLAGS += -I$(PSYSAPI_DIR)/static/src +PSYSAPI_FW_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION) +PSYSAPI_FW_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/private +PSYSAPI_FW_CPPFLAGS += -I$(PSYSAPI_DIR)/psys_server_manifest/$(PSYS_SERVER_MANIFEST_VERSION) +PSYSAPI_SYSTEM_GLOBAL_CPPFLAGS += -I$(PSYSAPI_DIR)/sim/interface +PSYSAPI_SYSTEM_GLOBAL_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION) +PSYSAPI_SYSTEM_GLOBAL_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/private +PSYSAPI_SYSTEM_GLOBAL_CPPFLAGS += -I$(PSYSAPI_DIR)/psys_server_manifest/$(PSYS_SERVER_MANIFEST_VERSION) + +# Defining the trace level for the PSYSAPI +PSYSAPI_HOST_CPPFLAGS += -DPSYSAPI_TRACE_CONFIG=PSYSAPI_TRACE_LOG_LEVEL_NORMAL +# Enable/Disable 'late binding' support and it's additional queues +PSYSAPI_HOST_CPPFLAGS += -DHAS_LATE_BINDING_SUPPORT=$(PSYS_HAS_LATE_BINDING_SUPPORT) + +#Example: how to switch to a different log level for a sub-module +#PSYSAPI_HOST_CPPFLAGS += -DPSYSAPI_DYNAMIC_TRACING_OVERRIDE=PSYSAPI_TRACE_LOG_LEVEL_DEBUG + +# enable host side implementation +# TODO: better name for the flag to enable the impl... +PSYSAPI_HOST_CPPFLAGS += -D__X86_SIM__ + +# Files for Firmware +PSYSAPI_FW_FILES = $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_process.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_process_group.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_terminal.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_buffer_set.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/param/src/ia_css_program_group_param.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/data/src/ia_css_program_group_data.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/sim/src/vied_nci_psys_system.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/sim/src/ia_css_psys_sim_data.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_program_group_manifest.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_program_manifest.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_terminal_manifest.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/vied_nci_psys_resource_model.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/psys_server_manifest/$(PSYS_SERVER_MANIFEST_VERSION)/ia_css_psys_server_manifest.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/kernel/src/ia_css_kernel_bitmap.c + +# resource model +PSYSAPI_RESOURCE_MODEL_FILES = $(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/vied_nci_psys_resource_model.c + +ifeq ($(PSYS_HAS_DUAL_CMD_CTX_SUPPORT), 1) +PSYSAPI_HOST_CPPFLAGS += -DHAS_DUAL_CMD_CTX_SUPPORT=$(PSYS_HAS_DUAL_CMD_CTX_SUPPORT) +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/resource_model/bxtB0/vied_nci_psys_resource_model.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/resource_model/bxtB0/vied_nci_psys_resource_model.c new file mode 100644 index 0000000000000..03359e378d9b6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/resource_model/bxtB0/vied_nci_psys_resource_model.c @@ -0,0 +1,322 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "vied_nci_psys_resource_model.h" + +/* + * Cell types by cell IDs + */ +const vied_nci_cell_type_ID_t vied_nci_cell_type[VIED_NCI_N_CELL_ID] = { + VIED_NCI_SP_CTRL_TYPE_ID, + VIED_NCI_SP_SERVER_TYPE_ID, + VIED_NCI_SP_SERVER_TYPE_ID, + VIED_NCI_VP_TYPE_ID, + VIED_NCI_VP_TYPE_ID, + VIED_NCI_VP_TYPE_ID, + VIED_NCI_VP_TYPE_ID, + VIED_NCI_ACC_ISA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_OSA_TYPE_ID, + VIED_NCI_GDC_TYPE_ID, + VIED_NCI_GDC_TYPE_ID +}; + +/* + * Memory types by memory IDs + */ +const vied_nci_mem_type_ID_t vied_nci_mem_type[VIED_NCI_N_MEM_ID] = { + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_GMEM_TYPE_ID,/* VMEM4 is GMEM according to vied_nci_cell_mem */ + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID +}; + +/* + * Cell mem count by cell type ID + */ +const uint16_t vied_nci_N_cell_mem[VIED_NCI_N_CELL_TYPE_ID] = { + VIED_NCI_N_SP_CTRL_MEM, + VIED_NCI_N_SP_SERVER_MEM, + VIED_NCI_N_VP_MEM, + VIED_NCI_N_ACC_PSA_MEM, + VIED_NCI_N_ACC_ISA_MEM, + VIED_NCI_N_ACC_OSA_MEM +}; + +/* + * Cell mem type by cell type ID and memory index + */ +const vied_nci_mem_type_ID_t +vied_nci_cell_mem_type[VIED_NCI_N_CELL_TYPE_ID][VIED_NCI_N_MEM_TYPE_ID] = { + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + }, + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + }, + { + VIED_NCI_GMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID + }, + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + }, + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + }, + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + }, + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + } +}; + +/* + * Ext mem ID by memory index + */ +const vied_nci_mem_ID_t +vied_nci_ext_mem[VIED_NCI_N_MEM_TYPE_ID] = { + VIED_NCI_VMEM4_ID, /* VIED_NCI_GMEM_TYPE_ID */ + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID +}; + +/* + * Cell mem ID by cell ID and memory index + */ +const vied_nci_mem_ID_t +vied_nci_cell_mem[VIED_NCI_N_CELL_ID][VIED_NCI_N_MEM_TYPE_ID] = { + { + VIED_NCI_N_MEM_ID, + VIED_NCI_DMEM0_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_DMEM1_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_DMEM2_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_VMEM4_ID, + VIED_NCI_DMEM4_ID, + VIED_NCI_VMEM0_ID, + VIED_NCI_BAMEM0_ID, + VIED_NCI_PMEM0_ID + }, + { + VIED_NCI_VMEM4_ID, + VIED_NCI_DMEM5_ID, + VIED_NCI_VMEM1_ID, + VIED_NCI_BAMEM1_ID, + VIED_NCI_PMEM1_ID + }, + { + VIED_NCI_VMEM4_ID, + VIED_NCI_DMEM6_ID, + VIED_NCI_VMEM2_ID, + VIED_NCI_BAMEM2_ID, + VIED_NCI_PMEM2_ID + }, + { + VIED_NCI_VMEM4_ID, + VIED_NCI_DMEM7_ID, + VIED_NCI_VMEM3_ID, + VIED_NCI_BAMEM3_ID, + VIED_NCI_PMEM3_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + } +}; + +/* + * Memory sizes by mem ID + */ +const uint16_t vied_nci_mem_size[VIED_NCI_N_MEM_ID] = { + VIED_NCI_VMEM0_MAX_SIZE, + VIED_NCI_VMEM1_MAX_SIZE, + VIED_NCI_VMEM2_MAX_SIZE, + VIED_NCI_VMEM3_MAX_SIZE, + VIED_NCI_VMEM4_MAX_SIZE, + VIED_NCI_BAMEM0_MAX_SIZE, + VIED_NCI_BAMEM1_MAX_SIZE, + VIED_NCI_BAMEM2_MAX_SIZE, + VIED_NCI_BAMEM3_MAX_SIZE, + VIED_NCI_DMEM0_MAX_SIZE, + VIED_NCI_DMEM1_MAX_SIZE, + VIED_NCI_DMEM2_MAX_SIZE, + VIED_NCI_DMEM3_MAX_SIZE, + VIED_NCI_DMEM4_MAX_SIZE, + VIED_NCI_DMEM5_MAX_SIZE, + VIED_NCI_DMEM6_MAX_SIZE, + VIED_NCI_DMEM7_MAX_SIZE, + VIED_NCI_PMEM0_MAX_SIZE, + VIED_NCI_PMEM1_MAX_SIZE, + VIED_NCI_PMEM2_MAX_SIZE, + VIED_NCI_PMEM3_MAX_SIZE +}; + +/* + * Memory word sizes by mem type ID + */ +const uint16_t vied_nci_mem_word_size[VIED_NCI_N_DATA_MEM_TYPE_ID] = { + VIED_NCI_GMEM_WORD_SIZE, + VIED_NCI_DMEM_WORD_SIZE, + VIED_NCI_VMEM_WORD_SIZE, + VIED_NCI_BAMEM_WORD_SIZE +}; + +/* + * Number of channels by device ID + */ +const uint16_t vied_nci_dev_chn_size[VIED_NCI_N_DEV_CHN_ID] = { + VIED_NCI_DEV_CHN_DMA_EXT0_MAX_SIZE, + VIED_NCI_DEV_CHN_GDC_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_EXT1_READ_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_EXT1_WRITE_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_INTERNAL_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_IPFD_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_ISA_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_FW_MAX_SIZE +}; diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/resource_model/bxtB0/vied_nci_psys_resource_model.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/resource_model/bxtB0/vied_nci_psys_resource_model.h new file mode 100644 index 0000000000000..1cb4e010d55d0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/resource_model/bxtB0/vied_nci_psys_resource_model.h @@ -0,0 +1,300 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __VIED_NCI_PSYS_RESOURCE_MODEL_H +#define __VIED_NCI_PSYS_RESOURCE_MODEL_H + +#include "type_support.h" +#include "storage_class.h" + +#define HAS_DFM 0 +#define NON_RELOC_RESOURCE_SUPPORT 0 +#define IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + +/* Defines for the routing bitmap in the program group manifest. + */ +#define VIED_NCI_RBM_MAX_MUX_COUNT 0 +#define VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT 0 +#define VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT 0 +#define N_PADDING_UINT8_IN_RBM_MANIFEST 2 + +/* The amount of padding bytes needed to make + * ia_css_process_s structure 64 bit aligned + */ +#define N_PADDING_UINT8_IN_PROCESS_STRUCT 4 +#define N_PADDING_UINT8_IN_PROGRAM_GROUP_MANFEST 4 + +/** + * Resource model for BXT B0 + */ + +/* + * Cell IDs + */ +typedef enum { + VIED_NCI_SP0_ID = 0, + VIED_NCI_SP1_ID, + VIED_NCI_SP2_ID, + VIED_NCI_VP0_ID, + VIED_NCI_VP1_ID, + VIED_NCI_VP2_ID, + VIED_NCI_VP3_ID, + VIED_NCI_ACC0_ID, + VIED_NCI_ACC1_ID, + VIED_NCI_ACC2_ID, + VIED_NCI_ACC3_ID, + VIED_NCI_ACC4_ID, + VIED_NCI_ACC5_ID, + VIED_NCI_ACC6_ID, + VIED_NCI_ACC7_ID, + VIED_NCI_GDC0_ID, + VIED_NCI_GDC1_ID, + VIED_NCI_N_CELL_ID +} vied_nci_cell_ID_t; + +/* + * Barrier bits (to model process group dependencies) + */ +typedef enum { + VIED_NCI_BARRIER0_ID, + VIED_NCI_BARRIER1_ID, + VIED_NCI_BARRIER2_ID, + VIED_NCI_BARRIER3_ID, + VIED_NCI_BARRIER4_ID, + VIED_NCI_BARRIER5_ID, + VIED_NCI_BARRIER6_ID, + VIED_NCI_BARRIER7_ID, + VIED_NCI_N_BARRIER_ID +} vied_nci_barrier_ID_t; + +/* + * Cell types + */ +typedef enum { + VIED_NCI_SP_CTRL_TYPE_ID = 0, + VIED_NCI_SP_SERVER_TYPE_ID, + VIED_NCI_VP_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_ISA_TYPE_ID, + VIED_NCI_ACC_OSA_TYPE_ID, + VIED_NCI_GDC_TYPE_ID, + VIED_NCI_N_CELL_TYPE_ID +} vied_nci_cell_type_ID_t; + +/* + * Memory IDs + */ +typedef enum { + VIED_NCI_VMEM0_ID = 0, + VIED_NCI_VMEM1_ID, + VIED_NCI_VMEM2_ID, + VIED_NCI_VMEM3_ID, + VIED_NCI_VMEM4_ID, + VIED_NCI_BAMEM0_ID, + VIED_NCI_BAMEM1_ID, + VIED_NCI_BAMEM2_ID, + VIED_NCI_BAMEM3_ID, + VIED_NCI_DMEM0_ID, + VIED_NCI_DMEM1_ID, + VIED_NCI_DMEM2_ID, + VIED_NCI_DMEM3_ID, + VIED_NCI_DMEM4_ID, + VIED_NCI_DMEM5_ID, + VIED_NCI_DMEM6_ID, + VIED_NCI_DMEM7_ID, + VIED_NCI_PMEM0_ID, + VIED_NCI_PMEM1_ID, + VIED_NCI_PMEM2_ID, + VIED_NCI_PMEM3_ID, + VIED_NCI_N_MEM_ID +} vied_nci_mem_ID_t; + +/* + * Memory types + */ +typedef enum { + VIED_NCI_GMEM_TYPE_ID = 0, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID +} vied_nci_mem_type_ID_t; + +/* Excluding PMEM */ +#define VIED_NCI_N_DATA_MEM_TYPE_ID (VIED_NCI_N_MEM_TYPE_ID - 1) + +#define VIED_NCI_N_SP_CTRL_MEM 2 +#define VIED_NCI_N_SP_SERVER_MEM 2 +#define VIED_NCI_N_VP_MEM 4 +#define VIED_NCI_N_ACC_PSA_MEM 0 +#define VIED_NCI_N_ACC_ISA_MEM 0 +#define VIED_NCI_N_ACC_OSA_MEM 0 + +#define VIED_NCI_N_VP_CELL 4 +#define VIED_NCI_N_ACC_CELL 8 + +/* + * Device IDs + */ +typedef enum { + VIED_NCI_DEV_CHN_DMA_EXT0_ID = 0, + VIED_NCI_DEV_CHN_GDC_ID, + VIED_NCI_DEV_CHN_DMA_EXT1_READ_ID, + VIED_NCI_DEV_CHN_DMA_EXT1_WRITE_ID, + VIED_NCI_DEV_CHN_DMA_INTERNAL_ID, + VIED_NCI_DEV_CHN_DMA_IPFD_ID, + VIED_NCI_DEV_CHN_DMA_ISA_ID, + VIED_NCI_DEV_CHN_DMA_FW_ID, + VIED_NCI_N_DEV_CHN_ID +} vied_nci_dev_chn_ID_t; + +typedef enum { + DFM_IS_NOT_AVAILABLE +} vied_nci_dev_dfm_id_t; + +#define VIED_NCI_N_DEV_DFM_ID 0 + + +/* + * Memory size (previously in vied_nci_psys_system.c) + * VMEM: in words, 64 Byte per word. + * BAMEM: in words, 64 Byte per word + * DMEM: in words, 4 Byte per word. + * PMEM: in words, 64 Byte per word. + */ +#define VIED_NCI_GMEM_WORD_SIZE 64 +#define VIED_NCI_DMEM_WORD_SIZE 4 +#define VIED_NCI_VMEM_WORD_SIZE 64 +#define VIED_NCI_BAMEM_WORD_SIZE 64 + +#define VIED_NCI_VMEM0_MAX_SIZE (0x0800) +#define VIED_NCI_VMEM1_MAX_SIZE (0x0800) +#define VIED_NCI_VMEM2_MAX_SIZE (0x0800) +#define VIED_NCI_VMEM3_MAX_SIZE (0x0800) +#define VIED_NCI_VMEM4_MAX_SIZE (0x0800) +#define VIED_NCI_BAMEM0_MAX_SIZE (0x0400) +#define VIED_NCI_BAMEM1_MAX_SIZE (0x0400) +#define VIED_NCI_BAMEM2_MAX_SIZE (0x0400) +#define VIED_NCI_BAMEM3_MAX_SIZE (0x0400) +#define VIED_NCI_DMEM0_MAX_SIZE (0x4000) +#define VIED_NCI_DMEM1_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM2_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM3_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM4_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM5_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM6_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM7_MAX_SIZE (0x1000) +#define VIED_NCI_PMEM0_MAX_SIZE (0x0500) +#define VIED_NCI_PMEM1_MAX_SIZE (0x0500) +#define VIED_NCI_PMEM2_MAX_SIZE (0x0500) +#define VIED_NCI_PMEM3_MAX_SIZE (0x0500) + +/* + * Number of channels per device + */ +#define VIED_NCI_DEV_CHN_DMA_EXT0_MAX_SIZE (30) +#define VIED_NCI_DEV_CHN_GDC_MAX_SIZE (4) +#define VIED_NCI_DEV_CHN_DMA_EXT1_READ_MAX_SIZE (30) +#define VIED_NCI_DEV_CHN_DMA_EXT1_WRITE_MAX_SIZE (20) +#define VIED_NCI_DEV_CHN_DMA_INTERNAL_MAX_SIZE (2) +#define VIED_NCI_DEV_CHN_DMA_IPFD_MAX_SIZE (5) +#define VIED_NCI_DEV_CHN_DMA_ISA_MAX_SIZE (2) +#define VIED_NCI_DEV_CHN_DMA_FW_MAX_SIZE (1) + +/* + * Storage of the resource and resource type enumerators + */ +#define VIED_NCI_RESOURCE_ID_BITS 8 +typedef uint8_t vied_nci_resource_id_t; + +#define VIED_NCI_RESOURCE_SIZE_BITS 16 +typedef uint16_t vied_nci_resource_size_t; + +#define VIED_NCI_RESOURCE_BITMAP_BITS 32 +typedef uint32_t vied_nci_resource_bitmap_t; + +#define IA_CSS_PROCESS_INVALID_DEPENDENCY ((vied_nci_resource_id_t)(-1)) +#define IA_CSS_PROCESS_INVALID_OFFSET ((vied_nci_resource_size_t)(-1)) +#define IA_CSS_PROCESS_MAX_CELLS 1 + +/* + * Resource specifications + * Note that the FAS uses the terminology local/remote memory. In the PSYS API, + * these are called internal/external memory. + */ + +/* resource spec for internal (local) memory */ +struct vied_nci_resource_spec_int_mem_s { + vied_nci_resource_id_t type_id; + vied_nci_resource_size_t size; + vied_nci_resource_size_t offset; +}; + +typedef struct vied_nci_resource_spec_int_mem_s + vied_nci_resource_spec_int_mem_t; + +/* resource spec for external (remote) memory */ +struct vied_nci_resource_spec_ext_mem_s { + vied_nci_resource_id_t type_id; + vied_nci_resource_size_t size; + vied_nci_resource_size_t offset; +}; + +typedef struct vied_nci_resource_spec_ext_mem_s + vied_nci_resource_spec_ext_mem_t; + +/* resource spec for device channel */ +struct vied_nci_resource_spec_dev_chn_s { + vied_nci_resource_id_t type_id; + vied_nci_resource_size_t size; + vied_nci_resource_size_t offset; +}; + +typedef struct vied_nci_resource_spec_dev_chn_s + vied_nci_resource_spec_dev_chn_t; + +/* resource spec for all contiguous resources */ +struct vied_nci_resource_spec_s { + vied_nci_resource_spec_int_mem_t int_mem[VIED_NCI_N_MEM_TYPE_ID]; + vied_nci_resource_spec_ext_mem_t ext_mem[VIED_NCI_N_DATA_MEM_TYPE_ID]; + vied_nci_resource_spec_dev_chn_t dev_chn[VIED_NCI_N_DEV_CHN_ID]; +}; + +typedef struct vied_nci_resource_spec_s vied_nci_resource_spec_t; + +#ifndef PIPE_GENERATION + +extern const vied_nci_cell_type_ID_t vied_nci_cell_type[VIED_NCI_N_CELL_ID]; +extern const vied_nci_mem_type_ID_t vied_nci_mem_type[VIED_NCI_N_MEM_ID]; +extern const uint16_t vied_nci_N_cell_mem[VIED_NCI_N_CELL_TYPE_ID]; +extern const vied_nci_mem_type_ID_t + vied_nci_cell_mem_type[VIED_NCI_N_CELL_TYPE_ID][VIED_NCI_N_MEM_TYPE_ID]; +extern const vied_nci_mem_ID_t + vied_nci_ext_mem[VIED_NCI_N_MEM_TYPE_ID]; +extern const vied_nci_mem_ID_t + vied_nci_cell_mem[VIED_NCI_N_CELL_ID][VIED_NCI_N_MEM_TYPE_ID]; +extern const uint16_t vied_nci_mem_size[VIED_NCI_N_MEM_ID]; +extern const uint16_t vied_nci_mem_word_size[VIED_NCI_N_DATA_MEM_TYPE_ID]; +extern const uint16_t vied_nci_dev_chn_size[VIED_NCI_N_DEV_CHN_ID]; + +STORAGE_CLASS_INLINE +uint32_t vied_nci_mem_is_ext_type(const vied_nci_mem_type_ID_t mem_type_id) +{ + return((mem_type_id == VIED_NCI_GMEM_TYPE_ID)); +} + +#endif /* PIPE_GENERATION */ + +#endif /* __VIED_NCI_PSYS_RESOURCE_MODEL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_data.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_data.h new file mode 100644 index 0000000000000..5b053a27686bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_data.h @@ -0,0 +1,50 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_SIM_DATA_H +#define __IA_CSS_PSYS_SIM_DATA_H + +/*! Set the seed if the random number generator + + @param seed[in] Random number generator seed + */ +extern void ia_css_psys_ran_set_seed(const unsigned int seed); + +/*! Generate a random number of a specified bit depth + + @param bit_depth[in] The number of bits of the random output + + @return out, weight(out) <= bit_depth, 0 on error + */ +extern unsigned int ia_css_psys_ran_var(const unsigned int bit_depth); + +/*! Generate a random number of a specified range + + @param range[in] The range of the random output + + @return 0 <= out < range, 0 on error + */ +extern unsigned int ia_css_psys_ran_val(const unsigned int range); + +/*! Generate a random number in a specified interval + + @param lo[in] The lower bound of the random output range + @param hi[in] The higher bound of the random output range + + @return lo <= out < hi, 0 on error + */ +extern unsigned int ia_css_psys_ran_interval(const unsigned int lo, + const unsigned int hi); + +#endif /* __IA_CSS_PSYS_SIM_DATA_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_storage_class.h new file mode 100644 index 0000000000000..61095257ec550 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_storage_class.h @@ -0,0 +1,28 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_SIM_STORAGE_CLASS_H +#define __IA_CSS_PSYS_SIM_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __IA_CSS_PSYS_SIM_INLINE__ +#define IA_CSS_PSYS_SIM_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PSYS_SIM_STORAGE_CLASS_C +#else +#define IA_CSS_PSYS_SIM_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PSYS_SIM_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PSYS_SIM_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_trace.h new file mode 100644 index 0000000000000..423ff19802707 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_trace.h @@ -0,0 +1,95 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_SIM_TRACE_H +#define __IA_CSS_PSYS_SIM_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_SIM_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_SIM_TRACING_OVERRIDE)) + #define PSYS_SIM_TRACE_LEVEL_CONFIG PSYS_SIM_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_SIM_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_SIM_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_SIM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_SIM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_SIM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_SIM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_SIM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_SIM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_SIM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_SIM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_SIM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_SIM_TRACE_METHOD PSYSAPI_TRACE_METHOD + #define PSYSAPI_SIM_TRACE_LEVEL_ASSERT PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_SIM_TRACE_LEVEL_ERROR PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_SIM_TRACE_LEVEL_WARNING PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_SIM_TRACE_LEVEL_INFO PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_SIM_TRACE_LEVEL_DEBUG PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_SIM_TRACE_LEVEL_VERBOSE PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_SIM_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/vied_nci_psys_system_global.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/vied_nci_psys_system_global.h new file mode 100644 index 0000000000000..ca4ad2a206d42 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/interface/vied_nci_psys_system_global.h @@ -0,0 +1,180 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __VIED_NCI_PSYS_SYSTEM_GLOBAL_H +#define __VIED_NCI_PSYS_SYSTEM_GLOBAL_H + +#include +#include "ia_css_base_types.h" +#include "ia_css_psys_sim_storage_class.h" +#include "vied_nci_psys_resource_model.h" + +/* + * Key system types + */ +/* Subsystem internal physical address */ +#define VIED_ADDRESS_BITS 32 + +/* typedef uint32_t vied_address_t; */ + +/* Subsystem internal virtual address */ + +/* Subsystem internal data bus */ +#define VIED_DATA_BITS 32 +typedef uint32_t vied_data_t; + +#define VIED_NULL ((vied_vaddress_t)0) + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bit_mask( + const unsigned int index); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_set( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_clear( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_bitmap_empty( + const vied_nci_resource_bitmap_t bitmap); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_bitmap_set( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_bit_set_in_bitmap( + const vied_nci_resource_bitmap_t bitmap, + const unsigned int index); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_bitmap_clear( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +int vied_nci_bitmap_compute_weight( + const vied_nci_resource_bitmap_t bitmap); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_union( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_intersection( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_xor( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_set_unique( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitfield_mask( + const unsigned int position, + const unsigned int size); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_set_bitfield( +const vied_nci_resource_bitmap_t bitmap, +const unsigned int index, +const unsigned int size); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bit_mask_set_unique( + const vied_nci_resource_bitmap_t bitmap, + const unsigned int index); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_cell_bit_mask( + const vied_nci_cell_ID_t cell_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_barrier_bit_mask( + const vied_nci_barrier_ID_t barrier_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_cell_type_ID_t vied_nci_cell_get_type( + const vied_nci_cell_ID_t cell_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_mem_type_ID_t vied_nci_mem_get_type( + const vied_nci_mem_ID_t mem_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +uint16_t vied_nci_mem_get_size( + const vied_nci_mem_ID_t mem_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +uint16_t vied_nci_dev_chn_get_size( + const vied_nci_dev_chn_ID_t dev_chn_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_cell_of_type( + const vied_nci_cell_ID_t cell_id, + const vied_nci_cell_type_ID_t cell_type_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_mem_of_type( + const vied_nci_mem_ID_t mem_id, + const vied_nci_mem_type_ID_t mem_type_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_cell_mem_of_type( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index, + const vied_nci_mem_type_ID_t mem_type_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_has_cell_mem_of_id( + const vied_nci_cell_ID_t cell_id, + const vied_nci_mem_ID_t mem_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +uint16_t vied_nci_cell_get_mem_count( + const vied_nci_cell_ID_t cell_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_mem_type_ID_t vied_nci_cell_get_mem_type( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_mem_ID_t vied_nci_cell_get_mem( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_mem_type_ID_t vied_nci_cell_type_get_mem_type( + const vied_nci_cell_type_ID_t cell_type_id, + const uint16_t mem_index); + +#ifdef __IA_CSS_PSYS_SIM_INLINE__ +#include "psys_system_global_impl.h" +#endif /* __IA_CSS_PSYS_SIM_INLINE__ */ + +#endif /* __VIED_NCI_PSYS_SYSTEM_GLOBAL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/src/ia_css_psys_sim_data.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/src/ia_css_psys_sim_data.c new file mode 100644 index 0000000000000..6dccac8238719 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/src/ia_css_psys_sim_data.c @@ -0,0 +1,91 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include + +#include "ia_css_psys_sim_trace.h" + +static unsigned int ia_css_psys_ran_seed; + +void ia_css_psys_ran_set_seed(const unsigned int seed) +{ + ia_css_psys_ran_seed = seed; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "ia_css_psys_ran_set_seed(): enter:\n"); + +} + +static unsigned int ia_css_psys_ran_int (void) +{ + ia_css_psys_ran_seed = 1664525UL * ia_css_psys_ran_seed + 1013904223UL; + return ia_css_psys_ran_seed; +} + +unsigned int ia_css_psys_ran_var(const unsigned int bit_depth) +{ + unsigned int out; + unsigned int tmp; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, "ia_css_psys_ran_var(): enter:\n"); + + tmp = ia_css_psys_ran_int(); + + if (bit_depth > 32) + out = tmp; + else if (bit_depth == 0) + out = 0; + else + out = (unsigned short)(tmp >> (32 - bit_depth)); + + return out; +} + +unsigned int ia_css_psys_ran_val(const unsigned int range) +{ + unsigned int out; + unsigned int tmp; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, "ia_css_psys_ran_val(): enter:\n"); + + tmp = ia_css_psys_ran_int(); + + if (range > 1) + out = tmp % range; + else + out = 0; + + return out; +} + +unsigned int ia_css_psys_ran_interval(const unsigned int lo, + const unsigned int hi) +{ + unsigned int out; + unsigned int tmp; + unsigned int range = hi - lo; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "ia_css_psys_ran_interval(): enter:\n"); + + tmp = ia_css_psys_ran_int(); + + if ((range > 1) && (lo < hi)) + out = lo + (tmp % range); + else + out = 0; + + return out; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/src/psys_system_global_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/src/psys_system_global_impl.h new file mode 100644 index 0000000000000..ff51175548ec0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/src/psys_system_global_impl.h @@ -0,0 +1,485 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PSYS_SYSTEM_GLOBAL_IMPL_H +#define __PSYS_SYSTEM_GLOBAL_IMPL_H + +#include + +#include "ia_css_psys_sim_trace.h" +#include + +/* Use vied_bits instead, however for test purposes we uses explicit type + * checking + */ +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bit_mask( + const unsigned int index) +{ + vied_nci_resource_bitmap_t bit_mask = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, "vied_nci_bit_mask(): enter:\n"); + + if (index < VIED_NCI_RESOURCE_BITMAP_BITS) + bit_mask = (vied_nci_resource_bitmap_t)1 << index; + + return bit_mask; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_set( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask) +{ + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, "vied_nci_bitmap_set(): enter:\n"); + +/* + assert(vied_nci_is_bitmap_one_hot(bit_mask)); +*/ + return bitmap | bit_mask; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_clear( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask) +{ + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bitmap_clear(): enter:\n"); + +/* + assert(vied_nci_is_bitmap_one_hot(bit_mask)); +*/ + return bitmap & (~bit_mask); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitfield_mask( + const unsigned int position, + const unsigned int size) +{ + vied_nci_resource_bitmap_t bit_mask = 0; + vied_nci_resource_bitmap_t ones = (vied_nci_resource_bitmap_t)-1; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bitfield_mask(): enter:\n"); + + if (position < VIED_NCI_RESOURCE_BITMAP_BITS) + bit_mask = (ones >> (sizeof(vied_nci_resource_bitmap_t) - size)) << position; + + return bit_mask; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_set_bitfield( + const vied_nci_resource_bitmap_t bitmap, + const unsigned int index, + const unsigned int size) +{ + vied_nci_resource_bitmap_t ret = 0; + vied_nci_resource_bitmap_t bit_mask = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bit_mask_set_bitfield(): enter:\n"); + + bit_mask = vied_nci_bitfield_mask(index, size); + ret = vied_nci_bitmap_set(bitmap, bit_mask); + + return ret; +} + + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_set_unique( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask) +{ + vied_nci_resource_bitmap_t ret = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bitmap_set_unique(): enter:\n"); + + if ((bitmap & bit_mask) == 0) + ret = bitmap | bit_mask; + + return ret; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bit_mask_set_unique( + const vied_nci_resource_bitmap_t bitmap, + const unsigned int index) +{ + vied_nci_resource_bitmap_t ret = 0; + vied_nci_resource_bitmap_t bit_mask; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bit_mask_set_unique(): enter:\n"); + + bit_mask = vied_nci_bit_mask(index); + + if (((bitmap & bit_mask) == 0) && (bit_mask != 0)) + ret = bitmap | bit_mask; + + return ret; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_bitmap_empty( + const vied_nci_resource_bitmap_t bitmap) +{ + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_bitmap_empty(): enter:\n"); + + return (bitmap == 0); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_bitmap_set( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask) +{ + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_bitmap_set(): enter:\n"); + +/* + assert(vied_nci_is_bitmap_one_hot(bit_mask)); +*/ + return !vied_nci_is_bitmap_clear(bitmap, bit_mask); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_bit_set_in_bitmap( + const vied_nci_resource_bitmap_t bitmap, + const unsigned int index) +{ + + vied_nci_resource_bitmap_t bitmask; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_bit_set_in_bitmap(): enter:\n"); + bitmask = vied_nci_bit_mask(index); + return vied_nci_is_bitmap_set(bitmap, bitmask); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_bitmap_clear( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask) +{ + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_bitmap_clear(): enter:\n"); + +/* + assert(vied_nci_is_bitmap_one_hot(bit_mask)); +*/ + return ((bitmap & bit_mask) == 0); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +int vied_nci_bitmap_compute_weight( + const vied_nci_resource_bitmap_t bitmap) +{ + vied_nci_resource_bitmap_t loc_bitmap = bitmap; + int weight = 0; + int i; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bitmap_compute_weight(): enter:\n"); + + /* Do not need the iterator "i" */ + for (i = 0; (i < VIED_NCI_RESOURCE_BITMAP_BITS) && + (loc_bitmap != 0); i++) { + weight += loc_bitmap & 0x01; + loc_bitmap >>= 1; + } + + return weight; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_union( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bitmap_union(): enter:\n"); + return (bitmap0 | bitmap1); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_intersection( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "ia_css_kernel_bitmap_intersection(): enter:\n"); + return (bitmap0 & bitmap1); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_xor( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, "vied_nci_bitmap_xor(): enter:\n"); + return (bitmap0 ^ bitmap1); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_cell_bit_mask( + const vied_nci_cell_ID_t cell_id) +{ + vied_nci_resource_bitmap_t bit_mask = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_bit_mask(): enter:\n"); + + if ((cell_id < VIED_NCI_N_CELL_ID) && + (cell_id < VIED_NCI_RESOURCE_BITMAP_BITS)) { + bit_mask = (vied_nci_resource_bitmap_t)1 << cell_id; + } + return bit_mask; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_barrier_bit_mask( + const vied_nci_barrier_ID_t barrier_id) +{ + vied_nci_resource_bitmap_t bit_mask = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_barrier_bit_mask(): enter:\n"); + + if ((barrier_id < VIED_NCI_N_BARRIER_ID) && + ((barrier_id + VIED_NCI_N_CELL_ID) < VIED_NCI_RESOURCE_BITMAP_BITS)) { + bit_mask = (vied_nci_resource_bitmap_t)1 << + (barrier_id + VIED_NCI_N_CELL_ID); + } + return bit_mask; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_cell_type_ID_t vied_nci_cell_get_type( + const vied_nci_cell_ID_t cell_id) +{ + vied_nci_cell_type_ID_t cell_type = VIED_NCI_N_CELL_TYPE_ID; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_get_type(): enter:\n"); + + if (cell_id < VIED_NCI_N_CELL_ID) { + cell_type = vied_nci_cell_type[cell_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_SIM, WARNING, + "vied_nci_cell_get_type(): invalid argument\n"); + } + + return cell_type; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_mem_type_ID_t vied_nci_mem_get_type( + const vied_nci_mem_ID_t mem_id) +{ + vied_nci_mem_type_ID_t mem_type = VIED_NCI_N_MEM_TYPE_ID; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_mem_get_type(): enter:\n"); + + if (mem_id < VIED_NCI_N_MEM_ID) { + mem_type = vied_nci_mem_type[mem_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_SIM, WARNING, + "vied_nci_mem_get_type(): invalid argument\n"); + } + + return mem_type; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +uint16_t vied_nci_mem_get_size( + const vied_nci_mem_ID_t mem_id) +{ + uint16_t mem_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_mem_get_size(): enter:\n"); + + if (mem_id < VIED_NCI_N_MEM_ID) { + mem_size = vied_nci_mem_size[mem_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_SIM, WARNING, + "vied_nci_mem_get_size(): invalid argument\n"); + } + + return mem_size; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +uint16_t vied_nci_dev_chn_get_size( + const vied_nci_dev_chn_ID_t dev_chn_id) +{ + uint16_t dev_chn_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_dev_chn_get_size(): enter:\n"); + + if (dev_chn_id < VIED_NCI_N_DEV_CHN_ID) { + dev_chn_size = vied_nci_dev_chn_size[dev_chn_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_SIM, WARNING, + "vied_nci_dev_chn_get_size(): invalid argument\n"); + } + + return dev_chn_size; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_cell_of_type( + const vied_nci_cell_ID_t cell_id, + const vied_nci_cell_type_ID_t cell_type_id) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_cell_of_type(): enter:\n"); + + return ((vied_nci_cell_get_type(cell_id) == + cell_type_id) && (cell_type_id != + VIED_NCI_N_CELL_TYPE_ID)); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_mem_of_type( + const vied_nci_mem_ID_t mem_id, + const vied_nci_mem_type_ID_t mem_type_id) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_mem_of_type(): enter:\n"); + + return ((vied_nci_mem_get_type(mem_id) == mem_type_id) && + (mem_type_id != VIED_NCI_N_MEM_TYPE_ID)); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_cell_mem_of_type( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index, + const vied_nci_mem_type_ID_t mem_type_id) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_cell_mem_of_type(): enter:\n"); + + return ((vied_nci_cell_get_mem_type(cell_id, mem_index) == mem_type_id) + && (mem_type_id != VIED_NCI_N_MEM_TYPE_ID)); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_has_cell_mem_of_id( + const vied_nci_cell_ID_t cell_id, + const vied_nci_mem_ID_t mem_id) +{ + uint16_t mem_index; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_has_cell_mem_of_id(): enter:\n"); + + for (mem_index = 0; mem_index < VIED_NCI_N_MEM_TYPE_ID; mem_index++) { + if ((vied_nci_cell_get_mem(cell_id, mem_index) == mem_id) && + (mem_id != VIED_NCI_N_MEM_ID)) { + break; + } + } + + return (mem_index < VIED_NCI_N_MEM_TYPE_ID); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +uint16_t vied_nci_cell_get_mem_count( + const vied_nci_cell_ID_t cell_id) +{ + uint16_t mem_count = 0; + vied_nci_cell_type_ID_t cell_type; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_get_mem_count(): enter:\n"); + + cell_type = vied_nci_cell_get_type(cell_id); + + if (cell_type < VIED_NCI_N_CELL_TYPE_ID) + mem_count = vied_nci_N_cell_mem[cell_type]; + + return mem_count; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_mem_type_ID_t vied_nci_cell_get_mem_type( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index) +{ + vied_nci_mem_type_ID_t mem_type = VIED_NCI_N_MEM_TYPE_ID; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_get_mem_type(): enter:\n"); + + if ((cell_id < VIED_NCI_N_CELL_ID) && + (mem_index < VIED_NCI_N_MEM_TYPE_ID)) { + mem_type = vied_nci_cell_mem_type[ + vied_nci_cell_get_type(cell_id)][mem_index]; + } + + return mem_type; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_mem_ID_t vied_nci_cell_get_mem( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index) +{ + vied_nci_mem_ID_t mem_id = VIED_NCI_N_MEM_ID; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_get_mem(): enter:\n"); + + if ((cell_id < VIED_NCI_N_CELL_ID) && + (mem_index < VIED_NCI_N_MEM_TYPE_ID)) { + mem_id = vied_nci_cell_mem[cell_id][mem_index]; + } + + return mem_id; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_mem_type_ID_t vied_nci_cell_type_get_mem_type( + const vied_nci_cell_type_ID_t cell_type_id, + const uint16_t mem_index) +{ + vied_nci_mem_type_ID_t mem_type = VIED_NCI_N_MEM_TYPE_ID; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_type_get_mem_type(): enter:\n"); + + if ((cell_type_id < VIED_NCI_N_CELL_TYPE_ID) + && (mem_index < VIED_NCI_N_MEM_TYPE_ID)) { + mem_type = vied_nci_cell_mem_type[cell_type_id][mem_index]; + } + + return mem_type; +} + +#endif /* __PSYS_SYSTEM_GLOBAL_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/src/vied_nci_psys_system.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/src/vied_nci_psys_system.c new file mode 100644 index 0000000000000..2cb52c1e0e9c9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/sim/src/vied_nci_psys_system.c @@ -0,0 +1,29 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_sim_storage_class.h" + +/* + * Functions to possibly inline + */ + +#ifdef __IA_CSS_PSYS_SIM_INLINE__ +STORAGE_CLASS_INLINE int +__ia_css_psys_system_global_avoid_warning_on_empty_file(void) +{ + return 0; +} +#else /* __IA_CSS_PSYS_SIM_INLINE__ */ +#include "psys_system_global_impl.h" +#endif /* __IA_CSS_PSYS_SIM_INLINE__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_manifest_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_manifest_types.h new file mode 100644 index 0000000000000..4a2f96e9405e8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_manifest_types.h @@ -0,0 +1,102 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_MANIFEST_TYPES_H +#define __IA_CSS_PSYS_MANIFEST_TYPES_H + +/*! \file */ + +/** @file ia_css_psys_manifest_types.h + * + * The types belonging to the terminal/program/ + * program group manifest static module + */ + +#include +#include "vied_nci_psys_resource_model.h" + + +/* This value is used in the manifest to indicate that the resource + * offset field must be ignored and the resource is relocatable + */ +#define IA_CSS_PROGRAM_MANIFEST_RESOURCE_OFFSET_IS_RELOCATABLE ((vied_nci_resource_size_t)(-1)) + +/* + * Connection type defining the interface source/sink + * + * Note that the connection type does not define the + * real-time configuration of the system, i.e. it + * does not describe whether a source and sink + * program group or sub-system operate synchronously + * that is a program script property {online, offline} + * (see FAS 5.16.3) + */ +#define IA_CSS_CONNECTION_BITMAP_BITS 8 +typedef uint8_t ia_css_connection_bitmap_t; + +#define IA_CSS_CONNECTION_TYPE_BITS 32 +typedef enum ia_css_connection_type { + /**< The terminal is in DDR */ + IA_CSS_CONNECTION_MEMORY = 0, + /**< The terminal is a (watermark) queued stream over DDR */ + IA_CSS_CONNECTION_MEMORY_STREAM, + /* The terminal is a device port */ + IA_CSS_CONNECTION_STREAM, + IA_CSS_N_CONNECTION_TYPES +} ia_css_connection_type_t; + +#define IA_CSS_PROGRAM_TYPE_BITS 32 +typedef enum ia_css_program_type { + IA_CSS_PROGRAM_TYPE_SINGULAR = 0, + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB, + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER, + IA_CSS_PROGRAM_TYPE_PARALLEL_SUB, + IA_CSS_PROGRAM_TYPE_PARALLEL_SUPER, + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB, + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER, +/* + * Future extension; A bitmap coding starts making more sense + * + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB_PARALLEL_SUB, + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB_PARALLEL_SUPER, + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER_PARALLEL_SUB, + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER_PARALLEL_SUPER, + */ + IA_CSS_N_PROGRAM_TYPES +} ia_css_program_type_t; + +#define IA_CSS_PROGRAM_GROUP_ID_BITS 32 +typedef uint32_t ia_css_program_group_ID_t; +#define IA_CSS_PROGRAM_ID_BITS 32 +typedef uint32_t ia_css_program_ID_t; + +#define IA_CSS_PROGRAM_INVALID_ID ((uint32_t)(-1)) +#define IA_CSS_PROGRAM_GROUP_INVALID_ID ((uint32_t)(-1)) + +typedef struct ia_css_program_group_manifest_s +ia_css_program_group_manifest_t; +typedef struct ia_css_program_manifest_s +ia_css_program_manifest_t; +typedef struct ia_css_data_terminal_manifest_s +ia_css_data_terminal_manifest_t; + +/* ============ Program Control Init Terminal Manifest - START ============ */ +typedef struct ia_css_program_control_init_manifest_program_desc_s + ia_css_program_control_init_manifest_program_desc_t; + +typedef struct ia_css_program_control_init_terminal_manifest_s + ia_css_program_control_init_terminal_manifest_t; +/* ============ Program Control Init Terminal Manifest - END ============ */ + +#endif /* __IA_CSS_PSYS_MANIFEST_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.h new file mode 100644 index 0000000000000..ee8321ea1f12b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.h @@ -0,0 +1,311 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_H +#define __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_H + +#include "ia_css_psys_static_storage_class.h" + +/*! \file */ + +/** @file ia_css_psys_program_group_manifest.h + * + * Define the methods on the program group manifest object that are not part of + * a single interface + */ + +#include + +#include /* uint8_t */ + +#include + +#include + +#include /* ia_css_kernel_bitmap_t */ +#include "ia_css_terminal_manifest.h" +#include "ia_css_rbm_manifest_types.h" + +#define IA_CSS_PROGRAM_GROUP_INVALID_ALIGNMENT ((uint8_t)(-1)) + +/*! Get the stored size of the program group manifest object + + @param manifest[in] program group manifest object + + @return size, 0 on invalid argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +size_t ia_css_program_group_manifest_get_size( + const ia_css_program_group_manifest_t *manifest); + +/*! Get the program group ID of the program group manifest object + + @param manifest[in] program group manifest object + + @return program group ID, IA_CSS_PROGRAM_GROUP_INVALID_ID on invalid argument +*/ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_program_group_ID_t +ia_css_program_group_manifest_get_program_group_ID( + const ia_css_program_group_manifest_t *manifest); + +/*! Set the program group ID of the program group manifest object + + @param manifest[in] program group manifest object + + @param program group ID + + @return 0 on success, -1 on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +int ia_css_program_group_manifest_set_program_group_ID( + ia_css_program_group_manifest_t *manifest, + ia_css_program_group_ID_t id); + +/*! Get the storage alignment constraint of the program group binary data + + @param manifest[in] program group manifest object + + @return alignment, IA_CSS_PROGRAM_GROUP_INVALID_ALIGNMENT on invalid manifest + argument +*/ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +uint8_t ia_css_program_group_manifest_get_alignment( + const ia_css_program_group_manifest_t *manifest); + +/*! Set the storage alignment constraint of the program group binary data + + @param manifest[in] program group manifest object + @param alignment[in] alignment desired + + @return < 0 on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +int ia_css_program_group_manifest_set_alignment( + ia_css_program_group_manifest_t *manifest, + const uint8_t alignment); + +/*! Get the kernel enable bitmap of the program group + + @param manifest[in] program group manifest object + + @return bitmap, 0 on invalid manifest argument + */ +extern ia_css_kernel_bitmap_t +ia_css_program_group_manifest_get_kernel_bitmap( + const ia_css_program_group_manifest_t *manifest); + +/*! Set the kernel enable bitmap of the program group + + @param manifest[in] program group manifest object + @param kernel bitmap[in] kernel enable bitmap + + @return < 0 on invalid manifest argument + */ +extern int ia_css_program_group_manifest_set_kernel_bitmap( + ia_css_program_group_manifest_t *manifest, + const ia_css_kernel_bitmap_t bitmap); + +/*! Get the number of programs in the program group manifest object + + @param manifest[in] program group manifest object + + @return program count, 0 on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +uint8_t ia_css_program_group_manifest_get_program_count( + const ia_css_program_group_manifest_t *manifest); + +/*! Get the number of terminals in the program group manifest object + + @param manifest[in] program group manifest object + + @return terminal count, 0 on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +uint8_t ia_css_program_group_manifest_get_terminal_count( + const ia_css_program_group_manifest_t *manifest); + +/*! Get the (pointer to) private data blob in the manifest + + @param manifest[in] program group manifest object + + @return private data blob, NULL on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +void *ia_css_program_group_manifest_get_private_data( + const ia_css_program_group_manifest_t *manifest); + +/*! Get the (pointer to) routing bitmap (rbm) manifest + + @param manifest[in] program group manifest object + + @return rbm manifest, NULL on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_rbm_manifest_t * +ia_css_program_group_manifest_get_rbm_manifest( + const ia_css_program_group_manifest_t *manifest); + +/*! Get the (pointer to) indexed program manifest in the program group manifest + * object + + @param manifest[in] program group manifest object + @param program_index[in] index of the program manifest object + + @return program manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_program_manifest_t * +ia_css_program_group_manifest_get_prgrm_mnfst( + const ia_css_program_group_manifest_t *manifest, + const unsigned int program_index); + +/*! Get the (pointer to) indexed terminal manifest in the program group + * manifest object + + @param manifest[in] program group manifest object + @param program_index[in] index of the terminal manifest object + + @return terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_terminal_manifest_t * +ia_css_program_group_manifest_get_term_mnfst( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! Get the (pointer to) indexed data terminal manifest in the program group + * manifest object + + @param manifest[in] program group manifest object + @param program_index[in] index of the terminal manifest object + + @return data terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_data_terminal_manifest_t * +ia_css_program_group_manifest_get_data_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! Get the (pointer to) indexed parameter terminal manifest in the program + * group manifest object + + @param manifest[in] program group manifest object + @param program_index[in] index of the terminal manifest object + + @return parameter terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_param_terminal_manifest_t * +ia_css_program_group_manifest_get_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! Get the (pointer to) indexed spatial param terminal manifest in the program + * group manifest object + + @param manifest[in] program group manifest object + @param program_index[in] index of the terminal manifest object + + @return spatial param terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_spatial_param_terminal_manifest_t * +ia_css_program_group_manifest_get_spatial_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! Get the (pointer to) indexed sliced param terminal manifest in the program + * group manifest object + + @param manifest[in] program group manifest object + @param program_index[in] index of the terminal manifest object + + @return sliced param terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_sliced_param_terminal_manifest_t * +ia_css_program_group_manifest_get_sliced_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! Get the (pointer to) indexed program terminal manifest in the program group + * manifest object + + @parammanifest[in]program group manifest object + @paramprogram_index[in]index of the terminal manifest object + + @return program terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_program_terminal_manifest_t * +ia_css_program_group_manifest_get_program_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! initialize program group manifest + + @param manifest[in] program group manifest object + @param program_count[in] number of programs. + @param terminal_count[in] number of terminals. + @param program_deps[in] program dependencies for programs in pg. + @param terminal_deps[in] terminal dependencies for programs in pg. + @param terminal_type[in] array of terminal types, binary specific + static frame data + @param cached_in_param_section_count[in]Number of parameter terminal sections + @param cached_out_param_section_count[in] Number of parameter out terminal + @param spatial_param_section_count[in] Array[spatial_terminal_count] + with sections per cached out + terminal + @param sliced_in_param_section_count[in] Array[sliced_in_terminal_count] + with sections per sliced in + terminal + @param sliced_out_param_section_count[in] Array[sliced_out_terminal_count] + with sections per sliced out + terminal + @param fragment_param_section_count[in] Number of fragment parameter + sections of the program init + terminal, + @param kernel_fragment_seq_count[in] Number of kernel fragment + seqence info. + @param progctrlinit_load_section_counts[in] Number of progctrinit load + sections (size of array is program_count) + @param progctrlinit_connect_section_counts[in] Number of progctrinit connect + sections (size of array is program_count) + @return none; + */ +extern void ia_css_program_group_manifest_init( + ia_css_program_group_manifest_t *blob, + const uint8_t program_count, + const uint8_t terminal_count, + const uint8_t *program_dependencies, + const uint8_t *terminal_dependencies, + const ia_css_terminal_type_t *terminal_type, + const uint16_t cached_in_param_section_count, + const uint16_t cached_out_param_section_count, + const uint16_t *spatial_param_section_count, + const uint16_t fragment_param_section_count, + const uint16_t *sliced_in_param_section_count, + const uint16_t *sliced_out_param_section_count, + const uint16_t kernel_fragment_seq_count, + const uint16_t *progctrlinit_load_section_counts, + const uint16_t *progctrlinit_connect_section_counts); + +#ifdef __IA_CSS_PSYS_STATIC_INLINE__ +#include "ia_css_psys_program_group_manifest_impl.h" +#endif /* __IA_CSS_PSYS_STATIC_INLINE__ */ + +#endif /* __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.hsys.user.h new file mode 100644 index 0000000000000..ce802ff5dd8d3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.hsys.user.h @@ -0,0 +1,69 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_HSYS_USER_H +#define __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_program_group_manifest.hsys.user.h + * + * Define the methods on the program group manifest object: Hsys user interface + */ + +#include + +#include /* bool */ + +/*! Print the program group manifest object to file/stream + + @param manifest[in] program group manifest object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_program_group_manifest_print( + const ia_css_program_group_manifest_t *manifest, + void *fid); + +/*! Read the program group manifest object from file/stream + + @param fid[in] file/stream handle + + @return NULL on error + */ +extern ia_css_program_group_manifest_t *ia_css_program_group_manifest_read( + void *fid); + +/*! Write the program group manifest object to file/stream + + @param manifest[in] program group manifest object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_program_group_manifest_write( + const ia_css_program_group_manifest_t *manifest, + void *fid); + +/*! Boolean test if the program group manifest is valid + + @param manifest[in] program group manifest + + @return true if program group manifest is correct, false on error + */ +extern bool ia_css_is_program_group_manifest_valid( + const ia_css_program_group_manifest_t *manifest); + +#endif /* __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.sim.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.sim.h new file mode 100644 index 0000000000000..242f02108dd84 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.sim.h @@ -0,0 +1,127 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_SIM_H +#define __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_SIM_H + +/*! \file */ + +/** @file ia_css_psys_program_group_manifest.sim.h + * + * Define the methods on the program group manifest object: Simulation only + */ + +#include + +#include /* uint8_t */ +#include "ia_css_terminal_defs.h" + +/*! Create a program group manifest object from specification + + @param specification[in] specification (index) + + @return NULL on error + */ +extern ia_css_program_group_manifest_t *ia_css_program_group_manifest_create( + const unsigned int specification); + +/*! Destroy the program group manifest object + + @param manifest[in] program group manifest + + @return NULL + */ +extern ia_css_program_group_manifest_t *ia_css_program_group_manifest_destroy( + ia_css_program_group_manifest_t *manifest); + +/*! Compute the size of storage required for allocating + * the program group (PG) manifest object + + @param program_count[in] Number of programs in the PG + @param terminal_count[in] Number of terminals on the PG + @param program_dependency_count[in] Array[program_count] with the PG + @param terminal_dependency_count[in] Array[program_count] with the + terminal dependencies + @param terminal_type[in] Array[terminal_count] with the + terminal type + @param cached_in_param_section_count[in] Number of parameter + in terminal sections + @param cached_out_param_section_count[in] Number of parameter + out terminal sections + @param sliced_param_section_count[in] Array[sliced_terminal_count] + with sections per + sliced in terminal + @param sliced_out_param_section_count[in] Array[sliced_terminal_count] + with sections per + sliced out terminal + @param spatial_param_section_count[in] Array[spatial_terminal_count] + with sections per + spatial terminal + @param fragment_param_section_count[in] Number of fragment parameter + sections of the + program init terminal, + @param kernel_fragment_seq_count[in] Number of + kernel_fragment_seq_count. + @param progctrlinit_load_section_counts[in] Number of progctrinit load + sections (size of array is program_count) + @param progctrlinit_connect_section_counts[in] Number of progctrinit connect + sections (size of array is program_count) + @return 0 on error + */ +size_t ia_css_sizeof_program_group_manifest( + const uint8_t program_count, + const uint8_t terminal_count, + const uint8_t *program_dependency_count, + const uint8_t *terminal_dependency_count, + const ia_css_terminal_type_t *terminal_type, + const uint16_t cached_in_param_section_count, + const uint16_t cached_out_param_section_count, + const uint16_t *spatial_param_section_count, + const uint16_t fragment_param_section_count, + const uint16_t *sliced_param_section_count, + const uint16_t *sliced_out_param_section_count, + const uint16_t kernel_fragment_seq_count, + const uint16_t *progctrlinit_load_section_counts, + const uint16_t *progctrlinit_connect_section_counts); + +/*! Create (the storage for) the program group manifest object + + @param program_count[in] Number of programs in the program group + @param terminal_count[in] Number of terminals on the program group + @param program_dependency_count[in] Array[program_count] with the + program dependencies + @param terminal_dependency_count[in] Array[program_count] with the + terminal dependencies + @param terminal_type[in] Array[terminal_count] with the + terminal type + + @return NULL on error + */ +extern ia_css_program_group_manifest_t *ia_css_program_group_manifest_alloc( + const uint8_t program_count, + const uint8_t terminal_count, + const uint8_t *program_dependency_count, + const uint8_t *terminal_dependency_count, + const ia_css_terminal_type_t *terminal_type); + +/*! Free (the storage of) the program group manifest object + + @param manifest[in] program group manifest + + @return NULL + */ +extern ia_css_program_group_manifest_t *ia_css_program_group_manifest_free( + ia_css_program_group_manifest_t *manifest); + +#endif /* __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_SIM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.h new file mode 100644 index 0000000000000..b7333671ed4fc --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.h @@ -0,0 +1,488 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_MANIFEST_H +#define __IA_CSS_PSYS_PROGRAM_MANIFEST_H + +/*! \file */ + +/** @file ia_css_psys_program_manifest.h + * + * Define the methods on the program manifest object that are not part of a + * single interface + */ + +#include + +#include /* uint8_t */ + +#include + +#include + +#include /* ia_css_kernel_bitmap_t */ + +/* + * Resources needs + */ +#include + +#define IA_CSS_PROGRAM_INVALID_DEPENDENCY ((uint8_t)(-1)) + +/*! Check if the program manifest object specifies a fixed cell allocation + + @param manifest[in] program manifest object + + @return has_fixed_cell, false on invalid argument + */ +extern bool ia_css_has_program_manifest_fixed_cell( + const ia_css_program_manifest_t *manifest); + +/*! Get the stored size of the program manifest object + + @param manifest[in] program manifest object + + @return size, 0 on invalid argument + */ +extern size_t ia_css_program_manifest_get_size( + const ia_css_program_manifest_t *manifest); + +/*! Get the program ID of the program manifest object + + @param manifest[in] program manifest object + + @return program ID, IA_CSS_PROGRAM_INVALID_ID on invalid argument + */ +extern ia_css_program_ID_t ia_css_program_manifest_get_program_ID( + const ia_css_program_manifest_t *manifest); + +/*! Set the program ID of the program manifest object + + @param manifest[in] program manifest object + + @param program ID + + @return 0 on success, -1 on invalid manifest argument + */ +extern int ia_css_program_manifest_set_program_ID( + ia_css_program_manifest_t *manifest, + ia_css_program_ID_t id); + +/*! Get the (pointer to) the program group manifest parent of the program + * manifest object + + @param manifest[in] program manifest object + + @return the pointer to the parent, NULL on invalid manifest argument + */ +extern ia_css_program_group_manifest_t *ia_css_program_manifest_get_parent( + const ia_css_program_manifest_t *manifest); + +/*! Set the (pointer to) the program group manifest parent of the program + * manifest object + + @param manifest[in] program manifest object + @param program_offset[in] this program's offset from + program_group_manifest's base address. + + @return < 0 on invalid manifest argument + */ +extern int ia_css_program_manifest_set_parent_offset( + ia_css_program_manifest_t *manifest, + int32_t program_offset); + +/*! Get the type of the program manifest object + + @param manifest[in] program manifest object + + @return program type, limit value (IA_CSS_N_PROGRAM_TYPES) on invalid manifest + argument +*/ +extern ia_css_program_type_t ia_css_program_manifest_get_type( + const ia_css_program_manifest_t *manifest); + +/*! Set the type of the program manifest object + + @param manifest[in] program manifest object + @param program_type[in] program type + + @return < 0 on invalid manifest argument + */ +extern int ia_css_program_manifest_set_type( + ia_css_program_manifest_t *manifest, + const ia_css_program_type_t program_type); + +/*! Set the cell id of the program manifest object + + @param manifest[in] program manifest object + @param program_cell_id[in] program cell id + + @return < 0 on invalid manifest argument + */ +extern int ia_css_program_manifest_set_cell_ID( + ia_css_program_manifest_t *manifest, + const vied_nci_cell_ID_t cell_id); + +/*! Set the cell type of the program manifest object + + @param manifest[in] program manifest object + @param program_cell_type[in] program cell type + + @return < 0 on invalid manifest argument + */ +extern int ia_css_program_manifest_set_cell_type_ID( + ia_css_program_manifest_t *manifest, + const vied_nci_cell_type_ID_t cell_type_id); + +/*! Set cells bitmap for the program + + @param manifest[in] program manifest object + @param bitmap[in] bitmap + + @return 0 when not applicable and/or invalid arguments + */ +extern int ia_css_program_manifest_set_cells_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_resource_bitmap_t bitmap); + +/*! Get cells bitmap for the program + + @param manifest[in] program manifest object + + @return 0 when not applicable and/or invalid arguments + */ +extern vied_nci_resource_bitmap_t ia_css_program_manifest_get_cells_bitmap( + const ia_css_program_manifest_t *manifest); + +/*! Set DFM port bitmap for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + @param bitmap[in] bitmap + + @return 0 when not applicable and/or invalid arguments + */ +extern int ia_css_program_manifest_set_dfm_port_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const vied_nci_resource_bitmap_t bitmap); + +/*! Get bitmap of DFM ports requested for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + + @return DFM port bitmap + */ +extern vied_nci_resource_bitmap_t ia_css_program_manifest_get_dfm_port_bitmap( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id); + + +/*! Set active DFM port specification bitmap for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + @param bitmap[in] bitmap + + @return 0 when not applicable and/or invalid arguments + */ +extern int ia_css_program_manifest_set_dfm_active_port_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const vied_nci_resource_bitmap_t bitmap); + +/*! Get active DFM port specification bitmap for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + + @return 0 when not applicable and/or invalid arguments + */ +extern vied_nci_resource_bitmap_t ia_css_program_manifest_get_dfm_active_port_bitmap( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id); + +/*! Set DFM device relocatability specification for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + @param is_relocatable[in] 1 if dfm device ports are relocatable, 0 otherwise + + @return 0 when not applicable and/or invalid arguments + */ +extern int ia_css_program_manifest_set_is_dfm_relocatable( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const uint8_t is_relocatable); + +/*! Get DFM device relocatability specification for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + + @return 1 if dfm device ports are relocatable, 0 otherwise + */ +extern uint8_t ia_css_program_manifest_get_is_dfm_relocatable( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id); + + +/*! Get the memory resource (size) specification for a memory + that belongs to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type ID + + @return 0 when not applicable and/or invalid arguments + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_int_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Set the memory resource (size) specification for a memory + that belongs to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type id + @param int_mem_size[in] internal memory size + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_int_mem_size( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t int_mem_size); + +/*! Get the memory resource (size) specification for a memory + that does not belong to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type ID + + @return 0 when not applicable and/or invalid arguments + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_ext_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Set the memory resource (size) specification for a memory + that does not belong to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type id + @param ext_mem_size[in] external memory size + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_ext_mem_size( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t ext_mem_size); + +/*! Get a device channel resource (size) specification + + @param manifest[in] program manifest object + @param dev_chn_id[in] device channel ID + + @return 0 when not applicable and/or invalid arguments + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_dev_chn_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id); + +/*! Set a device channel resource (size) specification + + @param manifest[in] program manifest object + @param dev_chn_id[in] device channel ID + @param dev_chn_size[in] device channel size + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_dev_chn_size( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t dev_chn_size); + +/*! Set a device channel resource (offset) specification + + @param manifest[in] program manifest object + @param dev_chn_id[in] device channel ID + @param dev_chn_offset[in] device channel offset + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_dev_chn_offset( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t dev_chn_offset); + + +/*! Set the memory resource (offset) specification for a memory + that does not belong to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type id + @param ext_mem_offset[in] external memory offset + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_ext_mem_offset( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t ext_mem_offset); + +/*! Get a device channel resource (offset) specification + + @param manifest[in] program manifest object + @param dev_chn_id[in] device channel ID + + @return Valid fixed offset (if value is greater or equal to 0) or + IA_CSS_PROGRAM_MANIFEST_RESOURCE_OFFSET_IS_RELOCATABLE if offset + is relocatable + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_dev_chn_offset( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id); + +/*! Get the memory resource (offset) specification for a memory + that does not belong to the cell where the program will be mapped. + + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type ID + + @return Valid fixed offset (if value is greater or equal to 0) or + IA_CSS_PROGRAM_MANIFEST_RESOURCE_OFFSET_IS_RELOCATABLE if offset + is relocatable + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_ext_mem_offset( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id); + + +/*! Get the kernel composition of the program manifest object + + @param manifest[in] program manifest object + + @return bitmap, 0 on invalid arguments + */ +extern ia_css_kernel_bitmap_t ia_css_program_manifest_get_kernel_bitmap( + const ia_css_program_manifest_t *manifest); + +/*! Set the kernel dependency of the program manifest object + + @param manifest[in] program manifest object + @param kernel_bitmap[in] kernel composition bitmap + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_kernel_bitmap( + ia_css_program_manifest_t *manifest, + const ia_css_kernel_bitmap_t kernel_bitmap); + +/*! Get the number of programs this programs depends on from the program group + * manifest object + + @param manifest[in] program manifest object + + @return program dependency count + */ +extern uint8_t ia_css_program_manifest_get_program_dependency_count( + const ia_css_program_manifest_t *manifest); + +/*! Get the index of the program which the programs at this index depends on + from the program manifest object + + @param manifest[in] program manifest object + + @return program dependency, + IA_CSS_PROGRAM_INVALID_DEPENDENCY on invalid arguments + */ +extern uint8_t ia_css_program_manifest_get_program_dependency( + const ia_css_program_manifest_t *manifest, + const unsigned int index); + +/*! Set the index of the program which the programs at this index depends on + in the program manifest object + + @param manifest[in] program manifest object + + @return program dependency + */ +extern int ia_css_program_manifest_set_program_dependency( + ia_css_program_manifest_t *manifest, + const uint8_t program_dependency, + const unsigned int index); + +/*! Get the number of terminals this programs depends on from the program group + * manifest object + + @param manifest[in] program manifest object + + @return program dependency count + */ +extern uint8_t ia_css_program_manifest_get_terminal_dependency_count( + const ia_css_program_manifest_t *manifest); + +/*! Get the index of the terminal which the programs at this index depends on + from the program manifest object + + @param manifest[in] program manifest object + + @return terminal dependency, IA_CSS_PROGRAM_INVALID_DEPENDENCY on error + */ +uint8_t ia_css_program_manifest_get_terminal_dependency( + const ia_css_program_manifest_t *manifest, + const unsigned int index); + +/*! Set the index of the terminal which the programs at this index depends on + in the program manifest object + + @param manifest[in] program manifest object + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_terminal_dependency( + ia_css_program_manifest_t *manifest, + const uint8_t terminal_dependency, + const unsigned int index); + +/*! Check if the program manifest object specifies a subnode program + + @param manifest[in] program manifest object + + @return is_subnode, false on invalid argument + */ +extern bool ia_css_is_program_manifest_subnode_program_type( + const ia_css_program_manifest_t *manifest); + +/*! Check if the program manifest object specifies a supernode program + + @param manifest[in] program manifest object + + @return is_supernode, false on invalid argument + */ +extern bool ia_css_is_program_manifest_supernode_program_type( + const ia_css_program_manifest_t *manifest); +/*! Check if the program manifest object specifies a singular program + + @param manifest[in] program manifest object + + @return is_singular, false on invalid argument + */ +extern bool ia_css_is_program_manifest_singular_program_type( + const ia_css_program_manifest_t *manifest); + +#endif /* __IA_CSS_PSYS_PROGRAM_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.kernel.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.kernel.h new file mode 100644 index 0000000000000..9d737b75a576b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.kernel.h @@ -0,0 +1,96 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_KERNEL_H +#define __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_KERNEL_H + +/*! \file */ + +/** @file ia_css_psys_program_manifest.hsys.kernel.h + * + * Define the methods on the program manifest object: Hsys kernel interface + */ + +#include + +#include + +#include /* uint8_t */ + +/* + * Resources needs + */ + +/*! Get the cell ID from the program manifest object + + @param manifest[in] program manifest object + + Note: If the cell ID is specified, the program this manifest belongs to + must be mapped on that instance. If the cell ID is invalid (limit value) + then the cell type ID must be specified instead + + @return cell ID, limit value if not specified + */ +extern vied_nci_cell_ID_t ia_css_program_manifest_get_cell_ID( + const ia_css_program_manifest_t *manifest); + +/*! Get the cell type ID from the program manifest object + + @param manifest[in] program manifest object + + Note: If the cell type ID is specified, the program this manifest belongs + to can be mapped on any instance of this clee type. If the cell type ID is + invalid (limit value) then a specific cell ID must be specified instead + + @return cell ID, limit value if not specified + */ +extern vied_nci_cell_type_ID_t ia_css_program_manifest_get_cell_type_ID( + const ia_css_program_manifest_t *manifest); + +/*! Get the memory resource (size) specification for a memory + that belongs to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type ID + + @return 0 when not applicable + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_int_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Get the memory resource (size) specification for a memory + that does not belong to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type ID + + @return 0 when not applicable + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_ext_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Get a device channel resource (size) specification + + @param manifest[in] program manifest object + @param dev_chn_id[in] device channel ID + + @return 0 when not applicable + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_dev_chn_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id); + +#endif /* __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_KERNEL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.user.h new file mode 100644 index 0000000000000..087c84b7106e5 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.user.h @@ -0,0 +1,38 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_USER_H +#define __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_program_manifest.hsys.user.h + * + * Define the methods on the program manifest object: Hsys user interface + */ + +#include + +/*! Print the program manifest object to file/stream + + @param manifest[in] program manifest object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_program_manifest_print( + const ia_css_program_manifest_t *manifest, + void *fid); + +#endif /* __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.sim.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.sim.h new file mode 100644 index 0000000000000..0c2cef11f30eb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.sim.h @@ -0,0 +1,61 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_MANIFEST_SIM_H +#define __IA_CSS_PSYS_PROGRAM_MANIFEST_SIM_H + +/*! \file */ + +/** @file ia_css_psys_program_manifest.sim.h + * + * Define the methods on the program manifest object: Simulation only + */ + +#include + +#include /* uint8_t */ + +/*! Compute the size of storage required for allocating + * the program manifest object + + @param program_dependency_count[in] Number of programs this one depends on + @param terminal_dependency_count[in] Number of terminals this one depends on + + @return 0 on error + */ +extern size_t ia_css_sizeof_program_manifest( + const uint8_t program_dependency_count, + const uint8_t terminal_dependency_count); + +/*! Create (the storage for) the program manifest object + + @param program_dependency_count[in] Number of programs this one depends on + @param terminal_dependency_count[in] Number of terminals this one depends on + + @return NULL on error + */ +extern ia_css_program_manifest_t *ia_css_program_manifest_alloc( + const uint8_t program_dependency_count, + const uint8_t terminal_dependency_count); + +/*! Destroy (the storage of) the program manifest object + + @param manifest[in] program manifest + + @return NULL + */ +extern ia_css_program_manifest_t *ia_css_program_manifest_free( + ia_css_program_manifest_t *manifest); + +#endif /* __IA_CSS_PSYS_PROGRAM_MANIFEST_SIM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_storage_class.h new file mode 100644 index 0000000000000..f3c832b5a4a33 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_storage_class.h @@ -0,0 +1,28 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +#define __IA_CSS_PSYS_STATIC_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __IA_CSS_PSYS_STATIC_INLINE__ +#define IA_CSS_PSYS_STATIC_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +#else +#define IA_CSS_PSYS_STATIC_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PSYS_STATIC_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PSYS_STATIC_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_trace.h new file mode 100644 index 0000000000000..7c5612cd09690 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_trace.h @@ -0,0 +1,103 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_STATIC_TRACE_H +#define __IA_CSS_PSYS_STATIC_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_STATIC_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_STATIC_TRACING_OVERRIDE)) + #define PSYS_STATIC_TRACE_LEVEL_CONFIG \ + PSYS_STATIC_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_STATIC_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_STATIC_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_STATIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_STATIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_STATIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_STATIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_STATIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_STATIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_STATIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_STATIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_STATIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_STATIC_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_STATIC_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_STATIC_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_STATIC_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_STATIC_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_STATIC_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_STATIC_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_STATIC_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.h new file mode 100644 index 0000000000000..0fa62b32e1a74 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.h @@ -0,0 +1,423 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_MANIFEST_H +#define __IA_CSS_PSYS_TERMINAL_MANIFEST_H + +/*! \file */ + +/** @file ia_css_psys_terminal_manifest.h + * + * Define the methods on the terminal manifest object that are not part of a + * single interface + */ + +#include + +#include + +#include + +#include /* ia_css_frame_format_bitmap_t */ +#include /* ia_css_kernel_bitmap_t */ + +#include /* size_t */ +#include "ia_css_terminal_manifest.h" +#include "ia_css_terminal_manifest_base_types.h" + + +/*! Check if the terminal manifest object specifies a spatial param terminal + * type + + @param manifest[in] terminal manifest object + + @return is_parameter_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_spatial_parameter_terminal( + const ia_css_terminal_manifest_t *manifest); + +/*! Check if the terminal manifest object specifies a program terminal type + + @param manifest[in] terminal manifest object + + @return is_parameter_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_program_terminal( + const ia_css_terminal_manifest_t *manifest); + + +/*! Check if the terminal manifest object specifies a program control init terminal type + * + * @param manifest[in] terminal manifest object + * + * @return is_parameter_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_program_control_init_terminal( + const ia_css_terminal_manifest_t *manifest); + +/*! Check if the terminal manifest object specifies a (cached) parameter + * terminal type + + @param manifest[in] terminal manifest object + + @return is_parameter_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_parameter_terminal( + const ia_css_terminal_manifest_t *manifest); + +/*! Check if the terminal manifest object specifies a (sliced) parameter + * terminal type + + @param manifest[in] terminal manifest object + + @return is_parameter_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_sliced_terminal( + const ia_css_terminal_manifest_t *manifest); + +/*! Check if the terminal manifest object specifies a data terminal type + + @param manifest[in] terminal manifest object + + @return is_data_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_data_terminal( + const ia_css_terminal_manifest_t *manifest); + +/*! Get the stored size of the terminal manifest object + + @param manifest[in] terminal manifest object + + @return size, 0 on invalid manifest argument + */ +extern size_t ia_css_terminal_manifest_get_size( + const ia_css_terminal_manifest_t *manifest); + +/*! Get the (pointer to) the program group manifest parent of the terminal + * manifest object + + @param manifest[in] terminal manifest object + + @return the pointer to the parent, NULL on invalid manifest argument + */ +extern ia_css_program_group_manifest_t *ia_css_terminal_manifest_get_parent( + const ia_css_terminal_manifest_t *manifest); + +/*! Set the (pointer to) the program group manifest parent of the terminal + * manifest object + + @param manifest[in] terminal manifest object + @param terminal_offset[in] this terminal's offset from + program_group_manifest base address. + + @return < 0 on invalid arguments + */ +extern int ia_css_terminal_manifest_set_parent_offset( + ia_css_terminal_manifest_t *manifest, + int32_t terminal_offset); + +/*! Get the type of the terminal manifest object + + @param manifest[in] terminal manifest object + + @return terminal type, limit value (IA_CSS_N_TERMINAL_TYPES) on invalid + manifest argument +*/ +extern ia_css_terminal_type_t ia_css_terminal_manifest_get_type( + const ia_css_terminal_manifest_t *manifest); + +/*! Set the type of the terminal manifest object + + @param manifest[in] terminal manifest object + @param terminal_type[in] terminal type + + @return < 0 on invalid manifest argument + */ +extern int ia_css_terminal_manifest_set_type( + ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_type_t terminal_type); + +/*! Set the ID of the terminal manifest object + + @param manifest[in] terminal manifest object + @param ID[in] terminal ID + + @return < 0 on invalid manifest argument + */ +int ia_css_terminal_manifest_set_ID( + ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_ID_t ID); + +/*! Get the type of the terminal manifest object + + @param manifest[in] terminal manifest object + + @return terminal id, IA_CSS_TERMINAL_INVALID_ID on invalid manifest argument + */ +extern ia_css_terminal_ID_t ia_css_terminal_manifest_get_ID( + const ia_css_terminal_manifest_t *manifest); + +/*! Get the supported frame types of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + + @return frame format bitmap, 0 on invalid manifest argument +*/ +extern ia_css_frame_format_bitmap_t + ia_css_data_terminal_manifest_get_frame_format_bitmap( + const ia_css_data_terminal_manifest_t *manifest); + +/*! Set the chosen frame type for the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param bitmap[in] frame format bitmap + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_frame_format_bitmap( + ia_css_data_terminal_manifest_t *manifest, + ia_css_frame_format_bitmap_t bitmap); + +/*! Check if the (data) terminal manifest object supports compression + + @param manifest[in] (data) terminal manifest object + + @return compression_support, true if compression is supported + */ +extern bool ia_css_data_terminal_manifest_can_support_compression( + const ia_css_data_terminal_manifest_t *manifest); + +/*! Set the compression support feature of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param compression_support[in] set true to support compression + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_compression_support( + ia_css_data_terminal_manifest_t *manifest, + bool compression_support); + +/*! Set the supported connection types of the terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param bitmap[in] connection bitmap + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_connection_bitmap( + ia_css_data_terminal_manifest_t *manifest, ia_css_connection_bitmap_t bitmap); + +/*! Get the connection bitmap of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + + @return connection bitmap, 0 on invalid manifest argument +*/ +extern ia_css_connection_bitmap_t + ia_css_data_terminal_manifest_get_connection_bitmap( + const ia_css_data_terminal_manifest_t *manifest); + +/*! Get the kernel dependency of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + + @return kernel bitmap, 0 on invalid manifest argument + */ +extern ia_css_kernel_bitmap_t ia_css_data_terminal_manifest_get_kernel_bitmap( + const ia_css_data_terminal_manifest_t *manifest); + +/*! Set the kernel dependency of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param kernel_bitmap[in] kernel dependency bitmap + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_kernel_bitmap( + ia_css_data_terminal_manifest_t *manifest, + const ia_css_kernel_bitmap_t kernel_bitmap); + +/*! Set the unique kernel dependency of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param index[in] kernel dependency bitmap index + + @return < 0 on invalid argument(s) + */ +extern int ia_css_data_terminal_manifest_set_kernel_bitmap_unique( + ia_css_data_terminal_manifest_t *manifest, + const unsigned int index); + +/*! Set the min size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param min_size[in] Minimum size of the frame array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_min_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t min_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Set the max size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param max_size[in] Maximum size of the frame array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_max_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t max_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Get the min size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param min_size[in] Minimum size of the frame array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_get_min_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t min_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Get the max size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param max_size[in] Maximum size of the frame array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_get_max_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t max_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Set the min fragment size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param min_size[in] Minimum size of the fragment array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_min_fragment_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t min_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Set the max fragment size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param max_size[in] Maximum size of the fragment array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_max_fragment_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t max_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Get the min fragment size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param min_size[in] Minimum size of the fragment array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_get_min_fragment_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t min_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Get the max fragment size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param max_size[in] Maximum size of the fragment array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_get_max_fragment_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t max_size[IA_CSS_N_DATA_DIMENSION]); + +/*! + * Get the program control init connect section count for program prog. + * @param prog[in] program control init terminal program desc + * @return number of connect section for program prog. + */ + +extern +unsigned int ia_css_program_control_init_terminal_manifest_get_connect_section_count( + const ia_css_program_control_init_manifest_program_desc_t *prog); + + +/*! + * Get the program control init load section count for program prog. + * @param prog[in] program control init terminal program desc + * @return number of load section for program prog. + */ + +extern +unsigned int ia_css_program_control_init_terminal_manifest_get_load_section_count( + const ia_css_program_control_init_manifest_program_desc_t *prog); + +/*! + * Get the program control init terminal manifest size. + * @param nof_programs[in] Number of programs. + * @param nof_load_sections[in] Array of size nof_programs, + * encoding the number of load sections. + * @param nof_connect_sections[in] Array of size nof_programs, + * encoding the number of connect sections. + * @return < 0 on invalid manifest argument + */ +extern +unsigned int ia_css_program_control_init_terminal_manifest_get_size( + const uint16_t nof_programs, + const uint16_t *nof_load_sections, + const uint16_t *nof_connect_sections); + +/*! + * Get the program control init terminal manifest program desc. + * @param terminal[in] Program control init terminal. + * @param program[in] Number of programs. + * @return program control init terminal program desc (or NULL if error). + */ +extern +ia_css_program_control_init_manifest_program_desc_t * +ia_css_program_control_init_terminal_manifest_get_program_desc( + const ia_css_program_control_init_terminal_manifest_t *terminal, + unsigned int program); + +/*! + * Initialize the program control init terminal manifest. + * @param nof_programs[in] Number of programs + * @param nof_load_sections[in] Array of size nof_programs, + * encoding the number of load sections. + * @param nof_connect_sections[in] Array of size nof_programs, + * encoding the number of connect sections. + * @return < 0 on invalid manifest argument + */ +extern +int ia_css_program_control_init_terminal_manifest_init( + ia_css_program_control_init_terminal_manifest_t *terminal, + const uint16_t nof_programs, + const uint16_t *nof_load_sections, + const uint16_t *nof_connect_sections); + +/*! + * Pretty prints the program control init terminal manifest. + * @param terminal[in] Program control init terminal. + */ +extern +void ia_css_program_control_init_terminal_manifest_print( + ia_css_program_control_init_terminal_manifest_t *terminal); + +#endif /* __IA_CSS_PSYS_TERMINAL_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.hsys.user.h new file mode 100644 index 0000000000000..1d2f06f3cbce9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.hsys.user.h @@ -0,0 +1,38 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_MANIFEST_HSYS_USER_H +#define __IA_CSS_PSYS_TERMINAL_MANIFEST_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_terminal.hsys.user.h + * + * Define the methods on the termianl manifest object: Hsys user interface + */ + +#include + +/*! Print the terminal manifest object to file/stream + + @param manifest[in] terminal manifest object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_terminal_manifest_print( + const ia_css_terminal_manifest_t *manifest, + void *fid); + +#endif /* __IA_CSS_PSYS_TERMINAL_MANIFEST_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.sim.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.sim.h new file mode 100644 index 0000000000000..f7da810d82f19 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.sim.h @@ -0,0 +1,48 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_MANIFEST_SIM_H +#define __IA_CSS_PSYS_TERMINAL_MANIFEST_SIM_H + +/*! \file */ + +/** @file ia_css_psys_terminal_manifest.sim.h + * + * Define the methods on the terminal manifest object: Simulation only + */ + +#include /* size_t */ +#include "ia_css_terminal.h" +#include "ia_css_terminal_manifest.h" +#include "ia_css_terminal_defs.h" + +/*! Create (the storage for) the terminal manifest object + + @param terminal_type[in] type of the terminal manifest {parameter, data} + + @return NULL on error + */ +extern ia_css_terminal_manifest_t *ia_css_terminal_manifest_alloc( + const ia_css_terminal_type_t terminal_type); + +/*! Destroy (the storage of) the terminal manifest object + + @param manifest[in] terminal manifest + + @return NULL + */ +extern ia_css_terminal_manifest_t *ia_css_terminal_manifest_free( + ia_css_terminal_manifest_t *manifest); + +#endif /* __IA_CSS_PSYS_TERMINAL_MANIFEST_SIM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest.c new file mode 100644 index 0000000000000..443096c721011 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest.c @@ -0,0 +1,1038 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_static_storage_class.h" +#include "ia_css_psys_program_group_manifest.h" +#include "ia_css_rbm_manifest.h" + +/* + * Functions to possibly inline + */ + +#ifndef __IA_CSS_PSYS_STATIC_INLINE__ +#include "ia_css_psys_program_group_manifest_impl.h" +#endif /* __IA_CSS_PSYS_STATIC_INLINE__ */ + +/* + * Functions not to inline + */ + +/* + * We need to refactor those files in order to + * build in the firmware only what is needed, + * switches are put current to workaround compilation problems + * in the firmware (for example lack of uint64_t support) + * supported in the firmware + */ +#if !defined(__HIVECC) +size_t ia_css_sizeof_program_group_manifest( + const uint8_t program_count, + const uint8_t terminal_count, + const uint8_t *program_dependency_count, + const uint8_t *terminal_dependency_count, + const ia_css_terminal_type_t *terminal_type, + const uint16_t cached_in_param_section_count, + const uint16_t cached_out_param_section_count, + const uint16_t *spatial_param_section_count, + const uint16_t fragment_param_section_count, + const uint16_t *sliced_param_section_count, + const uint16_t *sliced_out_param_section_count, + const uint16_t kernel_fragment_seq_count, + const uint16_t *progctrlinit_load_section_counts, + const uint16_t *progctrlinit_connect_section_counts) +{ + size_t size = 0; + int i = 0; + int j = 0; + int m = 0; + int n = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_sizeof_program_group_manifest(): enter:\n"); + + verifexit(program_count != 0); + verifexit(program_dependency_count != NULL); + verifexit(terminal_dependency_count != NULL); + + size += sizeof(ia_css_program_group_manifest_t); + + /* Private payload in the program group manifest */ + size += ceil_mul(sizeof(struct ia_css_psys_private_pg_data), + sizeof(uint64_t)); + /* RBM manifest in the program group manifest */ + size += ceil_mul(sizeof(ia_css_rbm_manifest_t), + sizeof(uint64_t)); + + for (i = 0; i < (int)program_count; i++) { + size += ia_css_sizeof_program_manifest( + program_dependency_count[i], + terminal_dependency_count[i]); + } + + for (i = 0; i < (int)terminal_count; i++) { + switch (terminal_type[i]) { + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN: + size += ia_css_param_terminal_manifest_get_size( + cached_in_param_section_count); + break; + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT: + size += ia_css_param_terminal_manifest_get_size( + cached_out_param_section_count); + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + size += ia_css_spatial_param_terminal_manifest_get_size( + spatial_param_section_count[j]); + j++; + break; + case IA_CSS_TERMINAL_TYPE_PROGRAM: + size += ia_css_program_terminal_manifest_get_size( + fragment_param_section_count, + kernel_fragment_seq_count); + break; + case IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT: + size += ia_css_program_control_init_terminal_manifest_get_size( + program_count, + progctrlinit_load_section_counts, + progctrlinit_connect_section_counts); + break; + case IA_CSS_TERMINAL_TYPE_DATA_IN: + case IA_CSS_TERMINAL_TYPE_DATA_OUT: + size += sizeof(ia_css_data_terminal_manifest_t); + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN: + size += ia_css_sliced_param_terminal_manifest_get_size( + sliced_param_section_count[m]); + m++; + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT: + size += ia_css_sliced_param_terminal_manifest_get_size( + sliced_out_param_section_count[n]); + n++; + break; + default: + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_sizeof_program_group_manifest invalid argument\n"); + } + } + +EXIT: + if (0 == program_count || 0 == terminal_count || + NULL == program_dependency_count || + NULL == terminal_dependency_count) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_sizeof_program_group_manifest invalid argument\n"); + } + return size; +} + +/* + * Currently, the design of XNR kernel inside the *_pregdc program group, + * does not fit the exact model as is being asserted on in + * ia_css_is_program_group_manifest_valid. We therefore disable some checks. + * Further investigation is needed to determine whether *_pregdc program group + * can be canged or that the model must be changed. + * #define USE_SIMPLIFIED_GRAPH_MODEL 1 allows multiple programs to be + * connected to the same terminal, and it allows a kernel be mapped over + * multiple programs. + */ +#define USE_SIMPLIFIED_GRAPH_MODEL 1 + +/* + * Model and/or check refinements + * - Parallel programs do not yet have mutual exclusive alternatives + * - The pgram dependencies do not need to be acyclic + * - Parallel programs need to have an equal kernel requirement + */ +bool ia_css_is_program_group_manifest_valid( + const ia_css_program_group_manifest_t *manifest) +{ + int i; + bool is_valid = false; + uint8_t terminal_count; + uint8_t program_count; + ia_css_kernel_bitmap_t total_bitmap; + ia_css_kernel_bitmap_t check_bitmap; + ia_css_kernel_bitmap_t terminal_bitmap; + /* + * Use a standard bitmap type for the minimum logic to check the DAG, + * generic functions can be used for the kernel enable bitmaps; Later + */ + vied_nci_resource_bitmap_t resource_bitmap; + int terminal_bitmap_weight; + bool has_parameter_terminal_in = false; + bool has_parameter_terminal_out = false; + bool has_program_control_init_terminal = false; + bool has_program_terminal = false; + bool has_program_terminal_sequencer_info = false; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_program_group_manifest_valid(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(ia_css_program_group_manifest_get_size(manifest) != 0); + verifexit(ia_css_program_group_manifest_get_alignment(manifest) != 0); + verifexit(ia_css_program_group_manifest_get_program_group_ID(manifest) != 0); + + terminal_count = + ia_css_program_group_manifest_get_terminal_count(manifest); + program_count = + ia_css_program_group_manifest_get_program_count(manifest); + total_bitmap = + ia_css_program_group_manifest_get_kernel_bitmap(manifest); + check_bitmap = ia_css_kernel_bitmap_clear(); + resource_bitmap = vied_nci_bit_mask(VIED_NCI_RESOURCE_BITMAP_BITS); + terminal_bitmap = ia_css_kernel_bitmap_clear(); + + verifexit(program_count != 0); + verifexit(terminal_count != 0); + verifexit(!ia_css_is_kernel_bitmap_empty(total_bitmap)); + verifexit(vied_nci_is_bitmap_empty(resource_bitmap)); + + /* Check the kernel bitmaps for terminals */ + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_manifest_t *terminal_manifest_i = + ia_css_program_group_manifest_get_term_mnfst( + manifest, i); + bool is_parameter_in = + (IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN == + ia_css_terminal_manifest_get_type( + terminal_manifest_i)); + bool is_parameter_out = + (IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT == + ia_css_terminal_manifest_get_type( + terminal_manifest_i)); + bool is_data = + ia_css_is_terminal_manifest_data_terminal( + terminal_manifest_i); + bool is_program = + ia_css_is_terminal_manifest_program_terminal( + terminal_manifest_i); + bool is_spatial_param = + ia_css_is_terminal_manifest_spatial_parameter_terminal( + terminal_manifest_i); + bool is_program_control_init = + ia_css_is_terminal_manifest_program_control_init_terminal( + terminal_manifest_i); + + if (is_parameter_in) { + /* + * There can be only one cached in parameter terminal + * it serves kernels, not programs + */ + verifexit(!has_parameter_terminal_in); + has_parameter_terminal_in = is_parameter_in; + } else if (is_parameter_out) { + /* + * There can be only one cached out parameter terminal + * it serves kernels, not programs + */ + verifexit(!has_parameter_terminal_out); + has_parameter_terminal_out = is_parameter_out; + } else if (is_data) { + ia_css_data_terminal_manifest_t *dterminal_manifest_i = + (ia_css_data_terminal_manifest_t *) + terminal_manifest_i; + ia_css_kernel_bitmap_t terminal_bitmap_i = + ia_css_data_terminal_manifest_get_kernel_bitmap( + dterminal_manifest_i); + /* + * A terminal must depend on kernels that are a subset + * of the total, correction, it can only depend on one + * kernel + */ + verifexit(!ia_css_is_kernel_bitmap_empty( + terminal_bitmap_i)); + verifexit(ia_css_is_kernel_bitmap_subset( + total_bitmap, terminal_bitmap_i)); + verifexit(ia_css_is_kernel_bitmap_onehot( + terminal_bitmap_i)); + } else if (is_program) { + verifexit(!has_program_terminal); + verifexit(terminal_manifest_i); + has_program_terminal = is_program; + has_program_terminal_sequencer_info = + (((ia_css_program_terminal_manifest_t *) + terminal_manifest_i)-> + kernel_fragment_sequencer_info_manifest_info_count + != 0); + } else if (is_program_control_init) { + has_program_control_init_terminal = is_program_control_init; + } else { + const ia_css_spatial_param_terminal_manifest_t + *spatial_param_man = + (const ia_css_spatial_param_terminal_manifest_t *) + terminal_manifest_i; + verifexit(spatial_param_man); + verifexit(is_spatial_param); + + terminal_bitmap = + ia_css_kernel_bitmap_set(terminal_bitmap, + spatial_param_man->kernel_id); + verifexit(!ia_css_is_kernel_bitmap_empty(terminal_bitmap)); + verifexit(ia_css_is_kernel_bitmap_subset( + total_bitmap, terminal_bitmap)); + } + } + + /* Check the kernel bitmaps for programs */ + for (i = 0; i < (int)program_count; i++) { + int j; + ia_css_program_manifest_t *program_manifest_i = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, i); + ia_css_program_type_t program_type_i = + ia_css_program_manifest_get_type(program_manifest_i); + ia_css_kernel_bitmap_t program_bitmap_i = + ia_css_program_manifest_get_kernel_bitmap( + program_manifest_i); + uint8_t program_dependency_count_i = + ia_css_program_manifest_get_program_dependency_count( + program_manifest_i); + uint8_t terminal_dependency_count_i = + ia_css_program_manifest_get_terminal_dependency_count( + program_manifest_i); + uint8_t program_dependency_i0 = + ia_css_program_manifest_get_program_dependency( + program_manifest_i, 0); + bool is_sub_i = + ia_css_is_program_manifest_subnode_program_type( + program_manifest_i); + bool is_exclusive_sub_i = + (program_type_i == IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB); + bool is_virtual_sub_i = + (program_type_i == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB); + bool is_super_i = + ia_css_is_program_manifest_supernode_program_type( + program_manifest_i); + + /* + * A program must have kernels that + * are a subset of the total + */ + verifexit(!ia_css_is_kernel_bitmap_empty( + program_bitmap_i)); + verifexit(ia_css_is_kernel_bitmap_subset( + total_bitmap, program_bitmap_i)); + verifexit((program_type_i != IA_CSS_N_PROGRAM_TYPES)); + verifexit((program_dependency_count_i + terminal_dependency_count_i) != 0); + /* + * Checks for subnodes + * - Parallel subnodes cannot depend on terminals + * - Exclusive subnodes must depend on + * fewer terminals than the supernode + * - Subnodes only depend on a supernode of the same type + * - Must have a subset of the supernode's kernels + * (but not equal) + * - This tests only positive cases + * Checks for singular or supernodes + * - Cannot depend on exclusive subnodes + * - No intersection between kernels + * (too strict for multiple instances ?) + */ + if (is_sub_i) { + /* Subnode */ + ia_css_program_manifest_t *program_manifest_k = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, program_dependency_i0); + ia_css_program_type_t program_type_k = + ia_css_program_manifest_get_type( + program_manifest_k); + ia_css_kernel_bitmap_t program_bitmap_k = + ia_css_program_manifest_get_kernel_bitmap( + program_manifest_k); + + verifexit(program_dependency_count_i == 1); + if (is_exclusive_sub_i || is_virtual_sub_i) { + verifexit(terminal_dependency_count_i <= + ia_css_program_manifest_get_terminal_dependency_count( + program_manifest_k)); + } else { + verifexit(terminal_dependency_count_i == 0); + } + verifexit(program_type_k == + (is_exclusive_sub_i ? + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER : + is_virtual_sub_i ? + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER : + IA_CSS_PROGRAM_TYPE_PARALLEL_SUPER)); + verifexit(!ia_css_is_kernel_bitmap_equal( + program_bitmap_k, program_bitmap_i)); + verifexit(ia_css_is_kernel_bitmap_subset( + program_bitmap_k, program_bitmap_i)); + } else { + /* Singular or Supernode */ + int k; + + for (k = 0; k < program_dependency_count_i; k++) { + uint8_t program_dependency_k = + ia_css_program_manifest_get_program_dependency( + program_manifest_i, k); + ia_css_program_manifest_t *program_manifest_k = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, (int)program_dependency_k); + ia_css_program_type_t program_type_k = + ia_css_program_manifest_get_type( + program_manifest_k); + ia_css_kernel_bitmap_t program_bitmap_k = + ia_css_program_manifest_get_kernel_bitmap( + program_manifest_k); + + verifexit(program_dependency_k < + program_count); + verifexit((program_type_k != + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) && + (program_type_k != + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB)); +#if USE_SIMPLIFIED_GRAPH_MODEL == 0 + verifexit(ia_css_is_kernel_bitmap_intersection_empty( + program_bitmap_i, program_bitmap_k)); +#else + (void)program_bitmap_k; +#endif + } + } + + /* Check for relations */ + for (j = 0; j < (int)program_count; j++) { + int k; + ia_css_program_manifest_t *program_manifest_j = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, j); + ia_css_program_type_t program_type_j = + ia_css_program_manifest_get_type(program_manifest_j); + ia_css_kernel_bitmap_t program_bitmap_j = + ia_css_program_manifest_get_kernel_bitmap( + program_manifest_j); + uint8_t program_dependency_count_j = + ia_css_program_manifest_get_program_dependency_count( + program_manifest_j); + uint8_t program_dependency_j0 = + ia_css_program_manifest_get_program_dependency( + program_manifest_j, 0); + bool is_sub_j = + ia_css_is_program_manifest_subnode_program_type( + program_manifest_j); + bool is_super_j = + ia_css_is_program_manifest_supernode_program_type( + program_manifest_j); + bool is_virtual_sub_j = + (program_type_j == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB); + bool is_j_subset_i = + ia_css_is_kernel_bitmap_subset( + program_bitmap_i, program_bitmap_j); + bool is_i_subset_j = + ia_css_is_kernel_bitmap_subset( + program_bitmap_j, program_bitmap_i); + + /* Test below would fail for i==j */ + if (i == j) + continue; + + /* Empty sets are always subsets, but meaningless */ + verifexit(!ia_css_is_kernel_bitmap_empty( + program_bitmap_j)); + + /* + * Checks for mutual subnodes + * - Parallel subnodes must have an equal + * set of kernels + * - Exclusive and virtual subnodes must + * have an unequal set of kernels + * Checks for subnodes + * - Subnodes must have a subset of kernels + */ + if (((program_type_i == + IA_CSS_PROGRAM_TYPE_PARALLEL_SUB) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_PARALLEL_SUB)) || + ((program_type_i == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB)) || + ((program_type_i == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB))) { + + verifexit(program_dependency_count_j == 1); + verifexit(program_dependency_i0 != i); + verifexit(program_dependency_j0 != i); + + if (program_dependency_i0 == + program_dependency_j0) { + verifexit(is_sub_i); + /* + * Subnodes are subsets, + * not for virtual nodes + */ + if (!is_virtual_sub_i) + verifexit( + ((is_j_subset_i || + is_i_subset_j))); + /* + * That must be equal for + * parallel subnodes, + * must be unequal for + * exlusive and virtual subnodes + */ + verifexit( + ((is_j_subset_i && is_i_subset_j) ^ + (is_exclusive_sub_i | + is_virtual_sub_i))); + + } + if (is_j_subset_i || is_i_subset_j) { + verifexit(program_dependency_i0 == + program_dependency_j0); + } + } + + if (((program_type_i == + IA_CSS_PROGRAM_TYPE_PARALLEL_SUPER) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_PARALLEL_SUB)) || + ((program_type_i == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB)) || + ((program_type_i == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB))) { + + verifexit(program_dependency_count_j == 1); + verifexit(!is_i_subset_j); + + if (program_dependency_j0 == i) { + verifexit(program_dependency_i0 != + program_dependency_j0); + verifexit(is_super_i); + verifexit(is_j_subset_i); + + } + if (is_j_subset_i) { + verifexit(program_dependency_j0 == i); + } + } + + /* + * Checks for dependent nodes + * - Cannot depend on exclusive subnodes + * - No intersection between kernels + * (too strict for multiple instances ?) + * unless a subnode + */ + for (k = 0; k < (int)program_dependency_count_j; k++) { + uint8_t program_dependency_k = + ia_css_program_manifest_get_program_dependency( + program_manifest_j, k); + + verifexit((program_dependency_k < + program_count)); + if (program_dependency_k == i) { + /* program[j] depends on program[i] */ + verifexit((i != j)); + verifexit((program_type_i != + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) && + (program_type_i != + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB)); + verifexit(USE_SIMPLIFIED_GRAPH_MODEL || + (ia_css_is_kernel_bitmap_intersection_empty( + program_bitmap_i, program_bitmap_j) ^ is_sub_j)); + } + } + + /* + * Checks for supernodes and subnodes + * - Detect nodes that kernel-wise are subsets, + * but not connected to the correct supernode + * - We do not (yet) detect if programs properly + * depend on all parallel nodes + */ + if (!ia_css_is_kernel_bitmap_intersection_empty( + program_bitmap_i, program_bitmap_j)) { + /* + * This test will pass if + * the program manifest is NULL, + * but that's no concern here + */ +#if USE_SIMPLIFIED_GRAPH_MODEL == 0 + verifexit(!ia_css_is_program_manifest_singular_program_type( + program_manifest_i)); + verifexit(!ia_css_is_program_manifest_singular_program_type( + program_manifest_j)); + if (!is_virtual_sub_j) + verifexit((is_j_subset_i || is_i_subset_j)); +#else + (void)is_virtual_sub_j; +#endif + if (is_super_i) { + verifexit(is_sub_j); + verifexit(program_dependency_j0 == i); + } + if (is_super_j) { + verifexit(is_sub_i); + verifexit(program_dependency_i0 == j); + } + } + } + check_bitmap = ia_css_kernel_bitmap_union( + check_bitmap, program_bitmap_i); + /* + * A terminal can be bound to only a single + * (of multiple concurrent) program(s), + * i.e. the one that holds the iterator to control it + * Only singular and super nodes can depend on a terminal. + * This loop accumulates all terminal + * dependencies over all programs + */ + for (j = 0; j < (int)terminal_dependency_count_i; j++) { + uint8_t terminal_dependency = + ia_css_program_manifest_get_terminal_dependency( + program_manifest_i, j); + + verifexit(terminal_dependency < terminal_count); + if ((program_type_i != + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) && + (program_type_i != + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB)) { + /* If the subnode always came after the */ + /* supernode we could check for presence */ + resource_bitmap = + vied_nci_bit_mask_set_unique( + resource_bitmap, + terminal_dependency); +#if USE_SIMPLIFIED_GRAPH_MODEL == 0 + verifexit(!vied_nci_is_bitmap_empty( + resource_bitmap)); +#endif + } + } + } + verifexit(ia_css_is_kernel_bitmap_equal( + total_bitmap, check_bitmap)); + + terminal_bitmap_weight = + vied_nci_bitmap_compute_weight(resource_bitmap); + verifexit(terminal_bitmap_weight >= 0); + if (has_parameter_terminal_in || + has_parameter_terminal_out || + has_program_terminal || + has_program_control_init_terminal) { + int skip_terminal_count = 0; + + if (has_parameter_terminal_in) + skip_terminal_count++; + if (has_parameter_terminal_out) + skip_terminal_count++; + if (has_program_control_init_terminal) { + skip_terminal_count++; + } + if (has_program_terminal) + skip_terminal_count++; + if (has_program_terminal_sequencer_info) + skip_terminal_count--; +#if USE_SIMPLIFIED_GRAPH_MODEL == 0 + verifexit((terminal_bitmap_weight == + (terminal_count - skip_terminal_count))); +#endif + } else + verifexit((terminal_bitmap_weight == terminal_count)); + + is_valid = true; +EXIT: + if (is_valid == false) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_is_program_group_manifest_valid: failed\n"); + } + return is_valid; +} + +int ia_css_program_group_manifest_set_kernel_bitmap( + ia_css_program_group_manifest_t *manifest, + const ia_css_kernel_bitmap_t bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_set_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + manifest->kernel_bitmap = bitmap; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_set_kernel_bitmap invalid argument\n"); + } + return retval; +} + +ia_css_kernel_bitmap_t ia_css_program_group_manifest_get_kernel_bitmap( + const ia_css_program_group_manifest_t *manifest) +{ + ia_css_kernel_bitmap_t bitmap = ia_css_kernel_bitmap_clear(); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + bitmap = manifest->kernel_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_kernel_bitmap invalid argument\n"); + } + return bitmap; +} + +void ia_css_program_group_manifest_init( + ia_css_program_group_manifest_t *blob, + const uint8_t program_count, + const uint8_t terminal_count, + const uint8_t *program_dependencies, + const uint8_t *terminal_dependencies, + const ia_css_terminal_type_t *terminal_type, + const uint16_t cached_in_param_section_count, + const uint16_t cached_out_param_section_count, + const uint16_t *spatial_param_section_count, + const uint16_t fragment_param_section_count, + const uint16_t *sliced_in_param_section_count, + const uint16_t *sliced_out_param_section_count, + const uint16_t kernel_fragment_seq_count, + const uint16_t *progctrlinit_load_section_counts, + const uint16_t *progctrlinit_connect_section_counts) +{ + int i = 0; + int j = 0; + int m = 0; + int n = 0; + int result; + uint32_t offset = 0; + char *prg_manifest_base, *terminal_manifest_base; + size_t program_size = 0; + + /* + * assert(blob != NULL); + */ + COMPILATION_ERROR_IF( + SIZE_OF_DATA_TERMINAL_MANIFEST_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_data_terminal_manifest_t))); + COMPILATION_ERROR_IF( + SIZE_OF_PROGRAM_GROUP_MANIFEST_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_program_group_manifest_t))); + COMPILATION_ERROR_IF( + SIZE_OF_PROGRAM_MANIFEST_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_program_manifest_t))); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, + "ia_css_program_group_manifest_init(): enter:\n"); + + for (i = 0; i < (int)program_count; i++) { + program_size += + ia_css_sizeof_program_manifest(program_dependencies[i], + terminal_dependencies[i]); + } + + /* A program group ID cannot be zero */ + blob->ID = 1; + blob->program_count = program_count; + blob->terminal_count = terminal_count; + blob->program_manifest_offset = sizeof(ia_css_program_group_manifest_t); + blob->terminal_manifest_offset = + (uint32_t)blob->program_manifest_offset + program_size; + + prg_manifest_base = (char *) + (((char *)blob) + blob->program_manifest_offset); + offset = blob->program_manifest_offset; + for (i = 0; i < (int)program_count; i++) { + ia_css_program_manifest_init( + (ia_css_program_manifest_t *)prg_manifest_base, + program_dependencies[i], terminal_dependencies[i]); + ia_css_program_manifest_set_parent_offset( + (ia_css_program_manifest_t *)prg_manifest_base, offset); + program_size = + ia_css_sizeof_program_manifest(program_dependencies[i], + terminal_dependencies[i]); + prg_manifest_base += program_size; + offset += (uint32_t)program_size; + } + + offset = blob->terminal_manifest_offset; + terminal_manifest_base = (char *) (((char *)blob) + offset); + for (i = 0; i < (int)terminal_count; i++) { + size_t terminal_size = 0; + ia_css_terminal_manifest_t *term_manifest = + (ia_css_terminal_manifest_t *)terminal_manifest_base; + + ia_css_terminal_manifest_set_parent_offset( + (ia_css_terminal_manifest_t *) + terminal_manifest_base, + offset); + switch (terminal_type[i]) { + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN: + result = ia_css_param_terminal_manifest_init( + (ia_css_param_terminal_manifest_t *) + term_manifest, + cached_in_param_section_count); + if (result == 0) { + terminal_size = + ia_css_param_terminal_manifest_get_size( + cached_in_param_section_count); + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_param_terminal_manifest_init failed in cached in terminal\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT: + result = ia_css_param_terminal_manifest_init( + (ia_css_param_terminal_manifest_t *) + term_manifest, + cached_out_param_section_count); + if (result == 0) { + terminal_size = + ia_css_param_terminal_manifest_get_size( + cached_out_param_section_count); + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_param_terminal_manifest_init failed\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + result = ia_css_spatial_param_terminal_manifest_init( + (ia_css_spatial_param_terminal_manifest_t *) + term_manifest, + spatial_param_section_count[j]); + if (result == 0) { + terminal_size = + ia_css_spatial_param_terminal_manifest_get_size( + spatial_param_section_count[j]); + j++; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_spatial_param_terminal_manifest_init failed in spatial terminal\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_PROGRAM: + result = ia_css_program_terminal_manifest_init( + (ia_css_program_terminal_manifest_t *) + term_manifest, + fragment_param_section_count, + kernel_fragment_seq_count); + if (result == 0) { + terminal_size = + ia_css_program_terminal_manifest_get_size( + fragment_param_section_count, + kernel_fragment_seq_count); + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_program_terminal_manifest_init failed in program terminal\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT: + result = ia_css_program_control_init_terminal_manifest_init( + (ia_css_program_control_init_terminal_manifest_t *) + term_manifest, + program_count, + progctrlinit_load_section_counts, + progctrlinit_connect_section_counts); + if (result == 0) { + terminal_size = + ia_css_program_control_init_terminal_manifest_get_size( + program_count, + NULL, + NULL); + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_program_control_init_terminal_manifest_init failed\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_DATA_IN: + case IA_CSS_TERMINAL_TYPE_DATA_OUT: + terminal_size = sizeof(ia_css_data_terminal_manifest_t); + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN: + result = ia_css_sliced_param_terminal_manifest_init( + (ia_css_sliced_param_terminal_manifest_t *) + term_manifest, + sliced_in_param_section_count[m]); + if (result == 0) { + terminal_size = + ia_css_sliced_param_terminal_manifest_get_size( + sliced_in_param_section_count[m]); + m++; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_param_terminal_manifest_init in sliced terminal failed\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT: + result = ia_css_sliced_param_terminal_manifest_init( + (ia_css_sliced_param_terminal_manifest_t *) + term_manifest, + sliced_out_param_section_count[n]); + if (result == 0) { + terminal_size = + ia_css_sliced_param_terminal_manifest_get_size( + sliced_out_param_section_count[n]); + n++; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_param_terminal_manifest_init in sliced out terminal failed\n"); + } + break; + default: + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_init invalid argument\n"); + } + term_manifest->size = (uint16_t)terminal_size; + term_manifest->terminal_type = terminal_type[i]; + terminal_manifest_base += terminal_size; + offset += (uint32_t)terminal_size; + } + + /* Set the private program group manifest blob offset */ + blob->private_data_offset = offset; + offset += ceil_mul(sizeof(struct ia_css_psys_private_pg_data), + sizeof(uint64_t)); + + /* Set the RBM manifest blob offset */ + blob->rbm_manifest_offset = offset; + offset += ceil_mul(sizeof(ia_css_rbm_manifest_t), + sizeof(uint64_t)); + + assert(offset <= UINT16_MAX); + blob->size = (uint16_t)offset; +} + +int ia_css_program_group_manifest_print( + const ia_css_program_group_manifest_t *manifest, + void *fid) +{ + int retval = -1; + int i; + uint8_t program_count, terminal_count; + ia_css_kernel_bitmap_t bitmap; + struct ia_css_psys_private_pg_data *priv_data; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, + "ia_css_program_group_manifest_print(): enter:\n"); + + NOT_USED(fid); + + verifexit(manifest != NULL); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "sizeof(manifest) = %d\n", + (int)ia_css_program_group_manifest_get_size(manifest)); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "alignment(manifest) = %d\n", + (int)ia_css_program_group_manifest_get_alignment(manifest)); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "program group ID = %d\n", + (int)ia_css_program_group_manifest_get_program_group_ID( + manifest)); + + program_count = + ia_css_program_group_manifest_get_program_count(manifest); + terminal_count = + ia_css_program_group_manifest_get_terminal_count(manifest); + + bitmap = ia_css_program_group_manifest_get_kernel_bitmap(manifest); + verifexit(ia_css_kernel_bitmap_print(bitmap, fid) == 0); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "%d program manifests\n", (int)program_count); + for (i = 0; i < (int)program_count; i++) { + ia_css_program_manifest_t *program_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, i); + + retval = ia_css_program_manifest_print(program_manifest, fid); + verifjmpexit(retval == 0); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "%d terminal manifests\n", (int)terminal_count); + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_manifest_t *terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst( + manifest, i); + + retval = ia_css_terminal_manifest_print( + terminal_manifest, fid); + verifjmpexit(retval == 0); + } + + priv_data = + (struct ia_css_psys_private_pg_data *) + ia_css_program_group_manifest_get_private_data(manifest); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "private_data_offset %d\n", manifest->private_data_offset); + + for (i = 0; i < IPU_DEVICE_GP_PSA_MUX_NUM_MUX; i++) { + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "PSA MUX id %d mux val %d\n", i, + priv_data->psa_mux_conf[i]); + + } + + for (i = 0; i < IPU_DEVICE_GP_ISA_STATIC_MUX_NUM_MUX; i++) { + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "ISA MUX id %d mux val %d\n", i, + priv_data->isa_mux_conf[i]); + + } + + for (i = 0; i < IPU_DEVICE_ACB_NUM_ACB; i++) { + + if (priv_data->acb_route[i].in_select != + NCI_ACB_PORT_INVALID) { + + assert(priv_data->acb_route[i].in_select != + NCI_ACB_PORT_INVALID && + priv_data->acb_route[i].out_select != + NCI_ACB_PORT_INVALID); + + IA_CSS_TRACE_3(PSYSAPI_STATIC, INFO, + "Route Cell id %d In %d Out %d\n", i, + priv_data->acb_route[i].in_select, + priv_data->acb_route[i].out_select); + } + + } + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: buffer_base_addr 0x%x\n", + priv_data->input_buffer_info.buffer_base_addr); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: bpe = %d\n", + priv_data->input_buffer_info.bpe); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: buffer_width = %d\n", + priv_data->input_buffer_info.buffer_width); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: buffer_height = %d\n", + priv_data->input_buffer_info.buffer_height); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: num_of_buffers = %d\n", + priv_data->input_buffer_info.num_of_buffers); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: dfm_port_addr = 0x%x\n", + priv_data->input_buffer_info.dfm_port_addr); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_group_manifest_print failed (%i)\n", + retval); + } + return retval; +} +#endif /* !defined(__HIVECC) */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest_impl.h new file mode 100644 index 0000000000000..a3a729b0d104a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest_impl.h @@ -0,0 +1,415 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_IMPL_H +#define __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_IMPL_H + +#include +#include +#include +#include +#include "ia_css_psys_program_group_private.h" +#include "ia_css_terminal_manifest_types.h" +#include "ia_css_psys_private_pg_data.h" +#include /* Safer bit mask functions */ +#include "ia_css_psys_static_trace.h" +#include "ia_css_rbm_manifest_types.h" +#include +#include +#include + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +size_t ia_css_program_group_manifest_get_size( + const ia_css_program_group_manifest_t *manifest) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_size(): enter:\n"); + + if (manifest != NULL) { + size = manifest->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_size invalid argument\n"); + } + return size; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_program_group_ID_t +ia_css_program_group_manifest_get_program_group_ID( + const ia_css_program_group_manifest_t *manifest) +{ + ia_css_program_group_ID_t id = IA_CSS_PROGRAM_GROUP_INVALID_ID; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_program_group_ID(): enter:\n"); + + if (manifest != NULL) { + id = manifest->ID; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_program_group_ID invalid argument\n"); + } + return id; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +int ia_css_program_group_manifest_set_program_group_ID( + ia_css_program_group_manifest_t *manifest, + ia_css_program_group_ID_t id) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_set_program_group_ID(): enter:\n"); + + if (manifest != NULL) { + manifest->ID = id; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_set_program_group_ID invalid argument\n"); + } + return retval; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +int ia_css_program_group_manifest_set_alignment( + ia_css_program_group_manifest_t *manifest, + const uint8_t alignment) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_set_alignment(): enter:\n"); + + if (manifest != NULL) { + manifest->alignment = alignment; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_set_alignment invalid argument\n"); + } + return retval; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +uint8_t ia_css_program_group_manifest_get_alignment( + const ia_css_program_group_manifest_t *manifest) +{ + uint8_t alignment = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_alignment(): enter:\n"); + + if (manifest != NULL) { + alignment = manifest->alignment; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_alignment invalid argument\n"); + } + return alignment; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +void *ia_css_program_group_manifest_get_private_data( + const ia_css_program_group_manifest_t *manifest) +{ + void *private_data = NULL; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_private_data(%p): enter:\n", + manifest); + + verifexit(manifest != NULL); + + private_data = (void *)((const char *)manifest + + manifest->private_data_offset); +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_private_data invalid argument\n"); + } + return private_data; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_rbm_manifest_t *ia_css_program_group_manifest_get_rbm_manifest( + const ia_css_program_group_manifest_t *manifest) +{ + ia_css_rbm_manifest_t *rbm_manifest = NULL; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_rbm_manifest(%p): enter:\n", + manifest); + + verifexit(manifest != NULL); + + rbm_manifest = (ia_css_rbm_manifest_t *)((const char *)manifest + + manifest->rbm_manifest_offset); + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_rbm_manifest invalid argument\n"); + } + return rbm_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_program_manifest_t * +ia_css_program_group_manifest_get_prgrm_mnfst( + const ia_css_program_group_manifest_t *manifest, + const unsigned int program_index) +{ + ia_css_program_manifest_t *prg_manifest_base; + uint8_t *program_manifest = NULL; + uint8_t program_count; + unsigned int i; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_prgrm_mnfst(%p,%d): enter:\n", + manifest, program_index); + + program_count = + ia_css_program_group_manifest_get_program_count(manifest); + + verifexit(manifest != NULL); + verifexit(program_index < program_count); + + prg_manifest_base = (ia_css_program_manifest_t *)((char *)manifest + + manifest->program_manifest_offset); + if (program_index < program_count) { + program_manifest = (uint8_t *)prg_manifest_base; + for (i = 0; i < program_index; i++) { + program_manifest += ((ia_css_program_manifest_t *) + program_manifest)->size; + } + } + +EXIT: + if (NULL == manifest || program_index >= program_count) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_prgrm_mnfst invalid argument\n"); + } + return (ia_css_program_manifest_t *)program_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_data_terminal_manifest_t * +ia_css_program_group_manifest_get_data_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_data_terminal_manifest_t *data_terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_data_terminal_manifest(%p, %d): enter:\n", + manifest, (int)terminal_index); + + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst(manifest, + terminal_index); + + verifexit(ia_css_is_terminal_manifest_data_terminal(terminal_manifest)); + + data_terminal_manifest = + (ia_css_data_terminal_manifest_t *)terminal_manifest; +EXIT: + return data_terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_param_terminal_manifest_t * +ia_css_program_group_manifest_get_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_param_terminal_manifest_t *param_terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_param_terminal_manifest(%p, %d): enter:\n", + manifest, (int)terminal_index); + + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst(manifest, + terminal_index); + + verifexit(ia_css_is_terminal_manifest_parameter_terminal( + terminal_manifest)); + param_terminal_manifest = + (ia_css_param_terminal_manifest_t *)terminal_manifest; +EXIT: + return param_terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_spatial_param_terminal_manifest_t * +ia_css_program_group_manifest_get_spatial_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_spatial_param_terminal_manifest_t * + spatial_param_terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_spatial_param_terminal_manifest(%p, %d): enter:\n", + manifest, (int)terminal_index); + + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst(manifest, + terminal_index); + + verifexit(ia_css_is_terminal_manifest_spatial_parameter_terminal( + terminal_manifest)); + + spatial_param_terminal_manifest = + (ia_css_spatial_param_terminal_manifest_t *)terminal_manifest; +EXIT: + return spatial_param_terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_sliced_param_terminal_manifest_t * +ia_css_program_group_manifest_get_sliced_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_sliced_param_terminal_manifest_t * + sliced_param_terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_sliced_param_terminal_manifest(%p, %d): enter:\n", + manifest, (int)terminal_index); + + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst(manifest, + terminal_index); + + verifexit(ia_css_is_terminal_manifest_sliced_terminal( + terminal_manifest)); + + sliced_param_terminal_manifest = + (ia_css_sliced_param_terminal_manifest_t *)terminal_manifest; +EXIT: + return sliced_param_terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_program_terminal_manifest_t * +ia_css_program_group_manifest_get_program_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_program_terminal_manifest_t *program_terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_program_terminal_manifest(%p, %d): enter:\n", + manifest, (int)terminal_index); + + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst(manifest, + terminal_index); + + verifexit(ia_css_is_terminal_manifest_program_terminal( + terminal_manifest)); + + program_terminal_manifest = + (ia_css_program_terminal_manifest_t *)terminal_manifest; + EXIT: + return program_terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_terminal_manifest_t * +ia_css_program_group_manifest_get_term_mnfst( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_terminal_manifest_t *terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest_base; + uint8_t terminal_count; + uint8_t i = 0; + uint32_t offset; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_term_mnfst(%p,%d): enter:\n", + manifest, (int)terminal_index); + + verifexit(manifest != NULL); + + terminal_count = + ia_css_program_group_manifest_get_terminal_count(manifest); + + verifexit(terminal_index < terminal_count); + + terminal_manifest_base = + (ia_css_terminal_manifest_t *)((char *)manifest + + manifest->terminal_manifest_offset); + terminal_manifest = terminal_manifest_base; + while (i < terminal_index) { + offset = + (uint32_t)ia_css_terminal_manifest_get_size(terminal_manifest); + terminal_manifest = (ia_css_terminal_manifest_t *) + ((char *)terminal_manifest + offset); + i++; + } +EXIT: + return terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +uint8_t ia_css_program_group_manifest_get_program_count( + const ia_css_program_group_manifest_t *manifest) +{ + uint8_t program_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_program_count(): enter:\n"); + + if (manifest != NULL) { + program_count = manifest->program_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_program_count invalid argument\n"); + } + return program_count; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +uint8_t ia_css_program_group_manifest_get_terminal_count( + const ia_css_program_group_manifest_t *manifest) +{ + uint8_t terminal_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_terminal_count(): enter:\n"); + + if (manifest != NULL) { + terminal_count = manifest->terminal_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_terminal_count invalid argument\n"); + } + return terminal_count; +} + +#endif /* __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_private.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_private.h new file mode 100644 index 0000000000000..f4b9d7ee5a04b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_private.h @@ -0,0 +1,213 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_GROUP_PRIVATE_H +#define __IA_CSS_PSYS_PROGRAM_GROUP_PRIVATE_H + +#include "ia_css_psys_manifest_types.h" +#include "ia_css_terminal_manifest_types.h" +#include "ia_css_kernel_bitmap.h" +#include "ia_css_program_group_data.h" +#include "vied_nci_psys_resource_model.h" +#include "ia_css_rbm_manifest_types.h" +#include +#include + +#include + +#define SIZE_OF_PROGRAM_GROUP_MANIFEST_STRUCT_IN_BITS \ + ((IA_CSS_KERNEL_BITMAP_BITS) \ + + (IA_CSS_PROGRAM_GROUP_ID_BITS) \ + + (5 * IA_CSS_UINT16_T_BITS) \ + + (5 * IA_CSS_UINT8_T_BITS) \ + + (5 * IA_CSS_UINT8_T_BITS)) + +struct ia_css_program_group_manifest_s { + /**< Indicate kernels are present in this program group */ + ia_css_kernel_bitmap_t kernel_bitmap; + /**< Referral ID to program group FW */ + ia_css_program_group_ID_t ID; + uint16_t program_manifest_offset; + uint16_t terminal_manifest_offset; + /**< Offset to private data (not part of the official API) */ + uint16_t private_data_offset; + /**< Offset to RBM manifest */ + uint16_t rbm_manifest_offset; + /**< Size of this structure */ + uint16_t size; + /**< Storage alignment requirement (in uint8_t) */ + uint8_t alignment; + /**< Total number of kernels in this program group */ + uint8_t kernel_count; + /**< Total number of program in this program group */ + uint8_t program_count; + /**< Total number of terminals on this program group */ + uint8_t terminal_count; + /**< Total number of independent subgraphs in this program group */ + uint8_t subgraph_count; + /**< Padding; esnures that rbm_manifest starts on 64bit alignment */ + uint8_t reserved[5]; +}; + +#define SIZE_OF_PROGRAM_MANIFEST_STRUCT_IN_BITS \ + (IA_CSS_KERNEL_BITMAP_BITS \ + + IA_CSS_PROGRAM_ID_BITS \ + + IA_CSS_PROGRAM_TYPE_BITS \ + + (3 * IA_CSS_UINT32_T_BITS) \ + + (VIED_NCI_RESOURCE_BITMAP_BITS * VIED_NCI_N_DEV_DFM_ID) \ + + (VIED_NCI_RESOURCE_BITMAP_BITS * VIED_NCI_N_DEV_DFM_ID) \ + + IA_CSS_UINT16_T_BITS \ + + (VIED_NCI_RESOURCE_SIZE_BITS * VIED_NCI_N_MEM_TYPE_ID) \ + + (VIED_NCI_RESOURCE_SIZE_BITS * VIED_NCI_N_DATA_MEM_TYPE_ID * 2) \ + + (VIED_NCI_RESOURCE_SIZE_BITS * VIED_NCI_N_DEV_CHN_ID * 2) \ + + (IA_CSS_UINT8_T_BITS * VIED_NCI_N_DEV_DFM_ID) \ + + (IA_CSS_PROCESS_MAX_CELLS * VIED_NCI_RESOURCE_ID_BITS) \ + + (VIED_NCI_RESOURCE_ID_BITS) \ + + (2 * IA_CSS_UINT8_T_BITS) \ + + (N_PADDING_UINT8_IN_PROGRAM_GROUP_MANFEST * IA_CSS_UINT8_T_BITS)) +/* + * This structure contains only the information required for resource + * management and construction of the process group. + * The header for the program binary load is separate + */ + +struct ia_css_program_manifest_s { + /**< Indicate which kernels lead to this program being used */ + ia_css_kernel_bitmap_t kernel_bitmap; + /**< Referral ID to a specific program FW, valid ID's != 0 */ + ia_css_program_ID_t ID; + /**< Specification of for exclusive or parallel programs */ + ia_css_program_type_t program_type; + /**< offset to add to reach parent. This is negative value.*/ + int32_t parent_offset; + uint32_t program_dependency_offset; + uint32_t terminal_dependency_offset; +#if (VIED_NCI_N_DEV_DFM_ID > 0) + /**< DFM port allocation of this program */ + vied_nci_resource_bitmap_t dfm_port_bitmap[VIED_NCI_N_DEV_DFM_ID]; + /**< Active DFM ports which need a kick + * If an empty port is configured to run in active mode, the empty + * port and the corresponding full port(s) in the stream must be kicked. + * The empty port must always be kicked aster the full port. + */ + vied_nci_resource_bitmap_t dfm_active_port_bitmap[VIED_NCI_N_DEV_DFM_ID]; +#endif + /**< Size of this structure */ + uint16_t size; + /**< (internal) Memory allocation size needs of this program */ + vied_nci_resource_size_t int_mem_size[VIED_NCI_N_MEM_TYPE_ID]; + /**< (external) Memory allocation size needs of this program */ + vied_nci_resource_size_t ext_mem_size[VIED_NCI_N_DATA_MEM_TYPE_ID]; + vied_nci_resource_size_t ext_mem_offset[VIED_NCI_N_DATA_MEM_TYPE_ID]; + /**< Device channel allocation size needs of this program */ + vied_nci_resource_size_t dev_chn_size[VIED_NCI_N_DEV_CHN_ID]; + vied_nci_resource_size_t dev_chn_offset[VIED_NCI_N_DEV_CHN_ID]; +#if (VIED_NCI_N_DEV_DFM_ID > 0) + /**< DFM ports are relocatable if value is set to 1. + * The flag is per dfm port type. + * This will not be supported for now. + */ + uint8_t is_dfm_relocatable[VIED_NCI_N_DEV_DFM_ID]; +#endif + /** Array of all the cells this program needs */ +#if IA_CSS_PROCESS_MAX_CELLS == 1 + vied_nci_resource_id_t cell_id; +#else + vied_nci_resource_id_t cells[IA_CSS_PROCESS_MAX_CELLS]; +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ + /**< (exclusive) indication of a cell type to be used by this program */ + vied_nci_resource_id_t cell_type_id; + + /**< Number of programs this program depends on */ + uint8_t program_dependency_count; + /**< Number of terminals this program depends on */ + uint8_t terminal_dependency_count; + /**< Padding bytes for 64bit alignment*/ +#if N_PADDING_UINT8_IN_PROGRAM_GROUP_MANFEST > 0 + /*hivecc does not allow an array of zero length*/ + uint8_t padding[N_PADDING_UINT8_IN_PROGRAM_GROUP_MANFEST]; +#endif +}; + +/* + *Calculation for manual size check for struct ia_css_data_terminal_manifest_s + */ +#define SIZE_OF_DATA_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + (SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + + IA_CSS_FRAME_FORMAT_BITMAP_BITS \ + + IA_CSS_CONNECTION_BITMAP_BITS \ + + IA_CSS_KERNEL_BITMAP_BITS \ + + (4 * (IA_CSS_UINT16_T_BITS * IA_CSS_N_DATA_DIMENSION)) \ + + IA_CSS_UINT16_T_BITS \ + + IA_CSS_UINT8_T_BITS \ + + (4*IA_CSS_UINT8_T_BITS)) +/* + * Inherited data terminal class + */ +struct ia_css_data_terminal_manifest_s { + /**< Data terminal base */ + ia_css_terminal_manifest_t base; + /**< Supported (4CC / MIPI / parameter) formats */ + ia_css_frame_format_bitmap_t frame_format_bitmap; + /**< Indicate which kernels lead to this terminal being used */ + ia_css_kernel_bitmap_t kernel_bitmap; + /**< Minimum size of the frame */ + uint16_t min_size[IA_CSS_N_DATA_DIMENSION]; + /**< Maximum size of the frame */ + uint16_t max_size[IA_CSS_N_DATA_DIMENSION]; + /**< Minimum size of a fragment that the program port can accept */ + uint16_t min_fragment_size[IA_CSS_N_DATA_DIMENSION]; + /**< Maximum size of a fragment that the program port can accept */ + uint16_t max_fragment_size[IA_CSS_N_DATA_DIMENSION]; + /**< Indicate if this terminal is derived from a principal terminal */ + uint16_t terminal_dependency; + /**< Indicate what (streaming) interface types this terminal supports */ + ia_css_connection_bitmap_t connection_bitmap; + /**< Indicates if compression is supported on the data associated with + * this terminal. '1' indicates compression is supported, + * '0' otherwise + */ + uint8_t compression_support; + uint8_t reserved[4]; +}; + +/* ============ Program Control Init Terminal Manifest - START ============ */ +#define N_PADDING_UINT8_IN_PROGCTRLINIT_MANIFEST_PROGRAM_DESC_STRUCT 4 +struct ia_css_program_control_init_manifest_program_desc_s { + uint16_t load_section_count; + uint16_t connect_section_count; + uint8_t padding[N_PADDING_UINT8_IN_PROGCTRLINIT_MANIFEST_PROGRAM_DESC_STRUCT]; +}; + +#define N_PADDING_UINT8_IN_PROGCTRLINIT_TERMINAL_MANIFEST_STRUCT 2 +struct ia_css_program_control_init_terminal_manifest_s { + ia_css_terminal_manifest_t base; + /* Number of programs in program group */ + uint32_t program_count; + /* + * Points to array of ia_css_program_control_init_terminal_program_desc_t + * with size program_count. + */ + uint16_t program_desc_offset; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PROGCTRLINIT_TERMINAL_MANIFEST_STRUCT]; +}; +/* ============ Program Control Init Terminal Manifest - END ============ */ + +extern void ia_css_program_manifest_init( + ia_css_program_manifest_t *blob, + const uint8_t program_dependency_count, + const uint8_t terminal_dependency_count); + +#endif /* __IA_CSS_PSYS_PROGRAM_GROUP_PRIVATE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_manifest.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_manifest.c new file mode 100644 index 0000000000000..6cacdecba4647 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_manifest.c @@ -0,0 +1,1240 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include +#include +/* for ia_css_kernel_bitmap_t, ia_css_kernel_bitmap_print */ +#include + +#include +#include "ia_css_psys_program_group_private.h" +#include "ia_css_psys_static_trace.h" + +#include +#include + +size_t ia_css_sizeof_program_manifest( + const uint8_t program_dependency_count, + const uint8_t terminal_dependency_count) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_sizeof_program_manifest(): enter:\n"); + + size += sizeof(ia_css_program_manifest_t); + size += program_dependency_count * sizeof(uint8_t); + size += terminal_dependency_count * sizeof(uint8_t); + size = ceil_mul(size, sizeof(uint64_t)); + + return size; +} + +bool ia_css_has_program_manifest_fixed_cell( + const ia_css_program_manifest_t *manifest) +{ + bool has_fixed_cell = false; + + vied_nci_cell_ID_t cell_id; + vied_nci_cell_type_ID_t cell_type_id; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_has_program_manifest_fixed_cell(): enter:\n"); + + verifexit(manifest != NULL); + + cell_id = ia_css_program_manifest_get_cell_ID(manifest); + cell_type_id = ia_css_program_manifest_get_cell_type_ID(manifest); + + has_fixed_cell = ((cell_id != VIED_NCI_N_CELL_ID) && + (cell_type_id == VIED_NCI_N_CELL_TYPE_ID)); + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_has_program_manifest_fixed_cell invalid argument\n"); + } + return has_fixed_cell; +} + +size_t ia_css_program_manifest_get_size( + const ia_css_program_manifest_t *manifest) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_size(): enter:\n"); + + if (manifest != NULL) { + size = manifest->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_size invalid argument\n"); + } + + return size; +} + +ia_css_program_ID_t ia_css_program_manifest_get_program_ID( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_ID_t program_id = IA_CSS_PROGRAM_INVALID_ID; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_program_ID(): enter:\n"); + + if (manifest != NULL) { + program_id = manifest->ID; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_program_ID invalid argument\n"); + } + return program_id; +} + +int ia_css_program_manifest_set_program_ID( + ia_css_program_manifest_t *manifest, + ia_css_program_ID_t id) +{ + int ret = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_program_ID(): enter:\n"); + + if (manifest != NULL) { + manifest->ID = id; + ret = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_program_ID failed (%i)\n", ret); + } + return ret; +} + +ia_css_program_group_manifest_t *ia_css_program_manifest_get_parent( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_group_manifest_t *parent = NULL; + char *base; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_parent(): enter:\n"); + + verifexit(manifest != NULL); + + base = (char *)((char *)manifest + manifest->parent_offset); + + parent = (ia_css_program_group_manifest_t *) (base); +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_parent invalid argument\n"); + } + return parent; +} + +int ia_css_program_manifest_set_parent_offset( + ia_css_program_manifest_t *manifest, + int32_t program_offset) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_parent_offset(): enter:\n"); + + verifexit(manifest != NULL); + + /* parent is at negative offset away from current program offset*/ + manifest->parent_offset = -program_offset; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_parent_offset failed (%i)\n", + retval); + } + return retval; +} + +ia_css_program_type_t ia_css_program_manifest_get_type( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_type_t program_type = IA_CSS_N_PROGRAM_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_type(): enter:\n"); + + if (manifest != NULL) { + program_type = manifest->program_type; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_type invalid argument\n"); + } + return program_type; +} + +int ia_css_program_manifest_set_type( + ia_css_program_manifest_t *manifest, + const ia_css_program_type_t program_type) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_type(): enter:\n"); + + if (manifest != NULL) { + manifest->program_type = program_type; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_type failed (%i)\n", retval); + } + return retval; +} + +ia_css_kernel_bitmap_t ia_css_program_manifest_get_kernel_bitmap( + const ia_css_program_manifest_t *manifest) +{ + ia_css_kernel_bitmap_t kernel_bitmap = ia_css_kernel_bitmap_clear(); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + kernel_bitmap = manifest->kernel_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_kernel_bitmap invalid argument\n"); + } + return kernel_bitmap; +} + +int ia_css_program_manifest_set_kernel_bitmap( + ia_css_program_manifest_t *manifest, + const ia_css_kernel_bitmap_t kernel_bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + manifest->kernel_bitmap = kernel_bitmap; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_kernel_bitmap failed (%i)\n", + retval); + } + return retval; +} + +vied_nci_cell_ID_t ia_css_program_manifest_get_cell_ID( + const ia_css_program_manifest_t *manifest) +{ + vied_nci_cell_ID_t cell_id = VIED_NCI_N_CELL_ID; +#if IA_CSS_PROCESS_MAX_CELLS > 1 + int i = 0; +#endif /* IA_CSS_PROCESS_MAX_CELLS > 1 */ + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_cell_ID(): enter:\n"); + + verifexit(manifest != NULL); + +#if IA_CSS_PROCESS_MAX_CELLS == 1 + cell_id = manifest->cell_id; +#else + for (i = 1; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + assert(manifest->cells[i] == VIED_NCI_N_CELL_ID); +#ifdef __HIVECC +#pragma hivecc unroll +#endif + } + cell_id = manifest->cells[0]; +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_cell_ID invalid argument\n"); + } + return cell_id; +} + +int ia_css_program_manifest_set_cell_ID( + ia_css_program_manifest_t *manifest, + const vied_nci_cell_ID_t cell_id) +{ + int retval = -1; +#if IA_CSS_PROCESS_MAX_CELLS > 1 + int i = 0; +#endif /* IA_CSS_PROCESS_MAX_CELLS > 1 */ + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_cell_ID(): enter:\n"); + if (manifest != NULL) { +#if IA_CSS_PROCESS_MAX_CELLS == 1 + manifest->cell_id = cell_id; +#else + manifest->cells[0] = cell_id; + for (i = 1; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + manifest->cells[i] = VIED_NCI_N_CELL_ID; + } +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_cell_ID failed (%i)\n", retval); + } + return retval; +} + +vied_nci_cell_type_ID_t ia_css_program_manifest_get_cell_type_ID( + const ia_css_program_manifest_t *manifest) +{ + vied_nci_cell_type_ID_t cell_type_id = VIED_NCI_N_CELL_TYPE_ID; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_cell_type_ID(): enter:\n"); + + verifexit(manifest != NULL); + + cell_type_id = (vied_nci_cell_type_ID_t)(manifest->cell_type_id); +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_cell_type_ID invalid argument\n"); + } + return cell_type_id; +} + +int ia_css_program_manifest_set_cell_type_ID( + ia_css_program_manifest_t *manifest, + const vied_nci_cell_type_ID_t cell_type_id) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_cell_type_ID(): enter:\n"); + if (manifest != NULL) { + manifest->cell_type_id = cell_type_id; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_cell_type_ID failed (%i)\n", + retval); + } + return retval; +} + +vied_nci_resource_size_t ia_css_program_manifest_get_int_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id) +{ + vied_nci_resource_size_t int_mem_size = 0; + vied_nci_cell_type_ID_t cell_type_id; + int mem_index; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_int_mem_size(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(mem_type_id < VIED_NCI_N_MEM_TYPE_ID); + + if (ia_css_has_program_manifest_fixed_cell(manifest)) { + vied_nci_cell_ID_t cell_id = + ia_css_program_manifest_get_cell_ID(manifest); + + cell_type_id = vied_nci_cell_get_type(cell_id); + } else { + cell_type_id = + ia_css_program_manifest_get_cell_type_ID(manifest); + } + + /* loop over vied_nci_cell_mem_type to verify mem_type_id for a + * specific cell_type_id + */ + for (mem_index = 0; mem_index < VIED_NCI_N_MEM_TYPE_ID; mem_index++) { + if ((int)mem_type_id == + (int)vied_nci_cell_type_get_mem_type( + cell_type_id, mem_index)) { + int_mem_size = manifest->int_mem_size[mem_index]; + } + } + +EXIT: + if (NULL == manifest || mem_type_id >= VIED_NCI_N_MEM_TYPE_ID) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_int_mem_size invalid argument\n"); + } + return int_mem_size; +} + +int ia_css_program_manifest_set_cells_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + int array_index = 0; + int bit_index; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_cells_bitmap(): enter:\n"); + + if (manifest != NULL) { + for (bit_index = 0; bit_index < VIED_NCI_N_CELL_ID; bit_index++) { + if (vied_nci_is_bit_set_in_bitmap(bitmap, bit_index)) { + verifexit(array_index < IA_CSS_PROCESS_MAX_CELLS); +#if IA_CSS_PROCESS_MAX_CELLS == 1 + manifest->cell_id = (vied_nci_cell_ID_t)bit_index; +#else + manifest->cells[array_index] = (vied_nci_cell_ID_t)bit_index; +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ + array_index++; + } + } + for (; array_index < IA_CSS_PROCESS_MAX_CELLS; array_index++) { +#if IA_CSS_PROCESS_MAX_CELLS == 1 + manifest->cell_id = VIED_NCI_N_CELL_ID; +#else + manifest->cells[array_index] = VIED_NCI_N_CELL_ID; +#endif /* IA_CSS_PROCESS_MAX_CELLS */ + } + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_cells_bitmap invalid argument\n"); + } +EXIT: + return retval; +} + +vied_nci_resource_bitmap_t ia_css_program_manifest_get_cells_bitmap( + const ia_css_program_manifest_t *manifest) +{ + vied_nci_resource_bitmap_t bitmap = 0; +#if IA_CSS_PROCESS_MAX_CELLS > 1 + int i = 0; +#endif /* IA_CSS_PROCESS_MAX_CELLS > 1 */ + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_cells_bitmap(): enter:\n"); + + verifexit(manifest != NULL); + +#if IA_CSS_PROCESS_MAX_CELLS == 1 + bitmap = (1 << manifest->cell_id); +#else + for (i = 0; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + if (manifest->cells[i] != VIED_NCI_N_CELL_ID) { + bitmap |= (1 << manifest->cells[i]); + } +#ifdef __HIVECC +#pragma hivecc unroll +#endif + } +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_cells_bitmap invalid argument\n"); + } + return bitmap; +} + +int ia_css_program_manifest_set_dfm_port_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_dfm_port_bitmap(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + manifest->dfm_port_bitmap[dfm_type_id] = bitmap; +#else + (void)bitmap; + (void)dfm_type_id; +#endif + retval = 0; + +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_dfm_port_bitmap invalid argument\n"); + } + return retval; +} + +int ia_css_program_manifest_set_dfm_active_port_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_dfm_active_port_bitmap(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + manifest->dfm_active_port_bitmap[dfm_type_id] = bitmap; +#else + (void)bitmap; + (void)dfm_type_id; +#endif + retval = 0; + +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_dfm_active_port_bitmap invalid argument\n"); + } + return retval; +} + +int ia_css_program_manifest_set_is_dfm_relocatable( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const uint8_t is_relocatable) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_is_dfm_relocatable(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + manifest->is_dfm_relocatable[dfm_type_id] = is_relocatable; +#else + (void)is_relocatable; + (void)dfm_type_id; +#endif + retval = 0; + +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_is_dfm_relocatable invalid argument\n"); + } + + return retval; +} + +uint8_t ia_css_program_manifest_get_is_dfm_relocatable( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id) +{ + uint8_t ret = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_is_dfm_relocatable(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + ret = manifest->is_dfm_relocatable[dfm_type_id]; +#else + ret = 0; + (void)dfm_type_id; +#endif +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_is_dfm_relocatable invalid argument\n"); + } + return ret; +} + +vied_nci_resource_bitmap_t ia_css_program_manifest_get_dfm_port_bitmap( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id) +{ + vied_nci_resource_bitmap_t bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_dfm_port_bitmap(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + bitmap = manifest->dfm_port_bitmap[dfm_type_id]; +#else + bitmap = 0; + (void)dfm_type_id; +#endif +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_dfm_port_bitmap invalid argument\n"); + } + return bitmap; +} + +vied_nci_resource_bitmap_t ia_css_program_manifest_get_dfm_active_port_bitmap( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id) +{ + vied_nci_resource_bitmap_t bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_dfm_active_port_bitmap(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + bitmap = manifest->dfm_active_port_bitmap[dfm_type_id]; +#else + bitmap = 0; + (void)dfm_type_id; +#endif +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_dfm_active_port_bitmap invalid argument\n"); + } + return bitmap; +} + +int ia_css_program_manifest_set_int_mem_size( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t int_mem_size) +{ + int retval = -1; + vied_nci_cell_type_ID_t cell_type_id; + int mem_index; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_int_mem_size(): enter:\n"); + + if (ia_css_has_program_manifest_fixed_cell(manifest)) { + vied_nci_cell_ID_t cell_id = + ia_css_program_manifest_get_cell_ID(manifest); + + cell_type_id = vied_nci_cell_get_type(cell_id); + } else { + cell_type_id = + ia_css_program_manifest_get_cell_type_ID(manifest); + } + + if (manifest != NULL && mem_type_id < VIED_NCI_N_MEM_TYPE_ID) { + /* loop over vied_nci_cell_mem_type to verify mem_type_id for + * a specific cell_type_id + */ + for (mem_index = 0; mem_index < VIED_NCI_N_MEM_TYPE_ID; + mem_index++) { + if ((int)mem_type_id == + (int)vied_nci_cell_type_get_mem_type( + cell_type_id, mem_index)) { + manifest->int_mem_size[mem_index] = + int_mem_size; + retval = 0; + } + } + } + if (retval != 0) { + IA_CSS_TRACE_2(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_int_mem_size cell_type_id %d has no mem_type_id %d\n", + (int)cell_type_id, (int)mem_type_id); + } + + return retval; +} + +vied_nci_resource_size_t ia_css_program_manifest_get_ext_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id) +{ + vied_nci_resource_size_t ext_mem_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_ext_mem_size(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID); + + ext_mem_size = manifest->ext_mem_size[mem_type_id]; +EXIT: + if (NULL == manifest || mem_type_id >= VIED_NCI_N_DATA_MEM_TYPE_ID) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_ext_mem_size invalid argument\n"); + } + return ext_mem_size; +} + +vied_nci_resource_size_t ia_css_program_manifest_get_ext_mem_offset( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id) +{ + vied_nci_resource_size_t ext_mem_offset = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_ext_mem_offset(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID); + + ext_mem_offset = manifest->ext_mem_offset[mem_type_id]; +EXIT: + if (NULL == manifest || mem_type_id >= VIED_NCI_N_DATA_MEM_TYPE_ID) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_ext_mem_offset invalid argument\n"); + } + return ext_mem_offset; +} + +int ia_css_program_manifest_set_ext_mem_size( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t ext_mem_size) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_ext_mem_size(): enter:\n"); + + if (manifest != NULL && mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID) { + manifest->ext_mem_size[mem_type_id] = ext_mem_size; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_ext_mem_size invalid argument\n"); + } + + return retval; +} + +int ia_css_program_manifest_set_ext_mem_offset( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t ext_mem_offset) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_ext_mem_offset(): enter:\n"); + + if (manifest != NULL && mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID) { + manifest->ext_mem_offset[mem_type_id] = ext_mem_offset; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_ext_mem_offset invalid argument\n"); + } + + return retval; +} + +vied_nci_resource_size_t ia_css_program_manifest_get_dev_chn_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id) +{ + vied_nci_resource_size_t dev_chn_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_dev_chn_size(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(dev_chn_id < VIED_NCI_N_DEV_CHN_ID); + + dev_chn_size = manifest->dev_chn_size[dev_chn_id]; +EXIT: + if (NULL == manifest || dev_chn_id >= VIED_NCI_N_DEV_CHN_ID) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_dev_chn_size invalid argument\n"); + } + return dev_chn_size; +} + +vied_nci_resource_size_t ia_css_program_manifest_get_dev_chn_offset( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id) +{ + vied_nci_resource_size_t dev_chn_offset = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_dev_chn_offset(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(dev_chn_id < VIED_NCI_N_DEV_CHN_ID); + + dev_chn_offset = manifest->dev_chn_offset[dev_chn_id]; +EXIT: + if (NULL == manifest || dev_chn_id >= VIED_NCI_N_DEV_CHN_ID) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_dev_chn_offset invalid argument\n"); + } + return dev_chn_offset; +} + +int ia_css_program_manifest_set_dev_chn_size( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t dev_chn_size) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_dev_chn_size(): enter:\n"); + + if (manifest != NULL && dev_chn_id < VIED_NCI_N_DEV_CHN_ID) { + manifest->dev_chn_size[dev_chn_id] = dev_chn_size; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_dev_chn_size invalid argument\n"); + } + + return retval; +} + +int ia_css_program_manifest_set_dev_chn_offset( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t dev_chn_offset) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_dev_chn_offset(): enter:\n"); + + if (manifest != NULL && dev_chn_id < VIED_NCI_N_DEV_CHN_ID) { + manifest->dev_chn_offset[dev_chn_id] = dev_chn_offset; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_dev_chn_offset invalid argument\n"); + } + + return retval; +} + +uint8_t ia_css_program_manifest_get_program_dependency_count( + const ia_css_program_manifest_t *manifest) +{ + uint8_t program_dependency_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_program_dependency_count(): enter:\n"); + + if (manifest != NULL) { + program_dependency_count = manifest->program_dependency_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_program_dependency_count invalid argument\n"); + } + return program_dependency_count; +} + +uint8_t ia_css_program_manifest_get_program_dependency( + const ia_css_program_manifest_t *manifest, + const unsigned int index) +{ + uint8_t program_dependency = IA_CSS_PROGRAM_INVALID_DEPENDENCY; + uint8_t *program_dep_ptr; + uint8_t program_dependency_count; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_program_dependency(): enter:\n"); + + program_dependency_count = + ia_css_program_manifest_get_program_dependency_count(manifest); + + if (index < program_dependency_count) { + program_dep_ptr = + (uint8_t *)((uint8_t *)manifest + + manifest->program_dependency_offset + + index * sizeof(uint8_t)); + program_dependency = *program_dep_ptr; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_program_dependency invalid argument\n"); + } + return program_dependency; +} + +int ia_css_program_manifest_set_program_dependency( + ia_css_program_manifest_t *manifest, + const uint8_t program_dependency, + const unsigned int index) +{ + int retval = -1; + uint8_t *program_dep_ptr; + uint8_t program_dependency_count; + uint8_t program_count; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_program_dependency(): enter:\n"); + + program_dependency_count = + ia_css_program_manifest_get_program_dependency_count(manifest); + program_count = + ia_css_program_group_manifest_get_program_count( + ia_css_program_manifest_get_parent(manifest)); + + if ((index < program_dependency_count) && + (program_dependency < program_count)) { + program_dep_ptr = (uint8_t *)((uint8_t *)manifest + + manifest->program_dependency_offset + + index*sizeof(uint8_t)); + *program_dep_ptr = program_dependency; + retval = 0; + } + + if (retval != 0) { + IA_CSS_TRACE_3(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_program_dependency(m, %d, %d) failed (%i)\n", + program_dependency, index, retval); + } + return retval; +} + +uint8_t ia_css_program_manifest_get_terminal_dependency_count( + const ia_css_program_manifest_t *manifest) +{ + uint8_t terminal_dependency_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_terminal_dependency_count(): enter:\n"); + + if (manifest != NULL) { + terminal_dependency_count = manifest->terminal_dependency_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_terminal_dependency_count invalid argument\n"); + } + return terminal_dependency_count; +} + +uint8_t ia_css_program_manifest_get_terminal_dependency( + const ia_css_program_manifest_t *manifest, + const unsigned int index) +{ + uint8_t terminal_dependency = IA_CSS_PROGRAM_INVALID_DEPENDENCY; + uint8_t *terminal_dep_ptr; + uint8_t terminal_dependency_count = + ia_css_program_manifest_get_terminal_dependency_count(manifest); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_terminal_dependency(): enter:\n"); + + if (index < terminal_dependency_count) { + terminal_dep_ptr = (uint8_t *)((uint8_t *)manifest + + manifest->terminal_dependency_offset + index); + terminal_dependency = *terminal_dep_ptr; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_terminal_dependency invalid argument\n"); + } + return terminal_dependency; +} + +int ia_css_program_manifest_set_terminal_dependency( + ia_css_program_manifest_t *manifest, + const uint8_t terminal_dependency, + const unsigned int index) +{ + int retval = -1; + uint8_t *terminal_dep_ptr; + uint8_t terminal_dependency_count = + ia_css_program_manifest_get_terminal_dependency_count(manifest); + uint8_t terminal_count = + ia_css_program_group_manifest_get_terminal_count( + ia_css_program_manifest_get_parent(manifest)); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_terminal_dependency(): enter:\n"); + + if ((index < terminal_dependency_count) && + (terminal_dependency < terminal_count)) { + terminal_dep_ptr = (uint8_t *)((uint8_t *)manifest + + manifest->terminal_dependency_offset + index); + *terminal_dep_ptr = terminal_dependency; + retval = 0; + } + + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_terminal_dependency failed (%i)\n", + retval); + } + return retval; +} + +bool ia_css_is_program_manifest_subnode_program_type( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_type_t program_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_program_manifest_subnode_program_type(): enter:\n"); + + program_type = ia_css_program_manifest_get_type(manifest); +/* The error return is the limit value, so no need to check on the manifest + * pointer + */ + return (program_type == IA_CSS_PROGRAM_TYPE_PARALLEL_SUB) || + (program_type == IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) || + (program_type == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB); +} + +bool ia_css_is_program_manifest_supernode_program_type( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_type_t program_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_program_manifest_supernode_program_type(): enter:\n"); + + program_type = ia_css_program_manifest_get_type(manifest); + +/* The error return is the limit value, so no need to check on the manifest + * pointer + */ + return (program_type == IA_CSS_PROGRAM_TYPE_PARALLEL_SUPER) || + (program_type == IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER) || + (program_type == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER); +} + +bool ia_css_is_program_manifest_singular_program_type( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_type_t program_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_program_manifest_singular_program_type(): enter:\n"); + + program_type = ia_css_program_manifest_get_type(manifest); + +/* The error return is the limit value, so no need to check on the manifest + * pointer + */ + return (program_type == IA_CSS_PROGRAM_TYPE_SINGULAR); +} + +void ia_css_program_manifest_init( + ia_css_program_manifest_t *blob, + const uint8_t program_dependency_count, + const uint8_t terminal_dependency_count) +{ + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, + "ia_css_program_manifest_init(): enter:\n"); + + /*TODO: add assert*/ + if (!blob) + return; + + blob->ID = 1; + blob->program_dependency_count = program_dependency_count; + blob->terminal_dependency_count = terminal_dependency_count; + blob->program_dependency_offset = sizeof(ia_css_program_manifest_t); + blob->terminal_dependency_offset = blob->program_dependency_offset + + sizeof(uint8_t) * program_dependency_count; + blob->size = + (uint16_t)ia_css_sizeof_program_manifest( + program_dependency_count, + terminal_dependency_count); +} + +/* We need to refactor those files in order to build in the firmware only + what is needed, switches are put current to workaround compilation problems + in the firmware (for example lack of uint64_t support) + supported in the firmware + */ +#if !defined(__HIVECC) + +#if defined(_MSC_VER) +/* WA for a visual studio compiler bug, refer to + developercommunity.visualstudio.com/content/problem/209359/ice-with-fpfast-in-156-and-msvc-daily-1413263051-p.html +*/ +#pragma optimize("", off) +#endif + +int ia_css_program_manifest_print( + const ia_css_program_manifest_t *manifest, + void *fid) +{ + int retval = -1; + int i, mem_index, dev_chn_index; + + vied_nci_cell_type_ID_t cell_type_id; + uint8_t program_dependency_count; + uint8_t terminal_dependency_count; + ia_css_kernel_bitmap_t bitmap; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, + "ia_css_program_manifest_print(): enter:\n"); + + verifexit(manifest != NULL); + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "sizeof(manifest) = %d\n", + (int)ia_css_program_manifest_get_size(manifest)); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "program ID = %d\n", + (int)ia_css_program_manifest_get_program_ID(manifest)); + + bitmap = ia_css_program_manifest_get_kernel_bitmap(manifest); + verifexit(ia_css_kernel_bitmap_print(bitmap, fid) == 0); + + if (ia_css_has_program_manifest_fixed_cell(manifest)) { + vied_nci_cell_ID_t cell_id = + ia_css_program_manifest_get_cell_ID(manifest); + + cell_type_id = vied_nci_cell_get_type(cell_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "cell(program) = %d\n", + (int)cell_id); + } else { + cell_type_id = + ia_css_program_manifest_get_cell_type_ID(manifest); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "cell type(program) = %d\n", + (int)cell_type_id); + + for (mem_index = 0; mem_index < (int)VIED_NCI_N_MEM_TYPE_ID; + mem_index++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(internal mem) type = %d\n", + (int)vied_nci_cell_type_get_mem_type(cell_type_id, mem_index)); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(internal mem) size = %d\n", + manifest->int_mem_size[mem_index]); + } + + for (mem_index = 0; mem_index < (int)VIED_NCI_N_DATA_MEM_TYPE_ID; + mem_index++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(external mem) type = %d\n", + (int)(vied_nci_mem_type_ID_t)mem_index); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(external mem) size = %d\n", + manifest->ext_mem_size[mem_index]); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(external mem) offset = %d\n", + manifest->ext_mem_offset[mem_index]); + } + + for (dev_chn_index = 0; dev_chn_index < (int)VIED_NCI_N_DEV_CHN_ID; + dev_chn_index++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(device channel) type = %d\n", + (int)dev_chn_index); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(device channel) size = %d\n", + manifest->dev_chn_size[dev_chn_index]); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(device channel) offset = %d\n", + manifest->dev_chn_offset[dev_chn_index]); + } +#if HAS_DFM + for (dev_chn_index = 0; dev_chn_index < (int)VIED_NCI_N_DEV_DFM_ID; + dev_chn_index++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(dfm port) type = %d\n", + (int)dev_chn_index); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(dfm port) port_bitmap = %d\n", + manifest->dfm_port_bitmap[dev_chn_index]); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(dfm port) active_port_bitmap = %d\n", + manifest->dfm_active_port_bitmap[dev_chn_index]); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(dfm port) is_dfm_relocatable = %d\n", + manifest->is_dfm_relocatable[dev_chn_index]); + } +#endif + +#if IA_CSS_PROCESS_MAX_CELLS == 1 + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(cells) bitmap = %d\n", + manifest->cell_id); +#else + for (i = 0; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(cells) bitmap = %d\n", + manifest->cells[i]); + } +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ + program_dependency_count = + ia_css_program_manifest_get_program_dependency_count(manifest); + if (program_dependency_count == 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "program_dependencies[%d] {};\n", + program_dependency_count); + } else { + uint8_t prog_dep; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "program_dependencies[%d] {\n", + program_dependency_count); + for (i = 0; i < (int)program_dependency_count - 1; i++) { + prog_dep = + ia_css_program_manifest_get_program_dependency( + manifest, i); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t %4d,\n", prog_dep); + } + prog_dep = + ia_css_program_manifest_get_program_dependency(manifest, i); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\t %4d }\n", prog_dep); + (void)prog_dep; + } + + terminal_dependency_count = + ia_css_program_manifest_get_terminal_dependency_count(manifest); + if (terminal_dependency_count == 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "terminal_dependencies[%d] {};\n", + terminal_dependency_count); + } else { + uint8_t term_dep; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "terminal_dependencies[%d] {\n", + terminal_dependency_count); + for (i = 0; i < (int)terminal_dependency_count - 1; i++) { + term_dep = + ia_css_program_manifest_get_terminal_dependency( + manifest, i); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t %4d,\n", term_dep); + } + term_dep = + ia_css_program_manifest_get_terminal_dependency(manifest, i); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\t %4d }\n", term_dep); + (void)term_dep; + } + (void)cell_type_id; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_print failed (%i)\n", retval); + } + return retval; +} + +#if defined(_MSC_VER) +/* WA for a visual studio compiler bug */ +#pragma optimize("", off) +#endif + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_terminal_manifest.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_terminal_manifest.c new file mode 100644 index 0000000000000..9d8434a13d8d9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_terminal_manifest.c @@ -0,0 +1,1137 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include + +/* Data object types on the terminals */ +#include +/* for ia_css_kernel_bitmap_t, ia_css_kernel_bitmap_clear, ia_css_... */ +#include + +#include "ia_css_psys_program_group_private.h" +#include "ia_css_terminal_manifest.h" +#include "ia_css_terminal_manifest_types.h" + +#include +#include +#include +#include "ia_css_psys_static_trace.h" + +/* We need to refactor those files in order to build in the firmware only + what is needed, switches are put current to workaround compilation problems + in the firmware (for example lack of uint64_t support) + supported in the firmware + */ +#if !defined(__HIVECC) +static const char *terminal_type_strings[IA_CSS_N_TERMINAL_TYPES + 1] = { + "IA_CSS_TERMINAL_TYPE_DATA_IN", + "IA_CSS_TERMINAL_TYPE_DATA_OUT", + "IA_CSS_TERMINAL_TYPE_PARAM_STREAM", + /**< Type 1-5 parameter input */ + "IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN", + /**< Type 1-5 parameter output */ + "IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT", + /**< Represent the new type of terminal for + * the "spatial dependent parameters", when params go in + */ + "IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN", + /**< Represent the new type of terminal for + * the "spatial dependent parameters", when params go out + */ + "IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT", + /**< Represent the new type of terminal for + * the explicit slicing, when params go in + */ + "IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN", + /**< Represent the new type of terminal for + * the explicit slicing, when params go out + */ + "IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT", + /**< State (private data) input */ + "IA_CSS_TERMINAL_TYPE_STATE_IN", + /**< State (private data) output */ + "IA_CSS_TERMINAL_TYPE_STATE_OUT", + "IA_CSS_TERMINAL_TYPE_PROGRAM", + "IA_CSS_TERMINAL_TYPR_PROGRAM_CONTROL_INIT", + "UNDEFINED_TERMINAL_TYPE"}; + +#endif + +bool ia_css_is_terminal_manifest_spatial_parameter_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_parameter_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return ((terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN) || + (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT)); +} + +bool ia_css_is_terminal_manifest_program_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_parameter_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM); +} + +bool ia_css_is_terminal_manifest_program_control_init_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_program_control_init_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT); +} + + +bool ia_css_is_terminal_manifest_parameter_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + /* will return an error value on error */ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_parameter_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT); +} + +bool ia_css_is_terminal_manifest_data_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + /* will return an error value on error */ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_data_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return ((terminal_type == IA_CSS_TERMINAL_TYPE_DATA_IN) || + (terminal_type == IA_CSS_TERMINAL_TYPE_DATA_OUT)); +} + +bool ia_css_is_terminal_manifest_sliced_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_sliced_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return ((terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN) || + (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT)); +} + +size_t ia_css_terminal_manifest_get_size( + const ia_css_terminal_manifest_t *manifest) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_get_size(): enter:\n"); + + if (manifest != NULL) { + size = manifest->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_terminal_manifest_get_size: invalid argument\n"); + } + return size; +} + +ia_css_terminal_type_t ia_css_terminal_manifest_get_type( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_get_type(): enter:\n"); + + if (manifest != NULL) { + terminal_type = manifest->terminal_type; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_terminal_manifest_get_type: invalid argument\n"); + } + return terminal_type; +} + +int ia_css_terminal_manifest_set_type( + ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_type_t terminal_type) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_set_type(): enter:\n"); + + if (manifest != NULL) { + manifest->terminal_type = terminal_type; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_terminal_manifest_set_type failed (%i)\n", + retval); + } + return retval; +} + +int ia_css_terminal_manifest_set_ID( + ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_ID_t ID) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_set_ID(): enter:\n"); + + if (manifest != NULL) { + manifest->ID = ID; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_terminal_manifest_set_ID failed (%i)\n", + retval); + } + return retval; +} + +ia_css_terminal_ID_t ia_css_terminal_manifest_get_ID( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_ID_t retval; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_get_ID(): enter:\n"); + + if (manifest != NULL) { + retval = manifest->ID; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_terminal_manifest_get_ID failed\n"); + retval = IA_CSS_TERMINAL_INVALID_ID; + } + return retval; +} + +ia_css_program_group_manifest_t *ia_css_terminal_manifest_get_parent( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_program_group_manifest_t *parent = NULL; + char *base; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_get_parent(): enter:\n"); + + verifexit(manifest != NULL); + + base = (char *)((char *)manifest + manifest->parent_offset); + + parent = (ia_css_program_group_manifest_t *)(base); +EXIT: + return parent; +} + +int ia_css_terminal_manifest_set_parent_offset( + ia_css_terminal_manifest_t *manifest, + int32_t terminal_offset) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_set_parent_offset(): enter:\n"); + + verifexit(manifest != NULL); + + /* parent is at negative offset away from current terminal offset*/ + manifest->parent_offset = -terminal_offset; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_terminal_manifest_set_parent_offset failed (%i)\n", + retval); + } + return retval; +} + +ia_css_frame_format_bitmap_t +ia_css_data_terminal_manifest_get_frame_format_bitmap( + const ia_css_data_terminal_manifest_t *manifest) +{ + ia_css_frame_format_bitmap_t bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_frame_format_bitmap(): enter:\n"); + + if (manifest != NULL) { + bitmap = manifest->frame_format_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_data_terminal_manifest_get_frame_format_bitmap invalid argument\n"); + } + return bitmap; +} + +int ia_css_data_terminal_manifest_set_frame_format_bitmap( + ia_css_data_terminal_manifest_t *manifest, + ia_css_frame_format_bitmap_t bitmap) +{ + int ret = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_frame_format_bitmap(): enter:\n"); + + if (manifest != NULL) { + manifest->frame_format_bitmap = bitmap; + ret = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_frame_format_bitmap failed (%i)\n", + ret); + } + + return ret; +} + +bool ia_css_data_terminal_manifest_can_support_compression( + const ia_css_data_terminal_manifest_t *manifest) +{ + bool compression_support = false; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_compression_support(): enter:\n"); + + if (manifest != NULL) { + /* compression_support is used boolean encoded in uint8_t. + * So we only need to check + * if this is non-zero + */ + compression_support = (manifest->compression_support != 0); + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_can_support_compression invalid argument\n"); + } + + return compression_support; +} + +int ia_css_data_terminal_manifest_set_compression_support( + ia_css_data_terminal_manifest_t *manifest, + bool compression_support) +{ + int ret = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_compression_support(): enter:\n"); + + if (manifest != NULL) { + manifest->compression_support = + (compression_support == true) ? 1 : 0; + ret = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_compression_support failed (%i)\n", + ret); + } + + return ret; +} + +ia_css_connection_bitmap_t ia_css_data_terminal_manifest_get_connection_bitmap( + const ia_css_data_terminal_manifest_t *manifest) +{ + ia_css_connection_bitmap_t connection_bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_connection_bitmap(): enter:\n"); + + if (manifest != NULL) { + connection_bitmap = manifest->connection_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_data_terminal_manifest_get_connection_bitmap invalid argument\n"); + } + return connection_bitmap; +} + +int ia_css_data_terminal_manifest_set_connection_bitmap( + ia_css_data_terminal_manifest_t *manifest, ia_css_connection_bitmap_t bitmap) +{ + int ret = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_connection_bitmap(): enter:\n"); + + if (manifest != NULL) { + assert(bitmap != 0); /* zero means there is no connection, this is invalid. */ + assert((bitmap >> IA_CSS_N_CONNECTION_TYPES) == 0); + + manifest->connection_bitmap = bitmap; + ret = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_data_terminal_manifest_set_connection_bitmap invalid argument\n"); + } + return ret; +} + +/* We need to refactor those files in order to build in the firmware only + what is needed, switches are put current to workaround compilation problems + in the firmware (for example lack of uint64_t support) + supported in the firmware + */ +#if !defined(__HIVECC) +ia_css_kernel_bitmap_t ia_css_data_terminal_manifest_get_kernel_bitmap( + const ia_css_data_terminal_manifest_t *manifest) +{ + ia_css_kernel_bitmap_t kernel_bitmap = ia_css_kernel_bitmap_clear(); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + kernel_bitmap = manifest->kernel_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_data_terminal_manifest_get_kernel_bitmap: invalid argument\n"); + } + return kernel_bitmap; +} + +int ia_css_data_terminal_manifest_set_kernel_bitmap( + ia_css_data_terminal_manifest_t *manifest, + const ia_css_kernel_bitmap_t kernel_bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + manifest->kernel_bitmap = kernel_bitmap; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_kernel_bitmap: failed (%i)\n", + retval); + } + + return retval; +} + +int ia_css_data_terminal_manifest_set_kernel_bitmap_unique( + ia_css_data_terminal_manifest_t *manifest, + const unsigned int index) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_kernel_bitmap_unique(): enter:\n"); + + if (manifest != NULL) { + ia_css_kernel_bitmap_t kernel_bitmap = + ia_css_kernel_bitmap_clear(); + + kernel_bitmap = ia_css_kernel_bitmap_set(kernel_bitmap, index); + verifexit(!ia_css_is_kernel_bitmap_empty(kernel_bitmap)); + verifexit(ia_css_data_terminal_manifest_set_kernel_bitmap( + manifest, kernel_bitmap) == 0); + retval = 0; + } + +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_kernel_bitmap_unique failed (%i)\n", + retval); + } + return retval; +} +#endif + +int ia_css_data_terminal_manifest_set_min_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t min_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_min_size(): enter:\n"); + + verifexit(manifest != NULL); + + manifest->min_size[IA_CSS_COL_DIMENSION] = + min_size[IA_CSS_COL_DIMENSION]; + manifest->min_size[IA_CSS_ROW_DIMENSION] = + min_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_min_size: invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_set_max_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t max_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_max_size(): enter:\n"); + + verifexit(manifest != NULL); + + manifest->max_size[IA_CSS_COL_DIMENSION] = + max_size[IA_CSS_COL_DIMENSION]; + manifest->max_size[IA_CSS_ROW_DIMENSION] = + max_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_max_size: invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_get_min_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t min_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_min_size(): enter:\n"); + + verifexit(manifest != NULL); + + min_size[IA_CSS_COL_DIMENSION] = + manifest->min_size[IA_CSS_COL_DIMENSION]; + min_size[IA_CSS_ROW_DIMENSION] = + manifest->min_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_get_min_size: invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_get_max_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t max_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_max_size(): enter:\n"); + + verifexit(manifest != NULL); + + max_size[IA_CSS_COL_DIMENSION] = + manifest->max_size[IA_CSS_COL_DIMENSION]; + max_size[IA_CSS_ROW_DIMENSION] = + manifest->max_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_get_max_size: invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_set_min_fragment_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t min_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_min_fragment_size(): enter:\n"); + + verifexit(manifest != NULL); + + manifest->min_fragment_size[IA_CSS_COL_DIMENSION] = + min_size[IA_CSS_COL_DIMENSION]; + manifest->min_fragment_size[IA_CSS_ROW_DIMENSION] = + min_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_min_fragment_size invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_set_max_fragment_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t max_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_max_fragment_size(): enter:\n"); + + verifexit(manifest != NULL); + + manifest->max_fragment_size[IA_CSS_COL_DIMENSION] = + max_size[IA_CSS_COL_DIMENSION]; + manifest->max_fragment_size[IA_CSS_ROW_DIMENSION] = + max_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_max_fragment_size invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_get_min_fragment_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t min_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_min_fragment_size(): enter:\n"); + + verifexit(manifest != NULL); + + min_size[IA_CSS_COL_DIMENSION] = + manifest->min_fragment_size[IA_CSS_COL_DIMENSION]; + min_size[IA_CSS_ROW_DIMENSION] = + manifest->min_fragment_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_get_min_fragment_size invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_get_max_fragment_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t max_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_max_fragment_size(): enter:\n"); + + verifexit(manifest != NULL); + + max_size[IA_CSS_COL_DIMENSION] = + manifest->max_fragment_size[IA_CSS_COL_DIMENSION]; + max_size[IA_CSS_ROW_DIMENSION] = + manifest->max_fragment_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_get_max_fragment_size invalid argument\n"); + } + return retval; +} + +/* We need to refactor those files in order to build in the firmware only + what is needed, switches are put current to workaround compilation problems + in the firmware (for example lack of uint64_t support) + supported in the firmware + */ +#if !defined(__HIVECC) + +#define PRINT_DIMENSION(name, var) IA_CSS_TRACE_3(PSYSAPI_STATIC, \ + INFO, "%s:\t%d %d\n", \ + (name), \ + (var)[IA_CSS_COL_DIMENSION], \ + (var)[IA_CSS_ROW_DIMENSION]) + +int ia_css_terminal_manifest_print( + const ia_css_terminal_manifest_t *manifest, + void *fid) +{ + int retval = -1; + ia_css_terminal_type_t terminal_type = + ia_css_terminal_manifest_get_type(manifest); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, + "ia_css_terminal_manifest_print(): enter:\n"); + + verifexit(manifest != NULL); + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "sizeof(manifest) = %d\n", + (int)ia_css_terminal_manifest_get_size(manifest)); + + PRINT("typeof(manifest) = %s\n", terminal_type_strings[terminal_type]); + + if (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT) { + ia_css_param_terminal_manifest_t *pterminal_manifest = + (ia_css_param_terminal_manifest_t *)manifest; + uint16_t section_count = + pterminal_manifest->param_manifest_section_desc_count; + int i; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "sections(manifest) = %d\n", (int)section_count); + for (i = 0; i < section_count; i++) { + const ia_css_param_manifest_section_desc_t *manifest = + ia_css_param_terminal_manifest_get_prm_sct_desc( + pterminal_manifest, i); + verifjmpexit(manifest != NULL); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "kernel_id = %d\n", (int)manifest->kernel_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "mem_type_id = %d\n", + (int)manifest->mem_type_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "max_mem_size = %d\n", + (int)manifest->max_mem_size); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "region_id = %d\n", + (int)manifest->region_id); + } + } else if (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT) { + ia_css_sliced_param_terminal_manifest_t + *sliced_terminal_manifest = + (ia_css_sliced_param_terminal_manifest_t *)manifest; + uint32_t kernel_id; + uint16_t section_count; + uint16_t section_idx; + + kernel_id = sliced_terminal_manifest->kernel_id; + section_count = + sliced_terminal_manifest->sliced_param_section_count; + + NOT_USED(kernel_id); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "kernel_id = %d\n", (int)kernel_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "section_count = %d\n", (int)section_count); + + for (section_idx = 0; section_idx < section_count; + section_idx++) { + ia_css_sliced_param_manifest_section_desc_t + *sliced_param_manifest_section_desc; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "section %d\n", (int)section_idx); + sliced_param_manifest_section_desc = + ia_css_sliced_param_terminal_manifest_get_sliced_prm_sct_desc( + sliced_terminal_manifest, section_idx); + verifjmpexit(sliced_param_manifest_section_desc != + NULL); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "mem_type_id = %d\n", + (int)sliced_param_manifest_section_desc->mem_type_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "region_id = %d\n", + (int)sliced_param_manifest_section_desc->region_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "max_mem_size = %d\n", + (int)sliced_param_manifest_section_desc->max_mem_size); + } + } else if (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM) { + ia_css_program_terminal_manifest_t *program_terminal_manifest = + (ia_css_program_terminal_manifest_t *)manifest; + uint32_t sequencer_info_kernel_id; + uint16_t max_kernel_fragment_sequencer_command_desc; + uint16_t kernel_fragment_sequencer_info_manifest_info_count; + uint16_t seq_info_idx; + + sequencer_info_kernel_id = + program_terminal_manifest->sequencer_info_kernel_id; + max_kernel_fragment_sequencer_command_desc = + program_terminal_manifest-> + max_kernel_fragment_sequencer_command_desc; + kernel_fragment_sequencer_info_manifest_info_count = + program_terminal_manifest-> + kernel_fragment_sequencer_info_manifest_info_count; + + NOT_USED(sequencer_info_kernel_id); + NOT_USED(max_kernel_fragment_sequencer_command_desc); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "sequencer_info_kernel_id = %d\n", + (int)sequencer_info_kernel_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "max_kernel_fragment_sequencer_command_desc = %d\n", + (int)max_kernel_fragment_sequencer_command_desc); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "kernel_fragment_sequencer_info_manifest_info_count = %d\n", + (int) + kernel_fragment_sequencer_info_manifest_info_count); + + for (seq_info_idx = 0; seq_info_idx < + kernel_fragment_sequencer_info_manifest_info_count; + seq_info_idx++) { + ia_css_kernel_fragment_sequencer_info_manifest_desc_t + *sequencer_info_manifest_desc; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "sequencer info %d\n", (int)seq_info_idx); + sequencer_info_manifest_desc = + ia_css_program_terminal_manifest_get_kernel_frgmnt_seq_info_desc + (program_terminal_manifest, seq_info_idx); + verifjmpexit(sequencer_info_manifest_desc != NULL); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "min_fragment_grid_slice_dimension[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + min_fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + min_fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "max_fragment_grid_slice_dimension[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + max_fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + max_fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "min_fragment_grid_slice_count[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + min_fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + min_fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "max_fragment_grid_slice_count[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + max_fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + max_fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "min_fragment_grid_point_decimation_factor[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + min_fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + min_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "max_fragment_grid_point_decimation_factor[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + max_fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + max_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "min_fragment_grid_overlay_on_pixel_topleft_index[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "max_fragment_grid_overlay_on_pixel_topleft_index[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "min_fragment_grid_overlay_on_pixel_dimension[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "max_fragment_grid_overlay_on_pixel_dimension[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + } + } else if (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT) { + ia_css_program_control_init_terminal_manifest_t *progctrlinit_man = + (ia_css_program_control_init_terminal_manifest_t *)manifest; + ia_css_program_control_init_terminal_manifest_print(progctrlinit_man); + } else if (terminal_type == IA_CSS_TERMINAL_TYPE_DATA_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_DATA_OUT) { + + ia_css_data_terminal_manifest_t *dterminal_manifest = + (ia_css_data_terminal_manifest_t *)manifest; + int i; + + NOT_USED(dterminal_manifest); + + verifexit(ia_css_kernel_bitmap_print( + ia_css_data_terminal_manifest_get_kernel_bitmap( + dterminal_manifest), fid) == 0); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "formats(manifest) = %04x\n", + (int)ia_css_data_terminal_manifest_get_frame_format_bitmap( + dterminal_manifest)); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "connection(manifest) = %04x\n", + (int)ia_css_data_terminal_manifest_get_connection_bitmap( + dterminal_manifest)); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "dependent(manifest) = %d\n", + (int)dterminal_manifest->terminal_dependency); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\tmin_size[%d] = {\n", + IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d,\n", dterminal_manifest->min_size[i]); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d }\n", dterminal_manifest->min_size[i]); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\tmax_size[%d] = {\n", IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d,\n", dterminal_manifest->max_size[i]); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d }\n", dterminal_manifest->max_size[i]); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\tmin_fragment_size[%d] = {\n", + IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d,\n", + dterminal_manifest->min_fragment_size[i]); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d }\n", + dterminal_manifest->min_fragment_size[i]); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\tmax_fragment_size[%d] = {\n", + IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d,\n", + dterminal_manifest->max_fragment_size[i]); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d }\n", + dterminal_manifest->max_fragment_size[i]); + + } else if (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT) { + + ia_css_spatial_param_terminal_manifest_t *stm = + (ia_css_spatial_param_terminal_manifest_t *)manifest; + ia_css_frame_grid_param_manifest_section_desc_t *sec; + int sec_count = + stm->frame_grid_param_manifest_section_desc_count; + ia_css_fragment_grid_manifest_desc_t *fragd = + &stm->common_fragment_grid_desc; + ia_css_frame_grid_manifest_desc_t *framed = + &stm->frame_grid_desc; + int sec_index; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "kernel_id:\t\t%d\n", + stm->kernel_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "compute_units_p_elem:\t%d\n", + stm->compute_units_p_elem); + + PRINT_DIMENSION("min_fragment_grid_dimension", + fragd->min_fragment_grid_dimension); + PRINT_DIMENSION("max_fragment_grid_dimension", + fragd->max_fragment_grid_dimension); + PRINT_DIMENSION("min_frame_grid_dimension", + framed->min_frame_grid_dimension); + PRINT_DIMENSION("max_frame_grid_dimension", + framed->max_frame_grid_dimension); + + NOT_USED(framed); + NOT_USED(fragd); + + for (sec_index = 0; sec_index < sec_count; sec_index++) { + sec = ia_css_spatial_param_terminal_manifest_get_frm_grid_prm_sct_desc( + stm, sec_index); + verifjmpexit(sec != NULL); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, "--------------------------\n"); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\tmem_type_id:\t%d\n", + sec->mem_type_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\tregion_id:\t%d\n", + sec->region_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\telem_size:\t%d\n", + sec->elem_size); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\tmax_mem_size:\t%d\n", + sec->max_mem_size); + } + } else if (terminal_type < IA_CSS_N_TERMINAL_TYPES) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "terminal type can not be pretty printed, not supported\n"); + } + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_terminal_manifest_print failed (%i)\n", + retval); + } + return retval; +} + +/* Program control init Terminal */ +unsigned int ia_css_program_control_init_terminal_manifest_get_connect_section_count( + const ia_css_program_control_init_manifest_program_desc_t *prog) +{ + assert(prog); + return prog->connect_section_count; +} + + +unsigned int ia_css_program_control_init_terminal_manifest_get_load_section_count( + const ia_css_program_control_init_manifest_program_desc_t *prog) +{ + assert(prog); + return prog->load_section_count; +} + +unsigned int ia_css_program_control_init_terminal_manifest_get_size( + const uint16_t nof_programs, + const uint16_t *nof_load_sections, + const uint16_t *nof_connect_sections) +{ + (void)nof_load_sections; /* might be needed in future */ + (void)nof_connect_sections; /* might be needed in future */ + + return sizeof(ia_css_program_control_init_terminal_manifest_t) + + nof_programs * + sizeof(ia_css_program_control_init_manifest_program_desc_t); +} + +ia_css_program_control_init_manifest_program_desc_t * +ia_css_program_control_init_terminal_manifest_get_program_desc( + const ia_css_program_control_init_terminal_manifest_t *terminal, + unsigned int program) +{ + ia_css_program_control_init_manifest_program_desc_t *progs; + + assert(terminal != NULL); + assert(program < terminal->program_count); + + progs = (ia_css_program_control_init_manifest_program_desc_t *) + ((const char *)terminal + terminal->program_desc_offset); + + return &progs[program]; +} + +int ia_css_program_control_init_terminal_manifest_init( + ia_css_program_control_init_terminal_manifest_t *terminal, + const uint16_t nof_programs, + const uint16_t *nof_load_sections, + const uint16_t *nof_connect_sections) +{ + unsigned int i; + ia_css_program_control_init_manifest_program_desc_t *progs; + + if (terminal == NULL) { + return -EFAULT; + } + + terminal->program_count = nof_programs; + terminal->program_desc_offset = + sizeof(ia_css_program_control_init_terminal_manifest_t); + + progs = ia_css_program_control_init_terminal_manifest_get_program_desc( + terminal, 0); + + for (i = 0; i < nof_programs; i++) { + progs[i].load_section_count = nof_load_sections[i]; + progs[i].connect_section_count = nof_connect_sections[i]; + } + return 0; +} + +void ia_css_program_control_init_terminal_manifest_print( + ia_css_program_control_init_terminal_manifest_t *terminal) +{ + unsigned int i; + + ia_css_program_control_init_manifest_program_desc_t *progs; + + progs = ia_css_program_control_init_terminal_manifest_get_program_desc( + terminal, 0); + + assert(progs); + (void)progs; + + for (i = 0; i < terminal->program_count; i++) { + IA_CSS_TRACE_3(PSYSAPI_STATIC, INFO, + "program index: %d, load sec: %d, connect sec: %d\n", + i, + progs[i].load_section_count, + progs[i].connect_section_count); + } +} + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/reg_dump/src/psys/bxtB0_gen_reg_dump/ia_css_debug_dump.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/reg_dump/src/psys/bxtB0_gen_reg_dump/ia_css_debug_dump.c new file mode 100644 index 0000000000000..c51d65c8cb647 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/reg_dump/src/psys/bxtB0_gen_reg_dump/ia_css_debug_dump.c @@ -0,0 +1,15 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#include "ia_css_debug_dump.h" + void ia_css_debug_dump(void) {} \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/reg_dump/src/psys/bxtB0_gen_reg_dump/ia_css_debug_dump.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/reg_dump/src/psys/bxtB0_gen_reg_dump/ia_css_debug_dump.h new file mode 100644 index 0000000000000..5dd23ddbd180b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/reg_dump/src/psys/bxtB0_gen_reg_dump/ia_css_debug_dump.h @@ -0,0 +1,17 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#ifndef __IA_CSS_DEBUG_DUMP_H_ + #define __IA_CSS_DEBUG_DUMP_H_ + void ia_css_debug_dump(void); + #endif /* __IA_CSS_DEBUG_DUMP_H_ */ \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/reg_dump/src/reg_dump_generic_bridge.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/reg_dump/src/reg_dump_generic_bridge.c new file mode 100644 index 0000000000000..9b9161ae78cf2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/reg_dump/src/reg_dump_generic_bridge.c @@ -0,0 +1,39 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include +#include "ia_css_trace.h" +#ifdef USE_LOGICAL_SSIDS +/* + Logical names can be used to define the SSID + In order to resolve these names the following include file should be provided + and the define above should be enabled +*/ +#include +#endif + +#define REG_DUMP_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#define REG_DUMP_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED + +/* SSID value is defined in test makefiles as either isys0 or psys0 */ +#define REG_DUMP_READ_REGISTER(addr) vied_subsystem_load_32(SSID, addr) + +#define REG_DUMP_PRINT_0(...) \ +EXPAND_VA_ARGS(IA_CSS_TRACE_0(REG_DUMP, VERBOSE, __VA_ARGS__)) +#define REG_DUMP_PRINT_1(...) \ +EXPAND_VA_ARGS(IA_CSS_TRACE_1(REG_DUMP, VERBOSE, __VA_ARGS__)) +#define EXPAND_VA_ARGS(x) x + +/* Including generated source code for reg_dump */ +#include "ia_css_debug_dump.c" diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/interface/regmem_access.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/interface/regmem_access.h new file mode 100644 index 0000000000000..d4576af936f6d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/interface/regmem_access.h @@ -0,0 +1,67 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_ACCESS_H +#define __REGMEM_ACCESS_H + +#include "storage_class.h" + +enum regmem_id { + /* pass pkg_dir address to SPC in non-secure mode */ + PKG_DIR_ADDR_REG = 0, + /* pass syscom configuration to SPC */ + SYSCOM_CONFIG_REG = 1, + /* syscom state - modified by SP */ + SYSCOM_STATE_REG = 2, + /* syscom commands - modified by the host */ + SYSCOM_COMMAND_REG = 3, + /* Store interrupt status - updated by SP */ + SYSCOM_IRQ_REG = 4, + /* Store VTL0_ADDR_MASK in trusted secure regision - provided by host.*/ + SYSCOM_VTL0_ADDR_MASK = 5, +#if HAS_DUAL_CMD_CTX_SUPPORT + /* Initialized if trustlet exists - updated by host */ + TRUSTLET_STATUS = 6, + /* identify if SPC access blocker programming is completed - updated by SP */ + AB_SPC_STATUS = 7, + /* first syscom queue pointer register */ + SYSCOM_QPR_BASE_REG = 8 +#else + /* first syscom queue pointer register */ + SYSCOM_QPR_BASE_REG = 6 +#endif +}; + +#if HAS_DUAL_CMD_CTX_SUPPORT +/* Bit 0: for untrusted non-secure DRV driver on VTL0 + * Bit 1: for trusted secure TEE driver on VTL1 + */ +#define SYSCOM_IRQ_VTL0_MASK 0x1 +#define SYSCOM_IRQ_VTL1_MASK 0x2 +#endif + +STORAGE_CLASS_INLINE unsigned int +regmem_load_32(unsigned int mem_address, unsigned int reg, unsigned int ssid); + +STORAGE_CLASS_INLINE void +regmem_store_32(unsigned int mem_address, unsigned int reg, unsigned int value, + unsigned int ssid); + +#ifdef __VIED_CELL +#include "regmem_access_cell.h" +#else +#include "regmem_access_host.h" +#endif + +#endif /* __REGMEM_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/regmem.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/regmem.mk new file mode 100644 index 0000000000000..24ebc1c325d8e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/regmem.mk @@ -0,0 +1,32 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +ifndef REGMEM_MK +REGMEM_MK=1 + +# MODULE is REGMEM + +REGMEM_DIR=$${MODULES_DIR}/regmem + +REGMEM_INTERFACE=$(REGMEM_DIR)/interface +REGMEM_SOURCES=$(REGMEM_DIR)/src + +REGMEM_HOST_FILES = +REGMEM_FW_FILES = $(REGMEM_SOURCES)/regmem.c + +REGMEM_CPPFLAGS = -I$(REGMEM_INTERFACE) -I$(REGMEM_SOURCES) +REGMEM_HOST_CPPFLAGS = $(REGMEM_CPPFLAGS) +REGMEM_FW_CPPFLAGS = $(REGMEM_CPPFLAGS) + +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/src/regmem_access_host.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/src/regmem_access_host.h new file mode 100644 index 0000000000000..8878d7074fabb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/src/regmem_access_host.h @@ -0,0 +1,41 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_ACCESS_HOST_H +#define __REGMEM_ACCESS_HOST_H + +#include "regmem_access.h" /* implemented interface */ + +#include "storage_class.h" +#include "regmem_const.h" +#include +#include "ia_css_cmem.h" + +STORAGE_CLASS_INLINE unsigned int +regmem_load_32(unsigned int mem_addr, unsigned int reg, unsigned int ssid) +{ + /* No need to add REGMEM_OFFSET, it is already included in mem_addr. */ + return ia_css_cmem_load_32(ssid, mem_addr + (REGMEM_WORD_BYTES*reg)); +} + +STORAGE_CLASS_INLINE void +regmem_store_32(unsigned int mem_addr, unsigned int reg, + unsigned int value, unsigned int ssid) +{ + /* No need to add REGMEM_OFFSET, it is already included in mem_addr. */ + ia_css_cmem_store_32(ssid, mem_addr + (REGMEM_WORD_BYTES*reg), + value); +} + +#endif /* __REGMEM_ACCESS_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/src/regmem_const.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/src/regmem_const.h new file mode 100644 index 0000000000000..ac7e3a98a434f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/regmem/src/regmem_const.h @@ -0,0 +1,28 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_CONST_H +#define __REGMEM_CONST_H + +#ifndef REGMEM_SIZE +#define REGMEM_SIZE (16) +#endif /* REGMEM_SIZE */ +#ifndef REGMEM_OFFSET +#define REGMEM_OFFSET (0) +#endif /* REGMEM_OFFSET */ +#ifndef REGMEM_WORD_BYTES +#define REGMEM_WORD_BYTES (4) +#endif + +#endif /* __REGMEM_CONST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm.h new file mode 100644 index 0000000000000..4a04a98903264 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm.h @@ -0,0 +1,173 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_H +#define __IA_CSS_RBM_H + +#include "ia_css_rbm_storage_class.h" +#include + +#define IA_CSS_RBM_BITS 64 +/** An element is a 32 bit unsigned integer. 64 bit integers might cause + * problems in the compiler. + */ +#define IA_CSS_RBM_ELEM_TYPE uint32_t +#define IA_CSS_RBM_ELEM_BITS \ + (sizeof(IA_CSS_RBM_ELEM_TYPE)*8) +#define IA_CSS_RBM_NOF_ELEMS \ + ((IA_CSS_RBM_BITS) / (IA_CSS_RBM_ELEM_BITS)) + +/** Users should make no assumption about the actual type of + * ia_css_rbm_t. + */ +typedef struct { + IA_CSS_RBM_ELEM_TYPE data[IA_CSS_RBM_NOF_ELEMS]; +} ia_css_rbm_elems_t; +typedef ia_css_rbm_elems_t ia_css_rbm_t; + +/** Print the bits of a routing bitmap + * @return < 0 on error + */ +IA_CSS_RBM_STORAGE_CLASS_H +int ia_css_rbm_print( + const ia_css_rbm_t bitmap, + void *fid); + +/** Create an empty routing bitmap + * @return bitmap = 0 + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_clear(void); + +/** Creates the complement of a routing bitmap + * @param bitmap[in] routing bitmap + * @return ~bitmap + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_complement( + const ia_css_rbm_t bitmap); + +/** Create the union of two routing bitmaps + * @param bitmap0[in] routing bitmap 0 + * @param bitmap1[in] routing bitmap 1 + * @return bitmap0 | bitmap1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_union( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1); + +/** Create the intersection of two routing bitmaps + * @param bitmap0[in] routing bitmap 0 + * @param bitmap1[in] routing bitmap 1 + * @return bitmap0 & bitmap1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_intersection( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1); + +/** Check if the routing bitmaps is empty + * @param bitmap[in] routing bitmap + * @return bitmap == 0 + */ +IA_CSS_RBM_STORAGE_CLASS_H +bool ia_css_is_rbm_empty( + const ia_css_rbm_t bitmap); + +/** Check if the intersection of two routing bitmaps is empty + * @param bitmap0[in] routing bitmap 0 + * @param bitmap1[in] routing bitmap 1 + * @return (bitmap0 & bitmap1) == 0 + */ +IA_CSS_RBM_STORAGE_CLASS_H +bool ia_css_is_rbm_intersection_empty( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1); + +/** Check if the second routing bitmap is a subset of the first (or equal) + * @param bitmap0[in] routing bitmap 0 + * @param bitmap1[in routing bitmap 1 + * Note: An empty set is always a subset, this function + * returns true if bitmap 1 is empty + * @return (bitmap0 & bitmap1) == bitmap1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +bool ia_css_is_rbm_subset( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1); + +/** Check if the routing bitmaps are equal + * @param bitmap0[in] routing bitmap 0 + * @param bitmap1[in] routing bitmap 1 + * @return bitmap0 == bitmap1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +bool ia_css_is_rbm_equal( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1); + +/** Checks whether a specific kernel bit is set + * @return bitmap[index] == 1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +int ia_css_is_rbm_set( + const ia_css_rbm_t bitmap, + const unsigned int index); + +/** Create the union of a routing bitmap with a onehot bitmap + * with a bit set at index + * @return bitmap[index] |= 1 +*/ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_set( + const ia_css_rbm_t bitmap, + const unsigned int index); + +/** Creates routing bitmap using a uint64 value. + * @return bitmap with the same bits set as in value (provided that width of bitmap is sufficient). + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_create_from_uint64( + const uint64_t value); + +/** Converts an ia_css_rbm_t type to uint64_t. Note that if + * ia_css_rbm_t contains more then 64 bits, only the lowest 64 bits + * are returned. + * @return uint64_t representation of value + */ +IA_CSS_RBM_STORAGE_CLASS_H +uint64_t ia_css_rbm_to_uint64( + const ia_css_rbm_t value); + +/** Creates a routing bitmap with the bit at index 'index' removed. + * @return ~(1 << index) & bitmap + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_unset( + const ia_css_rbm_t bitmap, + const unsigned int index); + +/** Create a onehot routing bitmap with a bit set at index + * @return bitmap[index] = 1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_bit_mask( + const unsigned int index); + +#ifdef __IA_CSS_RBM_INLINE__ +#include "ia_css_rbm_impl.h" +#endif /* __IA_CSS_RBM_INLINE__ */ + +#endif /* __IA_CSS_RBM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest.h new file mode 100644 index 0000000000000..f497a7de90a93 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest.h @@ -0,0 +1,133 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_MANIFEST_H +#define __IA_CSS_RBM_MANIFEST_H + +#include "type_support.h" +#include "ia_css_rbm_manifest_types.h" + +/** Returns the descriptor size of the RBM manifest. + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +unsigned int +ia_css_rbm_manifest_get_size(void); + +/** Initializes the RBM manifest. + * @param rbm[in] Routing bitmap. + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +void +ia_css_rbm_manifest_init(struct ia_css_rbm_manifest_s *rbm); + +/** Returns a pointer to the array of mux descriptors. + * @param manifest[in] Routing bitmap manifest. + * @return NULL on error + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +ia_css_rbm_mux_desc_t * +ia_css_rbm_manifest_get_muxes(const ia_css_rbm_manifest_t *manifest); + +/** Returns the size of mux descriptors array. + * @param manifest[in] Routing bitmap manifest. + * @return size + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +unsigned int +ia_css_rbm_manifest_get_mux_count(const ia_css_rbm_manifest_t *manifest); + +/** Returns a pointer to the array of validation descriptors. + * @param manifest[in] Routing bitmap manifest. + * @return NULL on error + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +ia_css_rbm_validation_rule_t * +ia_css_rbm_manifest_get_validation_rules(const ia_css_rbm_manifest_t *manifest); + +/** Returns the size of the validation descriptor array. + * @param manifest[in] Routing bitmap manifest. + * @return size + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +unsigned int +ia_css_rbm_manifest_get_validation_rule_count(const ia_css_rbm_manifest_t *manifest); + +/** Returns a pointer to the array of terminal routing descriptors. + * @param manifest[in] Routing bitmap manifest. + * @return NULL on error + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +ia_css_rbm_terminal_routing_desc_t * +ia_css_rbm_manifest_get_terminal_routing_desc(const ia_css_rbm_manifest_t *manifest); + +/** \brief Returns the size of the terminal routing descriptor array. + * Note: pretty printing differs from on host and on IPU. + * @param manifest[in] Routing bitmap manifest. + * @return size + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +unsigned int +ia_css_rbm_manifest_get_terminal_routing_desc_count(const ia_css_rbm_manifest_t *manifest); + +/** Pretty prints the routing bitmap manifest. + * @param manifest[in] Routing bitmap manifest. + */ +void +ia_css_rbm_manifest_print(const ia_css_rbm_manifest_t *manifest); + +/** \brief Pretty prints a RBM (routing bitmap). + * Note: pretty printing differs from on host and on IPU. + * @param rbm[in] Routing bitmap. + * @param mux[in] List of mux descriptors corresponding to rbm. + * @param mux_desc_count[in] Number of muxes in list mux. + */ +void +ia_css_rbm_pretty_print( + const ia_css_rbm_t *rbm, + const ia_css_rbm_mux_desc_t *mux, + unsigned int mux_desc_count); + +/** \brief check for the validity of a routing bitmap. + * @param manifest[in] Routing bitmap manifest. + * @param rbm[in] Routing bitmap + * @return true on match. + */ +bool +ia_css_rbm_manifest_check_rbm_validity( + const ia_css_rbm_manifest_t *manifest, + const ia_css_rbm_t *rbm); + +/** \brief sets, using manifest info, the value of a mux in the routing bitmap. + * @param rbm[in] Routing bitmap. + * @param mux[in] List of mux descriptors corresponding to rbm. + * @param mux_count[in] Number of muxes in list mux. + * @param gp_dev_id[in] ID of sub system (PSA/ISA) where the mux is located. + * @param mux_id[in] ID of mux to set configuration for. + * @param value[in] Value of the mux. + * @return routing bitmap. + */ +ia_css_rbm_t +ia_css_rbm_set_mux( + ia_css_rbm_t rbm, + ia_css_rbm_mux_desc_t *mux, + unsigned int mux_count, + unsigned int gp_dev_id, + unsigned int mux_id, + unsigned int value); + +#ifdef __IA_CSS_RBM_MANIFEST_INLINE__ +#include "ia_css_rbm_manifest_impl.h" +#endif /* __IA_CSS_RBM_MANIFEST_INLINE__ */ + +#endif /* __IA_CSS_RBM_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest_types.h new file mode 100644 index 0000000000000..ade20446b9f64 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest_types.h @@ -0,0 +1,95 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_MANIFEST_TYPES_H +#define __IA_CSS_RBM_MANIFEST_TYPES_H + +#include "ia_css_rbm.h" +#include "vied_nci_psys_resource_model.h" + +#ifndef VIED_NCI_RBM_MAX_MUX_COUNT +#error Please define VIED_NCI_RBM_MAX_MUX_COUNT +#endif +#ifndef VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT +#error Please define VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT +#endif +#ifndef VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT +#error Please define VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT +#endif +#ifndef N_PADDING_UINT8_IN_RBM_MANIFEST +#error Please define N_PADDING_UINT8_IN_RBM_MANIFEST +#endif + +#define SIZE_OF_RBM_MUX_DESC_S ( \ + (4 * IA_CSS_UINT8_T_BITS)) + +typedef struct ia_css_rbm_mux_desc_s { + uint8_t gp_dev_id; + uint8_t mux_id; + uint8_t offset; + uint8_t size_bits; +} ia_css_rbm_mux_desc_t; + +#define SIZE_OF_RBM_VALIDATION_RULE_DESC_S ( \ + (2 * IA_CSS_RBM_BITS) \ + + (1 * IA_CSS_UINT32_T_BITS)) + +typedef struct ia_css_rbm_validation_rule_s { + ia_css_rbm_t match; /* RBM is an array of 32 bit elements */ + ia_css_rbm_t mask; + uint32_t expected_value; +} ia_css_rbm_validation_rule_t; + +#define SIZE_OF_RBM_TERMINAL_ROUTING_DESC_S ( \ + (4 * IA_CSS_UINT8_T_BITS)) + +typedef struct ia_css_rbm_terminal_routing_desc_s { + uint8_t terminal_id; + uint8_t connection_state; + uint8_t mux_id; + uint8_t state; +} ia_css_rbm_terminal_routing_desc_t; + +#define SIZE_OF_RBM_MANIFEST_S ( \ + (VIED_NCI_RBM_MAX_MUX_COUNT * SIZE_OF_RBM_MUX_DESC_S) \ + + (VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT * SIZE_OF_RBM_VALIDATION_RULE_DESC_S) \ + + (VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT * SIZE_OF_RBM_TERMINAL_ROUTING_DESC_S) \ + + (3 * IA_CSS_UINT16_T_BITS) \ + + (N_PADDING_UINT8_IN_RBM_MANIFEST * IA_CSS_UINT8_T_BITS)) + +typedef struct ia_css_rbm_manifest_s { +#if VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT > 0 + ia_css_rbm_validation_rule_t + validation_rules[VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT]; +#endif + uint16_t mux_desc_count; + uint16_t validation_rule_count; + uint16_t terminal_routing_desc_count; + +#if VIED_NCI_RBM_MAX_MUX_COUNT > 0 + ia_css_rbm_mux_desc_t + mux_desc[VIED_NCI_RBM_MAX_MUX_COUNT]; +#endif + +#if VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT > 0 + ia_css_rbm_terminal_routing_desc_t + terminal_routing_desc[VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT]; +#endif + +#if N_PADDING_UINT8_IN_RBM_MANIFEST > 0 + uint8_t padding[N_PADDING_UINT8_IN_RBM_MANIFEST]; +#endif +} ia_css_rbm_manifest_t; + +#endif /* __IA_CSS_RBM_MANIFEST_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_storage_class.h new file mode 100644 index 0000000000000..9548e9a9fabbc --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_storage_class.h @@ -0,0 +1,36 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_STORAGE_CLASS_H +#define __IA_CSS_RBM_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __IA_CSS_RBM_INLINE__ +#define IA_CSS_RBM_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_RBM_STORAGE_CLASS_C +#else +#define IA_CSS_RBM_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_RBM_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#ifndef __IA_CSS_RBM_MANIFEST_INLINE__ +#define IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +#else +#define IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_RBM_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_trace.h new file mode 100644 index 0000000000000..dd060323da5c2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_trace.h @@ -0,0 +1,77 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_TRACE_H +#define __IA_CSS_RBM_TRACE_H + +#include "ia_css_trace.h" + +/* Not using 0 to identify wrong configuration being passed from the .mk file outside. +* Log levels not in the range below will cause a "No RBM_TRACE_CONFIG Tracing level defined" +*/ +#define RBM_TRACE_LOG_LEVEL_OFF 1 +#define RBM_TRACE_LOG_LEVEL_NORMAL 2 +#define RBM_TRACE_LOG_LEVEL_DEBUG 3 + +#define RBM_TRACE_CONFIG_DEFAULT RBM_TRACE_LOG_LEVEL_NORMAL + +#if !defined(RBM_TRACE_CONFIG) +# define RBM_TRACE_CONFIG RBM_TRACE_CONFIG_DEFAULT +#endif + +/* IPU_RESOURCE Module tracing backend is mapped to TUNIT tracing for target platforms */ +#ifdef __HIVECC +# ifndef HRT_CSIM +# define RBM_TRACE_METHOD IA_CSS_TRACE_METHOD_TRACE +# else +# define RBM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +# endif +#else +# define RBM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#endif + +#if (defined(RBM_TRACE_CONFIG)) +/* Module specific trace setting */ +# if RBM_TRACE_CONFIG == RBM_TRACE_LOG_LEVEL_OFF +/* RBM_TRACE_LOG_LEVEL_OFF */ +# define RBM_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED +# elif RBM_TRACE_CONFIG == RBM_TRACE_LOG_LEVEL_NORMAL +/* RBM_TRACE_LOG_LEVEL_NORMAL */ +# define RBM_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED +# elif RBM_TRACE_CONFIG == RBM_TRACE_LOG_LEVEL_DEBUG +/* RBM_TRACE_LOG_LEVEL_DEBUG */ +# define RBM_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED +# else +# error "No RBM_TRACE_CONFIG Tracing level defined" +# endif +#else +# error "RBM_TRACE_CONFIG not defined" +#endif + +#endif /* __RBM_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/routing_bitmap.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/routing_bitmap.mk new file mode 100644 index 0000000000000..f4251f9740fde --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/routing_bitmap.mk @@ -0,0 +1,39 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# + +ifdef _H_ROUTING_BITMAP_MK +$(error ERROR: routing_bitmap.mk included multiple times, please check makefile) +else +_H_ROUTING_BITMAP_MK=1 +endif + +ROUTING_BITMAP_FILES += $(ROUTING_BITMAP_DIR)/src/ia_css_rbm_manifest.c + +ROUTING_BITMAP_DIR = $(MODULES_DIR)/routing_bitmap +ROUTING_BITMAP_INTERFACE = $(ROUTING_BITMAP_DIR)/interface +ROUTING_BITMAP_SOURCES = $(ROUTING_BITMAP_DIR)/src + +ROUTING_BITMAP_CPPFLAGS = -I$(ROUTING_BITMAP_INTERFACE) +ROUTING_BITMAP_CPPFLAGS += -I$(ROUTING_BITMAP_SOURCES) + +ifeq ($(ROUTING_BITMAP_INLINE),1) +ROUTING_BITMAP_CPPFLAGS += -D__IA_CSS_RBM_INLINE__ +else +ROUTING_BITMAP_FILES += $(ROUTING_BITMAP_DIR)/src/ia_css_rbm.c +endif + +ifeq ($(ROUTING_BITMAP_MANIFEST_INLINE),1) +ROUTING_BITMAP_CPPFLAGS += -D__IA_CSS_RBM_MANIFEST_INLINE__ +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm.c new file mode 100644 index 0000000000000..bc5bf14efbd77 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm.c @@ -0,0 +1,17 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_INLINE__ +#include "ia_css_rbm_impl.h" +#endif /* __IA_CSS_RBM_INLINE__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_impl.h new file mode 100644 index 0000000000000..926a93e2278cd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_impl.h @@ -0,0 +1,339 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_rbm.h" +#include "type_support.h" +#include "misc_support.h" +#include "assert_support.h" +#include "ia_css_rbm_trace.h" + +#include "math_support.h" + +STORAGE_CLASS_INLINE int ia_css_rbm_compute_weight( + const ia_css_rbm_t bitmap); + +STORAGE_CLASS_INLINE ia_css_rbm_t ia_css_rbm_shift( + const ia_css_rbm_t bitmap); + +IA_CSS_RBM_STORAGE_CLASS_C +bool ia_css_is_rbm_intersection_empty( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1) +{ + ia_css_rbm_t intersection; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_is_rbm_intersection_empty(): enter:\n"); + + intersection = ia_css_rbm_intersection(bitmap0, bitmap1); + return ia_css_is_rbm_empty(intersection); +} + +IA_CSS_RBM_STORAGE_CLASS_C +bool ia_css_is_rbm_empty( + const ia_css_rbm_t bitmap) +{ + unsigned int i; + bool is_empty = true; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_is_rbm_empty(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + is_empty &= bitmap.data[i] == 0; + } + return is_empty; +} + +IA_CSS_RBM_STORAGE_CLASS_C +bool ia_css_is_rbm_equal( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1) +{ + unsigned int i; + bool is_equal = true; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_is_rbm_equal(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + is_equal = is_equal && (bitmap0.data[i] == bitmap1.data[i]); + } + return is_equal; +} + +IA_CSS_RBM_STORAGE_CLASS_C +bool ia_css_is_rbm_subset( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1) +{ + ia_css_rbm_t intersection; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_is_rbm_subset(): enter:\n"); + + intersection = ia_css_rbm_intersection(bitmap0, bitmap1); + return ia_css_is_rbm_equal(intersection, bitmap1); +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_clear(void) +{ + unsigned int i; + ia_css_rbm_t bitmap; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_clear(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + bitmap.data[i] = 0; + } + return bitmap; +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_complement( + const ia_css_rbm_t bitmap) +{ + unsigned int i; + ia_css_rbm_t result; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_complement(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + result.data[i] = ~bitmap.data[i]; + } + return result; +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_union( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1) +{ + unsigned int i; + ia_css_rbm_t result; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_union(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + result.data[i] = (bitmap0.data[i] | bitmap1.data[i]); + } + return result; +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_intersection( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1) +{ + unsigned int i; + ia_css_rbm_t result; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_intersection(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + result.data[i] = (bitmap0.data[i] & bitmap1.data[i]); + } + return result; +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_set( + const ia_css_rbm_t bitmap, + const unsigned int index) +{ + ia_css_rbm_t bit_mask; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_set(): enter:\n"); + + bit_mask = ia_css_rbm_bit_mask(index); + return ia_css_rbm_union(bitmap, bit_mask); +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_create_from_uint64( + const uint64_t value) +{ + unsigned int i; + ia_css_rbm_t result; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_create_from_uint64(): enter:\n"); + + result = ia_css_rbm_clear(); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + /* masking is done implictly, the MSB bits of casting will be chopped off */ + result.data[i] = (IA_CSS_RBM_ELEM_TYPE) + (value >> (i * IA_CSS_RBM_ELEM_BITS)); + } + return result; +} + +IA_CSS_RBM_STORAGE_CLASS_C +uint64_t ia_css_rbm_to_uint64( + const ia_css_rbm_t value) +{ + const unsigned int bits64 = sizeof(uint64_t) * 8; + const unsigned int nof_elems_bits64 = bits64 / IA_CSS_RBM_ELEM_BITS; + unsigned int i; + uint64_t res = 0; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_to_uint64(): enter:\n"); + + assert((bits64 % IA_CSS_RBM_ELEM_BITS) == 0); + assert(nof_elems_bits64 > 0); + + for (i = 0; i < MIN(IA_CSS_RBM_NOF_ELEMS, nof_elems_bits64); i++) { + res |= ((uint64_t)(value.data[i]) << (i * IA_CSS_RBM_ELEM_BITS)); + } + for (i = nof_elems_bits64; i < IA_CSS_RBM_NOF_ELEMS; i++) { + assert(value.data[i] == 0); + } + return res; +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_unset( + const ia_css_rbm_t bitmap, + const unsigned int index) +{ + ia_css_rbm_t result; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_unset(): enter:\n"); + + result = ia_css_rbm_bit_mask(index); + result = ia_css_rbm_complement(result); + return ia_css_rbm_intersection(bitmap, result); +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_bit_mask( + const unsigned int index) +{ + unsigned int elem_index; + unsigned int elem_bit_index; + ia_css_rbm_t bit_mask = ia_css_rbm_clear(); + + assert(index < IA_CSS_RBM_BITS); + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_bit_mask(): enter:\n"); + if (index < IA_CSS_RBM_BITS) { + elem_index = index / IA_CSS_RBM_ELEM_BITS; + elem_bit_index = index % IA_CSS_RBM_ELEM_BITS; + assert(elem_index < IA_CSS_RBM_NOF_ELEMS); + + bit_mask.data[elem_index] = 1 << elem_bit_index; + } + return bit_mask; +} + +STORAGE_CLASS_INLINE +int ia_css_rbm_compute_weight( + const ia_css_rbm_t bitmap) +{ + ia_css_rbm_t loc_bitmap; + int weight = 0; + int i; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_compute_weight(): enter:\n"); + + loc_bitmap = bitmap; + + /* In fact; do not need the iterator "i" */ + for (i = 0; (i < IA_CSS_RBM_BITS) && + !ia_css_is_rbm_empty(loc_bitmap); i++) { + weight += ia_css_is_rbm_set(loc_bitmap, 0); + loc_bitmap = ia_css_rbm_shift(loc_bitmap); + } + + return weight; +} + +IA_CSS_RBM_STORAGE_CLASS_C +int ia_css_is_rbm_set( + const ia_css_rbm_t bitmap, + const unsigned int index) +{ + unsigned int elem_index; + unsigned int elem_bit_index; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_is_rbm_set(): enter:\n"); + + assert(index < IA_CSS_RBM_BITS); + + elem_index = index / IA_CSS_RBM_ELEM_BITS; + elem_bit_index = index % IA_CSS_RBM_ELEM_BITS; + assert(elem_index < IA_CSS_RBM_NOF_ELEMS); + return (((bitmap.data[elem_index] >> elem_bit_index) & 0x1) == 1); +} + +STORAGE_CLASS_INLINE +ia_css_rbm_t ia_css_rbm_shift( + const ia_css_rbm_t bitmap) +{ + int i; + unsigned int lsb_current_elem = 0; + unsigned int lsb_previous_elem = 0; + ia_css_rbm_t loc_bitmap; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_shift(): enter:\n"); + + loc_bitmap = bitmap; + + for (i = IA_CSS_RBM_NOF_ELEMS - 1; i >= 0; i--) { + lsb_current_elem = bitmap.data[i] & 0x01; + loc_bitmap.data[i] >>= 1; + loc_bitmap.data[i] |= (lsb_previous_elem << (IA_CSS_RBM_ELEM_BITS - 1)); + lsb_previous_elem = lsb_current_elem; + } + return loc_bitmap; +} + +IA_CSS_RBM_STORAGE_CLASS_C +int ia_css_rbm_print( + const ia_css_rbm_t bitmap, + void *fid) +{ + int retval = -1; + int bit; + unsigned int bit_index = 0; + ia_css_rbm_t loc_bitmap; + + IA_CSS_TRACE_0(RBM, INFO, + "ia_css_rbm_print(): enter:\n"); + + NOT_USED(fid); + NOT_USED(bit); + + IA_CSS_TRACE_0(RBM, INFO, "kernel bitmap {\n"); + + loc_bitmap = bitmap; + + for (bit_index = 0; (bit_index < IA_CSS_RBM_BITS) && + !ia_css_is_rbm_empty(loc_bitmap); bit_index++) { + + bit = ia_css_is_rbm_set(loc_bitmap, 0); + loc_bitmap = ia_css_rbm_shift(loc_bitmap); + IA_CSS_TRACE_2(RBM, INFO, "\t%d\t = %d\n", bit_index, bit); + } + IA_CSS_TRACE_0(RBM, INFO, "}\n"); + + retval = 0; + return retval; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest.c new file mode 100644 index 0000000000000..630eaae4f1487 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest.c @@ -0,0 +1,225 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_rbm_manifest.h" +#include "ia_css_rbm.h" +#include "type_support.h" +#include "misc_support.h" +#include "assert_support.h" +#include "ia_css_rbm_trace.h" + +#ifndef __IA_CSS_RBM_MANIFEST_INLINE__ +#include "ia_css_rbm_manifest_impl.h" +#endif /* __IA_CSS_RBM_MANIFEST_INLINE__ */ + +#include "math_support.h" + +STORAGE_CLASS_INLINE void +ia_css_rbm_print_with_header( + const ia_css_rbm_t *rbm, + const ia_css_rbm_mux_desc_t *mux, + unsigned int mux_desc_count, + bool print_header) +{ +#ifdef __HIVECC + ia_css_rbm_print(*rbm, NULL); + (void)print_header; + (void)mux_desc_count; + (void)mux; +#else + int i, j; + + assert(mux != NULL); + assert(rbm != NULL); + if (mux == NULL || rbm == NULL) + return; + + if (print_header) { + for (i = mux_desc_count - 1; i >= 0; i--) { + PRINT("%*d|", mux[i].size_bits, mux[i].mux_id); + } + PRINT("\n"); + } + for (i = mux_desc_count - 1; i >= 0; i--) { + for (j = mux[i].size_bits - 1; j >= 0; j--) { + PRINT("%d", ia_css_is_rbm_set(*rbm, j + mux[i].offset)); + } + PRINT("|"); + } +#endif +} + +STORAGE_CLASS_INLINE void +ia_css_rbm_validation_rule_print( + ia_css_rbm_validation_rule_t *rule, + ia_css_rbm_mux_desc_t *mux_desc, + unsigned int mux_desc_count, + bool print_header) +{ + ia_css_rbm_print_with_header(&rule->match, mux_desc, mux_desc_count, print_header); +#ifdef __HIVECC + IA_CSS_TRACE_0(RBM, INFO, "Mask\n"); +#else + PRINT("\t"); +#endif + ia_css_rbm_print_with_header(&rule->mask, mux_desc, mux_desc_count, false); +#ifdef __HIVECC + IA_CSS_TRACE_1(RBM, INFO, "Rule expected_value: %d\n", rule->expected_value); +#else + PRINT("\t%d\n", rule->expected_value); +#endif +} + +void +ia_css_rbm_pretty_print( + const ia_css_rbm_t *rbm, + const ia_css_rbm_mux_desc_t *mux, + unsigned int mux_desc_count) +{ + ia_css_rbm_print_with_header(rbm, mux, mux_desc_count, false); +#ifndef __HIVECC + PRINT("\n"); +#endif +} + +void +ia_css_rbm_manifest_print( + const ia_css_rbm_manifest_t *manifest) +{ + int retval = -1; + unsigned int i; + bool print_header = true; + ia_css_rbm_mux_desc_t *muxes; + ia_css_rbm_validation_rule_t *validation_rule; + ia_css_rbm_terminal_routing_desc_t *terminal_routing_desc; + + verifjmpexit(manifest != NULL); + muxes = ia_css_rbm_manifest_get_muxes(manifest); + verifjmpexit(muxes != NULL || manifest->mux_desc_count == 0); + + for (i = 0; i < manifest->mux_desc_count; i++) { + IA_CSS_TRACE_4(RBM, INFO, "id: %d.%d offstet: %d size_bits: %d\n", + muxes[i].gp_dev_id, + muxes[i].mux_id, + muxes[i].offset, + muxes[i].size_bits); + } +#if VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT != 0 + validation_rule = ia_css_rbm_manifest_get_validation_rules(manifest); + verifjmpexit(validation_rule != NULL || manifest->validation_rule_count == 0); + + for (i = 0; i < manifest->validation_rule_count; i++) { + ia_css_rbm_validation_rule_print(&validation_rule[i], muxes, manifest->mux_desc_count, print_header); + print_header = false; + } +#else + (void) validation_rule; + (void) print_header; +#endif + terminal_routing_desc = ia_css_rbm_manifest_get_terminal_routing_desc(manifest); + verifjmpexit(terminal_routing_desc != NULL || manifest->terminal_routing_desc_count == 0); + for (i = 0; i < manifest->terminal_routing_desc_count; i++) { + IA_CSS_TRACE_4(RBM, INFO, "terminal_id: %d connection_state: %d mux_id: %d state: %d\n", + terminal_routing_desc[i].terminal_id, + terminal_routing_desc[i].connection_state, + terminal_routing_desc[i].mux_id, + terminal_routing_desc[i].state); + } + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(RBM, ERROR, "ia_css_rbm_manifest_print failed\n"); + } +} + +bool +ia_css_rbm_manifest_check_rbm_validity( + const ia_css_rbm_manifest_t *manifest, + const ia_css_rbm_t *rbm) +{ + unsigned int i; + ia_css_rbm_t res; + ia_css_rbm_t final_rbm = ia_css_rbm_clear(); + ia_css_rbm_validation_rule_t *rules; + bool matches_rules; + + verifjmpexit(manifest != NULL); + verifjmpexit(rbm != NULL); + + if (ia_css_is_rbm_empty(*rbm)) { + IA_CSS_TRACE_0(RBM, ERROR, "ia_css_rbm_manifest_check_rbm_validity failes: RBM is empty.\n"); + return false; + } + +#if VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT != 0 + rules = ia_css_rbm_manifest_get_validation_rules(manifest); + verifjmpexit(rules != NULL || manifest->validation_rule_count == 0); + + for (i = 0; i < manifest->validation_rule_count; i++) { + res = ia_css_rbm_intersection(*rbm, rules[i].mask); + matches_rules = ia_css_is_rbm_equal(res, rules[i].match); + + if (!matches_rules) + continue; + + if (rules[i].expected_value == 1) { + final_rbm = ia_css_rbm_union(final_rbm, res); + } else { + IA_CSS_TRACE_1(RBM, INFO, "ia_css_rbm_manifest_check_rbm_validity failes on rule %d\n", 1); + return false; + } + } +#else + (void)matches_rules; + (void)i; + (void)rules; + (void)res; +#endif + return ia_css_is_rbm_equal(final_rbm, *rbm); +EXIT: + return false; +} + +ia_css_rbm_t +ia_css_rbm_set_mux( + ia_css_rbm_t rbm, + ia_css_rbm_mux_desc_t *mux, + unsigned int mux_count, + unsigned int gp_dev_id, + unsigned int mux_id, + unsigned int value) +{ + unsigned int i; + + verifjmpexit(mux != NULL); + + for (i = 0; i < mux_count; i++) { + if (mux[i].gp_dev_id == gp_dev_id && mux[i].mux_id == mux_id) + break; + } + if (i >= mux_count) { + IA_CSS_TRACE_2(RBM, ERROR, + "ia_css_rbm_set_mux mux with mux_id %d.%d not found\n", gp_dev_id, mux_id); + return rbm; + } + if (value >= mux[i].size_bits) { + IA_CSS_TRACE_3(RBM, ERROR, + "ia_css_rbm_set_mux mux mux_id %d.%d, value %d illegal\n", gp_dev_id, mux_id, value); + return rbm; + } + rbm = ia_css_rbm_set(rbm, mux[i].offset + value); +EXIT: + return rbm; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest_impl.h new file mode 100644 index 0000000000000..7059b6bc898e0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest_impl.h @@ -0,0 +1,108 @@ + + +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_rbm_manifest.h" +#include "ia_css_rbm_trace.h" + +#include "type_support.h" +#include "math_support.h" +#include "error_support.h" +#include "assert_support.h" +#include "print_support.h" + +STORAGE_CLASS_INLINE +void __ia_css_rbm_manifest_check_struct(void) +{ + COMPILATION_ERROR_IF( + sizeof(ia_css_rbm_manifest_t) != (SIZE_OF_RBM_MANIFEST_S / IA_CSS_UINT8_T_BITS)); + COMPILATION_ERROR_IF( + (sizeof(ia_css_rbm_manifest_t) % 8 /* 64 bit */) != 0); +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +unsigned int +ia_css_rbm_manifest_get_size(void) +{ + unsigned int size = sizeof(struct ia_css_rbm_manifest_s); + + return ceil_mul(size, sizeof(uint64_t)); +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +void +ia_css_rbm_manifest_init(struct ia_css_rbm_manifest_s *rbm) +{ + rbm->mux_desc_count = 0; + rbm->terminal_routing_desc_count = 0; + rbm->validation_rule_count = 0; +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +ia_css_rbm_mux_desc_t * +ia_css_rbm_manifest_get_muxes(const ia_css_rbm_manifest_t *manifest) +{ +#if VIED_NCI_RBM_MAX_MUX_COUNT == 0 + (void)manifest; + return NULL; +#else + return (ia_css_rbm_mux_desc_t *)manifest->mux_desc; +#endif +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +unsigned int +ia_css_rbm_manifest_get_mux_count(const ia_css_rbm_manifest_t *manifest) +{ + return manifest->mux_desc_count; +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +ia_css_rbm_validation_rule_t * +ia_css_rbm_manifest_get_validation_rules(const ia_css_rbm_manifest_t *manifest) +{ +#if VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT == 0 + (void)manifest; + return NULL; +#else + return (ia_css_rbm_validation_rule_t *)manifest->validation_rules; +#endif +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +unsigned int +ia_css_rbm_manifest_get_validation_rule_count(const ia_css_rbm_manifest_t *manifest) +{ + return manifest->validation_rule_count; +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +ia_css_rbm_terminal_routing_desc_t * +ia_css_rbm_manifest_get_terminal_routing_desc(const ia_css_rbm_manifest_t *manifest) +{ +#if VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT == 0 + (void)manifest; + return NULL; +#else + return (ia_css_rbm_terminal_routing_desc_t *)manifest->terminal_routing_desc; +#endif +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +unsigned int +ia_css_rbm_manifest_get_terminal_routing_desc_count(const ia_css_rbm_manifest_t *manifest) +{ + return manifest->terminal_routing_desc_count; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/assert_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/assert_support.h new file mode 100644 index 0000000000000..ec24488bf6b11 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/assert_support.h @@ -0,0 +1,197 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __ASSERT_SUPPORT_H +#define __ASSERT_SUPPORT_H + +/* This file provides support for run-time assertions + * and compile-time assertions. + * + * Run-time asstions are provided via the following syntax: + * assert(condition) + * Run-time assertions are disabled using the NDEBUG flag. + * + * Compile time assertions are provided via the following syntax: + * COMPILATION_ERROR_IF(condition); + * A compile-time assertion will fail to compile if the condition is false. + * The condition must be constant, such that it can be evaluated + * at compile time. + * + * OP___assert is deprecated. + */ + +#define IA_CSS_ASSERT(expr) assert(expr) + +#ifdef __KLOCWORK__ +/* Klocwork does not see that assert will lead to abortion + * as there is no good way to tell this to KW and the code + * should not depend on assert to function (actually the assert + * could be disabled in a release build) it was decided to + * disable the assert for KW scans (by defining NDEBUG) + */ +#define NDEBUG +#endif /* __KLOCWORK__ */ + +/** + * The following macro can help to test the size of a struct at compile + * time rather than at run-time. It does not work for all compilers; see + * below. + * + * Depending on the value of 'condition', the following macro is expanded to: + * - condition==true: + * an expression containing an array declaration with negative size, + * usually resulting in a compilation error + * - condition==false: + * (void) 1; // C statement with no effect + * + * example: + * COMPILATION_ERROR_IF( sizeof(struct host_sp_queues) != + * SIZE_OF_HOST_SP_QUEUES_STRUCT); + * + * verify that the macro indeed triggers a compilation error with your compiler: + * COMPILATION_ERROR_IF( sizeof(struct host_sp_queues) != + * (sizeof(struct host_sp_queues)+1) ); + * + * Not all compilers will trigger an error with this macro; + * use a search engine to search for BUILD_BUG_ON to find other methods. + */ +#define COMPILATION_ERROR_IF(condition) \ +((void)sizeof(char[1 - 2*!!(condition)])) + +/* Compile time assertion */ +#ifndef CT_ASSERT +#define CT_ASSERT(cnd) ((void)sizeof(char[(cnd)?1 : -1])) +#endif /* CT_ASSERT */ + +#ifdef NDEBUG + +#define assert(cnd) ((void)0) + +#else + +#include "storage_class.h" + +#if defined(_MSC_VER) +#ifdef _KERNEL_MODE +/* Windows kernel mode compilation */ +#include +#define assert(cnd) ASSERT(cnd) +#else +/* Windows usermode compilation */ +#include +#endif + +#elif defined(__HIVECC) + +/* + * target: assert disabled + * sched: assert enabled only when SCHED_DEBUG is defined + * unsched: assert enabled + */ +#if defined(HRT_HW) +#define assert(cnd) ((void)0) +#elif defined(HRT_SCHED) && !defined(DEBUG_SCHED) +#define assert(cnd) ((void)0) +#elif defined(PIPE_GENERATION) +#define assert(cnd) ((void)0) +#else +#include +#define assert(cnd) OP___csim_assert(cnd) +#endif + +#elif defined(__KERNEL__) +#include + +#ifndef KERNEL_ASSERT_TO_BUG +#ifndef KERNEL_ASSERT_TO_BUG_ON +#ifndef KERNEL_ASSERT_TO_WARN_ON +#ifndef KERNEL_ASSERT_TO_WARN_ON_INF_LOOP +#ifndef KERNEL_ASSERT_UNDEFINED +/* Default */ +#define KERNEL_ASSERT_TO_BUG +#endif /*KERNEL_ASSERT_UNDEFINED*/ +#endif /*KERNEL_ASSERT_TO_WARN_ON_INF_LOOP*/ +#endif /*KERNEL_ASSERT_TO_WARN_ON*/ +#endif /*KERNEL_ASSERT_TO_BUG_ON*/ +#endif /*KERNEL_ASSERT_TO_BUG*/ + +#ifdef KERNEL_ASSERT_TO_BUG +/* TODO: it would be cleaner to use this: + * #define assert(cnd) BUG_ON(cnd) + * but that causes many compiler warnings (==errors) under Android + * because it seems that the BUG_ON() macro is not seen as a check by + * gcc like the BUG() macro is. */ +#define assert(cnd) \ + do { \ + if (!(cnd)) { \ + BUG(); \ + } \ + } while (0) +#endif /*KERNEL_ASSERT_TO_BUG*/ + +#ifdef KERNEL_ASSERT_TO_BUG_ON +#define assert(cnd) BUG_ON(!(cnd)) +#endif /*KERNEL_ASSERT_TO_BUG_ON*/ + +#ifdef KERNEL_ASSERT_TO_WARN_ON +#define assert(cnd) WARN_ON(!(cnd)) +#endif /*KERNEL_ASSERT_TO_WARN_ON*/ + +#ifdef KERNEL_ASSERT_TO_WARN_ON_INF_LOOP +#define assert(cnd) \ + do { \ + int not_cnd = !(cnd); \ + WARN_ON(not_cnd); \ + if (not_cnd) { \ + for (;;) { \ + } \ + } \ + } while (0) +#endif /*KERNEL_ASSERT_TO_WARN_ON_INF_LOOP*/ + +#ifdef KERNEL_ASSERT_UNDEFINED +#include KERNEL_ASSERT_DEFINITION_FILESTRING +#endif /*KERNEL_ASSERT_UNDEFINED*/ + +#elif defined(__FIST__) || defined(__GNUC__) + +#include "assert.h" + +#else /* default is for unknown environments */ +#define assert(cnd) ((void)0) +#endif + +#endif /* NDEBUG */ + +#ifndef PIPE_GENERATION +/* Deprecated OP___assert, this is still used in ~1000 places + * in the code. This will be removed over time. + * The implementation for the pipe generation tool is in see support.isp.h */ +#define OP___assert(cnd) assert(cnd) + +#ifdef C_RUN +#define compile_time_assert(cond) OP___assert(cond) +#else +#include "storage_class.h" +extern void _compile_time_assert(void); +STORAGE_CLASS_INLINE void compile_time_assert(unsigned int cond) +{ + /* Call undefined function if cond is false */ + if (!cond) + _compile_time_assert(); +} +#endif +#endif /* PIPE_GENERATION */ + +#endif /* __ASSERT_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/cpu_mem_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/cpu_mem_support.h new file mode 100644 index 0000000000000..defea068429ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/cpu_mem_support.h @@ -0,0 +1,233 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __CPU_MEM_SUPPORT_H +#define __CPU_MEM_SUPPORT_H + +#include "storage_class.h" +#include "assert_support.h" +#include "type_support.h" + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_copy(void *dst, const void *src, unsigned int size) +{ + /* memcpy cannot be used in Windows (function is not allowed), + * and the safer function memcpy_s is not available on other platforms. + * Because usage of ia_css_cpu_mem_copy is minimal, we implement it here in an easy, + * but sub-optimal way. + */ + unsigned int i; + + assert(dst != NULL && src != NULL); + + if (!(dst != NULL && src != NULL)) { + return NULL; + } + for (i = 0; i < size; i++) { + ((char *)dst)[i] = ((char *)src)[i]; + } + return dst; +} + +#if defined(__KERNEL__) + +#include +#include +#include +#include + +/* TODO: remove, workaround for issue in hrt file ibuf_ctrl_2600_config.c + * error checking code added to SDK that uses calls to exit function + */ +#define exit(a) return + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return kmalloc(size, GFP_KERNEL); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + return ia_css_cpu_mem_alloc(size); /* todo: align to page size */ +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_protect(void *ptr, unsigned int size, int prot) +{ + /* nothing here yet */ +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); /* available in kernel in linux/string.h */ +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + kfree(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ + /* parameter check here */ + if (ptr == NULL) + return; + + clflush_cache_range(ptr, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ + /* for now same as flush */ + ia_css_cpu_mem_cache_flush(ptr, size); +} + +#elif defined(_MSC_VER) + +#include +#include +#include + +extern void *hrt_malloc(size_t bytes, int zero_mem); +extern void *hrt_free(void *ptr); +extern void hrt_mem_cache_flush(void *ptr, unsigned int size); +extern void hrt_mem_cache_invalidate(void *ptr, unsigned int size); + +#define malloc(a) hrt_malloc(a, 1) +#define free(a) hrt_free(a) + +#define CSS_PAGE_SIZE (1<<12) + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return malloc(size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + unsigned int buffer_size = size; + + /* Currently hrt_malloc calls Windows ExAllocatePoolWithTag() routine + * to request system memory. If the number of bytes is equal or bigger + * than the page size, then the returned address is page aligned, + * but if it's smaller it's not necessarily page-aligned We agreed + * with Windows team that we allocate a full page + * if it's less than page size + */ + if (buffer_size < CSS_PAGE_SIZE) + buffer_size = CSS_PAGE_SIZE; + + return ia_css_cpu_mem_alloc(buffer_size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + free(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ +#ifdef _KERNEL_MODE + hrt_mem_cache_flush(ptr, size); +#else + (void)ptr; + (void)size; +#endif +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ +#ifdef _KERNEL_MODE + hrt_mem_cache_invalidate(ptr, size); +#else + (void)ptr; + (void)size; +#endif +} + +#else + +#include +#include +#include +/* Needed for the MPROTECT */ +#include +#include +#include +#include + + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return malloc(size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + int pagesize; + + pagesize = sysconf(_SC_PAGE_SIZE); + return memalign(pagesize, size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + free(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ + /* not needed in simulation */ + (void)ptr; + (void)size; +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ + /* not needed in simulation */ + (void)ptr; + (void)size; +} + +#endif + +#endif /* __CPU_MEM_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/error_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/error_support.h new file mode 100644 index 0000000000000..9fe1f65125e6c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/error_support.h @@ -0,0 +1,110 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __ERROR_SUPPORT_H +#define __ERROR_SUPPORT_H + +#if defined(__KERNEL__) +#include +#else +#include +#endif +#include + +/* OS-independent definition of IA_CSS errno values */ +/* #define IA_CSS_EINVAL 1 */ +/* #define IA_CSS_EFAULT 2 */ + +#ifdef __HIVECC +#define ERR_EMBEDDED 1 +#else +#define ERR_EMBEDDED 0 +#endif + +#if ERR_EMBEDDED +#define DECLARE_ERRVAL +#else +#define DECLARE_ERRVAL \ + int _errval = 0; +#endif + +/* Use "owl" in while to prevent compiler warnings in Windows */ +#define ALWAYS_FALSE ((void)0, 0) + +#define verifret(cond, error_type) \ +do { \ + if (!(cond)) { \ + return error_type; \ + } \ +} while (ALWAYS_FALSE) + +#define verifjmp(cond, error_tag) \ +do { \ + if (!(cond)) { \ + goto error_tag; \ + } \ +} while (ALWAYS_FALSE) + +#define verifexit(cond) \ +do { \ + if (!(cond)) { \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#if ERR_EMBEDDED +#define verifexitval(cond, error_tag) \ +do { \ + assert(cond); \ +} while (ALWAYS_FALSE) +#else +#define verifexitval(cond, error_tag) \ +do { \ + if (!(cond)) { \ + _errval = (error_tag); \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) +#endif + +#if ERR_EMBEDDED +#define haserror(error_tag) (0) +#else +#define haserror(error_tag) \ + (_errval == (error_tag)) +#endif + +#if ERR_EMBEDDED +#define noerror() (1) +#else +#define noerror() \ + (_errval == 0) +#endif + +#define verifjmpexit(cond) \ +do { \ + if (!(cond)) { \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#define verifjmpexitsetretval(cond, retval) \ +do { \ + if (!(cond)) { \ + retval = -1; \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#endif /* __ERROR_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/math_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/math_support.h new file mode 100644 index 0000000000000..9eb344e962600 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/math_support.h @@ -0,0 +1,316 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __MATH_SUPPORT_H +#define __MATH_SUPPORT_H + +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "type_support.h" +#include "assert_support.h" + +/* in case we have min/max/MIN/MAX macro's undefine them */ +#ifdef min +#undef min +#endif +#ifdef max +#undef max +#endif +#ifdef MIN /* also defined in include/hrt/numeric.h from SDK */ +#undef MIN +#endif +#ifdef MAX +#undef MAX +#endif + +#ifndef UINT16_MAX +#define UINT16_MAX (0xffffUL) +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX (0xffffffffUL) +#endif + +#define IS_ODD(a) ((a) & 0x1) +#define IS_EVEN(a) (!IS_ODD(a)) +#define IS_POWER2(a) (!((a)&((a)-1))) +#define IS_MASK_BITS_SET(a, b) ((a & b) != 0) + +/*To Find next power of 2 number from x */ +#define bit2(x) ((x) | ((x) >> 1)) +#define bit4(x) (bit2(x) | (bit2(x) >> 2)) +#define bit8(x) (bit4(x) | (bit4(x) >> 4)) +#define bit16(x) (bit8(x) | (bit8(x) >> 8)) +#define bit32(x) (bit16(x) | (bit16(x) >> 16)) +#define NEXT_POWER_OF_2(x) (bit32(x-1) + 1) + +/* force a value to a lower even value */ +#define EVEN_FLOOR(x) ((x) & ~1UL) + +/* A => B */ +#define IMPLIES(a, b) (!(a) || (b)) + +/* The ORIG_BITS th bit is the sign bit */ +/* Sign extends a ORIG_BITS bits long signed number to a 64-bit signed number */ +/* By type casting it can relimited to any valid type-size + * (32-bit signed or 16-bit or 8-bit) + */ +/* By masking it can be transformed to any arbitrary bit size */ +#define SIGN_EXTEND(VAL, ORIG_BITS) \ +((~(((VAL)&(1ULL<<((ORIG_BITS)-1)))-1))|(VAL)) + +#define EXTRACT_BIT(a, b) ((a >> b) & 1) + +/* for preprocessor and array sizing use MIN and MAX + otherwise use min and max */ +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define CLIP(a, b, c) MIN((MAX((a), (b))), (c)) +/* Integer round-down division of a with b */ +#define FLOOR_DIV(a, b) ((b) ? ((a) / (b)) : 0) +/* Align a to the lower multiple of b */ +#define FLOOR_MUL(a, b) (FLOOR_DIV(a, b) * (b)) +/* Integer round-up division of a with b */ +#define CEIL_DIV(a, b) ((b) ? (((a) + (b) - 1) / (b)) : 0) +/* Align a to the upper multiple of b */ +#define CEIL_MUL(a, b) (CEIL_DIV(a, b) * (b)) +/* Align a to the upper multiple of b - fast implementation + * for cases when b=pow(2,n) + */ +#define CEIL_MUL2(a, b) (((a) + (b) - 1) & ~((b) - 1)) +/* integer round-up division of a with pow(2,b) */ +#define CEIL_SHIFT(a, b) (((a) + (1UL << (b)) - 1) >> (b)) +/* Align a to the upper multiple of pow(2,b) */ +#define CEIL_SHIFT_MUL(a, b) (CEIL_SHIFT(a, b) << (b)) +/* Absolute difference of a and b */ +#define ABS_DIF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a))) +#define ABS(a) ABS_DIF(a, 0) +/* Square of x */ +#define SQR(x) ((x)*(x)) +/* Integer round-half-down division of a nad b */ +#define ROUND_HALF_DOWN_DIV(a, b) ((b) ? ((a) + (b / 2) - 1) / (b) : 0) +/* Align a to the round-half-down multiple of b */ +#define ROUND_HALF_DOWN_MUL(a, b) (ROUND_HALF_DOWN_DIV(a, b) * (b)) + +#define MAX3(a, b, c) MAX((a), MAX((b), (c))) +#define MIN3(a, b, c) MIN((a), MIN((b), (c))) +#define MAX4(a, b, c, d) MAX((MAX((a), (b))), (MAX((c), (d)))) +#define MIN4(a, b, c, d) MIN((MIN((a), (b))), (MIN((c), (d)))) + +/* min and max should not be macros as they will evaluate their arguments twice. + if you really need a macro (e.g. for CPP or for initializing an array) + use MIN() and MAX(), otherwise use min() and max() */ + +#ifndef ARRAY_SIZE +#ifndef __KERNEL__ +#define ARRAY_SIZE(a) ((sizeof(a) / sizeof(*(a)))) +#endif +#endif + +#ifndef BYTES +#define BYTES(bit) (((bit)+7)/8) +#endif + +#if !defined(PIPE_GENERATION) +STORAGE_CLASS_INLINE unsigned int max_value_bits(unsigned int bits) +{ + return (bits == 0) ? 0 : ((2 * ((1 << ((bits) - 1)) - 1)) + 1); +} +STORAGE_CLASS_INLINE unsigned int max_value_bytes(unsigned int bytes) +{ + return max_value_bits(IA_CSS_UINT8_T_BITS * bytes); +} +STORAGE_CLASS_INLINE int max(int a, int b) +{ + return MAX(a, b); +} + +STORAGE_CLASS_INLINE int min(int a, int b) +{ + return MIN(a, b); +} + +STORAGE_CLASS_INLINE int clip(int a, int b, int c) +{ + return min(max(a, b), c); +} + +STORAGE_CLASS_INLINE unsigned int ipu4_umax(unsigned int a, unsigned int b) +{ + return MAX(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ipu4_umin(unsigned int a, unsigned int b) +{ + return MIN(a, b); +} + +STORAGE_CLASS_INLINE unsigned int uclip(unsigned int a, unsigned int b, + unsigned int c) +{ + return ipu4_umin(ipu4_umax(a, b), c); +} + +STORAGE_CLASS_INLINE unsigned int ceil_div(unsigned int a, unsigned int b) +{ + return CEIL_DIV(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_mul(unsigned int a, unsigned int b) +{ + return CEIL_MUL(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_mul2(unsigned int a, unsigned int b) +{ + return CEIL_MUL2(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_shift(unsigned int a, unsigned int b) +{ + return CEIL_SHIFT(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_shift_mul(unsigned int a, unsigned int b) +{ + return CEIL_SHIFT_MUL(a, b); +} + +STORAGE_CLASS_INLINE int abs_dif(int a, int b) +{ + return ABS_DIF(a, b); +} + +STORAGE_CLASS_INLINE unsigned int uabs_dif(unsigned int a, unsigned int b) +{ + return ABS_DIF(a, b); +} + +STORAGE_CLASS_INLINE unsigned int round_half_down_div(unsigned int a, + unsigned int b) +{ + return ROUND_HALF_DOWN_DIV(a, b); +} + +STORAGE_CLASS_INLINE unsigned int round_half_down_mul(unsigned int a, + unsigned int b) +{ + return ROUND_HALF_DOWN_MUL(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_pow2(uint32_t a) +{ + unsigned int retval = 0; + + if (IS_POWER2(a)) { + retval = (unsigned int)a; + } else { + unsigned int v = a; + + v |= v>>1; + v |= v>>2; + v |= v>>4; + v |= v>>8; + v |= v>>16; + retval = (unsigned int)(v+1); + } + return retval; +} + +STORAGE_CLASS_INLINE unsigned int floor_log2(uint32_t a) +{ + static const uint8_t de_bruijn[] = { + 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 + }; + uint32_t v = a; + + v |= v>>1; + v |= v>>2; + v |= v>>4; + v |= v>>8; + v |= v>>16; + return (unsigned int)de_bruijn[(v*0x07C4ACDDU)>>27]; +} + +/* Divide by small power of two */ +STORAGE_CLASS_INLINE unsigned int +udiv2_small_i(uint32_t a, uint32_t b) +{ + assert(b <= 2); + return a >> (b-1); +} + +/* optimized divide for small results + * a will be divided by b + * outbits is the number of bits needed for the result + * the smaller the cheaper the function will be. + * if the result doesn't fit in the number of output bits + * the result is incorrect and the function will assert + */ +STORAGE_CLASS_INLINE unsigned int +udiv_medium(uint32_t a, uint32_t b, unsigned int outbits) +{ + int bit; + unsigned int res = 0; + unsigned int mask; + +#ifdef VOLCANO +#pragma ipu unroll +#endif + for (bit = outbits-1 ; bit >= 0; bit--) { + mask = 1<= (b<= c ? a+b-c : a+b); +} + +/* + * For SP and ISP, SDK provides the definition of OP_asp_slor. + * We need it only for host + */ +STORAGE_CLASS_INLINE unsigned int OP_asp_slor(int a, int b, int c) +{ + return ((a << c) | b); +} +#else +#include "hive/customops.h" +#endif /* !defined(__VIED_CELL) */ + +#endif /* !defined(PIPE_GENERATION) */ + +#if !defined(__KERNEL__) +#define clamp(a, min_val, max_val) MIN(MAX((a), (min_val)), (max_val)) +#endif /* !defined(__KERNEL__) */ + +#endif /* __MATH_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/misc_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/misc_support.h new file mode 100644 index 0000000000000..a2c2729e946d2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/misc_support.h @@ -0,0 +1,76 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __MISC_SUPPORT_H +#define __MISC_SUPPORT_H + +/* suppress compiler warnings on unused variables */ +#ifndef NOT_USED +#define NOT_USED(a) ((void)(a)) +#endif + +/* Calculate the total bytes for pow(2) byte alignment */ +#define tot_bytes_for_pow2_align(pow2, cur_bytes) \ + ((cur_bytes + (pow2 - 1)) & ~(pow2 - 1)) + +/* Display the macro value given a string */ +#define _STR(x) #x +#define STR(x) _STR(x) + +/* Concatenate */ +#ifndef CAT /* also defined in */ +#define _CAT(a, b) a ## b +#define CAT(a, b) _CAT(a, b) +#endif + +#define _CAT3(a, b, c) a ## b ## c +#define CAT3(a, b, c) _CAT3(a, b, c) + +/* NO_HOIST, NO_CSE, NO_ALIAS attributes must be ignored for host code */ +#ifndef __HIVECC +#ifndef NO_HOIST +#define NO_HOIST +#endif +#ifndef NO_CSE +#define NO_CSE +#endif +#ifndef NO_ALIAS +#define NO_ALIAS +#endif +#endif + +enum hive_method_id { + HIVE_METHOD_ID_CRUN, + HIVE_METHOD_ID_UNSCHED, + HIVE_METHOD_ID_SCHED, + HIVE_METHOD_ID_TARGET +}; + +/* Derive METHOD */ +#if defined(C_RUN) + #define HIVE_METHOD "crun" + #define HIVE_METHOD_ID HIVE_METHOD_ID_CRUN +#elif defined(HRT_UNSCHED) + #define HIVE_METHOD "unsched" + #define HIVE_METHOD_ID HIVE_METHOD_ID_UNSCHED +#elif defined(HRT_SCHED) + #define HIVE_METHOD "sched" + #define HIVE_METHOD_ID HIVE_METHOD_ID_SCHED +#else + #define HIVE_METHOD "target" + #define HIVE_METHOD_ID HIVE_METHOD_ID_TARGET + #define HRT_TARGET 1 +#endif + +#endif /* __MISC_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/platform_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/platform_support.h new file mode 100644 index 0000000000000..d281d841e1c33 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/platform_support.h @@ -0,0 +1,146 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PLATFORM_SUPPORT_H +#define __PLATFORM_SUPPORT_H + +#include "storage_class.h" + +#define MSEC_IN_SEC 1000 +#define NSEC_IN_MSEC 1000000 + +#if defined(_MSC_VER) +#include + +#define IA_CSS_EXTERN +#define SYNC_WITH(x) +#define CSS_ALIGN(d, a) _declspec(align(a)) d + +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + /* Placeholder for driver team*/ +} + +STORAGE_CLASS_INLINE void ia_css_sleep_msec(unsigned long delay_time_ms) +{ + /* Placeholder for driver team*/ + (void)delay_time_ms; +} + +#elif defined(__HIVECC) +#include +#include + +#define IA_CSS_EXTERN extern +#define CSS_ALIGN(d, a) d __aligned(a) +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + OP___schedule(); +} + +#elif defined(__KERNEL__) +#include +#include + +#define IA_CSS_EXTERN +#define CSS_ALIGN(d, a) d __aligned(a) + +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + usleep_range(1, 50); +} + +#elif defined(__GNUC__) +#include + +#define IA_CSS_EXTERN +#define CSS_ALIGN(d, a) d __aligned(a) + +/* Define some __HIVECC specific macros to nothing to allow host code compilation */ +#ifndef NO_ALIAS +#define NO_ALIAS +#endif + +#ifndef SYNC_WITH +#define SYNC_WITH(x) +#endif + +#if defined(HRT_CSIM) +#include "hrt/host.h" /* Using hrt_sleep from hrt/host.h */ +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + /* For the SDK still using hrt_sleep */ + hrt_sleep(); +} +STORAGE_CLASS_INLINE void ia_css_sleep_msec(long unsigned int delay_time_ms) +{ + /* For the SDK still using hrt_sleep */ + long unsigned int i = 0; + for (i = 0; i < delay_time_ms; i++) { + hrt_sleep(); + } +} +#else +#include +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + struct timespec delay_time; + + delay_time.tv_sec = 0; + delay_time.tv_nsec = 10; + nanosleep(&delay_time, NULL); +} +STORAGE_CLASS_INLINE void ia_css_sleep_msec(long unsigned int delay_time_ms) +{ + struct timespec delay_time; + + if (delay_time_ms >= MSEC_IN_SEC) { + delay_time.tv_sec = delay_time_ms / MSEC_IN_SEC; + delay_time.tv_nsec = (delay_time_ms % MSEC_IN_SEC) * NSEC_IN_MSEC; + } else { + delay_time.tv_sec = 0; + delay_time.tv_nsec = delay_time_ms * NSEC_IN_MSEC; + } + nanosleep(&delay_time, NULL); +} +#endif + +#else +#include +#endif + +/*needed for the include in stdint.h for various environments */ +#include "type_support.h" +#include "storage_class.h" + +#define MAX_ALIGNMENT 8 +#define aligned_uint8(type, obj) CSS_ALIGN(uint8_t obj, 1) +#define aligned_int8(type, obj) CSS_ALIGN(int8_t obj, 1) +#define aligned_uint16(type, obj) CSS_ALIGN(uint16_t obj, 2) +#define aligned_int16(type, obj) CSS_ALIGN(int16_t obj, 2) +#define aligned_uint32(type, obj) CSS_ALIGN(uint32_t obj, 4) +#define aligned_int32(type, obj) CSS_ALIGN(int32_t obj, 4) + +/* needed as long as hivecc does not define the type (u)int64_t */ +#if defined(__HIVECC) +#define aligned_uint64(type, obj) CSS_ALIGN(unsigned long long obj, 8) +#define aligned_int64(type, obj) CSS_ALIGN(signed long long obj, 8) +#else +#define aligned_uint64(type, obj) CSS_ALIGN(uint64_t obj, 8) +#define aligned_int64(type, obj) CSS_ALIGN(int64_t obj, 8) +#endif +#define aligned_enum(enum_type, obj) CSS_ALIGN(uint32_t obj, 4) +#define aligned_struct(struct_type, obj) struct_type obj + +#endif /* __PLATFORM_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/print_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/print_support.h new file mode 100644 index 0000000000000..0b614f7ef12d8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/print_support.h @@ -0,0 +1,90 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PRINT_SUPPORT_H +#define __PRINT_SUPPORT_H + +#if defined(_MSC_VER) +#ifdef _KERNEL_MODE + +/* TODO: Windows driver team to provide tracing mechanism for kernel mode + * e.g. DbgPrint and DbgPrintEx + */ +extern void FwTracePrintPWARN(const char *fmt, ...); +extern void FwTracePrintPRINT(const char *fmt, ...); +extern void FwTracePrintPERROR(const char *fmt, ...); +extern void FwTracePrintPDEBUG(const char *fmt, ...); + +#define PWARN(format, ...) FwTracePrintPWARN(format, __VA_ARGS__) +#define PRINT(format, ...) FwTracePrintPRINT(format, __VA_ARGS__) +#define PERROR(format, ...) FwTracePrintPERROR(format, __VA_ARGS__) +#define PDEBUG(format, ...) FwTracePrintPDEBUG(format, __VA_ARGS__) + +#else +/* Windows usermode compilation */ +#include + +/* To change the defines below, communicate with Windows team first + * to ensure they will not get flooded with prints + */ +/* This is temporary workaround to avoid flooding userspace + * Windows driver with prints + */ + +#define PWARN(format, ...) +#define PRINT(format, ...) +#define PERROR(format, ...) printf("error: " format, __VA_ARGS__) +#define PDEBUG(format, ...) + +#endif /* _KERNEL_MODE */ + +#elif defined(__HIVECC) +#include +/* To be revised + +#define PWARN(format) +#define PRINT(format) OP___printstring(format) +#define PERROR(variable) OP___dump(9999, arguments) +#define PDEBUG(variable) OP___dump(__LINE__, arguments) + +*/ + +#define PRINTSTRING(str) OP___printstring(str) + +#elif defined(__KERNEL__) +#include +#include + + +#define PWARN(format, arguments...) pr_debug(format, ##arguments) +#define PRINT(format, arguments...) pr_debug(format, ##arguments) +#define PERROR(format, arguments...) pr_debug(format, ##arguments) +#define PDEBUG(format, arguments...) pr_debug(format, ##arguments) + +#else +#include + +#define PRINT_HELPER(prefix, format, ...) printf(prefix format "%s", __VA_ARGS__) + +/* The trailing "" allows the edge case of printing single string */ +#define PWARN(...) PRINT_HELPER("warning: ", __VA_ARGS__, "") +#define PRINT(...) PRINT_HELPER("", __VA_ARGS__, "") +#define PERROR(...) PRINT_HELPER("error: ", __VA_ARGS__, "") +#define PDEBUG(...) PRINT_HELPER("debug: ", __VA_ARGS__, "") + +#define PRINTSTRING(str) PRINT(str) + +#endif + +#endif /* __PRINT_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/storage_class.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/storage_class.h new file mode 100644 index 0000000000000..58932a6b3ec76 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/storage_class.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __STORAGE_CLASS_H +#define __STORAGE_CLASS_H + +#define STORAGE_CLASS_EXTERN \ +extern + +#if defined(_MSC_VER) +#define STORAGE_CLASS_INLINE \ +static inline +#elif defined(__HIVECC) +#define STORAGE_CLASS_INLINE \ +static inline +#else +#define STORAGE_CLASS_INLINE \ +static inline +#endif + +/* Register struct */ +#ifndef __register +#if defined(__HIVECC) && !defined(PIPE_GENERATION) +#define __register register +#else +#define __register +#endif +#endif + +/* Memory attribute */ +#ifndef MEM +#ifdef PIPE_GENERATION +#elif defined(__HIVECC) +#include +#else +#define MEM(any_mem) +#endif +#endif + +#endif /* __STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/type_support.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/type_support.h new file mode 100644 index 0000000000000..7d8e00fdd95e1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/support/type_support.h @@ -0,0 +1,80 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __TYPE_SUPPORT_H +#define __TYPE_SUPPORT_H + +/* Per the DLI spec, types are in "type_support.h" and + * "platform_support.h" is for unclassified/to be refactored + * platform specific definitions. + */ +#define IA_CSS_UINT8_T_BITS 8 +#define IA_CSS_UINT16_T_BITS 16 +#define IA_CSS_UINT32_T_BITS 32 +#define IA_CSS_INT32_T_BITS 32 +#define IA_CSS_UINT64_T_BITS 64 + + +#if defined(_MSC_VER) +#include +#include +#include +#include +#if defined(_M_X64) +#define HOST_ADDRESS(x) ((unsigned long long)(x)) +#else +#define HOST_ADDRESS(x) ((unsigned long)(x)) +#endif + +#elif defined(PARAM_GENERATION) +/* Nothing */ +#elif defined(__HIVECC) +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#elif defined(__KERNEL__) +#include +#include + +#define CHAR_BIT (8) +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#elif defined(__GNUC__) +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#else /* default is for the FIST environment */ +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#endif + +#if !defined(PIPE_GENERATION) && !defined(IO_GENERATION) +/* genpipe cannot handle the void* syntax */ +typedef void *HANDLE; +#endif + +#endif /* __TYPE_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/interface/ia_css_syscom.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/interface/ia_css_syscom.h new file mode 100644 index 0000000000000..5426d6d18e0bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/interface/ia_css_syscom.h @@ -0,0 +1,247 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_H +#define __IA_CSS_SYSCOM_H + + +/* + * The CSS Subsystem Communication Interface - Host side + * + * It provides subsystem initialzation, send ports and receive ports + * The PSYS and ISYS interfaces are implemented on top of this interface. + */ + +#include "ia_css_syscom_config.h" + +#define FW_ERROR_INVALID_PARAMETER (-1) +#define FW_ERROR_BAD_ADDRESS (-2) +#define FW_ERROR_BUSY (-3) +#define FW_ERROR_NO_MEMORY (-4) + +struct ia_css_syscom_context; + +/** + * ia_css_syscom_size() - provide syscom external buffer requirements + * @config: pointer to the configuration data (read) + * @size: pointer to the buffer size (write) + * + * Purpose: + * - Provide external buffer requirements + * - To be used for external buffer allocation + * + */ +extern void +ia_css_syscom_size( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size *size +); + +/** + * ia_css_syscom_open() - initialize a subsystem context + * @config: pointer to the configuration data (read) + * @buf: pointer to externally allocated buffers (read) + * @returns: struct ia_css_syscom_context* on success, 0 otherwise. + * + * Purpose: + * - initialize host side data structures + * - boot the subsystem? + * + */ +extern struct ia_css_syscom_context* +ia_css_syscom_open( + struct ia_css_syscom_config *config, + struct ia_css_syscom_buf *buf +); + +/** + * ia_css_syscom_close() - signal close to cell + * @context: pointer to the subsystem context + * @returns: 0 on success, -2 (FW_ERROR_BUSY) if SPC is not ready yet. + * + * Purpose: + * Request from the Cell to terminate + */ +extern int +ia_css_syscom_close( + struct ia_css_syscom_context *context +); + +/** + * ia_css_syscom_release() - free context + * @context: pointer to the subsystem context + * @force: flag which specifies whether cell + * state will be checked before freeing the + * context. + * @returns: 0 on success, -2 (FW_ERROR_BUSY) if cell + * is busy and call was not forced. + * + * Purpose: + * 2 modes, with first (force==true) immediately + * free context, and second (force==false) verifying + * that the cell state is ok and freeing context if so, + * returning error otherwise. + */ +extern int +ia_css_syscom_release( + struct ia_css_syscom_context *context, + unsigned int force +); + +/** + * Open a port for sending tokens to the subsystem + * @context: pointer to the subsystem context + * @port: send port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_open( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Closes a port for sending tokens to the subsystem + * @context: pointer to the subsystem context + * @port: send port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_close( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Get the number of tokens that can be sent to a port without error. + * @context: pointer to the subsystem context + * @port: send port index + * @returns: number of available tokens on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_available( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Send a token to the subsystem port + * The token size is determined during initialization + * @context: pointer to the subsystem context + * @port: send port index + * @token: pointer to the token value that is transferred to the subsystem + * @returns: number of tokens sent on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_transfer( + struct ia_css_syscom_context *context, + unsigned int port, + const void *token +); + +/** + * Open a port for receiving tokens to the subsystem + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_open( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Closes a port for receiving tokens to the subsystem + * Returns 0 on success, otherwise negative value of error code + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_close( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Get the number of tokens that can be received from a port without errors. + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: number of available tokens on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_available( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Receive a token from the subsystem port + * The token size is determined during initialization + * @context: pointer to the subsystem context + * @port: receive port index + * @token (output): pointer to (space for) the token to be received + * @returns: number of tokens received on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_transfer( + struct ia_css_syscom_context *context, + unsigned int port, + void *token +); + +#if HAS_DUAL_CMD_CTX_SUPPORT +/** + * ia_css_syscom_store_dmem() - store subsystem context information in DMEM + * @context: pointer to the subsystem context + * @ssid: subsystem id + * @vtl0_addr_mask: VTL0 address mask; only applicable when the passed in context is secure + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_store_dmem( + struct ia_css_syscom_context *context, + unsigned int ssid, + unsigned int vtl0_addr_mask +); + +/** + * ia_css_syscom_set_trustlet_status() - store truslet configuration setting + * @context: pointer to the subsystem context + * @trustlet_exist: 1 if trustlet exists + */ +extern void +ia_css_syscom_set_trustlet_status( + unsigned int dmem_addr, + unsigned int ssid, + bool trustlet_exist +); + +/** + * ia_css_syscom_is_ab_spc_ready() - check if SPC access blocker programming is completed + * @context: pointer to the subsystem context + * @returns: 1 when status is ready. 0 otherwise + */ +bool +ia_css_syscom_is_ab_spc_ready( + struct ia_css_syscom_context *ctx +); +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +#endif /* __IA_CSS_SYSCOM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/interface/ia_css_syscom_config.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/interface/ia_css_syscom_config.h new file mode 100644 index 0000000000000..2f5eb309df94e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/interface/ia_css_syscom_config.h @@ -0,0 +1,97 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONFIG_H +#define __IA_CSS_SYSCOM_CONFIG_H + +#include +#include + +/* syscom size struct, output of ia_css_syscom_size, + * input for (external) allocation + */ +struct ia_css_syscom_size { + /* Size of host buffer */ + unsigned int cpu; + /* Size of shared config buffer (host to cell) */ + unsigned int shm; + /* Size of shared input queue buffers (host to cell) */ + unsigned int ibuf; + /* Size of shared output queue buffers (cell to host) */ + unsigned int obuf; +}; + +/* syscom buffer struct, output of (external) allocation, + * input for ia_css_syscom_open + */ +struct ia_css_syscom_buf { + char *cpu; /* host buffer */ + + /* shared memory buffer host address */ + host_virtual_address_t shm_host; + /* shared memory buffer cell address */ + vied_virtual_address_t shm_cell; + + /* input queue shared buffer host address */ + host_virtual_address_t ibuf_host; + /* input queue shared buffer cell address */ + vied_virtual_address_t ibuf_cell; + + /* output queue shared buffer host address */ + host_virtual_address_t obuf_host; + /* output queue shared buffer cell address */ + vied_virtual_address_t obuf_cell; +}; + +struct ia_css_syscom_queue_config { + unsigned int queue_size; /* tokens per queue */ + unsigned int token_size; /* bytes per token */ +}; + +/** + * Parameter struct for ia_css_syscom_open + */ +struct ia_css_syscom_config { + /* This member in no longer used in syscom. + It is kept to not break any driver builds, and will be removed when + all assignments have been removed from driver code */ + /* address of firmware in DDR/IMR */ + unsigned long long host_firmware_address; + + /* address of firmware in DDR, seen from SPC */ + unsigned int vied_firmware_address; + + unsigned int ssid; + unsigned int mmid; + + unsigned int num_input_queues; + unsigned int num_output_queues; + struct ia_css_syscom_queue_config *input; + struct ia_css_syscom_queue_config *output; + + unsigned int regs_addr; + unsigned int dmem_addr; + + /* firmware-specific configuration data */ + void *specific_addr; + unsigned int specific_size; + + /* if true; secure syscom in VTIO Case + * if false, non-secure syscom + */ + bool secure; + unsigned int vtl0_addr_mask; /* only applicable in 'secure' case */ +}; + +#endif /* __IA_CSS_SYSCOM_CONFIG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/interface/ia_css_syscom_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/interface/ia_css_syscom_trace.h new file mode 100644 index 0000000000000..2c32693c2a82e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/interface/ia_css_syscom_trace.h @@ -0,0 +1,51 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_SYSCOM_TRACE_H +#define __IA_CSS_SYSCOM_TRACE_H + +#include "ia_css_trace.h" + +#define SYSCOM_TRACE_LEVEL_DEFAULT 1 +#define SYSCOM_TRACE_LEVEL_DEBUG 2 + +/* Set to default level if no level is defined */ +#ifndef SYSCOM_TRACE_LEVEL +#define SYSCOM_TRACE_LEVEL SYSCOM_TRACE_LEVEL_DEFAULT +#endif /* SYSCOM_TRACE_LEVEL */ + +/* SYSCOM Module tracing backend is mapped to TUNIT tracing for target platforms */ +#ifdef __HIVECC +# ifndef HRT_CSIM +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_TRACE +# else +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +# endif +#else +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#endif + +#define SYSCOM_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED +#define SYSCOM_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED +#define SYSCOM_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + +#if (SYSCOM_TRACE_LEVEL == SYSCOM_TRACE_LEVEL_DEFAULT) +# define SYSCOM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED +#elif (SYSCOM_TRACE_LEVEL == SYSCOM_TRACE_LEVEL_DEBUG) +# define SYSCOM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED +#else +# error "Connection manager trace level not defined!" +#endif /* SYSCOM_TRACE_LEVEL */ + +#endif /* __IA_CSS_SYSCOM_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/src/ia_css_syscom.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/src/ia_css_syscom.c new file mode 100644 index 0000000000000..dffbf581eb2b3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/src/ia_css_syscom.c @@ -0,0 +1,652 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_syscom.h" + +#include "ia_css_syscom_context.h" +#include "ia_css_syscom_config_fw.h" +#include "ia_css_syscom_trace.h" + +#include "queue.h" +#include "send_port.h" +#include "recv_port.h" +#include "regmem_access.h" + +#include "error_support.h" +#include "cpu_mem_support.h" + +#include "queue_struct.h" +#include "send_port_struct.h" +#include "recv_port_struct.h" + +#include "type_support.h" +#include +#include +#include "platform_support.h" + +#include "ia_css_cell.h" + +/* struct of internal buffer sizes */ +struct ia_css_syscom_size_intern { + unsigned int context; + unsigned int input_queue; + unsigned int output_queue; + unsigned int input_port; + unsigned int output_port; + + unsigned int fw_config; + unsigned int specific; + + unsigned int input_buffer; + unsigned int output_buffer; +}; + +/* Allocate buffers internally, when no buffers are provided */ +static int +ia_css_syscom_alloc( + unsigned int ssid, + unsigned int mmid, + const struct ia_css_syscom_size *size, + struct ia_css_syscom_buf *buf) +{ + /* zero the buffer to set all pointers to zero */ + memset(buf, 0, sizeof(*buf)); + + /* allocate cpu_mem */ + buf->cpu = (char *)ia_css_cpu_mem_alloc(size->cpu); + if (!buf->cpu) + goto EXIT7; + + /* allocate and map shared config buffer */ + buf->shm_host = shared_memory_alloc(mmid, size->shm); + if (!buf->shm_host) + goto EXIT6; + buf->shm_cell = shared_memory_map(ssid, mmid, buf->shm_host); + if (!buf->shm_cell) + goto EXIT5; + + /* allocate and map input queue buffer */ + buf->ibuf_host = shared_memory_alloc(mmid, size->ibuf); + if (!buf->ibuf_host) + goto EXIT4; + buf->ibuf_cell = shared_memory_map(ssid, mmid, buf->ibuf_host); + if (!buf->ibuf_cell) + goto EXIT3; + + /* allocate and map output queue buffer */ + buf->obuf_host = shared_memory_alloc(mmid, size->obuf); + if (!buf->obuf_host) + goto EXIT2; + buf->obuf_cell = shared_memory_map(ssid, mmid, buf->obuf_host); + if (!buf->obuf_cell) + goto EXIT1; + + return 0; + +EXIT1: shared_memory_free(mmid, buf->obuf_host); +EXIT2: shared_memory_unmap(ssid, mmid, buf->ibuf_cell); +EXIT3: shared_memory_free(mmid, buf->ibuf_host); +EXIT4: shared_memory_unmap(ssid, mmid, buf->shm_cell); +EXIT5: shared_memory_free(mmid, buf->shm_host); +EXIT6: ia_css_cpu_mem_free(buf->cpu); +EXIT7: return FW_ERROR_NO_MEMORY; +} + +static void +ia_css_syscom_size_intern( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size_intern *size) +{ + /* convert syscom config into syscom internal size struct */ + + unsigned int i; + + size->context = sizeof(struct ia_css_syscom_context); + size->input_queue = cfg->num_input_queues * sizeof(struct sys_queue); + size->output_queue = cfg->num_output_queues * sizeof(struct sys_queue); + size->input_port = cfg->num_input_queues * sizeof(struct send_port); + size->output_port = cfg->num_output_queues * sizeof(struct recv_port); + + size->fw_config = sizeof(struct ia_css_syscom_config_fw); + size->specific = cfg->specific_size; + + /* accumulate input queue buffer sizes */ + size->input_buffer = 0; + for (i = 0; i < cfg->num_input_queues; i++) { + size->input_buffer += + sys_queue_buf_size(cfg->input[i].queue_size, + cfg->input[i].token_size); + } + + /* accumulate outut queue buffer sizes */ + size->output_buffer = 0; + for (i = 0; i < cfg->num_output_queues; i++) { + size->output_buffer += + sys_queue_buf_size(cfg->output[i].queue_size, + cfg->output[i].token_size); + } +} + +static void +ia_css_syscom_size_extern( + const struct ia_css_syscom_size_intern *i, + struct ia_css_syscom_size *e) +{ + /* convert syscom internal size struct into external size struct */ + + e->cpu = i->context + i->input_queue + i->output_queue + + i->input_port + i->output_port; + e->shm = i->fw_config + i->input_queue + i->output_queue + i->specific; + e->ibuf = i->input_buffer; + e->obuf = i->output_buffer; +} + +/* Function that provides buffer sizes to be allocated */ +void +ia_css_syscom_size( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size *size) +{ + struct ia_css_syscom_size_intern i; + + ia_css_syscom_size_intern(cfg, &i); + ia_css_syscom_size_extern(&i, size); +} + +static struct ia_css_syscom_context* +ia_css_syscom_assign_buf( + const struct ia_css_syscom_size_intern *i, + const struct ia_css_syscom_buf *buf) +{ + struct ia_css_syscom_context *ctx; + char *cpu_mem_buf; + host_virtual_address_t shm_buf_host; + vied_virtual_address_t shm_buf_cell; + + /* host context */ + cpu_mem_buf = buf->cpu; + + ctx = (struct ia_css_syscom_context *)cpu_mem_buf; + ia_css_cpu_mem_set_zero(ctx, i->context); + cpu_mem_buf += i->context; + + ctx->input_queue = (struct sys_queue *) cpu_mem_buf; + cpu_mem_buf += i->input_queue; + + ctx->output_queue = (struct sys_queue *) cpu_mem_buf; + cpu_mem_buf += i->output_queue; + + ctx->send_port = (struct send_port *) cpu_mem_buf; + cpu_mem_buf += i->input_port; + + ctx->recv_port = (struct recv_port *) cpu_mem_buf; + + + /* cell config */ + shm_buf_host = buf->shm_host; + shm_buf_cell = buf->shm_cell; + + ctx->config_host_addr = shm_buf_host; + shm_buf_host += i->fw_config; + ctx->config_vied_addr = shm_buf_cell; + shm_buf_cell += i->fw_config; + + ctx->input_queue_host_addr = shm_buf_host; + shm_buf_host += i->input_queue; + ctx->input_queue_vied_addr = shm_buf_cell; + shm_buf_cell += i->input_queue; + + ctx->output_queue_host_addr = shm_buf_host; + shm_buf_host += i->output_queue; + ctx->output_queue_vied_addr = shm_buf_cell; + shm_buf_cell += i->output_queue; + + ctx->specific_host_addr = shm_buf_host; + ctx->specific_vied_addr = shm_buf_cell; + + ctx->ibuf_host_addr = buf->ibuf_host; + ctx->ibuf_vied_addr = buf->ibuf_cell; + + ctx->obuf_host_addr = buf->obuf_host; + ctx->obuf_vied_addr = buf->obuf_cell; + + return ctx; +} + +struct ia_css_syscom_context* +ia_css_syscom_open( + struct ia_css_syscom_config *cfg, + struct ia_css_syscom_buf *buf_extern +) +{ + struct ia_css_syscom_size_intern size_intern; + struct ia_css_syscom_size size; + struct ia_css_syscom_buf buf_intern; + struct ia_css_syscom_buf *buf; + struct ia_css_syscom_context *ctx; + struct ia_css_syscom_config_fw fw_cfg; + unsigned int i; + struct sys_queue_res res; + + IA_CSS_TRACE_0(SYSCOM, INFO, "Entered: ia_css_syscom_open\n"); + + /* error handling */ + if (cfg == NULL) + return NULL; + + IA_CSS_TRACE_1(SYSCOM, INFO, "ia_css_syscom_open (secure %d) start\n", cfg->secure); + + /* check members of cfg: TBD */ + + /* + * Check if SP is in valid state, have to wait if not ready. + * In some platform (Such as VP), it will need more time to wait due to system performance; + * If return NULL without wait for SPC0 ready, Driver load FW will failed + */ + ia_css_cell_wait(cfg->ssid, SPC0); + + ia_css_syscom_size_intern(cfg, &size_intern); + ia_css_syscom_size_extern(&size_intern, &size); + + if (buf_extern) { + /* use externally allocated buffers */ + buf = buf_extern; + } else { + /* use internally allocated buffers */ + buf = &buf_intern; + if (ia_css_syscom_alloc(cfg->ssid, cfg->mmid, &size, buf) != 0) + return NULL; + } + + /* assign buffer pointers */ + ctx = ia_css_syscom_assign_buf(&size_intern, buf); + /* only need to free internally allocated buffers */ + ctx->free_buf = !buf_extern; + + ctx->cell_regs_addr = cfg->regs_addr; + /* regmem is at cell_dmem_addr + REGMEM_OFFSET */ + ctx->cell_dmem_addr = cfg->dmem_addr; + + ctx->num_input_queues = cfg->num_input_queues; + ctx->num_output_queues = cfg->num_output_queues; + + ctx->env.mmid = cfg->mmid; + ctx->env.ssid = cfg->ssid; + ctx->env.mem_addr = cfg->dmem_addr; + + ctx->regmem_idx = SYSCOM_QPR_BASE_REG; + + /* initialize input queues */ + res.reg = SYSCOM_QPR_BASE_REG; + res.host_address = ctx->ibuf_host_addr; + res.vied_address = ctx->ibuf_vied_addr; + for (i = 0; i < cfg->num_input_queues; i++) { + sys_queue_init(ctx->input_queue + i, + cfg->input[i].queue_size, + cfg->input[i].token_size, &res); + } + + /* initialize output queues */ + res.host_address = ctx->obuf_host_addr; + res.vied_address = ctx->obuf_vied_addr; + for (i = 0; i < cfg->num_output_queues; i++) { + sys_queue_init(ctx->output_queue + i, + cfg->output[i].queue_size, + cfg->output[i].token_size, &res); + } + + /* fill shared queue structs */ + shared_memory_store(cfg->mmid, ctx->input_queue_host_addr, + ctx->input_queue, + cfg->num_input_queues * sizeof(struct sys_queue)); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->input_queue_host_addr), + cfg->num_input_queues * sizeof(struct sys_queue)); + shared_memory_store(cfg->mmid, ctx->output_queue_host_addr, + ctx->output_queue, + cfg->num_output_queues * sizeof(struct sys_queue)); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->output_queue_host_addr), + cfg->num_output_queues * sizeof(struct sys_queue)); + + /* Zero the queue buffers. Is this really needed? */ + shared_memory_zero(cfg->mmid, buf->ibuf_host, size.ibuf); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(buf->ibuf_host), + size.ibuf); + shared_memory_zero(cfg->mmid, buf->obuf_host, size.obuf); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(buf->obuf_host), + size.obuf); + + /* copy firmware specific data */ + if (cfg->specific_addr && cfg->specific_size) { + shared_memory_store(cfg->mmid, ctx->specific_host_addr, + cfg->specific_addr, cfg->specific_size); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->specific_host_addr), + cfg->specific_size); + } + + fw_cfg.num_input_queues = cfg->num_input_queues; + fw_cfg.num_output_queues = cfg->num_output_queues; + fw_cfg.input_queue = ctx->input_queue_vied_addr; + fw_cfg.output_queue = ctx->output_queue_vied_addr; + fw_cfg.specific_addr = ctx->specific_vied_addr; + fw_cfg.specific_size = cfg->specific_size; + + shared_memory_store(cfg->mmid, ctx->config_host_addr, + &fw_cfg, sizeof(struct ia_css_syscom_config_fw)); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(ctx->config_host_addr), + sizeof(struct ia_css_syscom_config_fw)); + +#if !HAS_DUAL_CMD_CTX_SUPPORT + /* store syscom uninitialized state */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store STATE_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_STATE_UNINIT, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + SYSCOM_STATE_UNINIT, cfg->ssid); + /* store syscom uninitialized command */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store COMMAND_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_COMMAND_UNINIT, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_UNINIT, cfg->ssid); + /* store firmware configuration address */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store CONFIG_REG (%#x) @ dmem_addr %#x ssid %d\n", + ctx->config_vied_addr, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_CONFIG_REG, + ctx->config_vied_addr, cfg->ssid); +#endif + + /* Indicate if ctx is created for secure stream purpose */ + ctx->secure = cfg->secure; + + IA_CSS_TRACE_1(SYSCOM, INFO, "ia_css_syscom_open (secure %d) completed\n", cfg->secure); + return ctx; +} + + +int +ia_css_syscom_close( + struct ia_css_syscom_context *ctx +) +{ + int state; + + state = regmem_load_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle close request yet */ + return FW_ERROR_BUSY; + } + + /* set close request flag */ + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_INACTIVE, ctx->env.ssid); + + return 0; +} + +static void +ia_css_syscom_free(struct ia_css_syscom_context *ctx) +{ + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, ctx->ibuf_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->ibuf_host_addr); + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, ctx->obuf_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->obuf_host_addr); + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, + ctx->config_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->config_host_addr); + ia_css_cpu_mem_free(ctx); +} + +int +ia_css_syscom_release( + struct ia_css_syscom_context *ctx, + unsigned int force +) +{ + /* check if release is forced, an verify cell state if it is not */ + if (!force) { + if (!ia_css_cell_is_ready(ctx->env.ssid, SPC0)) + return FW_ERROR_BUSY; + } + + /* Reset the regmem idx */ + ctx->regmem_idx = 0; + + if (ctx->free_buf) + ia_css_syscom_free(ctx); + + return 0; +} + +int ia_css_syscom_send_port_open( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + int state; + + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + /* check if SP syscom is ready to open the queue */ + state = regmem_load_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle messages yet */ + return FW_ERROR_BUSY; + } + + /* initialize the port */ + send_port_open(ctx->send_port + port, + ctx->input_queue + port, &(ctx->env)); + + return 0; +} + +int ia_css_syscom_send_port_close( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return 0; +} + +int ia_css_syscom_send_port_available( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return send_port_available(ctx->send_port + port); +} + +int ia_css_syscom_send_port_transfer( + struct ia_css_syscom_context *ctx, + unsigned int port, + const void *token +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return send_port_transfer(ctx->send_port + port, token); +} + +int ia_css_syscom_recv_port_open( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + int state; + + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + /* check if SP syscom is ready to open the queue */ + state = regmem_load_32(ctx->cell_dmem_addr, + SYSCOM_STATE_REG, ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle messages yet */ + return FW_ERROR_BUSY; + } + + /* initialize the port */ + recv_port_open(ctx->recv_port + port, + ctx->output_queue + port, &(ctx->env)); + + return 0; +} + +int ia_css_syscom_recv_port_close( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return 0; +} + +/* + * Get the number of responses in the response queue + */ +int +ia_css_syscom_recv_port_available( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return recv_port_available(ctx->recv_port + port); +} + + +/* + * Dequeue the head of the response queue + * returns an error when the response queue is empty + */ +int +ia_css_syscom_recv_port_transfer( + struct ia_css_syscom_context *ctx, + unsigned int port, + void *token +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return recv_port_transfer(ctx->recv_port + port, token); +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +/* + * store subsystem context information in DMEM + */ +int +ia_css_syscom_store_dmem( + struct ia_css_syscom_context *ctx, + unsigned int ssid, + unsigned int vtl0_addr_mask +) +{ + unsigned int read_back; + + NOT_USED(vtl0_addr_mask); + NOT_USED(read_back); + + if (ctx->secure) { + /* store VTL0 address mask in 'secure' context */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem VTL0_ADDR_MASK (%#x) @ dmem_addr %#x ssid %d\n", + vtl0_addr_mask, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_VTL0_ADDR_MASK, vtl0_addr_mask, ssid); + } + /* store firmware configuration address */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem CONFIG_REG (%#x) @ dmem_addr %#x ssid %d\n", + ctx->config_vied_addr, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_CONFIG_REG, + ctx->config_vied_addr, ssid); + /* store syscom uninitialized state */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem STATE_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_STATE_UNINIT, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + SYSCOM_STATE_UNINIT, ssid); + /* store syscom uninitialized command */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem COMMAND_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_COMMAND_UNINIT, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_UNINIT, ssid); + + return 0; +} + +/* + * store truslet configuration status setting + */ +void +ia_css_syscom_set_trustlet_status( + unsigned int dmem_addr, + unsigned int ssid, + bool trustlet_exist +) +{ + unsigned int value; + + value = trustlet_exist ? TRUSTLET_EXIST : TRUSTLET_NOT_EXIST; + IA_CSS_TRACE_3(SYSCOM, INFO, + "ia_css_syscom_set_trustlet_status TRUSTLET_STATUS (%#x) @ dmem_addr %#x ssid %d\n", + value, dmem_addr, ssid); + regmem_store_32(dmem_addr, TRUSTLET_STATUS, value, ssid); +} + +/* + * check if SPC access blocker programming is completed + */ +bool +ia_css_syscom_is_ab_spc_ready( + struct ia_css_syscom_context *ctx +) +{ + unsigned int value; + + /* We only expect the call from non-secure context only */ + if (ctx->secure) { + IA_CSS_TRACE_0(SYSCOM, ERROR, "ia_css_syscom_is_spc_ab_ready - Please call from non-secure context\n"); + return false; + } + + value = regmem_load_32(ctx->cell_dmem_addr, AB_SPC_STATUS, ctx->env.ssid); + IA_CSS_TRACE_3(SYSCOM, INFO, + "ia_css_syscom_is_spc_ab_ready AB_SPC_STATUS @ dmem_addr %#x ssid %d - value %#x\n", + ctx->cell_dmem_addr, ctx->env.ssid, value); + + return (value == AB_SPC_READY); +} +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/src/ia_css_syscom_config_fw.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/src/ia_css_syscom_config_fw.h new file mode 100644 index 0000000000000..0cacd5a34934d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/src/ia_css_syscom_config_fw.h @@ -0,0 +1,69 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONFIG_FW_H +#define __IA_CSS_SYSCOM_CONFIG_FW_H + +#include "type_support.h" + +enum { + /* Program load or explicit host setting should init to this */ + SYSCOM_STATE_UNINIT = 0x57A7E000, + /* SP Syscom sets this when it is ready for use */ + SYSCOM_STATE_READY = 0x57A7E001, + /* SP Syscom sets this when no more syscom accesses will happen */ + SYSCOM_STATE_INACTIVE = 0x57A7E002 +}; + +enum { + /* Program load or explicit host setting should init to this */ + SYSCOM_COMMAND_UNINIT = 0x57A7F000, + /* Host Syscom requests syscom to become inactive */ + SYSCOM_COMMAND_INACTIVE = 0x57A7F001 +}; + +#if HAS_DUAL_CMD_CTX_SUPPORT +enum { + /* Program load or explicit host setting should init to this */ + TRUSTLET_UNINIT = 0x57A8E000, + /* Host Syscom informs SP that Trustlet exists */ + TRUSTLET_EXIST = 0x57A8E001, + /* Host Syscom informs SP that Trustlet does not exist */ + TRUSTLET_NOT_EXIST = 0x57A8E002 +}; + +enum { + /* Program load or explicit setting initialized by SP */ + AB_SPC_NOT_READY = 0x57A8F000, + /* SP informs host that SPC access programming is completed */ + AB_SPC_READY = 0x57A8F001 +}; +#endif + +/* firmware config: data that sent from the host to SP via DDR */ +/* Cell copies data into a context */ + +struct ia_css_syscom_config_fw { + unsigned int firmware_address; + + unsigned int num_input_queues; + unsigned int num_output_queues; + unsigned int input_queue; /* hmm_ptr / struct queue* */ + unsigned int output_queue; /* hmm_ptr / struct queue* */ + + unsigned int specific_addr; /* vied virtual address */ + unsigned int specific_size; +}; + +#endif /* __IA_CSS_SYSCOM_CONFIG_FW_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/src/ia_css_syscom_context.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/src/ia_css_syscom_context.h new file mode 100644 index 0000000000000..ecf22f6b7ac53 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/src/ia_css_syscom_context.h @@ -0,0 +1,65 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONTEXT_H +#define __IA_CSS_SYSCOM_CONTEXT_H + +#include + +#include "port_env_struct.h" +#include + +/* host context */ +struct ia_css_syscom_context { + vied_virtual_address_t cell_firmware_addr; + unsigned int cell_regs_addr; + unsigned int cell_dmem_addr; + + struct port_env env; + + unsigned int num_input_queues; + unsigned int num_output_queues; + + /* array of input queues (from host to SP) */ + struct sys_queue *input_queue; + /* array of output queues (from SP to host) */ + struct sys_queue *output_queue; + + struct send_port *send_port; + struct recv_port *recv_port; + + unsigned int regmem_idx; + unsigned int free_buf; + + host_virtual_address_t config_host_addr; + host_virtual_address_t input_queue_host_addr; + host_virtual_address_t output_queue_host_addr; + host_virtual_address_t specific_host_addr; + host_virtual_address_t ibuf_host_addr; + host_virtual_address_t obuf_host_addr; + + vied_virtual_address_t config_vied_addr; + vied_virtual_address_t input_queue_vied_addr; + vied_virtual_address_t output_queue_vied_addr; + vied_virtual_address_t specific_vied_addr; + vied_virtual_address_t ibuf_vied_addr; + vied_virtual_address_t obuf_vied_addr; + + /* if true; secure syscom object as in VTIO Case + * if false, non-secure syscom + */ + bool secure; +}; + +#endif /* __IA_CSS_SYSCOM_CONTEXT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/syscom.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/syscom.mk new file mode 100644 index 0000000000000..8d36b8928af55 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/syscom/syscom.mk @@ -0,0 +1,42 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is SYSCOM + +SYSCOM_DIR=$${MODULES_DIR}/syscom + +SYSCOM_INTERFACE=$(SYSCOM_DIR)/interface +SYSCOM_SOURCES1=$(SYSCOM_DIR)/src + +SYSCOM_HOST_FILES += $(SYSCOM_SOURCES1)/ia_css_syscom.c + +SYSCOM_HOST_CPPFLAGS += -I$(SYSCOM_INTERFACE) +SYSCOM_HOST_CPPFLAGS += -I$(SYSCOM_SOURCES1) +SYSCOM_HOST_CPPFLAGS += -I$${MODULES_DIR}/devices +ifdef REGMEM_SECURE_OFFSET +SYSCOM_HOST_CPPFLAGS += -DREGMEM_SECURE_OFFSET=$(REGMEM_SECURE_OFFSET) +else +SYSCOM_HOST_CPPFLAGS += -DREGMEM_SECURE_OFFSET=0 +endif + +SYSCOM_FW_FILES += $(SYSCOM_SOURCES1)/ia_css_syscom_fw.c + +SYSCOM_FW_CPPFLAGS += -I$(SYSCOM_INTERFACE) +SYSCOM_FW_CPPFLAGS += -I$(SYSCOM_SOURCES1) +SYSCOM_FW_CPPFLAGS += -DREGMEM_OFFSET=$(REGMEM_OFFSET) +ifdef REGMEM_SECURE_OFFSET +SYSCOM_FW_CPPFLAGS += -DREGMEM_SECURE_OFFSET=$(REGMEM_SECURE_OFFSET) +else +SYSCOM_FW_CPPFLAGS += -DREGMEM_SECURE_OFFSET=0 +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/trace/interface/ia_css_trace.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/trace/interface/ia_css_trace.h new file mode 100644 index 0000000000000..b85b1810f1070 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/trace/interface/ia_css_trace.h @@ -0,0 +1,883 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/*! \file */ + +#ifndef __IA_CSS_TRACE_H +#define __IA_CSS_TRACE_H + +/* +** Configurations +*/ + +/** + * STEP 1: Define {Module Name}_TRACE_METHOD to one of the following. + * Where: + * {Module Name} is the name of the targeted module. + * + * Example: + * #define NCI_DMA_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + */ + +/**< Use whatever method of tracing that best suits the platform + * this code is compiled for. + */ +#define IA_CSS_TRACE_METHOD_NATIVE 1 +/**< Use the Tracing NCI. */ +#define IA_CSS_TRACE_METHOD_TRACE 2 + +/** + * STEP 2: Define {Module Name}_TRACE_LEVEL_{Level} to one of the following. + * Where: + * {Module Name} is the name of the targeted module. + * {Level}, in decreasing order of severity, is one of the + * following values: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * + * Example: + * #define NCI_DMA_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED + * #define NCI_DMA_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + */ +/**< Disables the corresponding trace level. */ +#define IA_CSS_TRACE_LEVEL_DISABLED 0 +/**< Enables the corresponding trace level. */ +#define IA_CSS_TRACE_LEVEL_ENABLED 1 + +/* + * Used in macro definition with do-while loop + * for removing checkpatch warnings + */ +#define IA_CSS_TRACE_FILE_DUMMY_DEFINE + +/** + * STEP 3: Define IA_CSS_TRACE_PRINT_FILE_LINE to have file name and + * line printed with every log message. + * + * Example: + * #define IA_CSS_TRACE_PRINT_FILE_LINE + */ + +/* +** Interface +*/ + +/* +** Static +*/ + +/** + * Logs a message with zero arguments if the targeted severity level is enabled + * at compile-time. + * @param module The targeted module. + * @param severity The severity level of the trace message. In decreasing order: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * @param format The message to be traced. + */ +#define IA_CSS_TRACE_0(module, severity, format) \ + IA_CSS_TRACE_IMPL(module, 0, severity, format) + +/** + * Logs a message with one argument if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_1(module, severity, format, a1) \ + IA_CSS_TRACE_IMPL(module, 1, severity, format, a1) + +/** + * Logs a message with two arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_2(module, severity, format, a1, a2) \ + IA_CSS_TRACE_IMPL(module, 2, severity, format, a1, a2) + +/** + * Logs a message with three arguments if the targeted severity level + * is enabled at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_3(module, severity, format, a1, a2, a3) \ + IA_CSS_TRACE_IMPL(module, 3, severity, format, a1, a2, a3) + +/** + * Logs a message with four arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_4(module, severity, format, a1, a2, a3, a4) \ + IA_CSS_TRACE_IMPL(module, 4, severity, format, a1, a2, a3, a4) + +/** + * Logs a message with five arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_5(module, severity, format, a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_IMPL(module, 5, severity, format, a1, a2, a3, a4, a5) + +/** + * Logs a message with six arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_6(module, severity, format, a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_IMPL(module, 6, severity, format, a1, a2, a3, a4, a5, a6) + +/** + * Logs a message with seven arguments if the targeted severity level + * is enabled at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_7(module, severity, format, a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_IMPL(module, 7, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) + +/* +** Dynamic +*/ + +/** +* Declares, but does not define, dynamic tracing functions and variables +* for module \p module. For each module, place an instance of this macro +* in the compilation unit in which you want to use dynamic tracing facility +* so as to inform the compiler of the declaration of the available functions. +* An invocation of this function does not enable any of the available tracing +* levels. Do not place a semicolon after a call to this macro. +* @see IA_CSS_TRACE_DYNAMIC_DEFINE +*/ +#define IA_CSS_TRACE_DYNAMIC_DECLARE(module) \ + IA_CSS_TRACE_DYNAMIC_DECLARE_IMPL(module) +/** +* Declares the configuration function for the dynamic api seperatly, if one +* wants to use it. +*/ +#define IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC(module) \ + IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC_IMPL(module) + +/** +* Defines dynamic tracing functions and variables for module \p module. +* For each module, place an instance of this macro in one, and only one, +* of your SOURCE files so as to allow the linker resolve the related symbols. +* An invocation of this macro does not enable any of the available tracing +* levels. Do not place a semicolon after a call to this macro. +* @see IA_CSS_TRACE_DYNAMIC_DECLARE +*/ +#define IA_CSS_TRACE_DYNAMIC_DEFINE(module) \ + IA_CSS_TRACE_DYNAMIC_DEFINE_IMPL(module) +/** +* Defines the configuration function for the dynamic api seperatly, if one +* wants to use it. +*/ +#define IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC(module) \ + IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC_IMPL(module) + +/** + * Logs a message with zero arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @param module The targeted module. + * @param severity The severity level of the trace message. In decreasing order: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * @param format The message to be traced. + */ +#define IA_CSS_TRACE_DYNAMIC_0(module, severity, format) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 0, severity, format) + +/** + * Logs a message with one argument if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_1(module, severity, format, a1) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 1, severity, format, a1) + +/** + * Logs a message with two arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_2(module, severity, format, a1, a2) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 2, severity, format, a1, a2) + +/** + * Logs a message with three arguments if the targeted severity level + * is enabled both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_3(module, severity, format, a1, a2, a3) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 3, severity, format, a1, a2, a3) + +/** + * Logs a message with four arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_4(module, severity, format, a1, a2, a3, a4) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 4, severity, format, a1, a2, a3, a4) + +/** + * Logs a message with five arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_5(module, severity, format, a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 5, severity, format, \ + a1, a2, a3, a4, a5) + +/** + * Logs a message with six arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_6(module, severity, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 6, severity, format, \ + a1, a2, a3, a4, a5, a6) + +/** + * Logs a message with seven arguments if the targeted severity level + * is enabled both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_7(module, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 7, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) + +/* +** Implementation +*/ + +/* CAT */ +#define IA_CSS_TRACE_CAT_IMPL(a, b) a ## b +#define IA_CSS_TRACE_CAT(a, b) IA_CSS_TRACE_CAT_IMPL(a, b) + +/* Bridge */ +#if defined(__HIVECC) || defined(__GNUC__) +#define IA_CSS_TRACE_IMPL(module, argument_count, severity, arguments ...) \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_, \ + argument_count \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_LEVEL_ \ + ), \ + severity \ + ) \ + ( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_SEVERITY_, \ + severity \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + #module, \ + ## arguments \ + ) \ + ) + +/* Bridge */ +#define IA_CSS_TRACE_DYNAMIC_IMPL(module, argument_count, severity, \ + arguments ...) \ + do { \ + if (IA_CSS_TRACE_CAT(IA_CSS_TRACE_CAT(module, _trace_level_), \ + severity)) { \ + IA_CSS_TRACE_IMPL(module, argument_count, severity, \ + ## arguments); \ + } \ + } while (0) +#elif defined(_MSC_VER) +#define IA_CSS_TRACE_IMPL(module, argument_count, severity, ...) \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_, \ + argument_count \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_LEVEL_ \ + ), \ + severity \ + ) \ + ( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_SEVERITY_, \ + severity \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + #module, \ + __VA_ARGS__ \ + ) \ + ) + +/* Bridge */ +#define IA_CSS_TRACE_DYNAMIC_IMPL(module, argument_count, severity, ...) \ + do { \ + if (IA_CSS_TRACE_CAT(IA_CSS_TRACE_CAT(module, _trace_level_), \ + severity)) { \ + IA_CSS_TRACE_IMPL(module, argument_count, severity, \ + __VA_ARGS__); \ + } \ + } while (0) +#endif + +/* +** Native Backend +*/ + +#if defined(__HIVECC) + #define IA_CSS_TRACE_PLATFORM_CELL +#elif defined(__GNUC__) + #define IA_CSS_TRACE_PLATFORM_HOST + + #define IA_CSS_TRACE_NATIVE(severity, module, format, arguments ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, module, \ + format), ## arguments); \ + } while (0) + /* TODO: In case Host Side tracing is needed to be mapped to the + * Tunit, the following "IA_CSS_TRACE_TRACE" needs to be modified from + * PRINT to vied_nci_tunit_print function calls + */ + #define IA_CSS_TRACE_TRACE(severity, module, format, arguments ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, module, \ + format), ## arguments); \ + } while (0) + +#elif defined(_MSC_VER) + #define IA_CSS_TRACE_PLATFORM_HOST + + #define IA_CSS_TRACE_NATIVE(severity, module, format, ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, \ + module, format), __VA_ARGS__); \ + } while (0) + /* TODO: In case Host Side tracing is needed to be mapped to the + * Tunit, the following "IA_CSS_TRACE_TRACE" needs to be modified from + * PRINT to vied_nci_tunit_print function calls + */ + #define IA_CSS_TRACE_TRACE(severity, module, format, ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, \ + module, format), __VA_ARGS__); \ + } while (0) +#else + #error Unsupported platform! +#endif /* Platform */ + +#if defined(IA_CSS_TRACE_PLATFORM_CELL) + #include /* VOLATILE */ + + #ifdef IA_CSS_TRACE_PRINT_FILE_LINE + #define IA_CSS_TRACE_FILE_PRINT_COMMAND \ + do { \ + OP___printstring(__FILE__":") VOLATILE; \ + OP___printdec(__LINE__) VOLATILE; \ + OP___printstring("\n") VOLATILE; \ + } while (0) + #else + #define IA_CSS_TRACE_FILE_PRINT_COMMAND + #endif + + #define IA_CSS_TRACE_MODULE_SEVERITY_PRINT(module, severity) \ + do { \ + IA_CSS_TRACE_FILE_DUMMY_DEFINE; \ + OP___printstring("["module"]:["severity"]:") \ + VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_MSG_NATIVE(severity, module, format) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + OP___printstring("["module"]:["severity"]: "format) \ + VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_ARG_NATIVE(module, severity, i, value) \ + do { \ + IA_CSS_TRACE_MODULE_SEVERITY_PRINT(module, severity); \ + OP___dump(i, value) VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_0(severity, module, format) \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format) + + #define IA_CSS_TRACE_NATIVE_1(severity, module, format, a1) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_2(severity, module, format, a1, a2) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_3(severity, module, format, a1, a2, a3) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_4(severity, module, format, \ + a1, a2, a3, a4) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 6, a6); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 6, a6); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 7, a7); \ + } while (0) + /* + ** Tracing Backend + */ +#if !defined(HRT_CSIM) && !defined(NO_TUNIT) + #include "vied_nci_tunit.h" +#endif + #define IA_CSS_TRACE_AUG_FORMAT_TRACE(format, module) \ + "[" module "]" format " : PID = %x : Timestamp = %d : PC = %x" + + #define IA_CSS_TRACE_TRACE_0(severity, module, format) \ + vied_nci_tunit_print(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity) + + #define IA_CSS_TRACE_TRACE_1(severity, module, format, a1) \ + vied_nci_tunit_print1i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1) + + #define IA_CSS_TRACE_TRACE_2(severity, module, format, a1, a2) \ + vied_nci_tunit_print2i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2) + + #define IA_CSS_TRACE_TRACE_3(severity, module, format, a1, a2, a3) \ + vied_nci_tunit_print3i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3) + + #define IA_CSS_TRACE_TRACE_4(severity, module, format, a1, a2, a3, a4) \ + vied_nci_tunit_print4i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4) + + #define IA_CSS_TRACE_TRACE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + vied_nci_tunit_print5i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_TRACE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + vied_nci_tunit_print6i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_TRACE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + vied_nci_tunit_print7i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5, a6, a7) + +#elif defined(IA_CSS_TRACE_PLATFORM_HOST) + #include "print_support.h" + + #ifdef IA_CSS_TRACE_PRINT_FILE_LINE + #define IA_CSS_TRACE_FILE_PRINT_COMMAND \ + PRINT("%s:%d:\n", __FILE__, __LINE__) + #else + #define IA_CSS_TRACE_FILE_PRINT_COMMAND + #endif + + #define IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, module, format) \ + "[" module "]:[" severity "]: " format + + #define IA_CSS_TRACE_NATIVE_0(severity, module, format) \ + IA_CSS_TRACE_NATIVE(severity, module, format) + + #define IA_CSS_TRACE_NATIVE_1(severity, module, format, a1) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1) + + #define IA_CSS_TRACE_NATIVE_2(severity, module, format, a1, a2) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2) + + #define IA_CSS_TRACE_NATIVE_3(severity, module, format, a1, a2, a3) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2, a3) + + #define IA_CSS_TRACE_NATIVE_4(severity, module, format, \ + a1, a2, a3, a4) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2, a3, a4) + + #define IA_CSS_TRACE_NATIVE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_NATIVE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_NATIVE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) + + #define IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, module, format) \ + "["module"]:["severity"]: "format + + #define IA_CSS_TRACE_TRACE_0(severity, module, format) \ + IA_CSS_TRACE_TRACE(severity, module, format) + + #define IA_CSS_TRACE_TRACE_1(severity, module, format, a1) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1) + + #define IA_CSS_TRACE_TRACE_2(severity, module, format, a1, a2) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2) + + #define IA_CSS_TRACE_TRACE_3(severity, module, format, a1, a2, a3) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2, a3) + + #define IA_CSS_TRACE_TRACE_4(severity, module, format, \ + a1, a2, a3, a4) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2, a3, a4) + + #define IA_CSS_TRACE_TRACE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_TRACE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_TRACE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) +#endif + +/* Disabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_1_0(severity, module, format) +#define IA_CSS_TRACE_1_1_0(severity, module, format, arg1) +#define IA_CSS_TRACE_2_1_0(severity, module, format, arg1, arg2) +#define IA_CSS_TRACE_3_1_0(severity, module, format, arg1, arg2, arg3) +#define IA_CSS_TRACE_4_1_0(severity, module, format, arg1, arg2, arg3, arg4) +#define IA_CSS_TRACE_5_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5) +#define IA_CSS_TRACE_6_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6) +#define IA_CSS_TRACE_7_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7) + +/* Enabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_1_1 IA_CSS_TRACE_NATIVE_0 +#define IA_CSS_TRACE_1_1_1 IA_CSS_TRACE_NATIVE_1 +#define IA_CSS_TRACE_2_1_1 IA_CSS_TRACE_NATIVE_2 +#define IA_CSS_TRACE_3_1_1 IA_CSS_TRACE_NATIVE_3 +#define IA_CSS_TRACE_4_1_1 IA_CSS_TRACE_NATIVE_4 +#define IA_CSS_TRACE_5_1_1 IA_CSS_TRACE_NATIVE_5 +#define IA_CSS_TRACE_6_1_1 IA_CSS_TRACE_NATIVE_6 +#define IA_CSS_TRACE_7_1_1 IA_CSS_TRACE_NATIVE_7 + +/* Enabled */ +/* Legend: IA_CSS_TRACE_SEVERITY_{Severity Level}_{Backend ID} */ +#define IA_CSS_TRACE_SEVERITY_ASSERT_1 "Assert" +#define IA_CSS_TRACE_SEVERITY_ERROR_1 "Error" +#define IA_CSS_TRACE_SEVERITY_WARNING_1 "Warning" +#define IA_CSS_TRACE_SEVERITY_INFO_1 "Info" +#define IA_CSS_TRACE_SEVERITY_DEBUG_1 "Debug" +#define IA_CSS_TRACE_SEVERITY_VERBOSE_1 "Verbose" + +/* Disabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_2_0(severity, module, format) +#define IA_CSS_TRACE_1_2_0(severity, module, format, arg1) +#define IA_CSS_TRACE_2_2_0(severity, module, format, arg1, arg2) +#define IA_CSS_TRACE_3_2_0(severity, module, format, arg1, arg2, arg3) +#define IA_CSS_TRACE_4_2_0(severity, module, format, arg1, arg2, arg3, arg4) +#define IA_CSS_TRACE_5_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5) +#define IA_CSS_TRACE_6_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6) +#define IA_CSS_TRACE_7_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7) + +/* Enabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_2_1 IA_CSS_TRACE_TRACE_0 +#define IA_CSS_TRACE_1_2_1 IA_CSS_TRACE_TRACE_1 +#define IA_CSS_TRACE_2_2_1 IA_CSS_TRACE_TRACE_2 +#define IA_CSS_TRACE_3_2_1 IA_CSS_TRACE_TRACE_3 +#define IA_CSS_TRACE_4_2_1 IA_CSS_TRACE_TRACE_4 +#define IA_CSS_TRACE_5_2_1 IA_CSS_TRACE_TRACE_5 +#define IA_CSS_TRACE_6_2_1 IA_CSS_TRACE_TRACE_6 +#define IA_CSS_TRACE_7_2_1 IA_CSS_TRACE_TRACE_7 + +/* Enabled */ +/* Legend: IA_CSS_TRACE_SEVERITY_{Severity Level}_{Backend ID} */ +#define IA_CSS_TRACE_SEVERITY_ASSERT_2 VIED_NCI_TUNIT_MSG_SEVERITY_FATAL +#define IA_CSS_TRACE_SEVERITY_ERROR_2 VIED_NCI_TUNIT_MSG_SEVERITY_ERROR +#define IA_CSS_TRACE_SEVERITY_WARNING_2 VIED_NCI_TUNIT_MSG_SEVERITY_WARNING +#define IA_CSS_TRACE_SEVERITY_INFO_2 VIED_NCI_TUNIT_MSG_SEVERITY_NORMAL +#define IA_CSS_TRACE_SEVERITY_DEBUG_2 VIED_NCI_TUNIT_MSG_SEVERITY_USER1 +#define IA_CSS_TRACE_SEVERITY_VERBOSE_2 VIED_NCI_TUNIT_MSG_SEVERITY_USER2 + +/* +** Dynamicism +*/ + +#define IA_CSS_TRACE_DYNAMIC_DECLARE_IMPL(module) \ + do { \ + void IA_CSS_TRACE_CAT(module, _trace_assert_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_assert_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_error_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_error_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_warning_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_warning_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_info_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_info_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_debug_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_debug_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_disable)(void); \ + } while (0) + +#define IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC_IMPL(module) \ + do { \ + IA_CSS_TRACE_FILE_DUMMY_DEFINE; \ + void IA_CSS_TRACE_CAT(module, _trace_configure)\ + (int argc, const char *const *argv); \ + } while (0) + +#include "platform_support.h" +#include "type_support.h" + +#define IA_CSS_TRACE_DYNAMIC_DEFINE_IMPL(module) \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_assert); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_error); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_warning); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_info); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_debug); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_verbose); \ + \ + void IA_CSS_TRACE_CAT(module, _trace_assert_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_assert) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_assert_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_assert) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_error_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_error) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_error_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_error) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_warning_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_warning) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_warning_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_warning) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_info_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_info) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_info_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_info) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_debug_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_debug) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_debug_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_debug) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_verbose) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_verbose) = 0; \ + } + +#define IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC_IMPL(module) \ +void IA_CSS_TRACE_CAT(module, _trace_configure)(const int argc, \ + const char *const *const argv) \ +{ \ + int i = 1; \ + const char *levels = 0; \ + \ + while (i < argc) { \ + if (!strcmp(argv[i], "-" #module "_trace")) { \ + ++i; \ + \ + if (i < argc) { \ + levels = argv[i]; \ + \ + while (*levels) { \ + switch (*levels++) { \ + case 'a': \ + IA_CSS_TRACE_CAT \ + (module, _trace_assert_enable)(); \ + break; \ + \ + case 'e': \ + IA_CSS_TRACE_CAT \ + (module, _trace_error_enable)(); \ + break; \ + \ + case 'w': \ + IA_CSS_TRACE_CAT \ + (module, _trace_warning_enable)(); \ + break; \ + \ + case 'i': \ + IA_CSS_TRACE_CAT \ + (module, _trace_info_enable)(); \ + break; \ + \ + case 'd': \ + IA_CSS_TRACE_CAT \ + (module, _trace_debug_enable)(); \ + break; \ + \ + case 'v': \ + IA_CSS_TRACE_CAT \ + (module, _trace_verbose_enable)(); \ + break; \ + \ + default: \ + } \ + } \ + } \ + } \ + \ + ++i; \ + } \ +} + +#endif /* __IA_CSS_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/trace/trace.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/trace/trace.mk new file mode 100644 index 0000000000000..b232880b882bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/trace/trace.mk @@ -0,0 +1,40 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE Trace + +# Dependencies +IA_CSS_TRACE_SUPPORT = $${MODULES_DIR}/support + +# API +IA_CSS_TRACE = $${MODULES_DIR}/trace +IA_CSS_TRACE_INTERFACE = $(IA_CSS_TRACE)/interface + +# +# Host +# + +# Host CPP Flags +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE_SUPPORT) +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE_INTERFACE) +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE)/trace_modules + +# +# Firmware +# + +# Firmware CPP Flags +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE_SUPPORT) +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE_INTERFACE) +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE)/trace_modules diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/shared_memory_access.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/shared_memory_access.h new file mode 100644 index 0000000000000..fd11c12367fec --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/shared_memory_access.h @@ -0,0 +1,138 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _SHARED_MEMORY_ACCESS_H +#define _SHARED_MEMORY_ACCESS_H + +#include +#include +#include + +typedef enum { + sm_esuccess, + sm_enomem, + sm_ezeroalloc, + sm_ebadvaddr, + sm_einternalerror, + sm_ecorruption, + sm_enocontiguousmem, + sm_enolocmem, + sm_emultiplefree, +} shared_memory_error; + +/** + * \brief Virtual address of (DDR) shared memory space as seen from the VIED subsystem + */ +typedef uint32_t vied_virtual_address_t; + +/** + * \brief Virtual address of (DDR) shared memory space as seen from the host + */ +typedef unsigned long long host_virtual_address_t; + +/** + * \brief List of physical addresses of (DDR) shared memory space. This is used to represent a list of physical pages. + */ +typedef struct shared_memory_physical_page_list_s *shared_memory_physical_page_list; +typedef struct shared_memory_physical_page_list_s { + shared_memory_physical_page_list next; + vied_physical_address_t address; +} shared_memory_physical_page_list_s; + + +/** + * \brief Initialize the shared memory interface administration on the host. + * \param idm: id of ddr memory + * \param host_ddr_addr: physical address of memory as seen from host + * \param memory_size: size of ddr memory in bytes + * \param ps: size of page in bytes (for instance 4096) + */ +int shared_memory_allocation_initialize(vied_memory_t idm, vied_physical_address_t host_ddr_addr, size_t memory_size, size_t ps); + +/** + * \brief De-initialize the shared memory interface administration on the host. + * + */ +void shared_memory_allocation_uninitialize(vied_memory_t idm); + +/** + * \brief Allocate (DDR) shared memory space and return a host virtual address. Returns NULL when insufficient memory available + */ +host_virtual_address_t shared_memory_alloc(vied_memory_t idm, size_t bytes); + +/** + * \brief Free (DDR) shared memory space. +*/ +void shared_memory_free(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Translate a virtual host.address to a physical address. +*/ +vied_physical_address_t shared_memory_virtual_host_to_physical_address(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Return the allocated physical pages for a virtual host.address. +*/ +shared_memory_physical_page_list shared_memory_virtual_host_to_physical_pages(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Destroy a shared_memory_physical_page_list. +*/ +void shared_memory_physical_pages_list_destroy(shared_memory_physical_page_list ppl); + +/** + * \brief Store a byte into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_8(vied_memory_t idm, host_virtual_address_t addr, uint8_t data); + +/** + * \brief Store a 16-bit word into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_16(vied_memory_t idm, host_virtual_address_t addr, uint16_t data); + +/** + * \brief Store a 32-bit word into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_32(vied_memory_t idm, host_virtual_address_t addr, uint32_t data); + +/** + * \brief Store a number of bytes into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store(vied_memory_t idm, host_virtual_address_t addr, const void *data, size_t bytes); + +/** + * \brief Set a number of bytes of (DDR) shared memory space to 0 using a host virtual address + */ +void shared_memory_zero(vied_memory_t idm, host_virtual_address_t addr, size_t bytes); + +/** + * \brief Load a byte from (DDR) shared memory space using a host virtual address + */ +uint8_t shared_memory_load_8(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a 16-bit word from (DDR) shared memory space using a host virtual address + */ +uint16_t shared_memory_load_16(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a 32-bit word from (DDR) shared memory space using a host virtual address + */ +uint32_t shared_memory_load_32(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a number of bytes from (DDR) shared memory space using a host virtual address + */ +void shared_memory_load(vied_memory_t idm, host_virtual_address_t addr, void *data, size_t bytes); + +#endif /* _SHARED_MEMORY_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/shared_memory_map.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/shared_memory_map.h new file mode 100644 index 0000000000000..1bbedcf9e7fd8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/shared_memory_map.h @@ -0,0 +1,53 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _SHARED_MEMORY_MAP_H +#define _SHARED_MEMORY_MAP_H + +#include +#include +#include + +typedef void (*shared_memory_invalidate_mmu_tlb)(void); +typedef void (*shared_memory_set_page_table_base_address)(vied_physical_address_t); + +typedef void (*shared_memory_invalidate_mmu_tlb_ssid)(vied_subsystem_t id); +typedef void (*shared_memory_set_page_table_base_address_ssid)(vied_subsystem_t id, vied_physical_address_t); + +/** + * \brief Initialize the CSS virtual address system and MMU. The subsystem id will NOT be taken into account. +*/ +int shared_memory_map_initialize(vied_subsystem_t id, vied_memory_t idm, size_t mmu_ps, size_t mmu_pnrs, vied_physical_address_t ddr_addr, shared_memory_invalidate_mmu_tlb inv_tlb, shared_memory_set_page_table_base_address sbt); + +/** + * \brief Initialize the CSS virtual address system and MMU. The subsystem id will be taken into account. +*/ +int shared_memory_map_initialize_ssid(vied_subsystem_t id, vied_memory_t idm, size_t mmu_ps, size_t mmu_pnrs, vied_physical_address_t ddr_addr, shared_memory_invalidate_mmu_tlb_ssid inv_tlb, shared_memory_set_page_table_base_address_ssid sbt); + +/** + * \brief De-initialize the CSS virtual address system and MMU. +*/ +void shared_memory_map_uninitialize(vied_subsystem_t id, vied_memory_t idm); + +/** + * \brief Convert a host virtual address to a CSS virtual address and update the MMU. +*/ +vied_virtual_address_t shared_memory_map(vied_subsystem_t id, vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Free a CSS virtual address and update the MMU. +*/ +void shared_memory_unmap(vied_subsystem_t id, vied_memory_t idm, vied_virtual_address_t addr); + + +#endif /* _SHARED_MEMORY_MAP_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_config.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_config.h new file mode 100644 index 0000000000000..33ae98e27605d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_config.h @@ -0,0 +1,33 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_CONFIG_H +#define _HRT_VIED_CONFIG_H + +/* Defines from the compiler: + * HRT_HOST - this is code running on the host + * HRT_CELL - this is code running on a cell + */ +#ifdef HRT_HOST +# define CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL 1 +# undef CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL + +#elif defined(HRT_CELL) +# undef CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL +# define CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL 1 + +#else /* !HRT_CELL */ +/* Allow neither HRT_HOST nor HRT_CELL for testing purposes */ +#endif /* !HRT_CELL */ + +#endif /* _HRT_VIED_CONFIG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_memory_access_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_memory_access_types.h new file mode 100644 index 0000000000000..0b44492789e37 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_memory_access_types.h @@ -0,0 +1,36 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_MEMORY_ACCESS_TYPES_H +#define _HRT_VIED_MEMORY_ACCESS_TYPES_H + +/** Types for the VIED memory access interface */ + +#include "vied_types.h" + +/** + * \brief An identifier for a system memory. + * + * This identifier must be a compile-time constant. It is used in + * access to system memory. + */ +typedef unsigned int vied_memory_t; + +#ifndef __HIVECC +/** + * \brief The type for a physical address + */ +typedef unsigned long long vied_physical_address_t; +#endif + +#endif /* _HRT_VIED_MEMORY_ACCESS_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_subsystem_access.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_subsystem_access.h new file mode 100644 index 0000000000000..879bcb41253a9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_subsystem_access.h @@ -0,0 +1,70 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_H + +#include +#include "vied_config.h" +#include "vied_subsystem_access_types.h" + +#if !defined(CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL) && \ + !defined(CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL) +#error Implementation selection macro for vied subsystem access not defined +#endif + +#if defined(CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL) +#ifndef __HIVECC +#error "Inline implementation of subsystem access not supported for host" +#endif +#define _VIED_SUBSYSTEM_ACCESS_INLINE static inline +#include "vied_subsystem_access_impl.h" +#else +#define _VIED_SUBSYSTEM_ACCESS_INLINE +#endif + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_8(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint8_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_16(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint16_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_32(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint32_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store(vied_subsystem_t dev, + vied_subsystem_address_t addr, + const void *data, unsigned int size); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint8_t vied_subsystem_load_8(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint16_t vied_subsystem_load_16(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint32_t vied_subsystem_load_32(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_load(vied_subsystem_t dev, + vied_subsystem_address_t addr, + void *data, unsigned int size); + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_subsystem_access_initialization.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_subsystem_access_initialization.h new file mode 100644 index 0000000000000..344f31c4df104 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_subsystem_access_initialization.h @@ -0,0 +1,44 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H + +#include "vied_subsystem_access_types.h" + +/** @brief Initialises the access of a subsystem. + * @param[in] system The subsystem for which the access has to be initialised. + * + * vied_subsystem_access_initialize initilalises the access a subsystem. + * It sets the base address of the subsystem. This base address is extracted from the hsd file. + * + */ +void +vied_subsystem_access_initialize(vied_subsystem_t system); + + +/** @brief Initialises the access of multiple subsystems. + * @param[in] nr _subsystems The number of subsystems for which the access has to be initialised. + * @param[in] dev_base_addresses A pointer to an array of base addresses of subsystems. + * The size of this array must be "nr_subsystems". + * This array must be available during the accesses of the subsystem. + * + * vied_subsystems_access_initialize initilalises the access to multiple subsystems. + * It sets the base addresses of the subsystems that are provided by the array dev_base_addresses. + * + */ +void +vied_subsystems_access_initialize(unsigned int nr_subsystems + , const vied_subsystem_base_address_t *base_addresses); + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_subsystem_access_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_subsystem_access_types.h new file mode 100644 index 0000000000000..75fef6c4ddba2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_subsystem_access_types.h @@ -0,0 +1,34 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H + +/** Types for the VIED subsystem access interface */ +#include + +/** \brief An identifier for a VIED subsystem. + * + * This identifier must be a compile-time constant. It is used in + * access to a VIED subsystem. + */ +typedef unsigned int vied_subsystem_t; + + +/** \brief An address within a VIED subsystem */ +typedef uint32_t vied_subsystem_address_t; + +/** \brief A base address of a VIED subsystem seen from the host */ +typedef unsigned long long vied_subsystem_base_address_t; + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_types.h new file mode 100644 index 0000000000000..0acfdbb00cfa3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied/vied/vied_types.h @@ -0,0 +1,45 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_TYPES_H +#define _HRT_VIED_TYPES_H + +/** Types shared by VIED interfaces */ + +#include + +/** \brief An address within a VIED subsystem + * + * This will eventually replace teh vied_memory_address_t and vied_subsystem_address_t + */ +typedef uint32_t vied_address_t; + +/** \brief Memory address type + * + * A memory address is an offset within a memory. + */ +typedef uint32_t vied_memory_address_t; + +/** \brief Master port id */ +typedef int vied_master_port_id_t; + +/** + * \brief Require the existence of a certain type + * + * This macro can be used in interface header files to ensure that + * an implementation define type with a specified name exists. + */ +#define _VIED_REQUIRE_TYPE(T) enum { _VIED_SIZEOF_##T = sizeof(T) } + + +#endif /* _HRT_VIED_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_nci_acb/interface/vied_nci_acb_route_type.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_nci_acb/interface/vied_nci_acb_route_type.h new file mode 100644 index 0000000000000..b09d9f4d5d427 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_nci_acb/interface/vied_nci_acb_route_type.h @@ -0,0 +1,39 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef VIED_NCI_ACB_ROUTE_TYPE_H_ +#define VIED_NCI_ACB_ROUTE_TYPE_H_ + +#include "type_support.h" + +typedef enum { + NCI_ACB_PORT_ISP = 0, + NCI_ACB_PORT_ACC = 1, + NCI_ACB_PORT_INVALID = 0xFF +} nci_acb_port_t; + +typedef struct { + /* 0 = ISP, 1 = Acc */ + nci_acb_port_t in_select; + /* 0 = ISP, 1 = Acc */ + nci_acb_port_t out_select; + /* When set, Ack will be sent only when Eof arrives */ + uint32_t ignore_line_num; + /* Fork adapter to enable streaming to both output + * (next acb out and isp out) + */ + uint32_t fork_acb_output; +} nci_acb_route_t; + +#endif /* VIED_NCI_ACB_ROUTE_TYPE_H_ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_param_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_param_storage_class.h new file mode 100644 index 0000000000000..1ea7e729078c2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_param_storage_class.h @@ -0,0 +1,28 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PARAM_STORAGE_CLASS_H +#define __IA_CSS_PARAM_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __INLINE_PARAMETERS__ +#define IA_CSS_PARAMETERS_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PARAMETERS_STORAGE_CLASS_C +#else +#define IA_CSS_PARAMETERS_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PARAMETERS_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PARAM_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal.h new file mode 100644 index 0000000000000..4cc71be3fc389 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal.h @@ -0,0 +1,188 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_H +#define __IA_CSS_TERMINAL_H + +#include "type_support.h" +#include "ia_css_terminal_types.h" +#include "ia_css_param_storage_class.h" + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_param_in_terminal_get_descriptor_size( + const unsigned int nof_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_param_section_desc_t * +ia_css_param_in_terminal_get_param_section_desc( + const ia_css_param_terminal_t *param_terminal, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_param_out_terminal_get_descriptor_size( + const unsigned int nof_sections, + const unsigned int nof_fragments +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_param_section_desc_t * +ia_css_param_out_terminal_get_param_section_desc( + const ia_css_param_terminal_t *param_terminal, + const unsigned int section_index, + const unsigned int nof_sections, + const unsigned int fragment_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_param_terminal_create( + ia_css_param_terminal_t *param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal +); + + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_spatial_param_terminal_get_descriptor_size( + const unsigned int nof_frame_param_sections, + const unsigned int nof_fragments +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_fragment_grid_desc_t * +ia_css_spatial_param_terminal_get_fragment_grid_desc( + const ia_css_spatial_param_terminal_t *spatial_param_terminal, + const unsigned int fragment_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_frame_grid_param_section_desc_t * +ia_css_spatial_param_terminal_get_frame_grid_param_section_desc( + const ia_css_spatial_param_terminal_t *spatial_param_terminal, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_spatial_param_terminal_create( + ia_css_spatial_param_terminal_t *spatial_param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal, + const unsigned int nof_fragments, + const uint32_t kernel_id +); + + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_sliced_param_terminal_get_descriptor_size( + const unsigned int nof_slice_param_sections, + const unsigned int nof_slices[], + const unsigned int nof_fragments +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_fragment_slice_desc_t * +ia_css_sliced_param_terminal_get_fragment_slice_desc( + const ia_css_sliced_param_terminal_t *sliced_param_terminal, + const unsigned int fragment_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_slice_param_section_desc_t * +ia_css_sliced_param_terminal_get_slice_param_section_desc( + const ia_css_sliced_param_terminal_t *sliced_param_terminal, + const unsigned int fragment_index, + const unsigned int slice_index, + const unsigned int section_index, + const unsigned int nof_slice_param_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_sliced_param_terminal_create( + ia_css_sliced_param_terminal_t *sliced_param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal, + const unsigned int nof_slice_param_sections, + const unsigned int nof_slices[], + const unsigned int nof_fragments, + const uint32_t kernel_id +); + + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_program_terminal_get_descriptor_size( + const unsigned int nof_fragments, + const unsigned int nof_fragment_param_sections, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int nof_command_objs +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_fragment_param_section_desc_t * +ia_css_program_terminal_get_frgmnt_prm_sct_desc( + const ia_css_program_terminal_t *program_terminal, + const unsigned int fragment_index, + const unsigned int section_index, + const unsigned int nof_fragment_param_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_kernel_fragment_sequencer_info_desc_t * +ia_css_program_terminal_get_kernel_frgmnt_seq_info_desc( + const ia_css_program_terminal_t *program_terminal, + const unsigned int fragment_index, + const unsigned int info_index, + const unsigned int nof_kernel_fragment_sequencer_infos +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_program_terminal_create( + ia_css_program_terminal_t *program_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const unsigned int nof_fragments, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int nof_command_objs +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_program_terminal_get_command_base_offset( + const ia_css_program_terminal_t *program_terminal, + const unsigned int nof_fragments, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int commands_slots_used, + uint16_t *command_desc_offset +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +uint16_t *ia_css_program_terminal_get_line_count( + const ia_css_kernel_fragment_sequencer_command_desc_t + *kernel_fragment_sequencer_command_desc_base, + const unsigned int set_count +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_spatial_param_terminal_get_descriptor_size( + const unsigned int nof_frame_param_sections, + const unsigned int nof_fragments +); + +#ifdef __INLINE_PARAMETERS__ +#include "ia_css_terminal_impl.h" +#endif /* __INLINE_PARAMETERS__ */ + +#endif /* __IA_CSS_TERMINAL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest.h new file mode 100644 index 0000000000000..ca0a436082cf6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest.h @@ -0,0 +1,109 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_MANIFEST_H +#define __IA_CSS_TERMINAL_MANIFEST_H + +#include "type_support.h" +#include "ia_css_param_storage_class.h" +#include "ia_css_terminal_manifest_types.h" + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_param_terminal_manifest_get_size( + const unsigned int nof_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_param_terminal_manifest_init( + ia_css_param_terminal_manifest_t *param_terminal, + const uint16_t section_count +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_param_manifest_section_desc_t * +ia_css_param_terminal_manifest_get_prm_sct_desc( + const ia_css_param_terminal_manifest_t *param_terminal_manifest, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_spatial_param_terminal_manifest_get_size( + const unsigned int nof_frame_param_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_spatial_param_terminal_manifest_init( + ia_css_spatial_param_terminal_manifest_t *spatial_param_terminal, + const uint16_t section_count +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_frame_grid_param_manifest_section_desc_t * +ia_css_spatial_param_terminal_manifest_get_frm_grid_prm_sct_desc( + const ia_css_spatial_param_terminal_manifest_t * + spatial_param_terminal_manifest, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_sliced_param_terminal_manifest_get_size( + const unsigned int nof_slice_param_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_sliced_param_terminal_manifest_init( + ia_css_sliced_param_terminal_manifest_t *sliced_param_terminal, + const uint16_t section_count +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_sliced_param_manifest_section_desc_t * +ia_css_sliced_param_terminal_manifest_get_sliced_prm_sct_desc( + const ia_css_sliced_param_terminal_manifest_t * + sliced_param_terminal_manifest, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_program_terminal_manifest_get_size( + const unsigned int nof_fragment_param_sections, + const unsigned int nof_kernel_fragment_sequencer_infos +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_program_terminal_manifest_init( + ia_css_program_terminal_manifest_t *program_terminal, + const uint16_t fragment_param_section_count, + const uint16_t kernel_fragment_seq_info_section_count +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_fragment_param_manifest_section_desc_t * +ia_css_program_terminal_manifest_get_frgmnt_prm_sct_desc( + const ia_css_program_terminal_manifest_t *program_terminal_manifest, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_kernel_fragment_sequencer_info_manifest_desc_t * +ia_css_program_terminal_manifest_get_kernel_frgmnt_seq_info_desc( + const ia_css_program_terminal_manifest_t *program_terminal_manifest, + const unsigned int info_index +); + +#ifdef __INLINE_PARAMETERS__ +#include "ia_css_terminal_manifest_impl.h" +#endif /* __INLINE_PARAMETERS__ */ + +#endif /* __IA_CSS_TERMINAL_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest_types.h new file mode 100644 index 0000000000000..fe146395a8f4f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest_types.h @@ -0,0 +1,342 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_MANIFEST_TYPES_H +#define __IA_CSS_TERMINAL_MANIFEST_TYPES_H + + +#include "ia_css_terminal_defs.h" +#include "type_support.h" +#include "ia_css_base_types.h" +#include "ia_css_terminal_manifest_base_types.h" + +#define N_PADDING_UINT8_IN_PARAM_TERMINAL_MANIFEST_SEC_STRUCT 1 +#define SIZE_OF_PARAM_TERMINAL_MANIFEST_SEC_STRUCT_IN_BITS \ + (1 * IA_CSS_UINT32_T_BITS \ + + 3 * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_PARAM_TERMINAL_MANIFEST_SEC_STRUCT * IA_CSS_UINT8_T_BITS) + +/* =============== Cached Param Terminal Manifest - START ============== */ +struct ia_css_param_manifest_section_desc_s { + /* Maximum size of the related parameter region */ + uint32_t max_mem_size; + /* Indication of the kernel this parameter belongs to */ + uint8_t kernel_id; + /* Memory targeted by this section + * (Register MMIO Interface/DMEM/VMEM/GMEM etc) + */ + uint8_t mem_type_id; + /* Region id within the specified memory */ + uint8_t region_id; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PARAM_TERMINAL_MANIFEST_SEC_STRUCT]; +}; + +typedef struct ia_css_param_manifest_section_desc_s + ia_css_param_manifest_section_desc_t; + + +#define N_PADDING_UINT8_IN_PARAM_TERMINAL_MAN_STRUCT 4 +#define SIZE_OF_PARAM_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + (SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + + (2*IA_CSS_UINT16_T_BITS) \ + + (N_PADDING_UINT8_IN_PARAM_TERMINAL_MAN_STRUCT * IA_CSS_UINT8_T_BITS)) + +/* Frame constant parameters terminal manifest */ +struct ia_css_param_terminal_manifest_s { + /* Parameter terminal manifest base */ + ia_css_terminal_manifest_t base; + /* + * Number of cached parameter sections, coming from manifest + * but also shared by the terminal + */ + uint16_t param_manifest_section_desc_count; + /* + * Points to the variable array of + * struct ia_css_param_section_desc_s + */ + uint16_t param_manifest_section_desc_offset; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PARAM_TERMINAL_MAN_STRUCT]; +}; + +typedef struct ia_css_param_terminal_manifest_s + ia_css_param_terminal_manifest_t; +/* ================= Cached Param Terminal Manifest - End ================ */ + + +/* ================= Spatial Param Terminal Manifest - START ============= */ + +#define SIZE_OF_FRAG_GRID_MAN_STRUCT_IN_BITS \ + ((IA_CSS_N_DATA_DIMENSION*IA_CSS_UINT16_T_BITS) \ + + (IA_CSS_N_DATA_DIMENSION*IA_CSS_UINT16_T_BITS)) + +struct ia_css_fragment_grid_manifest_desc_s { + /* Min resolution width/height of the spatial parameters + * for the fragment measured in compute units + */ + uint16_t min_fragment_grid_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Max resolution width/height of the spatial parameters + * for the fragment measured in compute units + */ + uint16_t max_fragment_grid_dimension[IA_CSS_N_DATA_DIMENSION]; +}; + +typedef struct ia_css_fragment_grid_manifest_desc_s + ia_css_fragment_grid_manifest_desc_t; + +#define N_PADDING_UINT8_IN_FRAME_GRID_PARAM_MAN_SEC_STRUCT 1 +#define SIZE_OF_FRAME_GRID_PARAM_MAN_SEC_STRUCT_IN_BITS \ + (1 * IA_CSS_UINT32_T_BITS \ + + 3 * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_FRAME_GRID_PARAM_MAN_SEC_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_frame_grid_param_manifest_section_desc_s { + /* Maximum buffer total size allowed for + * this frame of parameters + */ + uint32_t max_mem_size; + /* Memory space targeted by this section + * (Register MMIO Interface/DMEM/VMEM/GMEM etc) + */ + uint8_t mem_type_id; + /* Region id within the specified memory space */ + uint8_t region_id; + /* size in bytes of each compute unit for + * the specified memory space and region + */ + uint8_t elem_size; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_FRAME_GRID_PARAM_MAN_SEC_STRUCT]; +}; + +typedef struct ia_css_frame_grid_param_manifest_section_desc_s + ia_css_frame_grid_param_manifest_section_desc_t; + +#define SIZE_OF_FRAME_GRID_MAN_STRUCT_IN_BITS \ + ((IA_CSS_N_DATA_DIMENSION*IA_CSS_UINT16_T_BITS) \ + + (IA_CSS_N_DATA_DIMENSION*IA_CSS_UINT16_T_BITS)) + +struct ia_css_frame_grid_manifest_desc_s { + /* Min resolution width/height of the spatial parameters for + * the frame measured in compute units + */ + uint16_t min_frame_grid_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Max resolution width/height of the spatial parameters for + * the frame measured in compute units + */ + uint16_t max_frame_grid_dimension[IA_CSS_N_DATA_DIMENSION]; +}; + +typedef struct ia_css_frame_grid_manifest_desc_s + ia_css_frame_grid_manifest_desc_t; + +#define N_PADDING_UINT8_IN_SPATIAL_PARAM_TERM_MAN_STRUCT 2 +#define SIZE_OF_SPATIAL_PARAM_TERM_MAN_STRUCT_IN_BITS \ + ((SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS) \ + + (SIZE_OF_FRAME_GRID_MAN_STRUCT_IN_BITS) \ + + (SIZE_OF_FRAG_GRID_MAN_STRUCT_IN_BITS) \ + + (2 * IA_CSS_UINT16_T_BITS) \ + + (2 * IA_CSS_UINT8_T_BITS) \ + + (N_PADDING_UINT8_IN_SPATIAL_PARAM_TERM_MAN_STRUCT * \ + IA_CSS_UINT8_T_BITS)) + +struct ia_css_spatial_param_terminal_manifest_s { + /* Spatial Parameter terminal manifest base */ + ia_css_terminal_manifest_t base; + /* Contains limits for the frame spatial parameters */ + ia_css_frame_grid_manifest_desc_t frame_grid_desc; + /* + * Constains limits for the fragment spatial parameters + * - COMMON AMONG FRAGMENTS + */ + ia_css_fragment_grid_manifest_desc_t common_fragment_grid_desc; + /* + * Number of frame spatial parameter sections, they are set + * in slice-steps through frame processing + */ + uint16_t frame_grid_param_manifest_section_desc_count; + /* + * Points to the variable array of + * ia_css_frame_spatial_param_manifest_section_desc_t + */ + uint16_t frame_grid_param_manifest_section_desc_offset; + /* + * Indication of the kernel this spatial parameter terminal belongs to + * SHOULD MATCH TO INDEX AND BE USED ONLY FOR CHECK + */ + uint8_t kernel_id; + /* + * Groups together compute units in order to achieve alignment + * requirements for transfes and to achieve canonical frame + * representation + */ + uint8_t compute_units_p_elem; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_SPATIAL_PARAM_TERM_MAN_STRUCT]; +}; + +typedef struct ia_css_spatial_param_terminal_manifest_s + ia_css_spatial_param_terminal_manifest_t; + +/* ================= Spatial Param Terminal Manifest - END ================ */ + +/* ================= Sliced Param Terminal Manifest - START =============== */ + +#define N_PADDING_UINT8_IN_SLICED_TERMINAL_MAN_SECTION_STRUCT (2) +#define SIZE_OF_SLICED_PARAM_MAN_SEC_STRUCT_IN_BITS \ + (1 * IA_CSS_UINT32_T_BITS \ + + 2 * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_SLICED_TERMINAL_MAN_SECTION_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_sliced_param_manifest_section_desc_s { + /* Maximum size of the related parameter region */ + uint32_t max_mem_size; + /* + * Memory targeted by this section + * (Register MMIO Interface/DMEM/VMEM/GMEM etc) + */ + uint8_t mem_type_id; + /* Region id within the specified memory */ + uint8_t region_id; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_SLICED_TERMINAL_MAN_SECTION_STRUCT]; +}; + +typedef struct ia_css_sliced_param_manifest_section_desc_s + ia_css_sliced_param_manifest_section_desc_t; + +#define N_PADDING_UINT8_IN_SLICED_TERMINAL_MANIFEST_STRUCT 3 +#define SIZE_OF_SLICED_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + (SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + + 2 * IA_CSS_UINT16_T_BITS \ + + 1 * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_SLICED_TERMINAL_MANIFEST_STRUCT * IA_CSS_UINT8_T_BITS) + +/* Frame constant parameters terminal manifest */ +struct ia_css_sliced_param_terminal_manifest_s { + /* Spatial Parameter terminal base */ + ia_css_terminal_manifest_t base; + /* + * Number of the array elements + * sliced_param_section_offset points to + */ + uint16_t sliced_param_section_count; + /* + * Points to array of ia_css_sliced_param_manifest_section_desc_s + * which constain info for the slicing of the parameters + */ + uint16_t sliced_param_section_offset; + /* Kernel identifier */ + uint8_t kernel_id; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_SLICED_TERMINAL_MANIFEST_STRUCT]; +}; + +typedef struct ia_css_sliced_param_terminal_manifest_s + ia_css_sliced_param_terminal_manifest_t; + +/* ================= Slice Param Terminal Manifest - End =============== */ + +/* ================= Program Terminal Manifest - START ================= */ + +#define N_PADDING_UINT8_IN_FRAG_PARAM_MAN_SEC_STRUCT 1 +#define SIZE_OF_FRAG_PARAM_MAN_SEC_STRUCT_IN_BITS \ + (1 * IA_CSS_UINT32_T_BITS \ + + 3 * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_FRAG_PARAM_MAN_SEC_STRUCT * IA_CSS_UINT8_T_BITS) + +/* Fragment constant parameters manifest */ +struct ia_css_fragment_param_manifest_section_desc_s { + /* Maximum size of the related parameter region */ + uint32_t max_mem_size; + /* Indication of the kernel this parameter belongs to */ + uint8_t kernel_id; + /* Memory targeted by this section + * (Register MMIO Interface/DMEM/VMEM/GMEM etc) + */ + uint8_t mem_type_id; + /* Region id within the specified memory space */ + uint8_t region_id; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_FRAG_PARAM_MAN_SEC_STRUCT]; +}; + +typedef struct ia_css_fragment_param_manifest_section_desc_s + ia_css_fragment_param_manifest_section_desc_t; + +#define SIZE_OF_KERNEL_FRAG_SEQ_INFO_MAN_STRUCT_IN_BITS \ + (10*IA_CSS_N_DATA_DIMENSION*IA_CSS_UINT16_T_BITS) + +struct ia_css_kernel_fragment_sequencer_info_manifest_desc_s { + /* Slice dimensions */ + uint16_t min_fragment_grid_slice_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Slice dimensions */ + uint16_t max_fragment_grid_slice_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Nof slices */ + uint16_t min_fragment_grid_slice_count[IA_CSS_N_DATA_DIMENSION]; + /* Nof slices */ + uint16_t max_fragment_grid_slice_count[IA_CSS_N_DATA_DIMENSION]; + /* Grid point decimation factor */ + uint16_t + min_fragment_grid_point_decimation_factor[IA_CSS_N_DATA_DIMENSION]; + /* Grid point decimation factor */ + uint16_t + max_fragment_grid_point_decimation_factor[IA_CSS_N_DATA_DIMENSION]; + /* Relative position of grid origin to pixel origin */ + int16_t + min_fragment_grid_overlay_pixel_topleft_index[IA_CSS_N_DATA_DIMENSION]; + /* Relative position of grid origin to pixel origin */ + int16_t + max_fragment_grid_overlay_pixel_topleft_index[IA_CSS_N_DATA_DIMENSION]; + /* Dimension of grid */ + int16_t + min_fragment_grid_overlay_pixel_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Dimension of grid */ + int16_t + max_fragment_grid_overlay_pixel_dimension[IA_CSS_N_DATA_DIMENSION]; +}; + +typedef struct ia_css_kernel_fragment_sequencer_info_manifest_desc_s + ia_css_kernel_fragment_sequencer_info_manifest_desc_t; + +#define N_PADDING_UINT8_IN_PROGRAM_TERM_MAN_STRUCT 2 +#define SIZE_OF_PROG_TERM_MAN_STRUCT_IN_BITS \ + ((SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS) \ + + (IA_CSS_UINT32_T_BITS) \ + + (5*IA_CSS_UINT16_T_BITS) \ + + (N_PADDING_UINT8_IN_PROGRAM_TERM_MAN_STRUCT * IA_CSS_UINT8_T_BITS)) + +struct ia_css_program_terminal_manifest_s { + ia_css_terminal_manifest_t base; + /* Connection manager passes seq info as single blob at the moment */ + uint32_t sequencer_info_kernel_id; + /* Maximum number of command secriptors supported + * by the program group + */ + uint16_t max_kernel_fragment_sequencer_command_desc; + uint16_t fragment_param_manifest_section_desc_count; + uint16_t fragment_param_manifest_section_desc_offset; + uint16_t kernel_fragment_sequencer_info_manifest_info_count; + uint16_t kernel_fragment_sequencer_info_manifest_info_offset; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PROGRAM_TERM_MAN_STRUCT]; +}; + +typedef struct ia_css_program_terminal_manifest_s + ia_css_program_terminal_manifest_t; + +/* ==================== Program Terminal Manifest - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_MANIFEST_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_types.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_types.h new file mode 100644 index 0000000000000..c5c89fb7ec917 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_types.h @@ -0,0 +1,351 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_TYPES_H +#define __IA_CSS_TERMINAL_TYPES_H + +#include "type_support.h" +#include "ia_css_base_types.h" +#include "ia_css_terminal_base_types.h" + + +typedef struct ia_css_program_control_init_load_section_desc_s + ia_css_program_control_init_load_section_desc_t; +typedef struct ia_css_program_control_init_connect_section_desc_s + ia_css_program_control_init_connect_section_desc_t; +typedef struct ia_css_program_control_init_program_desc_s + ia_css_program_control_init_program_desc_t; +typedef struct ia_css_program_control_init_terminal_s + ia_css_program_control_init_terminal_t; + +typedef struct ia_css_program_terminal_s ia_css_program_terminal_t; +typedef struct ia_css_fragment_param_section_desc_s + ia_css_fragment_param_section_desc_t; +typedef struct ia_css_kernel_fragment_sequencer_info_desc_s + ia_css_kernel_fragment_sequencer_info_desc_t; +typedef struct ia_css_kernel_fragment_sequencer_command_desc_s + ia_css_kernel_fragment_sequencer_command_desc_t; + +typedef struct ia_css_sliced_param_terminal_s ia_css_sliced_param_terminal_t; +typedef struct ia_css_fragment_slice_desc_s ia_css_fragment_slice_desc_t; +typedef struct ia_css_slice_param_section_desc_s + ia_css_slice_param_section_desc_t; + +typedef struct ia_css_spatial_param_terminal_s ia_css_spatial_param_terminal_t; +typedef struct ia_css_frame_grid_desc_s ia_css_frame_grid_desc_t; +typedef struct ia_css_frame_grid_param_section_desc_s + ia_css_frame_grid_param_section_desc_t; +typedef struct ia_css_fragment_grid_desc_s ia_css_fragment_grid_desc_t; + +typedef struct ia_css_param_terminal_s ia_css_param_terminal_t; +typedef struct ia_css_param_section_desc_s ia_css_param_section_desc_t; + +typedef struct ia_css_param_payload_s ia_css_param_payload_t; +typedef struct ia_css_terminal_s ia_css_terminal_t; + +/* =================== Generic Parameter Payload - START =================== */ +#define N_UINT64_IN_PARAM_PAYLOAD_STRUCT 1 +#define N_UINT32_IN_PARAM_PAYLOAD_STRUCT 1 + +#define IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + (N_UINT64_IN_PARAM_PAYLOAD_STRUCT * IA_CSS_UINT64_T_BITS \ + + VIED_VADDRESS_BITS \ + + N_UINT32_IN_PARAM_PAYLOAD_STRUCT * IA_CSS_UINT32_T_BITS) + +struct ia_css_param_payload_s { + /* + * Temporary variable holding the host address of the parameter buffer + * as PSYS is handling the parameters on the host side for the moment + */ + uint64_t host_buffer; + /* + * Base virtual addresses to parameters in subsystem virtual + * memory space + * NOTE: Used in legacy pg flow + */ + vied_vaddress_t buffer; + /* + * Offset to buffer address within external buffer set structure + * NOTE: Used in ppg flow + */ + uint32_t terminal_index; +}; +/* =================== Generic Parameter Payload - End ==================== */ + + +/* ==================== Cached Param Terminal - START ==================== */ +#define N_UINT32_IN_PARAM_SEC_STRUCT 2 + +#define SIZE_OF_PARAM_SEC_STRUCT_BITS \ + (N_UINT32_IN_PARAM_SEC_STRUCT * IA_CSS_UINT32_T_BITS) + +/* Frame constant parameters section */ +struct ia_css_param_section_desc_s { + /* Offset of the parameter allocation in memory */ + uint32_t mem_offset; + /* Memory allocation size needs of this parameter */ + uint32_t mem_size; +}; + +#define N_UINT16_IN_PARAM_TERMINAL_STRUCT 1 +#define N_PADDING_UINT8_IN_PARAM_TERMINAL_STRUCT 6 + +#define SIZE_OF_PARAM_TERMINAL_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + + N_UINT16_IN_PARAM_TERMINAL_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_IN_PARAM_TERMINAL_STRUCT * IA_CSS_UINT8_T_BITS) + +/* Frame constant parameters terminal */ +struct ia_css_param_terminal_s { + /* Parameter terminal base */ + ia_css_terminal_t base; + /* Parameter buffer handle attached to the terminal */ + ia_css_param_payload_t param_payload; + /* Points to the variable array of ia_css_param_section_desc_t */ + uint16_t param_section_desc_offset; + uint8_t padding[N_PADDING_UINT8_IN_PARAM_TERMINAL_STRUCT]; +}; +/* ==================== Cached Param Terminal - End ==================== */ + + +/* ==================== Spatial Param Terminal - START ==================== */ +#define N_UINT16_IN_FRAG_GRID_STRUCT (2 * IA_CSS_N_DATA_DIMENSION) + +#define SIZE_OF_FRAG_GRID_STRUCT_BITS \ + (N_UINT16_IN_FRAG_GRID_STRUCT * IA_CSS_UINT16_T_BITS) + +struct ia_css_fragment_grid_desc_s { + /* + * Offset width/height of the top-left compute unit of the + * fragment compared to the frame + */ + uint16_t fragment_grid_index[IA_CSS_N_DATA_DIMENSION]; + /* + * Resolution width/height of the spatial parameters that + * correspond to the fragment measured in compute units + */ + uint16_t fragment_grid_dimension[IA_CSS_N_DATA_DIMENSION]; +}; + +#define N_UINT32_IN_FRAME_GRID_PARAM_SEC_STRUCT 3 +#define N_PADDING_UINT8_IN_FRAME_GRID_PARAM_SEC_STRUCT 4 + +#define SIZE_OF_FRAME_GRID_PARAM_SEC_STRUCT_BITS \ + (N_UINT32_IN_FRAME_GRID_PARAM_SEC_STRUCT * IA_CSS_UINT32_T_BITS \ + + N_PADDING_UINT8_IN_FRAME_GRID_PARAM_SEC_STRUCT * IA_CSS_UINT8_T_BITS) + +/* + * A plane of parameters with spatial aspect + * (compute units correlated to pixel data) + */ +struct ia_css_frame_grid_param_section_desc_s { + /* Offset of the parameter allocation in memory */ + uint32_t mem_offset; + /* Memory allocation size needs of this parameter */ + uint32_t mem_size; + /* + * stride in bytes of each line of compute units for + * the specified memory space and region + */ + uint32_t stride; + uint8_t padding[N_PADDING_UINT8_IN_FRAME_GRID_PARAM_SEC_STRUCT]; +}; + +#define N_UINT16_IN_FRAME_GRID_STRUCT_STRUCT IA_CSS_N_DATA_DIMENSION +#define N_PADDING_UINT8_IN_FRAME_GRID_STRUCT 4 + +#define SIZE_OF_FRAME_GRID_STRUCT_BITS \ + (N_UINT16_IN_FRAME_GRID_STRUCT_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_IN_FRAME_GRID_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_frame_grid_desc_s { + /* Resolution width/height of the frame of + * spatial parameters measured in compute units + */ + uint16_t frame_grid_dimension[IA_CSS_N_DATA_DIMENSION]; + uint8_t padding[N_PADDING_UINT8_IN_FRAME_GRID_STRUCT]; +}; + +#define N_UINT32_IN_SPATIAL_PARAM_TERM_STRUCT 1 +#define N_UINT16_IN_SPATIAL_PARAM_TERM_STRUCT 2 + +#define SIZE_OF_SPATIAL_PARAM_TERM_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + + SIZE_OF_FRAME_GRID_STRUCT_BITS \ + + N_UINT32_IN_SPATIAL_PARAM_TERM_STRUCT * IA_CSS_UINT32_T_BITS \ + + N_UINT16_IN_SPATIAL_PARAM_TERM_STRUCT * IA_CSS_UINT16_T_BITS) + +struct ia_css_spatial_param_terminal_s { + /* Spatial Parameter terminal base */ + ia_css_terminal_t base; + /* Spatial Parameter buffer handle attached to the terminal */ + ia_css_param_payload_t param_payload; + /* Contains info for the frame of spatial parameters */ + ia_css_frame_grid_desc_t frame_grid_desc; + /* Kernel identifier */ + uint32_t kernel_id; + /* + * Points to the variable array of + * ia_css_frame_grid_param_section_desc_t + */ + uint16_t frame_grid_param_section_desc_offset; + /* + * Points to array of ia_css_fragment_spatial_desc_t + * which constain info for the fragments of spatial parameters + */ + uint16_t fragment_grid_desc_offset; +}; +/* ==================== Spatial Param Terminal - END ==================== */ + + +/* ==================== Sliced Param Terminal - START ==================== */ +#define N_UINT32_IN_SLICE_PARAM_SECTION_DESC_STRUCT 2 + +#define SIZE_OF_SLICE_PARAM_SECTION_DESC_STRUCT_BITS \ + (N_UINT32_IN_SLICE_PARAM_SECTION_DESC_STRUCT * IA_CSS_UINT32_T_BITS) + +/* A Slice of parameters ready to be trasferred from/to registers */ +struct ia_css_slice_param_section_desc_s { + /* Offset of the parameter allocation in memory */ + uint32_t mem_offset; + /* Memory allocation size needs of this parameter */ + uint32_t mem_size; +}; + +#define N_UINT16_IN_FRAGMENT_SLICE_DESC_STRUCT 2 +#define N_PADDING_UINT8_FRAGMENT_SLICE_DESC_STRUCT 4 + +#define SIZE_OF_FRAGMENT_SLICE_DESC_STRUCT_BITS \ + (N_UINT16_IN_FRAGMENT_SLICE_DESC_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_FRAGMENT_SLICE_DESC_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_fragment_slice_desc_s { + /* + * Points to array of ia_css_slice_param_section_desc_t + * which constain info for each prameter slice + */ + uint16_t slice_section_desc_offset; + /* Number of slices for the parameters for this fragment */ + uint16_t slice_count; + uint8_t padding[N_PADDING_UINT8_FRAGMENT_SLICE_DESC_STRUCT]; +}; + +#define N_UINT32_IN_SLICED_PARAM_TERMINAL_STRUCT 1 +#define N_UINT16_IN_SLICED_PARAM_TERMINAL_STRUCT 1 +#define N_PADDING_UINT8_SLICED_PARAM_TERMINAL_STRUCT 2 + +#define SIZE_OF_SLICED_PARAM_TERM_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + + N_UINT32_IN_SLICED_PARAM_TERMINAL_STRUCT * IA_CSS_UINT32_T_BITS \ + + N_UINT16_IN_SLICED_PARAM_TERMINAL_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_SLICED_PARAM_TERMINAL_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_sliced_param_terminal_s { + /* Spatial Parameter terminal base */ + ia_css_terminal_t base; + /* Spatial Parameter buffer handle attached to the terminal */ + ia_css_param_payload_t param_payload; + /* Kernel identifier */ + uint32_t kernel_id; + /* + * Points to array of ia_css_fragment_slice_desc_t + * which constain info for the slicing of the parameters + */ + uint16_t fragment_slice_desc_offset; + uint8_t padding[N_PADDING_UINT8_SLICED_PARAM_TERMINAL_STRUCT]; +}; +/* ==================== Sliced Param Terminal - END ==================== */ + + +/* ==================== Program Terminal - START ==================== */ + +#define N_UINT32_IN_FRAG_PARAM_SEC_STRUCT 2 + +#define SIZE_OF_FRAG_PARAM_SEC_STRUCT_BITS \ + (N_UINT32_IN_FRAG_PARAM_SEC_STRUCT * IA_CSS_UINT32_T_BITS) + +/* Fragment constant parameters section */ +struct ia_css_fragment_param_section_desc_s { + /* Offset of the parameter allocation in memory */ + uint32_t mem_offset; + /* Memory allocation size needs of this parameter */ + uint32_t mem_size; +}; + +#define N_UINT16_IN_FRAG_SEQ_COMMAND_STRUCT IA_CSS_N_COMMAND_COUNT + +#define SIZE_OF_FRAG_SEQ_COMMANDS_STRUCT_BITS \ + (N_UINT16_IN_FRAG_SEQ_COMMAND_STRUCT * IA_CSS_UINT16_T_BITS) + +/* 4 commands packe together to save memory space */ +struct ia_css_kernel_fragment_sequencer_command_desc_s { + /* Contains the "(command_index%4) == index" command desc */ + uint16_t line_count[IA_CSS_N_COMMAND_COUNT]; +}; + +#define N_UINT16_IN_FRAG_SEQ_INFO_STRUCT (5 * IA_CSS_N_DATA_DIMENSION + 2) + +#define SIZE_OF_FRAG_SEQ_INFO_STRUCT_BITS \ + (N_UINT16_IN_FRAG_SEQ_INFO_STRUCT * IA_CSS_UINT16_T_BITS) + +struct ia_css_kernel_fragment_sequencer_info_desc_s { + /* Slice dimensions */ + uint16_t fragment_grid_slice_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Nof slices */ + uint16_t fragment_grid_slice_count[IA_CSS_N_DATA_DIMENSION]; + /* Grid point decimation factor */ + uint16_t + fragment_grid_point_decimation_factor[IA_CSS_N_DATA_DIMENSION]; + /* Relative position of grid origin to pixel origin */ + int16_t + fragment_grid_overlay_pixel_topleft_index[IA_CSS_N_DATA_DIMENSION]; + /* Size of active fragment region */ + int16_t + fragment_grid_overlay_pixel_dimension[IA_CSS_N_DATA_DIMENSION]; + /* If >0 it overrides the standard fragment sequencer info */ + uint16_t command_count; + /* + * To be used only if command_count>0, points to the descriptors + * for the commands (ia_css_kernel_fragment_sequencer_command_desc_s) + */ + uint16_t command_desc_offset; +}; + +#define N_UINT16_IN_PROG_TERM_STRUCT 2 +#define N_PADDING_UINT8_IN_PROG_TERM_STRUCT 4 + +#define SIZE_OF_PROG_TERM_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + + N_UINT16_IN_PROG_TERM_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_IN_PROG_TERM_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_program_terminal_s { + /* Program terminal base */ + ia_css_terminal_t base; + /* Program terminal buffer handle attached to the terminal */ + ia_css_param_payload_t param_payload; + /* Points to array of ia_css_fragment_param_desc_s */ + uint16_t fragment_param_section_desc_offset; + /* Points to array of ia_css_kernel_fragment_sequencer_info_s */ + uint16_t kernel_fragment_sequencer_info_desc_offset; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PROG_TERM_STRUCT]; +}; +/* ==================== Program Terminal - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal.c new file mode 100644 index 0000000000000..683fb3a88cd87 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal.c @@ -0,0 +1,20 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifdef __INLINE_PARAMETERS__ +#include "storage_class.h" +STORAGE_CLASS_INLINE int __ia_css_param_avoid_warning_on_empty_file(void) { return 0; } +#else /* __INLINE_PARAMETERS__ */ +#include "ia_css_terminal_impl.h" +#endif /* __INLINE_PARAMETERS__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_impl.h new file mode 100644 index 0000000000000..9ccf3931e8e3d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_impl.h @@ -0,0 +1,495 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_IMPL_H +#define __IA_CSS_TERMINAL_IMPL_H + +#include "ia_css_terminal.h" +#include "ia_css_terminal_types.h" +#include "error_support.h" +#include "assert_support.h" +#include "storage_class.h" + +/* Param Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_param_in_terminal_get_descriptor_size( + const unsigned int nof_sections) +{ + return sizeof(ia_css_param_terminal_t) + + nof_sections*sizeof(ia_css_param_section_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_param_section_desc_t *ia_css_param_in_terminal_get_param_section_desc( + const ia_css_param_terminal_t *param_terminal, + const unsigned int section_index) +{ + ia_css_param_section_desc_t *param_section_base; + ia_css_param_section_desc_t *param_section_desc = NULL; + + verifjmpexit(param_terminal != NULL); + + param_section_base = + (ia_css_param_section_desc_t *) + (((const char *)param_terminal) + + param_terminal->param_section_desc_offset); + param_section_desc = &(param_section_base[section_index]); + +EXIT: + return param_section_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_param_out_terminal_get_descriptor_size( + const unsigned int nof_sections, + const unsigned int nof_fragments) +{ + return sizeof(ia_css_param_terminal_t) + + nof_fragments*nof_sections*sizeof(ia_css_param_section_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_param_section_desc_t *ia_css_param_out_terminal_get_param_section_desc( + const ia_css_param_terminal_t *param_terminal, + const unsigned int section_index, + const unsigned int nof_sections, + const unsigned int fragment_index) +{ + ia_css_param_section_desc_t *param_section_base; + ia_css_param_section_desc_t *param_section_desc = NULL; + + verifjmpexit(param_terminal != NULL); + + param_section_base = + (ia_css_param_section_desc_t *) + (((const char *)param_terminal) + + param_terminal->param_section_desc_offset); + param_section_desc = + &(param_section_base[(nof_sections * fragment_index) + + section_index]); + +EXIT: + return param_section_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_param_terminal_create( + ia_css_param_terminal_t *param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal) +{ + if (param_terminal == NULL) { + return -EFAULT; + } + + if (terminal_offset > (1<<15)) { + return -EINVAL; + } + + param_terminal->base.terminal_type = + is_input_terminal ? + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN : + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT; + param_terminal->base.parent_offset = + 0 - ((int16_t)terminal_offset); + param_terminal->base.size = terminal_size; + param_terminal->param_section_desc_offset = + sizeof(ia_css_param_terminal_t); + + return 0; +} + +/* Spatial Param Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_spatial_param_terminal_get_descriptor_size( + const unsigned int nof_frame_param_sections, + const unsigned int nof_fragments) +{ + return sizeof(ia_css_spatial_param_terminal_t) + + nof_frame_param_sections * sizeof( + ia_css_frame_grid_param_section_desc_t) + + nof_fragments * sizeof(ia_css_fragment_grid_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_fragment_grid_desc_t * +ia_css_spatial_param_terminal_get_fragment_grid_desc( + const ia_css_spatial_param_terminal_t *spatial_param_terminal, + const unsigned int fragment_index) +{ + ia_css_fragment_grid_desc_t *fragment_grid_desc_base; + ia_css_fragment_grid_desc_t *fragment_grid_desc = NULL; + + verifjmpexit(spatial_param_terminal != NULL); + + fragment_grid_desc_base = + (ia_css_fragment_grid_desc_t *) + (((const char *)spatial_param_terminal) + + spatial_param_terminal->fragment_grid_desc_offset); + fragment_grid_desc = &(fragment_grid_desc_base[fragment_index]); + +EXIT: + return fragment_grid_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_frame_grid_param_section_desc_t * +ia_css_spatial_param_terminal_get_frame_grid_param_section_desc( + const ia_css_spatial_param_terminal_t *spatial_param_terminal, + const unsigned int section_index) +{ + ia_css_frame_grid_param_section_desc_t * + frame_grid_param_section_base; + ia_css_frame_grid_param_section_desc_t * + frame_grid_param_section_desc = NULL; + + verifjmpexit(spatial_param_terminal != NULL); + + frame_grid_param_section_base = + (ia_css_frame_grid_param_section_desc_t *) + (((const char *)spatial_param_terminal) + + spatial_param_terminal->frame_grid_param_section_desc_offset); + frame_grid_param_section_desc = + &(frame_grid_param_section_base[section_index]); + +EXIT: + return frame_grid_param_section_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_spatial_param_terminal_create( + ia_css_spatial_param_terminal_t *spatial_param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal, + const unsigned int nof_fragments, + const uint32_t kernel_id) +{ + if (spatial_param_terminal == NULL) { + return -EFAULT; + } + + if (terminal_offset > (1<<15)) { + return -EINVAL; + } + + spatial_param_terminal->base.terminal_type = + is_input_terminal ? + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN : + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT; + spatial_param_terminal->base.parent_offset = + 0 - ((int16_t)terminal_offset); + spatial_param_terminal->base.size = terminal_size; + spatial_param_terminal->kernel_id = kernel_id; + spatial_param_terminal->fragment_grid_desc_offset = + sizeof(ia_css_spatial_param_terminal_t); + spatial_param_terminal->frame_grid_param_section_desc_offset = + spatial_param_terminal->fragment_grid_desc_offset + + (nof_fragments * sizeof(ia_css_fragment_grid_desc_t)); + + return 0; +} + +/* Sliced terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_sliced_param_terminal_get_descriptor_size( + const unsigned int nof_slice_param_sections, + const unsigned int nof_slices[], + const unsigned int nof_fragments) +{ + unsigned int descriptor_size = 0; + unsigned int fragment_index; + unsigned int nof_slices_total = 0; + + verifjmpexit(nof_slices != NULL); + + for (fragment_index = 0; + fragment_index < nof_fragments; fragment_index++) { + nof_slices_total += nof_slices[fragment_index]; + } + + descriptor_size = + sizeof(ia_css_sliced_param_terminal_t) + + nof_fragments*sizeof(ia_css_fragment_slice_desc_t) + + nof_slices_total*nof_slice_param_sections*sizeof( + ia_css_fragment_param_section_desc_t); + +EXIT: + return descriptor_size; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_fragment_slice_desc_t * +ia_css_sliced_param_terminal_get_fragment_slice_desc( + const ia_css_sliced_param_terminal_t *sliced_param_terminal, + const unsigned int fragment_index +) +{ + ia_css_fragment_slice_desc_t *fragment_slice_desc_base; + ia_css_fragment_slice_desc_t *fragment_slice_desc = NULL; + + verifjmpexit(sliced_param_terminal != NULL); + + fragment_slice_desc_base = + (ia_css_fragment_slice_desc_t *) + (((const char *)sliced_param_terminal) + + sliced_param_terminal->fragment_slice_desc_offset); + fragment_slice_desc = &(fragment_slice_desc_base[fragment_index]); + +EXIT: + return fragment_slice_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_slice_param_section_desc_t * +ia_css_sliced_param_terminal_get_slice_param_section_desc( + const ia_css_sliced_param_terminal_t *sliced_param_terminal, + const unsigned int fragment_index, + const unsigned int slice_index, + const unsigned int section_index, + const unsigned int nof_slice_param_sections) +{ + ia_css_fragment_slice_desc_t *fragment_slice_desc; + ia_css_slice_param_section_desc_t *slice_param_section_desc_base; + ia_css_slice_param_section_desc_t *slice_param_section_desc = NULL; + + fragment_slice_desc = + ia_css_sliced_param_terminal_get_fragment_slice_desc( + sliced_param_terminal, + fragment_index + ); + verifjmpexit(fragment_slice_desc != NULL); + + slice_param_section_desc_base = + (ia_css_slice_param_section_desc_t *) + (((const char *)sliced_param_terminal) + + fragment_slice_desc->slice_section_desc_offset); + slice_param_section_desc = + &(slice_param_section_desc_base[( + slice_index * nof_slice_param_sections) + + section_index]); + +EXIT: + return slice_param_section_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_sliced_param_terminal_create( + ia_css_sliced_param_terminal_t *sliced_param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal, + const unsigned int nof_slice_param_sections, + const unsigned int nof_slices[], + const unsigned int nof_fragments, + const uint32_t kernel_id) +{ + unsigned int fragment_index; + unsigned int nof_slices_total = 0; + + if (sliced_param_terminal == NULL) { + return -EFAULT; + } + + if (terminal_offset > (1<<15)) { + return -EINVAL; + } + + sliced_param_terminal->base.terminal_type = + is_input_terminal ? + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN : + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT; + sliced_param_terminal->base.parent_offset = + 0 - ((int16_t)terminal_offset); + sliced_param_terminal->base.size = terminal_size; + sliced_param_terminal->kernel_id = kernel_id; + /* set here to use below to find the pointer */ + sliced_param_terminal->fragment_slice_desc_offset = + sizeof(ia_css_sliced_param_terminal_t); + for (fragment_index = 0; + fragment_index < nof_fragments; fragment_index++) { + ia_css_fragment_slice_desc_t *fragment_slice_desc = + ia_css_sliced_param_terminal_get_fragment_slice_desc( + sliced_param_terminal, + fragment_index); + /* + * Error handling not required at this point + * since everything has been constructed/validated just above + */ + fragment_slice_desc->slice_count = nof_slices[fragment_index]; + fragment_slice_desc->slice_section_desc_offset = + sliced_param_terminal->fragment_slice_desc_offset + + (nof_fragments * sizeof( + ia_css_fragment_slice_desc_t)) + + (nof_slices_total * nof_slice_param_sections * sizeof( + ia_css_slice_param_section_desc_t)); + nof_slices_total += nof_slices[fragment_index]; + } + + return 0; +} + +/* Program terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_program_terminal_get_descriptor_size( + const unsigned int nof_fragments, + const unsigned int nof_fragment_param_sections, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int nof_command_objs) +{ + return sizeof(ia_css_program_terminal_t) + + nof_fragments * nof_fragment_param_sections * + sizeof(ia_css_fragment_param_section_desc_t) + + nof_fragments * nof_kernel_fragment_sequencer_infos * + sizeof(ia_css_kernel_fragment_sequencer_info_desc_t) + + nof_command_objs * sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_fragment_param_section_desc_t * +ia_css_program_terminal_get_frgmnt_prm_sct_desc( + const ia_css_program_terminal_t *program_terminal, + const unsigned int fragment_index, + const unsigned int section_index, + const unsigned int nof_fragment_param_sections) +{ + ia_css_fragment_param_section_desc_t * + fragment_param_section_desc_base; + ia_css_fragment_param_section_desc_t * + fragment_param_section_desc = NULL; + + verifjmpexit(program_terminal != NULL); + verifjmpexit(section_index < nof_fragment_param_sections); + + fragment_param_section_desc_base = + (ia_css_fragment_param_section_desc_t *) + (((const char *)program_terminal) + + program_terminal->fragment_param_section_desc_offset); + fragment_param_section_desc = + &(fragment_param_section_desc_base[(fragment_index * + nof_fragment_param_sections) + section_index]); + +EXIT: + return fragment_param_section_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_kernel_fragment_sequencer_info_desc_t * +ia_css_program_terminal_get_kernel_frgmnt_seq_info_desc( + const ia_css_program_terminal_t *program_terminal, + const unsigned int fragment_index, + const unsigned int info_index, + const unsigned int nof_kernel_fragment_sequencer_infos) +{ + ia_css_kernel_fragment_sequencer_info_desc_t * + kernel_fragment_sequencer_info_desc_base; + ia_css_kernel_fragment_sequencer_info_desc_t * + kernel_fragment_sequencer_info_desc = NULL; + + verifjmpexit(program_terminal != NULL); + if (nof_kernel_fragment_sequencer_infos > 0) { + verifjmpexit(info_index < nof_kernel_fragment_sequencer_infos); + } + + kernel_fragment_sequencer_info_desc_base = + (ia_css_kernel_fragment_sequencer_info_desc_t *) + (((const char *)program_terminal) + + program_terminal->kernel_fragment_sequencer_info_desc_offset); + kernel_fragment_sequencer_info_desc = + &(kernel_fragment_sequencer_info_desc_base[(fragment_index * + nof_kernel_fragment_sequencer_infos) + info_index]); + +EXIT: + return kernel_fragment_sequencer_info_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_program_terminal_create( + ia_css_program_terminal_t *program_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const unsigned int nof_fragments, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int nof_command_objs) +{ + if (program_terminal == NULL) { + return -EFAULT; + } + + if (terminal_offset > (1<<15)) { + return -EINVAL; + } + + program_terminal->base.terminal_type = IA_CSS_TERMINAL_TYPE_PROGRAM; + program_terminal->base.parent_offset = 0-((int16_t)terminal_offset); + program_terminal->base.size = terminal_size; + program_terminal->kernel_fragment_sequencer_info_desc_offset = + sizeof(ia_css_program_terminal_t); + program_terminal->fragment_param_section_desc_offset = + program_terminal->kernel_fragment_sequencer_info_desc_offset + + (nof_fragments * nof_kernel_fragment_sequencer_infos * + sizeof(ia_css_kernel_fragment_sequencer_info_desc_t)) + + (nof_command_objs * sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t)); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_program_terminal_get_command_base_offset( + const ia_css_program_terminal_t *program_terminal, + const unsigned int nof_fragments, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int commands_slots_used, + uint16_t *command_desc_offset) +{ + if (command_desc_offset == NULL) { + return -EFAULT; + } + + *command_desc_offset = 0; + + if (program_terminal == NULL) { + return -EFAULT; + } + + *command_desc_offset = + program_terminal->kernel_fragment_sequencer_info_desc_offset + + (nof_fragments * nof_kernel_fragment_sequencer_infos * + sizeof(ia_css_kernel_fragment_sequencer_info_desc_t)) + + (commands_slots_used * sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t)); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +uint16_t *ia_css_program_terminal_get_line_count( + const ia_css_kernel_fragment_sequencer_command_desc_t + *kernel_fragment_sequencer_command_desc_base, + const unsigned int set_count) +{ + uint16_t *line_count = NULL; + + verifjmpexit(kernel_fragment_sequencer_command_desc_base != NULL); + line_count = + (uint16_t *)&(kernel_fragment_sequencer_command_desc_base[ + set_count >> 2].line_count[set_count & 0x00000003]); +EXIT: + return line_count; +} + +#endif /* __IA_CSS_TERMINAL_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest.c new file mode 100644 index 0000000000000..53c4708c7fc90 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest.c @@ -0,0 +1,20 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifdef __INLINE_PARAMETERS__ +#include "storage_class.h" +STORAGE_CLASS_INLINE int __ia_css_param_avoid_warning_on_empty_file(void) { return 0; } +#else /* __INLINE_PARAMETERS__ */ +#include "ia_css_terminal_manifest_impl.h" +#endif /* __INLINE_PARAMETERS__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest_impl.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest_impl.h new file mode 100644 index 0000000000000..288b5c9a1164c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest_impl.h @@ -0,0 +1,348 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_MANIFEST_IMPL_H +#define __IA_CSS_TERMINAL_MANIFEST_IMPL_H + +#include "ia_css_terminal_manifest.h" +#include "error_support.h" +#include "assert_support.h" +#include "storage_class.h" + +STORAGE_CLASS_INLINE void __terminal_manifest_dummy_check_alignment(void) +{ + COMPILATION_ERROR_IF( + SIZE_OF_PARAM_TERMINAL_MANIFEST_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_param_terminal_manifest_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_param_terminal_manifest_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PARAM_TERMINAL_MANIFEST_SEC_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_param_manifest_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_param_manifest_section_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_SPATIAL_PARAM_TERM_MAN_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_spatial_param_terminal_manifest_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_spatial_param_terminal_manifest_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAME_GRID_PARAM_MAN_SEC_STRUCT_IN_BITS != + (CHAR_BIT * sizeof( + ia_css_frame_grid_param_manifest_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_frame_grid_param_manifest_section_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_TERM_MAN_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_program_terminal_manifest_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_terminal_manifest_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAG_PARAM_MAN_SEC_STRUCT_IN_BITS != + (CHAR_BIT * sizeof( + ia_css_fragment_param_manifest_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_fragment_param_manifest_section_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_KERNEL_FRAG_SEQ_INFO_MAN_STRUCT_IN_BITS != + (CHAR_BIT * sizeof( + ia_css_kernel_fragment_sequencer_info_manifest_desc_t)) + ); + + COMPILATION_ERROR_IF(0 != sizeof( + ia_css_kernel_fragment_sequencer_info_manifest_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PARAM_TERMINAL_MANIFEST_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_sliced_param_terminal_manifest_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_sliced_param_terminal_manifest_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_SLICED_PARAM_MAN_SEC_STRUCT_IN_BITS != + (CHAR_BIT * sizeof + (ia_css_sliced_param_manifest_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_sliced_param_manifest_section_desc_t) % + sizeof(uint64_t)); +} + +/* Parameter Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_param_terminal_manifest_get_size( + const unsigned int nof_sections) +{ + + return sizeof(ia_css_param_terminal_manifest_t) + + nof_sections*sizeof(ia_css_param_manifest_section_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_param_terminal_manifest_init( + ia_css_param_terminal_manifest_t *param_terminal, + const uint16_t section_count) +{ + if (param_terminal == NULL) { + return -EFAULT; + } + + param_terminal->param_manifest_section_desc_count = section_count; + param_terminal->param_manifest_section_desc_offset = sizeof( + ia_css_param_terminal_manifest_t); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_param_manifest_section_desc_t * +ia_css_param_terminal_manifest_get_prm_sct_desc( + const ia_css_param_terminal_manifest_t *param_terminal_manifest, + const unsigned int section_index) +{ + ia_css_param_manifest_section_desc_t *param_manifest_section_base; + + ia_css_param_manifest_section_desc_t * + param_manifest_section_desc = NULL; + + verifjmpexit(param_terminal_manifest != NULL); + + param_manifest_section_base = + (ia_css_param_manifest_section_desc_t *) + (((const char *)param_terminal_manifest) + + param_terminal_manifest->param_manifest_section_desc_offset); + + param_manifest_section_desc = + &(param_manifest_section_base[section_index]); + +EXIT: + return param_manifest_section_desc; +} + +/* Spatial Parameter Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_spatial_param_terminal_manifest_get_size( + const unsigned int nof_frame_param_sections) +{ + return sizeof(ia_css_spatial_param_terminal_manifest_t) + + nof_frame_param_sections * sizeof( + ia_css_frame_grid_param_manifest_section_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_spatial_param_terminal_manifest_init( + ia_css_spatial_param_terminal_manifest_t *spatial_param_terminal, + const uint16_t section_count) +{ + if (spatial_param_terminal == NULL) { + return -EFAULT; + } + + spatial_param_terminal-> + frame_grid_param_manifest_section_desc_count = section_count; + spatial_param_terminal-> + frame_grid_param_manifest_section_desc_offset = + sizeof(ia_css_spatial_param_terminal_manifest_t); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_frame_grid_param_manifest_section_desc_t * +ia_css_spatial_param_terminal_manifest_get_frm_grid_prm_sct_desc( + const ia_css_spatial_param_terminal_manifest_t * + spatial_param_terminal_manifest, + const unsigned int section_index) +{ + ia_css_frame_grid_param_manifest_section_desc_t * + frame_param_manifest_section_base; + ia_css_frame_grid_param_manifest_section_desc_t * + frame_param_manifest_section_desc = NULL; + + verifjmpexit(spatial_param_terminal_manifest != NULL); + + frame_param_manifest_section_base = + (ia_css_frame_grid_param_manifest_section_desc_t *) + (((const char *)spatial_param_terminal_manifest) + + spatial_param_terminal_manifest-> + frame_grid_param_manifest_section_desc_offset); + frame_param_manifest_section_desc = + &(frame_param_manifest_section_base[section_index]); + +EXIT: + return frame_param_manifest_section_desc; +} + +/* Sliced Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_sliced_param_terminal_manifest_get_size( + const unsigned int nof_slice_param_sections) +{ + return sizeof(ia_css_spatial_param_terminal_manifest_t) + + nof_slice_param_sections * + sizeof(ia_css_sliced_param_manifest_section_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_sliced_param_terminal_manifest_init( + ia_css_sliced_param_terminal_manifest_t *sliced_param_terminal, + const uint16_t section_count) +{ + if (sliced_param_terminal == NULL) { + return -EFAULT; + } + + sliced_param_terminal->sliced_param_section_count = section_count; + sliced_param_terminal->sliced_param_section_offset = + sizeof(ia_css_sliced_param_terminal_manifest_t); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_sliced_param_manifest_section_desc_t * +ia_css_sliced_param_terminal_manifest_get_sliced_prm_sct_desc( + const ia_css_sliced_param_terminal_manifest_t * + sliced_param_terminal_manifest, + const unsigned int section_index) +{ + ia_css_sliced_param_manifest_section_desc_t * + sliced_param_manifest_section_base; + ia_css_sliced_param_manifest_section_desc_t * + sliced_param_manifest_section_desc = NULL; + + verifjmpexit(sliced_param_terminal_manifest != NULL); + + sliced_param_manifest_section_base = + (ia_css_sliced_param_manifest_section_desc_t *) + (((const char *)sliced_param_terminal_manifest) + + sliced_param_terminal_manifest-> + sliced_param_section_offset); + sliced_param_manifest_section_desc = + &(sliced_param_manifest_section_base[section_index]); + +EXIT: + return sliced_param_manifest_section_desc; +} + +/* Program Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_program_terminal_manifest_get_size( + const unsigned int nof_fragment_param_sections, + const unsigned int nof_kernel_fragment_sequencer_infos) +{ + return sizeof(ia_css_program_terminal_manifest_t) + + nof_fragment_param_sections * + sizeof(ia_css_fragment_param_manifest_section_desc_t) + + nof_kernel_fragment_sequencer_infos * + sizeof(ia_css_kernel_fragment_sequencer_info_manifest_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_program_terminal_manifest_init( + ia_css_program_terminal_manifest_t *program_terminal, + const uint16_t fragment_param_section_count, + const uint16_t kernel_fragment_seq_info_section_count) +{ + if (program_terminal == NULL) { + return -EFAULT; + } + + program_terminal->fragment_param_manifest_section_desc_count = + fragment_param_section_count; + program_terminal->fragment_param_manifest_section_desc_offset = + sizeof(ia_css_program_terminal_manifest_t); + + program_terminal->kernel_fragment_sequencer_info_manifest_info_count = + kernel_fragment_seq_info_section_count; + program_terminal->kernel_fragment_sequencer_info_manifest_info_offset = + sizeof(ia_css_program_terminal_manifest_t) + + fragment_param_section_count*sizeof( + ia_css_fragment_param_manifest_section_desc_t); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_fragment_param_manifest_section_desc_t * +ia_css_program_terminal_manifest_get_frgmnt_prm_sct_desc( + const ia_css_program_terminal_manifest_t *program_terminal_manifest, + const unsigned int section_index) +{ + ia_css_fragment_param_manifest_section_desc_t * + fragment_param_manifest_section_base; + ia_css_fragment_param_manifest_section_desc_t * + fragment_param_manifest_section = NULL; + + verifjmpexit(program_terminal_manifest != NULL); + + fragment_param_manifest_section_base = + (ia_css_fragment_param_manifest_section_desc_t *) + (((const char *)program_terminal_manifest) + + program_terminal_manifest-> + fragment_param_manifest_section_desc_offset); + fragment_param_manifest_section = + &(fragment_param_manifest_section_base[section_index]); + +EXIT: + return fragment_param_manifest_section; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_kernel_fragment_sequencer_info_manifest_desc_t * +ia_css_program_terminal_manifest_get_kernel_frgmnt_seq_info_desc( + const ia_css_program_terminal_manifest_t *program_terminal_manifest, + const unsigned int info_index) +{ + ia_css_kernel_fragment_sequencer_info_manifest_desc_t * + kernel_manifest_fragment_sequencer_info_manifest_desc_base; + ia_css_kernel_fragment_sequencer_info_manifest_desc_t * + kernel_manifest_fragment_sequencer_info_manifest_desc = NULL; + + verifjmpexit(program_terminal_manifest != NULL); + + kernel_manifest_fragment_sequencer_info_manifest_desc_base = + (ia_css_kernel_fragment_sequencer_info_manifest_desc_t *) + (((const char *)program_terminal_manifest) + + program_terminal_manifest-> + kernel_fragment_sequencer_info_manifest_info_offset); + + kernel_manifest_fragment_sequencer_info_manifest_desc = + &(kernel_manifest_fragment_sequencer_info_manifest_desc_base[ + info_index]); + +EXIT: + return kernel_manifest_fragment_sequencer_info_manifest_desc; +} + +#endif /* __IA_CSS_TERMINAL_MANIFEST_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/vied_parameters.mk b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/vied_parameters.mk new file mode 100644 index 0000000000000..834a1a4b2bab6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/lib/vied_parameters/vied_parameters.mk @@ -0,0 +1,76 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is VIED_PARAMETERS + +VIED_PARAMETERS_DIR=$${MODULES_DIR}/vied_parameters + +VIED_PARAMETERS_INTERFACE=$(VIED_PARAMETERS_DIR)/interface +VIED_PARAMETERS_SOURCES=$(VIED_PARAMETERS_DIR)/src +VIED_PARAMETERS_EXTINCLUDE = $${MODULES_DIR}/support + +VIED_PARAMETERS_DYNAMIC_HOST_FILES += $(VIED_PARAMETERS_SOURCES)/ia_css_terminal.c +VIED_PARAMETERS_STATIC_HOST_FILES += $(VIED_PARAMETERS_SOURCES)/ia_css_terminal_manifest.c + +VIED_PARAMETERS_HOST_FILES = $(VIED_PARAMETERS_DYNAMIC_HOST_FILES) +VIED_PARAMETERS_HOST_FILES += $(VIED_PARAMETERS_STATIC_HOST_FILES) + +VIED_PARAMETERS_ISA_CLIENT_HOST_FILES = $(VIED_PARAMETERS_SOURCES)/ia_css_isys_process_group.c +VIED_PARAMETERS_ISA_CLIENT_HOST_FILES += $(VIED_PARAMETERS_DIR)/client/ia_css_isys_parameter_client.c + +VIED_PARAMETERS_DYNAMIC_FW_FILES += $(VIED_PARAMETERS_SOURCES)/ia_css_terminal.c +VIED_PARAMETERS_STATIC_FW_FILES += $(VIED_PARAMETERS_SOURCES)/ia_css_terminal_manifest.c + +VIED_PARAMETERS_FW_FILES = $(VIED_PARAMETERS_DYNAMIC_HOST_FILES) +VIED_PARAMETERS_FW_FILES += $(VIED_PARAMETERS_STATIC_HOST_FILES) +VIED_PARAMETERS_SUPPORT_CPPFLAGS = -I$(VIED_PARAMETERS_DIR)/support +VIED_PARAMETERS_SUPPORT_CPPFLAGS += -I$(VIED_PARAMETERS_DIR)/support/$(IPU_SYSVER) +VIED_PARAMETERS_ISA_CLIENT_HOST_CPPFLAGS = -I$(VIED_PARAMETERS_DIR)/client +VIED_PARAMETERS_PSA_UTILS_HOST_FILES = $(MODULES_DIR)/vied_parameters/support/ia_css_psys_parameter_utils.c +VIED_PARAMETERS_PSA_UTILS_HOST_FILES += $(MODULES_DIR)/vied_parameters/support/$(IPU_SYSVER)/ia_css_psys_parameter_utils_dep.c + +VIED_PARAMETERS_UTILS_HOST_CPPFLAGS = $(VIED_PARAMETERS_SUPPORT_CPPFLAGS) + +VIED_PARAMETERS_ISA_UTILS_HOST_FILES = $(MODULES_DIR)/vied_parameters/support/ia_css_isys_parameter_utils.c +VIED_PARAMETERS_ISA_UTILS_HOST_FILES += $(MODULES_DIR)/vied_parameters/support/$(IPU_SYSVER)/ia_css_isys_parameter_utils_dep.c + +VIED_PARAMETERS_PRINT_CPPFLAGS += -I$(VIED_PARAMETERS_DIR)/print/interface +VIED_PARAMETERS_PRINT_FILES += $(VIED_PARAMETERS_DIR)/print/src/ia_css_terminal_print.c + +# VIED_PARAMETERS Trace Log Level = VIED_PARAMETERS_TRACE_LOG_LEVEL_NORMAL +# Other options are [VIED_PARAMETERS_TRACE_LOG_LEVEL_OFF, VIED_PARAMETERS_TRACE_LOG_LEVEL_DEBUG] +ifndef VIED_PARAMETERS_TRACE_CONFIG_HOST + VIED_PARAMETERS_TRACE_CONFIG_HOST=VIED_PARAMETERS_TRACE_LOG_LEVEL_NORMAL +endif +ifndef VIED_PARAMETERS_TRACE_CONFIG_FW + VIED_PARAMETERS_TRACE_CONFIG_FW=VIED_PARAMETERS_TRACE_LOG_LEVEL_NORMAL +endif + +VIED_PARAMETERS_HOST_CPPFLAGS += -DVIED_PARAMETERS_TRACE_CONFIG=$(VIED_PARAMETERS_TRACE_CONFIG_HOST) +VIED_PARAMETERS_FW_CPPFLAGS += -DVIED_PARAMETERS_TRACE_CONFIG=$(VIED_PARAMETERS_TRACE_CONFIG_FW) + +VIED_PARAMETERS_HOST_CPPFLAGS += -I$(VIED_PARAMETERS_INTERFACE) +VIED_PARAMETERS_HOST_CPPFLAGS += -I$(VIED_PARAMETERS_SOURCES) +VIED_PARAMETERS_HOST_CPPFLAGS += -I$(VIED_PARAMETERS_EXTINCLUDE) +VIED_PARAMETERS_HOST_CPPFLAGS += $(VIED_PARAMETERS_SUPPORT_CPPFLAGS) +VIED_PARAMETERS_FW_CPPFLAGS += -I$(VIED_PARAMETERS_INTERFACE) +VIED_PARAMETERS_FW_CPPFLAGS += -I$(VIED_PARAMETERS_SOURCES) +VIED_PARAMETERS_FW_CPPFLAGS += -I$(VIED_PARAMETERS_EXTINCLUDE) +VIED_PARAMETERS_FW_CPPFLAGS += $(VIED_PARAMETERS_SUPPORT_CPPFLAGS) + +#For IPU interface +include $(MODULES_DIR)/fw_abi_common_types/cpu/fw_abi_cpu_types.mk +VIED_PARAMETERS_HOST_CPPFLAGS += $(FW_ABI_COMMON_TYPES_HOST_CPPFLAGS) + +VIED_PARAMETERS_FW_CPPFLAGS += $(FW_ABI_COMMON_TYPES_FW_CPPFLAGS) diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/libcsspsys2600.c b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/libcsspsys2600.c new file mode 100644 index 0000000000000..77b5414dc55cb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/libcsspsys2600.c @@ -0,0 +1,480 @@ +/* + * Copyright (c) 2015--2018 Intel Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include + +#include "ipu.h" +#include "ipu-mmu.h" +#include "ipu-psys.h" +#include "ipu-fw-psys.h" +#include "ipu-wrapper.h" +#include "libcsspsys2600.h" + +#include +#include +#include +#include +#include + +int ipu_fw_psys_pg_start(struct ipu_psys_kcmd *kcmd) +{ + return -ia_css_process_group_start((ia_css_process_group_t *) + kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_start); + +int ipu_fw_psys_pg_disown(struct ipu_psys_kcmd *kcmd) +{ + return -ia_css_process_group_disown((ia_css_process_group_t *) + kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_disown); + +int ipu_fw_psys_pg_abort(struct ipu_psys_kcmd *kcmd) +{ + int rval; + + rval = ia_css_process_group_stop((ia_css_process_group_t *) + kcmd->kpg->pg); + if (rval) { + dev_err(&kcmd->fh->psys->adev->dev, + "failed to abort kcmd!\n"); + kcmd->pg_user = NULL; + rval = -EIO; + /* TODO: need to reset PSYS by power cycling it */ + } + return rval; +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_abort); + +int ipu_fw_psys_pg_submit(struct ipu_psys_kcmd *kcmd) +{ + return -ia_css_process_group_submit((ia_css_process_group_t *) + kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_submit); + +static void *syscom_buffer; +static struct ia_css_syscom_config *syscom_config; +static struct ia_css_psys_server_init *server_init; + +int ipu_fw_psys_rcv_event(struct ipu_psys *psys, + struct ipu_fw_psys_event *event) +{ + return ia_css_psys_event_queue_receive(psys_syscom, + IA_CSS_PSYS_EVENT_QUEUE_MAIN_ID, + (struct ia_css_psys_event_s *)event); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_rcv_event); + +int ipu_fw_psys_terminal_set(struct ipu_fw_psys_terminal *terminal, + int terminal_idx, + struct ipu_psys_kcmd *kcmd, + u32 buffer, + unsigned int size) +{ + ia_css_terminal_type_t type; + u32 buffer_state; + + type = ia_css_terminal_get_type((ia_css_terminal_t *)terminal); + + switch (type) { + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT: + case IA_CSS_TERMINAL_TYPE_PROGRAM: + buffer_state = IA_CSS_BUFFER_UNDEFINED; + break; + case IA_CSS_TERMINAL_TYPE_PARAM_STREAM: + case IA_CSS_TERMINAL_TYPE_DATA_IN: + case IA_CSS_TERMINAL_TYPE_STATE_IN: + buffer_state = IA_CSS_BUFFER_FULL; + break; + case IA_CSS_TERMINAL_TYPE_DATA_OUT: + case IA_CSS_TERMINAL_TYPE_STATE_OUT: + buffer_state = IA_CSS_BUFFER_EMPTY; + break; + default: + dev_err(&kcmd->fh->psys->adev->dev, + "unknown terminal type: 0x%x\n", type); + return -EAGAIN; + } + + if (type == IA_CSS_TERMINAL_TYPE_DATA_IN || + type == IA_CSS_TERMINAL_TYPE_DATA_OUT) { + ia_css_frame_t *frame; + + if (ia_css_data_terminal_set_connection_type( + (ia_css_data_terminal_t *)terminal, + IA_CSS_CONNECTION_MEMORY)) + return -EIO; + frame = ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + if (!frame) + return -EIO; + + if (ia_css_frame_set_data_bytes(frame, size)) + return -EIO; + } + + return -ia_css_process_group_attach_buffer( + (ia_css_process_group_t *)kcmd->kpg->pg, buffer, + buffer_state, terminal_idx); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_terminal_set); + +void ipu_fw_psys_pg_dump(struct ipu_psys *psys, + struct ipu_psys_kcmd *kcmd, + const char *note) +{ + ia_css_process_group_t *pg = (ia_css_process_group_t *)kcmd->kpg->pg; + ia_css_program_group_ID_t pgid = + ia_css_process_group_get_program_group_ID(pg); + uint8_t processes = ia_css_process_group_get_process_count( + (ia_css_process_group_t *)kcmd->kpg->pg); + unsigned int p; + + dev_dbg(&psys->adev->dev, "%s %s pgid %i processes %i\n", + __func__, note, pgid, processes); + for (p = 0; p < processes; p++) { + ia_css_process_t *process = + ia_css_process_group_get_process(pg, p); + + dev_dbg(&psys->adev->dev, + "%s pgid %i process %i cell %i dev_chn: ext0 %i ext1r %i ext1w %i int %i ipfd %i isa %i\n", + __func__, pgid, p, + ia_css_process_get_cell(process), + ia_css_process_get_dev_chn(process, + VIED_NCI_DEV_CHN_DMA_EXT0_ID), + ia_css_process_get_dev_chn(process, + VIED_NCI_DEV_CHN_DMA_EXT1_READ_ID), + ia_css_process_get_dev_chn(process, + VIED_NCI_DEV_CHN_DMA_EXT1_WRITE_ID), + ia_css_process_get_dev_chn(process, + VIED_NCI_DEV_CHN_DMA_INTERNAL_ID), + ia_css_process_get_dev_chn(process, + VIED_NCI_DEV_CHN_DMA_IPFD_ID), + ia_css_process_get_dev_chn(process, + VIED_NCI_DEV_CHN_DMA_ISA_ID)); + } +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_dump); + +int ipu_fw_psys_pg_get_id(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_program_group_ID( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_id); + +int ipu_fw_psys_pg_get_terminal_count(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_terminal_count( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_terminal_count); + +int ipu_fw_psys_pg_get_size(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_size((ia_css_process_group_t *) + kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_size); + +int ipu_fw_psys_pg_set_ipu_vaddress(struct ipu_psys_kcmd *kcmd, + dma_addr_t vaddress) +{ + return ia_css_process_group_set_ipu_vaddress((ia_css_process_group_t *) + kcmd->kpg->pg, vaddress); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_set_ipu_vaddress); + +int ipu_fw_psys_pg_load_cycles(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_pg_load_cycles( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_load_cycles); + +int ipu_fw_psys_pg_init_cycles(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_pg_init_cycles( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_init_cycles); + +int ipu_fw_psys_pg_processing_cycles(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_pg_processing_cycles( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_processing_cycles); + +struct ipu_fw_psys_terminal * +ipu_fw_psys_pg_get_terminal(struct ipu_psys_kcmd *kcmd, int index) +{ + return (struct ipu_fw_psys_terminal *)ia_css_process_group_get_terminal( + (ia_css_process_group_t *)kcmd->kpg->pg, index); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_terminal); + +void ipu_fw_psys_pg_set_token(struct ipu_psys_kcmd *kcmd, u64 token) +{ + ia_css_process_group_set_token((ia_css_process_group_t *)kcmd->kpg->pg, + token); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_set_token); + +int ipu_fw_psys_pg_get_protocol( + struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_protocol_version( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_protocol); + +static int libcsspsys2600_init(void); +int ipu_fw_psys_open(struct ipu_psys *psys) +{ + bool opened; + int retry = IPU_PSYS_OPEN_RETRY; + + ipu_wrapper_init(PSYS_MMID, &psys->adev->dev, psys->pdata->base); + /* When fw psys open, make sure csslib init first */ + libcsspsys2600_init(); + + server_init->icache_prefetch_sp = psys->icache_prefetch_sp; + server_init->icache_prefetch_isp = psys->icache_prefetch_isp; + + psys_syscom = ia_css_psys_open(syscom_buffer, syscom_config); + if (!psys_syscom) { + dev_err(&psys->adev->dev, + "psys library open failed\n"); + return -ENODEV; + } + + do { + opened = ia_css_psys_open_is_ready(psys_syscom); + if (opened) + break; + usleep_range(IPU_PSYS_OPEN_TIMEOUT_US, + IPU_PSYS_OPEN_TIMEOUT_US + 10); + retry--; + } while (retry > 0); + + if (!retry && !opened) { + dev_err(&psys->adev->dev, + "psys library open ready failed\n"); + ia_css_psys_close(psys_syscom); + ia_css_psys_release(psys_syscom, 1); + psys_syscom = NULL; + return -ENODEV; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_open); + +int ipu_fw_psys_close(struct ipu_psys *psys) +{ + int rval; + unsigned int retry = IPU_PSYS_CLOSE_TIMEOUT; + + if (!psys_syscom) + return 0; + + if (ia_css_psys_close(psys_syscom)) { + dev_err(&psys->adev->dev, + "psys library close ready failed\n"); + return 0; + } + + do { + rval = ia_css_psys_release(psys_syscom, 0); + if (rval && rval != -EBUSY) { + dev_dbg(&psys->adev->dev, "psys library release failed\n"); + break; + } + usleep_range(IPU_PSYS_CLOSE_TIMEOUT_US, + IPU_PSYS_CLOSE_TIMEOUT_US + 10); + } while (rval && --retry); + + psys_syscom = NULL; + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_close); + +u64 ipu_fw_psys_pg_get_token(struct ipu_psys_kcmd *kcmd) +{ + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_token); + +static const struct ipu_fw_resource_definitions default_defs = { + .cells = vied_nci_cell_type, + .num_cells = VIED_NCI_N_CELL_ID, + .num_cells_type = VIED_NCI_N_CELL_TYPE_ID, + .dev_channels = vied_nci_dev_chn_size, + .num_dev_channels = VIED_NCI_N_DEV_CHN_ID, + + .num_ext_mem_types = VIED_NCI_N_DATA_MEM_TYPE_ID, + .num_ext_mem_ids = VIED_NCI_N_MEM_ID, + .ext_mem_ids = vied_nci_mem_size, + + .cell_mem_row = VIED_NCI_N_MEM_TYPE_ID, + .cell_mem = (enum ipu_mem_id *)vied_nci_cell_mem, +}; + +const struct ipu_fw_resource_definitions *res_defs = &default_defs; +EXPORT_SYMBOL_GPL(res_defs); + +int ipu_fw_psys_set_process_cell_id(struct ipu_fw_psys_process *ptr, u8 index, + u8 value) +{ + return ia_css_process_set_cell((ia_css_process_t *)ptr, + (vied_nci_cell_ID_t)value); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_set_process_cell_id); + +u8 ipu_fw_psys_get_process_cell_id(struct ipu_fw_psys_process *ptr, u8 index) +{ + return ia_css_process_get_cell((ia_css_process_t *)ptr); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_get_process_cell_id); + +int ipu_fw_psys_clear_process_cell(struct ipu_fw_psys_process *ptr) +{ + return ia_css_process_clear_cell((ia_css_process_t *)ptr); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_clear_process_cell); + +int ipu_fw_psys_set_process_dev_chn_offset(struct ipu_fw_psys_process *ptr, + u16 offset, u16 value) +{ + return ia_css_process_set_dev_chn((ia_css_process_t *)ptr, + (vied_nci_dev_chn_ID_t)offset, + (vied_nci_resource_size_t)value); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_set_process_dev_chn_offset); + +int ipu_fw_psys_set_process_ext_mem(struct ipu_fw_psys_process *ptr, + u16 type_id, u16 mem_id, u16 offset) +{ + return ia_css_process_set_ext_mem((ia_css_process_t *)ptr, mem_id, offset); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_set_process_ext_mem); + +int ipu_fw_psys_get_program_manifest_by_process( + struct ipu_fw_generic_program_manifest *gen_pm, + const struct ipu_fw_psys_program_group_manifest *pg_manifest, + struct ipu_fw_psys_process *process) +{ + ia_css_program_ID_t process_id = + ia_css_process_get_program_ID( + (const ia_css_process_t *)process); + int programs = + ia_css_program_group_manifest_get_program_count( + (const ia_css_program_group_manifest_t *)pg_manifest); + int i; + + for (i = 0; i < programs; i++) { + ia_css_program_ID_t program_id; + ia_css_program_manifest_t *pm = + ia_css_program_group_manifest_get_prgrm_mnfst( + (const ia_css_program_group_manifest_t *) + pg_manifest, i); + if (!pm) + continue; + program_id = ia_css_program_manifest_get_program_ID(pm); + if (program_id == process_id) { + gen_pm->dev_chn_size = (u16 *)pm->dev_chn_size; + gen_pm->ext_mem_size = (u16 *)pm->ext_mem_size; + gen_pm->cell_id = pm->cell_id; + gen_pm->cell_type_id = pm->cell_type_id; + return 0; + } + } + return -ENOENT; +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_get_program_manifest_by_process); + +static int libcsspsys2600_init(void) +{ + int rval; + static bool csslib_init; + + if (csslib_init) + return 0; + + syscom_buffer = kzalloc(ia_css_sizeof_psys(NULL), GFP_KERNEL); + if (!syscom_buffer) + return -ENOMEM; + + syscom_config = kzalloc(sizeof(struct ia_css_syscom_config), + GFP_KERNEL); + if (!syscom_config) { + rval = -ENOMEM; + goto out_syscom_buffer_free; + } + + server_init = kzalloc(sizeof(struct ia_css_psys_server_init), + GFP_KERNEL); + if (!server_init) { + rval = -ENOMEM; + goto out_syscom_config_free; + } + + server_init->ddr_pkg_dir_address = 0; + server_init->host_ddr_pkg_dir = 0; + server_init->pkg_dir_size = 0; + + *syscom_config = *ia_css_psys_specify(); + syscom_config->specific_addr = server_init; + syscom_config->specific_size = sizeof(struct ia_css_psys_server_init); + syscom_config->ssid = PSYS_SSID; + syscom_config->mmid = PSYS_MMID; + syscom_config->regs_addr = ipu_device_cell_memory_address(SPC0, + IPU_DEVICE_SP2600_CONTROL_REGS); + syscom_config->dmem_addr = ipu_device_cell_memory_address(SPC0, + IPU_DEVICE_SP2600_CONTROL_DMEM); + csslib_init = true; + + return 0; + +out_syscom_config_free: + kfree(syscom_config); +out_syscom_buffer_free: + kfree(syscom_buffer); + + return rval; +} + +static void __exit libcsspsys2600_exit(void) +{ + kfree(syscom_buffer); + kfree(syscom_config); + kfree(server_init); +} + +module_init(libcsspsys2600_init); +module_exit(libcsspsys2600_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu psys css library"); diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/libcsspsys2600.h b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/libcsspsys2600.h new file mode 100644 index 0000000000000..b8d790f561805 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/lib2600psys/libcsspsys2600.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015--2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef LIBCSSPSYS2600_H +#define LIBCSSPSYS2600_H + +#include +#include +#include +#include +#include +#include +#include + +extern struct ia_css_syscom_context *psys_syscom; +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4-css/libintel-ipu4.c b/drivers/media/pci/intel/ipu4/ipu4-css/libintel-ipu4.c new file mode 100644 index 0000000000000..59c9b5b858e03 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-css/libintel-ipu4.c @@ -0,0 +1,394 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2014 - 2018 Intel Corporation + +#include +#include +#include +#include "ipu-isys.h" +#include "ipu-wrapper.h" +#include + +#include "ipu-platform.h" + +#define ipu_lib_call_notrace_unlocked(func, isys, ...) \ + ({ \ + int rval; \ + \ + rval = -ia_css_isys_##func((isys)->fwcom, ##__VA_ARGS__); \ + \ + rval; \ + }) + +#define ipu_lib_call_notrace(func, isys, ...) \ + ({ \ + int rval; \ + \ + mutex_lock(&(isys)->lib_mutex); \ + \ + rval = ipu_lib_call_notrace_unlocked( \ + func, isys, ##__VA_ARGS__); \ + \ + mutex_unlock(&(isys)->lib_mutex); \ + \ + rval; \ + }) + +#define ipu_lib_call(func, isys, ...) \ + ({ \ + int rval; \ + dev_dbg(&(isys)->adev->dev, "hostlib: libcall %s\n", #func); \ + rval = ipu_lib_call_notrace(func, isys, ##__VA_ARGS__); \ + \ + rval; \ + }) + +static int wrapper_init_done; + +int ipu_fw_isys_close(struct ipu_isys *isys) +{ + struct device *dev = &isys->adev->dev; + int timeout = IPU_ISYS_TURNOFF_TIMEOUT; + int rval; + unsigned long flags; + + /* + * Ask library to stop the isys fw. Actual close takes + * some time as the FW must stop its actions including code fetch + * to SP icache. + */ + mutex_lock(&isys->lib_mutex); + spin_lock_irqsave(&isys->power_lock, flags); + rval = ipu_lib_call_notrace_unlocked(device_close, isys); + spin_unlock_irqrestore(&isys->power_lock, flags); + mutex_unlock(&isys->lib_mutex); + if (rval) + dev_err(dev, "Device close failure: %d\n", rval); + + /* release probably fails if the close failed. Let's try still */ + do { + usleep_range(IPU_ISYS_TURNOFF_DELAY_US, + 2 * IPU_ISYS_TURNOFF_DELAY_US); + rval = ipu_lib_call_notrace(device_release, isys, 0); + timeout--; + } while (rval != 0 && timeout); + + /* Spin lock to wait the interrupt handler to be finished */ + spin_lock_irqsave(&isys->power_lock, flags); + if (!rval) + isys->fwcom = NULL; /* No further actions needed */ + else + dev_err(dev, "Device release time out %d\n", rval); + spin_unlock_irqrestore(&isys->power_lock, flags); + return rval; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_close); + +int ipu_fw_isys_init(struct ipu_isys *isys, + unsigned int num_streams) +{ + int retry = IPU_ISYS_OPEN_RETRY; + unsigned int i; + + struct ia_css_isys_device_cfg_data isys_cfg = { + .driver_sys = { + .ssid = ISYS_SSID, + .mmid = ISYS_MMID, + .num_send_queues = clamp_t( + unsigned int, num_streams, 1, + IPU_ISYS_NUM_STREAMS), + .num_recv_queues = IPU_ISYS_NUM_RECV_QUEUE, + .send_queue_size = IPU_ISYS_SIZE_SEND_QUEUE, + .recv_queue_size = IPU_ISYS_SIZE_RECV_QUEUE, + .icache_prefetch = isys->icache_prefetch, + }, + }; + struct device *dev = &isys->adev->dev; + int rval; + + if (!wrapper_init_done) { + wrapper_init_done = true; + ipu_wrapper_init(ISYS_MMID, &isys->adev->dev, + isys->pdata->base); + } + + /* + * SRAM partitioning. Initially equal partitioning is set + * TODO: Fine tune the partitining based on the stream pixel load + */ + for (i = 0; i < min(IPU_NOF_SRAM_BLOCKS_MAX, NOF_SRAM_BLOCKS_MAX); i++) { + if (i < isys_cfg.driver_sys.num_send_queues) + isys_cfg.buffer_partition.num_gda_pages[i] = + (IPU_DEVICE_GDA_NR_PAGES * + IPU_DEVICE_GDA_VIRT_FACTOR) / + isys_cfg.driver_sys.num_send_queues; + else + isys_cfg.buffer_partition.num_gda_pages[i] = 0; + } + + rval = -ia_css_isys_device_open(&isys->fwcom, &isys_cfg); + if (rval < 0) { + dev_err(dev, "isys device open failed %d\n", rval); + return rval; + } + + do { + usleep_range(IPU_ISYS_OPEN_TIMEOUT_US, + IPU_ISYS_OPEN_TIMEOUT_US + 10); + rval = ipu_lib_call(device_open_ready, isys); + if (!rval) + break; + retry--; + } while (retry > 0); + + if (!retry && rval) { + dev_err(dev, "isys device open ready failed %d\n", rval); + ipu_fw_isys_close(isys); + } + + return rval; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_init); + +void ipu_fw_isys_cleanup(struct ipu_isys *isys) +{ + ipu_lib_call(device_release, isys, 1); + isys->fwcom = NULL; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_cleanup); + +struct ipu_fw_isys_resp_info_abi *ipu_fw_isys_get_resp( + void *context, unsigned int queue, + struct ipu_fw_isys_resp_info_abi *response) +{ + struct ia_css_isys_resp_info apiresp; + int rval; + + rval = -ia_css_isys_stream_handle_response(context, &apiresp); + if (rval < 0) + return NULL; + + response->buf_id = 0; + response->type = apiresp.type; + response->timestamp[0] = apiresp.timestamp[0]; + response->timestamp[1] = apiresp.timestamp[1]; + response->stream_handle = apiresp.stream_handle; + response->error_info.error = apiresp.error; + response->error_info.error_details = apiresp.error_details; + response->pin.out_buf_id = apiresp.pin.out_buf_id; + response->pin.addr = apiresp.pin.addr; + response->pin_id = apiresp.pin_id; + response->process_group_light.param_buf_id = + apiresp.process_group_light.param_buf_id; + response->process_group_light.addr = + apiresp.process_group_light.addr; + response->acc_id = apiresp.acc_id; +#ifdef IPU_OTF_SUPPORT + response->frame_counter = apiresp.frame_counter; + response->written_direct = apiresp.written_direct; +#endif + + return response; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_get_resp); + +void ipu_fw_isys_put_resp(void *context, unsigned int queue) +{ + /* Nothing to do here really */ +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_put_resp); + +int ipu_fw_isys_simple_cmd(struct ipu_isys *isys, + const unsigned int stream_handle, + enum ipu_fw_isys_send_type send_type) +{ + int rval = -1; + + switch (send_type) { + case IPU_FW_ISYS_SEND_TYPE_STREAM_START: + rval = ipu_lib_call(stream_start, isys, stream_handle, + NULL); + break; + case IPU_FW_ISYS_SEND_TYPE_STREAM_FLUSH: + rval = ipu_lib_call(stream_flush, isys, stream_handle); + break; + case IPU_FW_ISYS_SEND_TYPE_STREAM_STOP: + rval = ipu_lib_call(stream_stop, isys, stream_handle); + break; + case IPU_FW_ISYS_SEND_TYPE_STREAM_CLOSE: + rval = ipu_lib_call(stream_close, isys, stream_handle); + break; + default: + WARN_ON(1); + } + + return rval; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_simple_cmd); + +static void resolution_abi_to_api(const struct ipu_fw_isys_resolution_abi *abi, + struct ia_css_isys_resolution *api) +{ + api->width = abi->width; + api->height = abi->height; +} + +static void output_pin_payload_abi_to_api( + struct ipu_fw_isys_output_pin_payload_abi *abi, + struct ia_css_isys_output_pin_payload *api) +{ + api->out_buf_id = abi->out_buf_id; + api->addr = abi->addr; +} + +static void output_pin_info_abi_to_api( + struct ipu_fw_isys_output_pin_info_abi *abi, + struct ia_css_isys_output_pin_info *api) +{ + api->input_pin_id = abi->input_pin_id; + resolution_abi_to_api(&abi->output_res, &api->output_res); + api->stride = abi->stride; + api->pt = abi->pt; + api->watermark_in_lines = abi->watermark_in_lines; + api->payload_buf_size = abi->payload_buf_size; + api->send_irq = abi->send_irq; + api->ft = abi->ft; +#ifdef IPU_OTF_SUPPORT + api->link_id = abi->link_id; +#endif + api->reserve_compression = abi->reserve_compression; +} + +static void param_pin_abi_to_api(struct ipu_fw_isys_param_pin_abi *abi, + struct ia_css_isys_param_pin *api) +{ + api->param_buf_id = abi->param_buf_id; + api->addr = abi->addr; +} + +static void input_pin_info_abi_to_api( + struct ipu_fw_isys_input_pin_info_abi *abi, + struct ia_css_isys_input_pin_info *api) +{ + resolution_abi_to_api(&abi->input_res, &api->input_res); + api->dt = abi->dt; + api->mipi_store_mode = abi->mipi_store_mode; + api->mapped_dt = abi->mapped_dt; +} + +static void isa_cfg_abi_to_api(const struct ipu_fw_isys_isa_cfg_abi *abi, + struct ia_css_isys_isa_cfg *api) +{ + unsigned int i; + + for (i = 0; i < N_IA_CSS_ISYS_RESOLUTION_INFO; i++) + resolution_abi_to_api(&abi->isa_res[i], &api->isa_res[i]); + + api->blc_enabled = abi->cfg.blc; + api->lsc_enabled = abi->cfg.lsc; + api->dpc_enabled = abi->cfg.dpc; + api->downscaler_enabled = abi->cfg.downscaler; + api->awb_enabled = abi->cfg.awb; + api->af_enabled = abi->cfg.af; + api->ae_enabled = abi->cfg.ae; + api->paf_type = abi->cfg.paf; + api->send_irq_stats_ready = abi->cfg.send_irq_stats_ready; + api->send_resp_stats_ready = abi->cfg.send_irq_stats_ready; +} + +static void cropping_abi_to_api(struct ipu_fw_isys_cropping_abi *abi, + struct ia_css_isys_cropping *api) +{ + api->top_offset = abi->top_offset; + api->left_offset = abi->left_offset; + api->bottom_offset = abi->bottom_offset; + api->right_offset = abi->right_offset; +} + +static void stream_cfg_abi_to_api(struct ipu_fw_isys_stream_cfg_data_abi *abi, + struct ia_css_isys_stream_cfg_data *api) +{ + unsigned int i; + + api->src = abi->src; + api->vc = abi->vc; + api->isl_use = abi->isl_use; + api->compfmt = abi->compfmt; + isa_cfg_abi_to_api(&abi->isa_cfg, &api->isa_cfg); + for (i = 0; i < N_IA_CSS_ISYS_CROPPING_LOCATION; i++) + cropping_abi_to_api(&abi->crop[i], &api->crop[i]); + + api->send_irq_sof_discarded = abi->send_irq_sof_discarded; + api->send_irq_eof_discarded = abi->send_irq_eof_discarded; + api->send_resp_sof_discarded = abi->send_irq_sof_discarded; + api->send_resp_eof_discarded = abi->send_irq_eof_discarded; + api->nof_input_pins = abi->nof_input_pins; + api->nof_output_pins = abi->nof_output_pins; + for (i = 0; i < abi->nof_input_pins; i++) + input_pin_info_abi_to_api(&abi->input_pins[i], + &api->input_pins[i]); + + for (i = 0; i < abi->nof_output_pins; i++) + output_pin_info_abi_to_api(&abi->output_pins[i], + &api->output_pins[i]); +} + +static void frame_buff_set_abi_to_api( + struct ipu_fw_isys_frame_buff_set_abi *abi, + struct ia_css_isys_frame_buff_set *api) +{ + int i; + + for (i = 0; i < min(IPU_MAX_OPINS, MAX_OPINS); i++) + output_pin_payload_abi_to_api(&abi->output_pins[i], + &api->output_pins[i]); + + param_pin_abi_to_api(&abi->process_group_light, + &api->process_group_light); + + api->send_irq_sof = abi->send_irq_sof; + api->send_irq_eof = abi->send_irq_eof; + api->send_irq_capture_ack = abi->send_irq_capture_ack; + api->send_irq_capture_done = abi->send_irq_capture_done; +} + +int ipu_fw_isys_complex_cmd(struct ipu_isys *isys, + const unsigned int stream_handle, + void *cpu_mapped_buf, + dma_addr_t dma_mapped_buf, + size_t size, + enum ipu_fw_isys_send_type send_type) +{ + union { + struct ia_css_isys_stream_cfg_data stream_cfg; + struct ia_css_isys_frame_buff_set buf; + } param; + int rval = -1; + + memset(¶m, 0, sizeof(param)); + + switch (send_type) { + case IPU_FW_ISYS_SEND_TYPE_STREAM_CAPTURE: + frame_buff_set_abi_to_api(cpu_mapped_buf, ¶m.buf); + rval = ipu_lib_call(stream_capture_indication, + isys, stream_handle, ¶m.buf); + break; + case IPU_FW_ISYS_SEND_TYPE_STREAM_OPEN: + stream_cfg_abi_to_api(cpu_mapped_buf, ¶m.stream_cfg); + rval = ipu_lib_call(stream_open, isys, stream_handle, + ¶m.stream_cfg); + break; + case IPU_FW_ISYS_SEND_TYPE_STREAM_START_AND_CAPTURE: + frame_buff_set_abi_to_api(cpu_mapped_buf, ¶m.buf); + rval = ipu_lib_call(stream_start, isys, stream_handle, + ¶m.buf); + break; + default: + WARN_ON(1); + } + + return rval; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_complex_cmd); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu library"); diff --git a/drivers/media/pci/intel/ipu4/ipu4-fw-resources.c b/drivers/media/pci/intel/ipu4/ipu4-fw-resources.c new file mode 100644 index 0000000000000..78b477e9ed65e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-fw-resources.c @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2015 - 2018 Intel Corporation + +#include "ipu-fw-psys.h" + +#include + +/* resources table */ +/* + * Cell types by cell IDs + */ +const u32 ipu_fw_psys_cell_types[IPU_FW_PSYS_N_CELL_ID] = { + IPU_FW_PSYS_SP_CTRL_TYPE_ID, + IPU_FW_PSYS_SP_SERVER_TYPE_ID, + IPU_FW_PSYS_SP_SERVER_TYPE_ID, + IPU_FW_PSYS_VP_TYPE_ID, + IPU_FW_PSYS_VP_TYPE_ID, + IPU_FW_PSYS_VP_TYPE_ID, + IPU_FW_PSYS_VP_TYPE_ID, + IPU_FW_PSYS_ACC_ISA_TYPE_ID, + IPU_FW_PSYS_ACC_PSA_TYPE_ID, + IPU_FW_PSYS_ACC_PSA_TYPE_ID, + IPU_FW_PSYS_ACC_PSA_TYPE_ID, + IPU_FW_PSYS_ACC_PSA_TYPE_ID, + IPU_FW_PSYS_ACC_PSA_TYPE_ID, + IPU_FW_PSYS_ACC_PSA_TYPE_ID, + IPU_FW_PSYS_ACC_OSA_TYPE_ID, + IPU_FW_PSYS_GDC_TYPE_ID, + IPU_FW_PSYS_GDC_TYPE_ID +}; + +const u16 ipu_fw_num_dev_channels[IPU_FW_PSYS_N_DEV_CHN_ID] = { + IPU_FW_PSYS_DEV_CHN_DMA_EXT0_MAX_SIZE, + IPU_FW_PSYS_DEV_CHN_GDC_MAX_SIZE, + IPU_FW_PSYS_DEV_CHN_DMA_EXT1_READ_MAX_SIZE, + IPU_FW_PSYS_DEV_CHN_DMA_EXT1_WRITE_MAX_SIZE, + IPU_FW_PSYS_DEV_CHN_DMA_INTERNAL_MAX_SIZE, + IPU_FW_PSYS_DEV_CHN_DMA_IPFD_MAX_SIZE, + IPU_FW_PSYS_DEV_CHN_DMA_ISA_MAX_SIZE, + IPU_FW_PSYS_DEV_CHN_DMA_FW_MAX_SIZE, +#ifdef CONFIG_VIDEO_INTEL_IPU4P + IPU_FW_PSYS_DEV_CHN_DMA_CMPRS_MAX_SIZE +#endif +}; + +const u16 ipu_fw_psys_mem_size[IPU_FW_PSYS_N_MEM_ID] = { + IPU_FW_PSYS_VMEM0_MAX_SIZE, + IPU_FW_PSYS_VMEM1_MAX_SIZE, + IPU_FW_PSYS_VMEM2_MAX_SIZE, + IPU_FW_PSYS_VMEM3_MAX_SIZE, + IPU_FW_PSYS_VMEM4_MAX_SIZE, + IPU_FW_PSYS_BAMEM0_MAX_SIZE, + IPU_FW_PSYS_BAMEM1_MAX_SIZE, + IPU_FW_PSYS_BAMEM2_MAX_SIZE, + IPU_FW_PSYS_BAMEM3_MAX_SIZE, + IPU_FW_PSYS_DMEM0_MAX_SIZE, + IPU_FW_PSYS_DMEM1_MAX_SIZE, + IPU_FW_PSYS_DMEM2_MAX_SIZE, + IPU_FW_PSYS_DMEM3_MAX_SIZE, + IPU_FW_PSYS_DMEM4_MAX_SIZE, + IPU_FW_PSYS_DMEM5_MAX_SIZE, + IPU_FW_PSYS_DMEM6_MAX_SIZE, + IPU_FW_PSYS_DMEM7_MAX_SIZE, + IPU_FW_PSYS_PMEM0_MAX_SIZE, + IPU_FW_PSYS_PMEM1_MAX_SIZE, + IPU_FW_PSYS_PMEM2_MAX_SIZE, + IPU_FW_PSYS_PMEM3_MAX_SIZE +}; + +const enum ipu_mem_id +ipu_fw_psys_cell_mem[IPU_FW_PSYS_N_CELL_ID][IPU_FW_PSYS_N_MEM_TYPE_ID] = { + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_DMEM0_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_DMEM1_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_DMEM2_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_VMEM4_ID, + IPU_FW_PSYS_DMEM4_ID, + IPU_FW_PSYS_VMEM0_ID, + IPU_FW_PSYS_BAMEM0_ID, + IPU_FW_PSYS_PMEM0_ID + }, + { + IPU_FW_PSYS_VMEM4_ID, + IPU_FW_PSYS_DMEM5_ID, + IPU_FW_PSYS_VMEM1_ID, + IPU_FW_PSYS_BAMEM1_ID, + IPU_FW_PSYS_PMEM1_ID + }, + { + IPU_FW_PSYS_VMEM4_ID, + IPU_FW_PSYS_DMEM6_ID, + IPU_FW_PSYS_VMEM2_ID, + IPU_FW_PSYS_BAMEM2_ID, + IPU_FW_PSYS_PMEM2_ID, + }, + { + IPU_FW_PSYS_VMEM4_ID, + IPU_FW_PSYS_DMEM7_ID, + IPU_FW_PSYS_VMEM3_ID, + IPU_FW_PSYS_BAMEM3_ID, + IPU_FW_PSYS_PMEM3_ID, + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + }, + { + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID, + IPU_FW_PSYS_N_MEM_ID + } +}; + +static const struct ipu_fw_resource_definitions default_defs = { + .cells = ipu_fw_psys_cell_types, + .num_cells = IPU_FW_PSYS_N_CELL_ID, + .num_cells_type = IPU_FW_PSYS_N_CELL_TYPE_ID, + + .dev_channels = ipu_fw_num_dev_channels, + .num_dev_channels = IPU_FW_PSYS_N_DEV_CHN_ID, + + .num_ext_mem_types = IPU_FW_PSYS_N_DATA_MEM_TYPE_ID, + .num_ext_mem_ids = IPU_FW_PSYS_N_MEM_ID, + .ext_mem_ids = ipu_fw_psys_mem_size, + + .num_dfm_ids = IPU_FW_PSYS_N_DEV_DFM_ID, + + .cell_mem_row = IPU_FW_PSYS_N_MEM_TYPE_ID, + .cell_mem = &ipu_fw_psys_cell_mem[0][0], + + .process.ext_mem_id = offsetof(struct ipu_fw_psys_process, + ext_mem_id[0]), + .process.ext_mem_offset = offsetof(struct ipu_fw_psys_process, + ext_mem_offset[0]), + .process.dev_chn_offset = offsetof(struct ipu_fw_psys_process, + dev_chn_offset[0]), + .process.cell_id = offsetof(struct ipu_fw_psys_process, cell_id), +}; + +const struct ipu_fw_resource_definitions *res_defs = &default_defs; + +/********** Generic resource handling **********/ + +/* + * Extension library gives byte offsets to its internal structures. + * use those offsets to update fields. Without extension lib access + * structures directly. + */ +int ipu_fw_psys_set_process_cell_id(struct ipu_fw_psys_process *ptr, u8 index, + u8 value) +{ + struct ipu_fw_psys_process_group *parent = + (struct ipu_fw_psys_process_group *) ((char *)ptr + + ptr->parent_offset); + + ptr->cell_id = value; + parent->resource_bitmap |= 1 << value; + + return 0; +} + +u8 ipu_fw_psys_get_process_cell_id(struct ipu_fw_psys_process *ptr, u8 index) +{ + return ptr->cell_id; +} + +int ipu_fw_psys_clear_process_cell(struct ipu_fw_psys_process *ptr) +{ + struct ipu_fw_psys_process_group *parent; + u8 cell_id = ipu_fw_psys_get_process_cell_id(ptr, 0); + u8 cell_id_shift = cell_id << 1; + int retval = -1; + + parent = (struct ipu_fw_psys_process_group *) ((char *)ptr + + ptr->parent_offset); + if ((cell_id_shift) && ((cell_id_shift) & parent->resource_bitmap)) { + ipu_fw_psys_set_process_cell_id(ptr, 0, IPU_FW_PSYS_N_CELL_ID); + parent->resource_bitmap &= ~(1 << cell_id); + retval = 0; + } + + return retval; +} + +int ipu_fw_psys_set_process_dev_chn_offset(struct ipu_fw_psys_process *ptr, + u16 offset, u16 value) +{ + ptr->dev_chn_offset[offset] = value; + + return 0; +} + +int ipu_fw_psys_set_process_ext_mem(struct ipu_fw_psys_process *ptr, + u16 type_id, u16 mem_id, u16 offset) +{ + ptr->ext_mem_offset[type_id] = offset; + ptr->ext_mem_id[type_id] = mem_id; + + return 0; +} + +static struct ipu_fw_psys_program_manifest * +ipu_resource_get_program_manifest( + const struct ipu_fw_psys_program_group_manifest *manifest, + const unsigned int program_index) +{ + struct ipu_fw_psys_program_manifest *prg_manifest_base; + u8 *program_manifest = NULL; + u8 program_count; + unsigned int i; + + program_count = manifest->program_count; + + prg_manifest_base = (struct ipu_fw_psys_program_manifest *) + ((char *)manifest + manifest->program_manifest_offset); + if (program_index < program_count) { + program_manifest = (u8 *) prg_manifest_base; + for (i = 0; i < program_index; i++) + program_manifest += + ((struct ipu_fw_psys_program_manifest *) + program_manifest)->size; + } + + return (struct ipu_fw_psys_program_manifest *)program_manifest; +} + +int ipu_fw_psys_get_program_manifest_by_process( + struct ipu_fw_generic_program_manifest *gen_pm, + const struct ipu_fw_psys_program_group_manifest *pg_manifest, + struct ipu_fw_psys_process *process) +{ + u32 process_id = process->ID; + int programs = pg_manifest->program_count; + int i; + + for (i = 0; i < programs; i++) { + u32 program_id; + struct ipu_fw_psys_program_manifest *pm = + ipu_resource_get_program_manifest(pg_manifest, i); + if (!pm) + continue; + program_id = pm->ID; + if (program_id == process_id) { + gen_pm->dev_chn_size = pm->dev_chn_size; + gen_pm->dev_chn_offset = NULL; + gen_pm->ext_mem_offset = NULL; + gen_pm->cell_id = pm->cell_id; + gen_pm->cell_type_id = pm->cell_type_id; + gen_pm->ext_mem_size = pm->ext_mem_size; + return 0; + } + } + return -ENOENT; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-isys-csi2.c b/drivers/media/pci/intel/ipu4/ipu4-isys-csi2.c new file mode 100644 index 0000000000000..ff472887e6f5b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-isys-csi2.c @@ -0,0 +1,713 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2013 - 2018 Intel Corporation + +#include "ipu.h" +#include "ipu-buttress.h" +#include "ipu-isys.h" +#include "ipu-isys-csi2.h" +#include "ipu-platform-isys-csi2-reg.h" +#include "ipu-platform-regs.h" +#include "ipu-trace.h" +#include "ipu-isys-csi2.h" + +#define CSE_IPC_CMDPHYWRITEL 35 +#define CSE_IPC_CMDPHYWRITEH 36 +#define CSE_IPC_CMDLEGACYPHYWRITEL 39 +#define CSE_IPC_CMDLEGACYPHYWRITEH 40 + +#define NBR_BULK_MSGS 30 /* Space reservation for IPC messages */ + +#define CSI2_UPDATE_TIME_TRY_NUM 3 +#define CSI2_UPDATE_TIME_MAX_DIFF 20 + +static u32 +build_cse_ipc_commands(struct ipu_ipc_buttress_bulk_msg *target, + u32 nbr_msgs, u32 opcodel, u32 reg, u32 data) +{ + struct ipu_ipc_buttress_bulk_msg *msgs = &target[nbr_msgs]; + u32 opcodeh = opcodel == CSE_IPC_CMDPHYWRITEL ? + CSE_IPC_CMDPHYWRITEH : CSE_IPC_CMDLEGACYPHYWRITEH; + + /* + * Writing of 32 bits consist of 2 16 bit IPC messages to CSE. + * Messages must be in low-high order and nothing else between + * them. + * Register is in bits 8..15 as index (register value divided by 4) + */ + msgs->cmd = opcodel | (reg << (8 - 2)) | ((data & 0xffff) << 16); + msgs->expected_resp = opcodel; + msgs->require_resp = true; + msgs->cmd_size = 4; + msgs++; + + msgs->cmd = opcodeh | (reg << (8 - 2)) | (data & 0xffff0000); + msgs->expected_resp = opcodeh; + msgs->require_resp = true; + msgs->cmd_size = 4; + + nbr_msgs += 2; + + /* Hits only if code change introduces too many new IPC messages */ + WARN_ON(nbr_msgs > NBR_BULK_MSGS); + + return nbr_msgs; +} + +static int csi2_ev_correction_params(struct ipu_isys_csi2 *csi2, + unsigned int lanes) +{ + struct ipu_device *isp = csi2->isys->adev->isp; + struct ipu_ipc_buttress_bulk_msg *messages; + const struct ipu_receiver_electrical_params *ev_params; + const struct ipu_isys_internal_csi2_pdata *csi2_pdata; + + __s64 link_freq; + unsigned int i; + u32 val; + u32 nbr_msgs = 0; + int rval; + bool conf_set0; + bool conf_set1; + bool conf_combined = false; + + csi2_pdata = &csi2->isys->pdata->ipdata->csi2; + ev_params = csi2_pdata->evparams; + if (!ev_params) + return 0; + + if (csi2->isys->csi2_cse_ipc_not_supported) + return 0; + + rval = ipu_isys_csi2_get_link_freq(csi2, &link_freq); + if (rval) + return rval; + + i = 0; + while (ev_params[i].device) { + if (ev_params[i].device == isp->pdev->device && + ev_params[i].revision == isp->pdev->revision && + ev_params[i].min_freq < link_freq && + ev_params[i].max_freq >= link_freq) + break; + i++; + } + + if (!ev_params[i].device) { + dev_info(&csi2->isys->adev->dev, + "No rcomp value override for this HW revision\n"); + return 0; + } + + messages = kcalloc(NBR_BULK_MSGS, sizeof(*messages), GFP_KERNEL); + if (!messages) + return -ENOMEM; + + conf_set0 = csi2_pdata->evsetmask0 & (1 << csi2->index); + conf_set1 = csi2_pdata->evsetmask1 & (1 << csi2->index); + if (csi2_pdata->evlanecombine[csi2->index]) { + conf_combined = + lanes > csi2_pdata->evlanecombine[csi2->index] ? 1 : 0; + } + conf_set1 |= conf_combined; + + /* + * Note: There is no way to make R-M-W to these. Possible non-zero reset + * default is OR'd with the values + */ + val = 1 << CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_ENABLE_PORT1_SHIFT | + 1 << CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_ENABLE_PORT2_SHIFT | + 1 << CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_ENABLE_PORT3_SHIFT | + 1 << CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_ENABLE_PORT4_SHIFT | + 1 << CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_ENABLE_SHIFT | + ev_params[i].rcomp_val_legacy << + CSI2_SB_CSI_RCOMP_CONTROL_LEGACY_OVR_CODE_SHIFT; + + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDLEGACYPHYWRITEL, + CSI2_SB_CSI_RCOMP_CONTROL_LEGACY, + val); + + val = 2 << CSI2_SB_CSI_RCOMP_UPDATE_MODE_SHIFT | + 1 << CSI2_SB_CSI_RCOMP_OVR_ENABLE_SHIFT | + ev_params[i].rcomp_val_combo << CSI2_SB_CSI_RCOMP_OVR_CODE_SHIFT; + + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_CSI_RCOMP_CONTROL_COMBO, val); + + if (conf_set0) { + val = 0x380078 | ev_params[i].ports[0].ctle_val << + CSI2_SB_CPHY0_RX_CONTROL1_EQ_LANE0_SHIFT; + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_CPHY0_RX_CONTROL1, + val); + val = 0x10000; + if (ev_params[i].ports[0].crc_val != IPU_EV_AUTO) + val |= ev_params[i].ports[0].crc_val << + CSI2_SB_CPHY0_DLL_OVRD_CRCDC_FSM_DLANE0_SHIFT | + CSI2_SB_CPHY0_DLL_OVRD_LDEN_CRCDC_FSM_DLANE0; + + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_CPHY0_DLL_OVRD, val); + } + + if (conf_set1) { + val = 0x380078 | ev_params[i].ports[1].ctle_val << + CSI2_SB_CPHY2_RX_CONTROL1_EQ_LANE1_SHIFT; + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_CPHY2_RX_CONTROL1, + val); + + val = 0x10000; + if (ev_params[i].ports[1].crc_val != IPU_EV_AUTO) + val |= ev_params[i].ports[1].crc_val << + CSI2_SB_CPHY2_DLL_OVRD_CRCDC_FSM_DLANE1_SHIFT | + CSI2_SB_CPHY2_DLL_OVRD_LDEN_CRCDC_FSM_DLANE1; + + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_CPHY2_DLL_OVRD, val); + } + + mutex_lock(&csi2->isys->mutex); + /* This register is shared between two receivers */ + val = csi2->isys->csi2_rx_ctrl_cached; + if (conf_set0) { + val &= ~CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE01_MASK; + if (ev_params[i].ports[0].drc_val != IPU_EV_AUTO) + val |= + CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE01_MASK; + } + + if (conf_set1) { + val &= ~CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE23_MASK; + if (ev_params[i].ports[1].drc_val != IPU_EV_AUTO) + val |= + CSI2_SB_DPHY0_RX_CNTRL_SKEWCAL_CR_SEL_DLANE23_MASK; + } + csi2->isys->csi2_rx_ctrl_cached = val; + + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_DPHY0_RX_CNTRL, val); + mutex_unlock(&csi2->isys->mutex); + + if (conf_set0 && ev_params[i].ports[0].drc_val != IPU_EV_AUTO) { + /* Write value with FSM disabled */ + val = (conf_combined ? + ev_params[i].ports[0].drc_val_combined : + ev_params[i].ports[0].drc_val) << + CSI2_SB_DPHY0_DLL_OVRD_DRC_FSM_OVRD_SHIFT; + + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_DPHY0_DLL_OVRD, val); + + /* Write value with FSM enabled */ + val |= 1 << CSI2_SB_DPHY1_DLL_OVRD_LDEN_DRC_FSM_SHIFT; + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_DPHY0_DLL_OVRD, val); + } else if (conf_set0 && ev_params[i].ports[0].drc_val == IPU_EV_AUTO) { + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_DPHY0_DLL_OVRD, 0); + } + + if (conf_set1 && ev_params[i].ports[1].drc_val != IPU_EV_AUTO) { + val = (conf_combined ? + ev_params[i].ports[1].drc_val_combined : + ev_params[i].ports[1].drc_val) << + CSI2_SB_DPHY0_DLL_OVRD_DRC_FSM_OVRD_SHIFT; + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_DPHY1_DLL_OVRD, val); + + val |= 1 << CSI2_SB_DPHY1_DLL_OVRD_LDEN_DRC_FSM_SHIFT; + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_DPHY1_DLL_OVRD, val); + } else if (conf_set1 && ev_params[i].ports[1].drc_val == IPU_EV_AUTO) { + nbr_msgs = build_cse_ipc_commands(messages, nbr_msgs, + CSE_IPC_CMDPHYWRITEL, + CSI2_SB_DPHY1_DLL_OVRD, 0); + } + + rval = ipu_buttress_ipc_send_bulk(isp, + IPU_BUTTRESS_IPC_CSE, + messages, nbr_msgs); + + if (rval == -ENODEV) + csi2->isys->csi2_cse_ipc_not_supported = true; + + kfree(messages); + return 0; +} + +static void ipu_isys_register_errors(struct ipu_isys_csi2 *csi2) +{ + u32 status = readl(csi2->base + CSI2_REG_CSIRX_IRQ_STATUS); + + writel(status, csi2->base + CSI2_REG_CSIRX_IRQ_CLEAR); + csi2->receiver_errors |= status; +} + +void ipu_isys_csi2_error(struct ipu_isys_csi2 *csi2) +{ + /* + * Strings corresponding to CSI-2 receiver errors are here. + * Corresponding macros are defined in the header file. + */ + static const struct ipu_isys_csi2_error { + const char *error_string; + bool is_info_only; + } errors[] = { + {"Single packet header error corrected", true}, + {"Multiple packet header errors detected", true}, + {"Payload checksum (CRC) error", true}, + {"FIFO overflow", false}, + {"Reserved short packet data type detected", true}, + {"Reserved long packet data type detected", true}, + {"Incomplete long packet detected", false}, + {"Frame sync error", false}, + {"Line sync error", false}, + {"DPHY recoverable synchronization error", true}, + {"DPHY non-recoverable synchronization error", false}, + {"Escape mode error", true}, + {"Escape mode trigger event", true}, + {"Escape mode ultra-low power state for data lane(s)", true}, + {"Escape mode ultra-low power state exit for clock lane", true}, + {"Inter-frame short packet discarded", true}, + {"Inter-frame long packet discarded", true}, + }; + u32 status; + unsigned int i; + + /* Register errors once more in case of error interrupts are disabled */ + ipu_isys_register_errors(csi2); + status = csi2->receiver_errors; + csi2->receiver_errors = 0; + + for (i = 0; i < ARRAY_SIZE(errors); i++) { + if (!(status & BIT(i))) + continue; + + if (errors[i].is_info_only) + dev_dbg(&csi2->isys->adev->dev, + "csi2-%i info: %s\n", + csi2->index, errors[i].error_string); + else + dev_err_ratelimited(&csi2->isys->adev->dev, + "csi2-%i error: %s\n", + csi2->index, + errors[i].error_string); + } +} + +static u64 tunit_time_to_us(struct ipu_isys *isys, u64 time) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(isys->adev->iommu); + u64 isys_clk = IS_FREQ_SOURCE / adev->ctrl->divisor / 1000000; + + do_div(time, isys_clk); + + return time; +} + +static int update_timer_base(struct ipu_isys *isys) +{ + int rval, i; + u64 time; + + for (i = 0; i < CSI2_UPDATE_TIME_TRY_NUM; i++) { + rval = ipu_trace_get_timer(&isys->adev->dev, &time); + if (rval) { + dev_err(&isys->adev->dev, + "Failed to read Tunit timer.\n"); + return rval; + } + rval = ipu4_buttress_tsc_read(isys->adev->isp, + &isys->tsc_timer_base); + if (rval) { + dev_err(&isys->adev->dev, + "Failed to read TSC timer.\n"); + return rval; + } + rval = ipu_trace_get_timer(&isys->adev->dev, + &isys->tunit_timer_base); + if (rval) { + dev_err(&isys->adev->dev, + "Failed to read Tunit timer.\n"); + return rval; + } + if (tunit_time_to_us(isys, isys->tunit_timer_base - time) < + CSI2_UPDATE_TIME_MAX_DIFF) + return 0; + } + dev_dbg(&isys->adev->dev, "Timer base values may not be accurate.\n"); + return 0; +} + +static int +ipu_isys_csi2_configure_tunit(struct ipu_isys_csi2 *csi2, bool enable) +{ + struct ipu_isys *isys = csi2->isys; + void __iomem *isys_base = isys->pdata->base; + void __iomem *tunit_base = isys_base + TRACE_REG_IS_TRACE_UNIT_BASE; + int i, ret = 0; + + mutex_lock(&isys->short_packet_tracing_mutex); + if (!enable) { + isys->short_packet_tracing_count--; + if (isys->short_packet_tracing_count == 0) + writel(0, tunit_base + TRACE_REG_TUN_DDR_ENABLE); + goto out_release_mutex; + } + + isys->short_packet_tracing_count++; + if (isys->short_packet_tracing_count > 1) + goto out_release_mutex; + + memset(isys->short_packet_trace_buffer, 0, + IPU_ISYS_SHORT_PACKET_TRACE_BUFFER_SIZE); + dma_sync_single_for_device(&isys->adev->dev, + isys->short_packet_trace_buffer_dma_addr, + IPU_ISYS_SHORT_PACKET_TRACE_BUFFER_SIZE, + DMA_BIDIRECTIONAL); + + /* ring buffer base */ + writel(isys->short_packet_trace_buffer_dma_addr, + tunit_base + TRACE_REG_TUN_DRAM_BASE_ADDR); + + /* ring buffer end */ + writel(isys->short_packet_trace_buffer_dma_addr + + IPU_ISYS_SHORT_PACKET_TRACE_BUFFER_SIZE - + IPU_ISYS_SHORT_PACKET_TRACE_MSG_SIZE, + tunit_base + TRACE_REG_TUN_DRAM_END_ADDR); + + /* Infobits for ddr trace */ + writel(IPU_INFO_REQUEST_DESTINATION_PRIMARY, + tunit_base + TRACE_REG_TUN_DDR_INFO_VAL); + + /* Remove reset from trace timers */ + writel(TRACE_REG_GPREG_TRACE_TIMER_RST_OFF, + isys_base + TRACE_REG_IS_GPREG_TRACE_TIMER_RST_N); + + /* Reset CSI2 monitors */ + writel(1, isys->pdata->base + TRACE_REG_CSI2_TM_BASE + + TRACE_REG_CSI2_TM_RESET_REG_IDX); + writel(1, isys->pdata->base + TRACE_REG_CSI2_3PH_TM_BASE + + TRACE_REG_CSI2_TM_RESET_REG_IDX); + + /* Set trace address register. */ + writel(TRACE_REG_CSI2_TM_TRACE_ADDRESS_VAL, + isys->pdata->base + TRACE_REG_CSI2_TM_BASE + + TRACE_REG_CSI2_TM_TRACE_ADDRESS_REG_IDX); + writel(TRACE_REG_CSI2_TM_TRACE_HEADER_VAL, + isys->pdata->base + TRACE_REG_CSI2_TM_BASE + + TRACE_REG_CSI2_TM_TRACE_HEADER_REG_IDX); + writel(TRACE_REG_CSI2_3PH_TM_TRACE_ADDRESS_VAL, + isys->pdata->base + TRACE_REG_CSI2_3PH_TM_BASE + + TRACE_REG_CSI2_TM_TRACE_ADDRESS_REG_IDX); + writel(TRACE_REG_CSI2_TM_TRACE_HEADER_VAL, + isys->pdata->base + TRACE_REG_CSI2_3PH_TM_BASE + + TRACE_REG_CSI2_TM_TRACE_HEADER_REG_IDX); + + /* Enable DDR trace. */ + writel(1, tunit_base + TRACE_REG_TUN_DDR_ENABLE); + + /* Enable trace for CSI2 port. */ + for (i = 0; i < IPU_ISYS_MAX_CSI2_LEGACY_PORTS + + IPU_ISYS_MAX_CSI2_COMBO_PORTS; i++) { + void __iomem *event_mask_reg = + (i < IPU_ISYS_MAX_CSI2_LEGACY_PORTS) ? + isys->pdata->base + TRACE_REG_CSI2_TM_BASE + + TRACE_REG_CSI2_TM_TRACE_DDR_EN_REG_IDX_P(i) : + isys->pdata->base + TRACE_REG_CSI2_3PH_TM_BASE + + TRACE_REG_CSI2_3PH_TM_TRACE_DDR_EN_REG_IDX_P(i); + + writel(IPU_ISYS_SHORT_PACKET_TRACE_EVENT_MASK, + event_mask_reg); + } + + /* Enable CSI2 receiver monitor */ + writel(1, isys->pdata->base + TRACE_REG_CSI2_TM_BASE + + TRACE_REG_CSI2_TM_OVERALL_ENABLE_REG_IDX); + writel(1, isys->pdata->base + TRACE_REG_CSI2_3PH_TM_BASE + + TRACE_REG_CSI2_TM_OVERALL_ENABLE_REG_IDX); + + ret = update_timer_base(isys); + +out_release_mutex: + mutex_unlock(&isys->short_packet_tracing_mutex); + + return ret; +} + +int ipu_isys_csi2_set_stream(struct v4l2_subdev *sd, + struct ipu_isys_csi2_timing timing, + unsigned int nlanes, int enable) +{ + struct ipu_isys_csi2 *csi2 = to_ipu_isys_csi2(sd); + struct ipu_isys_pipeline *ip = container_of(media_entity_pipeline(&sd->entity), + struct ipu_isys_pipeline, + pipe); + unsigned int i; + int rval; + u32 val, csi2part = 0, csi2csirx; + + dev_dbg(&csi2->isys->adev->dev, "csi2 s_stream %d\n", enable); + + if (!enable) { + ipu_isys_csi2_error(csi2); + + val = readl(csi2->base + CSI2_REG_CSI_RX_CONFIG); + val &= ~(CSI2_CSI_RX_CONFIG_DISABLE_BYTE_CLK_GATING | + CSI2_CSI_RX_CONFIG_RELEASE_LP11); + writel(val, csi2->base + CSI2_REG_CSI_RX_CONFIG); + + writel(0, csi2->base + CSI2_REG_CSI_RX_ENABLE); + + /* Disable interrupts */ + writel(0, csi2->base + CSI2_REG_CSI2S2M_IRQ_MASK); + writel(0, csi2->base + CSI2_REG_CSI2S2M_IRQ_ENABLE); + writel(0, csi2->base + CSI2_REG_CSI2PART_IRQ_MASK); + writel(0, csi2->base + CSI2_REG_CSI2PART_IRQ_ENABLE); + if (ip->interlaced) + ipu_isys_csi2_configure_tunit(csi2, 0); + return 0; + } + + csi2_ev_correction_params(csi2, nlanes); + + writel(timing.ctermen, + csi2->base + CSI2_REG_CSI_RX_DLY_CNT_TERMEN_CLANE); + writel(timing.csettle, + csi2->base + CSI2_REG_CSI_RX_DLY_CNT_SETTLE_CLANE); + + for (i = 0; i < nlanes; i++) { + writel(timing.dtermen, + csi2->base + + CSI2_REG_CSI_RX_DLY_CNT_TERMEN_DLANE(i)); + writel(timing.dsettle, + csi2->base + + CSI2_REG_CSI_RX_DLY_CNT_SETTLE_DLANE(i)); + } + + val = readl(csi2->base + CSI2_REG_CSI_RX_CONFIG); + val |= CSI2_CSI_RX_CONFIG_DISABLE_BYTE_CLK_GATING | + CSI2_CSI_RX_CONFIG_RELEASE_LP11; + writel(val, csi2->base + CSI2_REG_CSI_RX_CONFIG); + + writel(nlanes, csi2->base + CSI2_REG_CSI_RX_NOF_ENABLED_LANES); + writel(CSI2_CSI_RX_ENABLE_ENABLE, + csi2->base + CSI2_REG_CSI_RX_ENABLE); + +#ifdef IPU_VC_SUPPORT + /* SOF/EOF of VC0-VC3 enabled from CSI2PART register in B0 */ + for (i = 0; i < NR_OF_CSI2_VC; i++) + csi2part |= CSI2_IRQ_FS_VC(i) | CSI2_IRQ_FE_VC(i); +#else + /* SOF/EOF enabled from CSI2PART register in B0 */ + csi2part |= CSI2_IRQ_FS_VC | CSI2_IRQ_FE_VC; +#endif + + /* Enable csi2 receiver error interrupts */ + csi2csirx = BIT(CSI2_CSIRX_NUM_ERRORS) - 1; + writel(csi2csirx, csi2->base + CSI2_REG_CSIRX_IRQ_EDGE); + writel(0, csi2->base + CSI2_REG_CSIRX_IRQ_LEVEL_NOT_PULSE); + writel(csi2csirx, csi2->base + CSI2_REG_CSIRX_IRQ_CLEAR); + writel(csi2csirx, csi2->base + CSI2_REG_CSIRX_IRQ_MASK); + writel(csi2csirx, csi2->base + CSI2_REG_CSIRX_IRQ_ENABLE); + + /* Enable csi2 error and SOF-related irqs */ + writel(csi2part, csi2->base + CSI2_REG_CSI2PART_IRQ_EDGE); + writel(0, csi2->base + CSI2_REG_CSI2PART_IRQ_LEVEL_NOT_PULSE); + writel(csi2part, csi2->base + CSI2_REG_CSI2PART_IRQ_CLEAR); + writel(csi2part, csi2->base + CSI2_REG_CSI2PART_IRQ_MASK); + writel(csi2part, csi2->base + CSI2_REG_CSI2PART_IRQ_ENABLE); + if (ip->interlaced) { + writel(CSI2_RX_SYNC_COUNTER_EXTERNAL, + csi2->base + CSI2_REG_CSI_RX_SYNC_COUNTER_SEL); + rval = ipu_isys_csi2_configure_tunit(csi2, 1); + if (rval) + return rval; + } + + return 0; +} + +void ipu_isys_csi2_isr(struct ipu_isys_csi2 *csi2) +{ + u32 status = readl(csi2->base + CSI2_REG_CSI2PART_IRQ_STATUS); + unsigned int i; + + writel(status, csi2->base + CSI2_REG_CSI2PART_IRQ_CLEAR); + + if (status & CSI2_CSI2PART_IRQ_CSIRX) + ipu_isys_register_errors(csi2); + +#ifdef IPU_VC_SUPPORT + for (i = 0; i < NR_OF_CSI2_VC; i++) { + if ((status & CSI2_IRQ_FS_VC(i))) + ipu_isys_csi2_sof_event(csi2, i); + + if ((status & CSI2_IRQ_FE_VC(i))) + ipu_isys_csi2_eof_event(csi2, i); + } +#else + if (status & CSI2_IRQ_FS_VC) + ipu_isys_csi2_sof_event(csi2); + if (status & CSI2_IRQ_FE_VC) + ipu_isys_csi2_eof_event(csi2); +#endif +} + +static u64 tsc_time_to_tunit_time(struct ipu_isys *isys, + u64 tsc_base, u64 tunit_base, u64 tsc_time) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(isys->adev->iommu); + u64 isys_clk = IS_FREQ_SOURCE / adev->ctrl->divisor / 100000; + u64 tsc_clk = IPU_BUTTRESS_TSC_CLK / 100000; + + tsc_time *= isys_clk; + tsc_base *= isys_clk; + do_div(tsc_time, tsc_clk); + do_div(tsc_base, tsc_clk); + + return tunit_base + tsc_time - tsc_base; +} + +/* Extract the timestamp from trace message. + * The timestamp in the traces message contains two parts. + * The lower part contains bit0 ~ 15 of the total 64bit timestamp. + * The higher part contains bit14 ~ 63 of the 64bit timestamp. + * These two parts are sampled at different time. + * Two overlaped bits are used to identify if there's roll overs + * in the lower part during the two samples. + * If the two overlapped bits do not match, a fix is needed to + * handle the roll over. + */ +static u64 +extract_time_from_short_packet_msg(struct ipu_isys_csi2_monitor_message *msg) +{ + u64 time_h = msg->timestamp_h << 14; + u64 time_l = msg->timestamp_l; + u64 time_h_ovl = time_h & 0xc000; + u64 time_h_h = time_h & (~0xffff); + + /* Fix possible roll overs. */ + if (time_h_ovl >= (time_l & 0xc000)) + return time_h_h | time_l; + else + return (time_h_h - 0x10000) | time_l; +} + +unsigned int +ipu_isys_csi2_get_current_field(struct ipu_isys_pipeline *ip, + unsigned int *timestamp) +{ + struct ipu_isys_video *av = container_of(ip, struct ipu_isys_video, ip); + struct ipu_isys *isys = av->isys; + unsigned int field = V4L2_FIELD_TOP; + + /* + * Find the nearest message that has matched msg type, + * port id, virtual channel and packet type. + */ + unsigned int i = ip->short_packet_trace_index; + bool msg_matched = false; + unsigned int monitor_id; + + update_timer_base(isys); + + if (ip->csi2->index >= IPU_ISYS_MAX_CSI2_LEGACY_PORTS) + monitor_id = TRACE_REG_CSI2_3PH_TM_MONITOR_ID; + else + monitor_id = TRACE_REG_CSI2_TM_MONITOR_ID; + + dma_sync_single_for_cpu(&isys->adev->dev, + isys->short_packet_trace_buffer_dma_addr, + IPU_ISYS_SHORT_PACKET_TRACE_BUFFER_SIZE, + DMA_BIDIRECTIONAL); + + do { + struct ipu_isys_csi2_monitor_message msg = + isys->short_packet_trace_buffer[i]; + u64 sof_time = tsc_time_to_tunit_time(isys, + isys->tsc_timer_base, + isys->tunit_timer_base, + (((u64) timestamp[1]) << + 32) | timestamp[0]); + u64 trace_time = extract_time_from_short_packet_msg(&msg); + u64 delta_time_us = tunit_time_to_us(isys, + (sof_time > trace_time) ? + sof_time - trace_time : + trace_time - sof_time); + + i = (i + 1) % IPU_ISYS_SHORT_PACKET_TRACE_MSG_NUMBER; + + if (msg.cmd == TRACE_REG_CMD_TYPE_D64MTS && + msg.monitor_id == monitor_id && + msg.fs == 1 && + msg.port == ip->csi2->index && +#ifdef IPU_VC_SUPPORT + msg.vc == ip->vc && +#endif + delta_time_us < IPU_ISYS_SHORT_PACKET_TRACE_MAX_TIMESHIFT) { + field = (msg.sequence % 2) ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; + ip->short_packet_trace_index = i; + msg_matched = true; + dev_dbg(&isys->adev->dev, + "Interlaced field ready. field = %d\n", field); + break; + } + } while (i != ip->short_packet_trace_index); + if (!msg_matched) + /* We have walked through the whole buffer. */ + dev_dbg(&isys->adev->dev, "No matched trace message found.\n"); + + return field; +} + +bool ipu_isys_csi2_skew_cal_required(struct ipu_isys_csi2 *csi2) +{ + __s64 link_freq; + int rval; + + if (!csi2) + return false; + + /* Not yet ? */ + if (csi2->remote_streams != csi2->stream_count) + return false; + + rval = ipu_isys_csi2_get_link_freq(csi2, &link_freq); + if (rval) + return false; + + if (link_freq <= IPU_SKEW_CAL_LIMIT_HZ) + return false; + + return true; +} + +int ipu_isys_csi2_set_skew_cal(struct ipu_isys_csi2 *csi2, int enable) +{ + u32 val; + + val = readl(csi2->base + CSI2_REG_CSI_RX_CONFIG); + + if (enable) + val |= CSI2_CSI_RX_CONFIG_SKEWCAL_ENABLE; + else + val &= ~CSI2_CSI_RX_CONFIG_SKEWCAL_ENABLE; + + writel(val, csi2->base + CSI2_REG_CSI_RX_CONFIG); + + return 0; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-isys-isa.c b/drivers/media/pci/intel/ipu4/ipu4-isys-isa.c new file mode 100644 index 0000000000000..a9652b66c1ae0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-isys-isa.c @@ -0,0 +1,1027 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2014 - 2018 Intel Corporation + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "ipu.h" +#include "ipu-bus.h" +#include "ipu-isys.h" +#include "ipu4-isys-isa.h" +#include "ipu-isys-subdev.h" +#include "ipu-isys-video.h" + +static const u32 isa_supported_codes_pad_sink[] = { + MEDIA_BUS_FMT_SBGGR14_1X14, + MEDIA_BUS_FMT_SGBRG14_1X14, + MEDIA_BUS_FMT_SGRBG14_1X14, + MEDIA_BUS_FMT_SRGGB14_1X14, + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + 0, +}; + +/* Regardless of the input mode ISA always produces 16 bit output */ +static const u32 isa_supported_codes_pad_source[] = { + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, + 0, +}; + +/* ISA configuration */ +struct ipu_isys_pixelformat isa_config_pfmts[] = { + {V4L2_FMT_IPU_ISA_CFG, 8, 8, 0, MEDIA_BUS_FMT_FIXED, 0}, + {}, +}; + +static const u32 isa_supported_codes_pad_cfg[] = { + MEDIA_BUS_FMT_FIXED, + 0, +}; + +static const u32 isa_supported_codes_pad_3a[] = { + MEDIA_BUS_FMT_FIXED, + 0, +}; + +static const u32 isa_supported_codes_pad_source_scaled[] = { + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_YUYV12_1X24, + 0, +}; + +static const u32 *isa_supported_codes[] = { + isa_supported_codes_pad_sink, + isa_supported_codes_pad_source, + isa_supported_codes_pad_cfg, + isa_supported_codes_pad_3a, + isa_supported_codes_pad_source_scaled, +}; + +static struct v4l2_subdev_internal_ops isa_sd_internal_ops = { + .open = ipu_isys_subdev_open, + .close = ipu_isys_subdev_close, +}; + +static int isa_config_vidioc_g_fmt_vid_out_mplane(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct ipu_isys_video *av = video_drvdata(file); + + fmt->fmt.pix_mp = av->mpix; + + return 0; +} + +static const struct ipu_isys_pixelformat * +isa_config_try_fmt_vid_out_mplane(struct ipu_isys_video *av, + struct v4l2_pix_format_mplane *mpix) +{ + const struct ipu_isys_pixelformat *pfmt = + ipu_isys_get_pixelformat(av, mpix->pixelformat); + + if (!pfmt) + return NULL; + mpix->pixelformat = pfmt->pixelformat; + mpix->num_planes = ISA_CFG_BUF_PLANES; + + mpix->plane_fmt[ISA_CFG_BUF_PLANE_PG].bytesperline = 0; + mpix->plane_fmt[ISA_CFG_BUF_PLANE_PG].sizeimage = + ALIGN(max_t(u32, sizeof(struct ia_css_process_group_light), + mpix->plane_fmt[ISA_CFG_BUF_PLANE_PG].sizeimage), + av->isys->line_align); + + mpix->plane_fmt[ISA_CFG_BUF_PLANE_DATA].bytesperline = 0; + mpix->plane_fmt[ISA_CFG_BUF_PLANE_DATA].sizeimage = + ALIGN(max(1U, + mpix->plane_fmt[ISA_CFG_BUF_PLANE_DATA].sizeimage), + av->isys->line_align); + + return pfmt; +} + +static int isa_config_vidioc_s_fmt_vid_out_mplane(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct ipu_isys_video *av = video_drvdata(file); + + if (av->aq.vbq.streaming) + return -EBUSY; + + av->pfmt = isa_config_try_fmt_vid_out_mplane(av, &f->fmt.pix_mp); + av->mpix = f->fmt.pix_mp; + + return 0; +} + +static int isa_config_vidioc_try_fmt_vid_out_mplane(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct ipu_isys_video *av = video_drvdata(file); + + isa_config_try_fmt_vid_out_mplane(av, &f->fmt.pix_mp); + return 0; +} + +static const struct v4l2_ioctl_ops isa_config_ioctl_ops = { + .vidioc_querycap = ipu_isys_vidioc_querycap, + .vidioc_enum_fmt_vid_cap = ipu_isys_vidioc_enum_fmt, + .vidioc_g_fmt_vid_out_mplane = isa_config_vidioc_g_fmt_vid_out_mplane, + .vidioc_s_fmt_vid_out_mplane = isa_config_vidioc_s_fmt_vid_out_mplane, + .vidioc_try_fmt_vid_out_mplane = + isa_config_vidioc_try_fmt_vid_out_mplane, + .vidioc_g_fmt_vid_cap_mplane = isa_config_vidioc_g_fmt_vid_out_mplane, + .vidioc_s_fmt_vid_cap_mplane = isa_config_vidioc_s_fmt_vid_out_mplane, + .vidioc_try_fmt_vid_cap_mplane = + isa_config_vidioc_try_fmt_vid_out_mplane, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_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 v4l2_subdev_core_ops isa_sd_core_ops = { + .subscribe_event = v4l2_ctrl_subdev_subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, +}; + +static int set_stream(struct v4l2_subdev *sd, int enable) +{ + struct ipu_isys_isa *isa = to_ipu_isys_isa(sd); + unsigned int i; + + if (enable) + return 0; + + for (i = 0; i < ISA_CFG_BUF_PLANES; i++) + isa->next_param[i] = NULL; + + return 0; +} + +static const struct v4l2_subdev_video_ops isa_sd_video_ops = { + .s_stream = set_stream, +}; + +static const struct v4l2_subdev_pad_ops isa_sd_pad_ops = { + .link_validate = ipu_isys_subdev_link_validate, + .get_fmt = ipu_isys_subdev_get_ffmt, + .set_fmt = ipu_isys_subdev_set_ffmt, + .get_selection = ipu_isys_subdev_get_sel, + .set_selection = ipu_isys_subdev_set_sel, + .enum_mbus_code = ipu_isys_subdev_enum_mbus_code, +}; + +static struct v4l2_subdev_ops isa_sd_ops = { + .core = &isa_sd_core_ops, + .video = &isa_sd_video_ops, + .pad = &isa_sd_pad_ops, +}; + +static int isa_link_validate(struct media_link *link) +{ + struct ipu_isys_pipeline *ip; + struct media_pipeline *pipe; + + /* Non-video node source */ + if (is_media_entity_v4l2_subdev(link->source->entity)) + return v4l2_subdev_link_validate(link); + + pipe = media_entity_pipeline(link->sink->entity); + ip = to_ipu_isys_pipeline(pipe); + ip->nr_queues++; + + return 0; +} + +static struct media_entity_operations isa_entity_ops = { + .link_validate = isa_link_validate, +}; + +void ipu_isys_isa_cleanup(struct ipu_isys_isa *isa) +{ + if (!isa->asd.sd.v4l2_dev) + return; + + v4l2_device_unregister_subdev(&isa->asd.sd); + ipu_isys_subdev_cleanup(&isa->asd); + ipu_isys_video_cleanup(&isa->av_scaled); + ipu_isys_video_cleanup(&isa->av_config); + ipu_isys_video_cleanup(&isa->av_3a); + ipu_isys_video_cleanup(&isa->av); +} + +static void isa_set_ffmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *cfg, + struct v4l2_subdev_format *fmt) +{ + struct v4l2_mbus_framefmt *ffmt = +#ifdef IPU_VC_SUPPORT + __ipu_isys_get_ffmt(sd, cfg, fmt->pad, fmt->stream, + fmt->which); +#else + __ipu_isys_get_ffmt(sd, cfg, fmt->pad, fmt->which); +#endif + enum ipu_isys_subdev_pixelorder order; + enum isys_subdev_prop_tgt tgt; + + switch (fmt->pad) { + case ISA_PAD_SINK: + fmt->format.field = V4L2_FIELD_NONE; + *ffmt = fmt->format; + tgt = IPU_ISYS_SUBDEV_PROP_TGT_SINK_FMT; + ipu_isys_subdev_fmt_propagate(sd, cfg, &fmt->format, + NULL, tgt, fmt->pad, fmt->which); + return; + case ISA_PAD_SOURCE: { + struct v4l2_mbus_framefmt *sink_ffmt = +#ifdef IPU_VC_SUPPORT + __ipu_isys_get_ffmt(sd, cfg, ISA_PAD_SINK, + fmt->stream, fmt->which); +#else + __ipu_isys_get_ffmt(sd, cfg, ISA_PAD_SINK, fmt->which); +#endif + struct v4l2_rect *r = + __ipu_isys_get_selection(sd, cfg, + V4L2_SEL_TGT_CROP, + ISA_PAD_SOURCE, + fmt->which); + + ffmt->width = r->width; + ffmt->height = r->height; + ffmt->field = sink_ffmt->field; + order = ipu_isys_subdev_get_pixelorder(sink_ffmt->code); + ffmt->code = isa_supported_codes_pad_source[order]; + return; + } + case ISA_PAD_CONFIG: + case ISA_PAD_3A: + ffmt->code = MEDIA_BUS_FMT_FIXED; + ffmt->width = 0; + ffmt->height = 0; + fmt->format = *ffmt; + return; + case ISA_PAD_SOURCE_SCALED: { + struct v4l2_mbus_framefmt *sink_ffmt = +#ifdef IPU_VC_SUPPORT + __ipu_isys_get_ffmt(sd, cfg, ISA_PAD_SINK, + fmt->stream, fmt->which); +#else + __ipu_isys_get_ffmt(sd, cfg, ISA_PAD_SINK, fmt->which); +#endif + struct v4l2_rect *r = + __ipu_isys_get_selection(sd, cfg, + V4L2_SEL_TGT_CROP, + ISA_PAD_SOURCE_SCALED, + fmt->which); + + ffmt->width = r->width; + ffmt->height = r->height; + ffmt->field = sink_ffmt->field; + order = ipu_isys_subdev_get_pixelorder(sink_ffmt->code); + ffmt->code = + isa_supported_codes_pad_source_scaled[order]; + if (fmt->format.code == MEDIA_BUS_FMT_YUYV12_1X24) + ffmt->code = MEDIA_BUS_FMT_YUYV12_1X24; + + return; + } + default: + WARN_ON(1); + } +} + +static int isa_s_ctrl(struct v4l2_ctrl *ctrl) +{ + return 0; +} + +static const struct v4l2_ctrl_ops isa_ctrl_ops = { + .s_ctrl = isa_s_ctrl, +}; + +static void isa_capture_done(struct ipu_isys_pipeline *ip, + struct ipu_fw_isys_resp_info_abi *info) +{ + struct ipu_isys_isa *isa = &ip->isys->isa; + struct ipu_isys_queue *aq = &isa->av_config.aq; + struct ipu_isys_buffer *ib; + unsigned long flags; + + if (WARN_ON_ONCE(list_empty(&aq->active))) + return; + + spin_lock_irqsave(&aq->lock, flags); + ib = list_last_entry(&aq->active, struct ipu_isys_buffer, head); + list_del(&ib->head); + dev_dbg(&ip->isys->adev->dev, "isa cfg: dequeued buffer %p", ib); + spin_unlock_irqrestore(&aq->lock, flags); + + ipu_isys_buf_calc_sequence_time(ib, info); + ipu_isys_queue_buf_done(ib); + + aq = &isa->av_3a.aq; + + if (media_entity_pipeline(&isa->av_3a.vdev.entity) != media_entity_pipeline(&isa->av_config.vdev.entity)) { + dev_dbg(&ip->isys->adev->dev, "3a disabled\n"); + return; + } + + if (WARN_ON_ONCE(list_empty(&aq->active))) + return; + + spin_lock_irqsave(&aq->lock, flags); + ib = list_last_entry(&aq->active, struct ipu_isys_buffer, head); + list_del(&ib->head); + dev_dbg(&ip->isys->adev->dev, "isa 3a: dequeued buffer %p", ib); + spin_unlock_irqrestore(&aq->lock, flags); + + ipu_isys_buf_calc_sequence_time(ib, info); + ipu_isys_queue_buf_done(ib); +} + +/* Maximum size of the buffer-specific process group. */ +#define PGL_SIZE PAGE_SIZE + +static int isa_3a_buf_init(struct vb2_buffer *vb) +{ + struct ipu_isys_isa_buffer *isa_buf = + vb2_buffer_to_ipu_isys_isa_buffer(vb); + + isa_buf->pgl.pg = kzalloc(PGL_SIZE, GFP_KERNEL); + if (!isa_buf->pgl.pg) + return -ENOMEM; + + return 0; +} + +static void isa_3a_buf_cleanup(struct vb2_buffer *vb) +{ + struct ipu_isys_isa_buffer *isa_buf = + vb2_buffer_to_ipu_isys_isa_buffer(vb); + + kfree(isa_buf->pgl.pg); +} + +static int isa_config_buf_init(struct vb2_buffer *vb) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct ipu_isys_isa_buffer *isa_buf = + vb2_buffer_to_ipu_isys_isa_buffer(vb); + unsigned long attrs; + int rval; + + rval = isa_3a_buf_init(vb); + if (rval) + return rval; + + isa_buf->pgl.common_pg = + dma_alloc_attrs(&av->isys->adev->dev, PGL_SIZE << 1, + &isa_buf->pgl.iova, GFP_KERNEL | __GFP_ZERO, + attrs + ); + + dev_dbg(&av->isys->adev->dev, + "buf_init: index %u, cpu addr %p, dma addr %pad\n", + vb->index, + isa_buf->pgl.common_pg, &isa_buf->pgl.iova); + + if (!isa_buf->pgl.common_pg) { + isa_3a_buf_cleanup(vb); + return -ENOMEM; + } + + return 0; +} + +static void isa_config_buf_cleanup(struct vb2_buffer *vb) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct ipu_isys_isa_buffer *isa_buf = + vb2_buffer_to_ipu_isys_isa_buffer(vb); + unsigned long attrs; + + dev_dbg(&av->isys->adev->dev, + "buf_cleanup: index %u, cpu addr %p, dma addr %pad\n", + vb->index, + isa_buf->pgl.pg, &isa_buf->pgl.iova); + if (!isa_buf->pgl.pg) + return; + + dma_free_attrs(&av->isys->adev->dev, PGL_SIZE << 1, + isa_buf->pgl.common_pg, isa_buf->pgl.iova, + attrs + ); + + isa_3a_buf_cleanup(vb); +} + +static void +isa_prepare_firmware_stream_cfg(struct ipu_isys_video *av, + struct ipu_fw_isys_stream_cfg_data_abi *cfg) +{ + struct v4l2_rect *r; + unsigned int pad, cropping_location, res_info; + + if (av == &av->isys->isa.av) { + pad = ISA_PAD_SOURCE; + cropping_location = + IPU_FW_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED; + res_info = IPU_FW_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED; + } else if (av == &av->isys->isa.av_scaled) { + pad = ISA_PAD_SOURCE_SCALED; + cropping_location = + IPU_FW_ISYS_CROPPING_LOCATION_POST_ISA_SCALED; + res_info = IPU_FW_ISYS_RESOLUTION_INFO_POST_ISA_SCALED; + } else { + WARN_ON(1); + return; + } + + r = __ipu_isys_get_selection(&av->isys->isa.asd.sd, NULL, + V4L2_SEL_TGT_CROP, pad, + V4L2_SUBDEV_FORMAT_ACTIVE); + + cfg->crop[cropping_location].top_offset = r->top; + cfg->crop[cropping_location].left_offset = r->left; + cfg->crop[cropping_location].bottom_offset = r->top + r->height; + cfg->crop[cropping_location].right_offset = r->left + r->width; + + r = __ipu_isys_get_selection(&av->isys->isa.asd.sd, NULL, + V4L2_SEL_TGT_COMPOSE, pad, + V4L2_SUBDEV_FORMAT_ACTIVE); + + cfg->isa_cfg.isa_res[res_info].height = r->height; + cfg->isa_cfg.isa_res[res_info].width = r->width; + ipu_isys_prepare_firmware_stream_cfg_default(av, cfg); +} + +static void +isa_prepare_firmware_stream_cfg_param(struct ipu_isys_video *av, + struct ipu_fw_isys_stream_cfg_data_abi + *cfg) +{ + struct ipu_isys_isa *isa = &av->isys->isa; + struct ipu_isys_pipeline *ip = + to_ipu_isys_pipeline(media_entity_pipeline(&av->vdev.entity)); + + cfg->isa_cfg.cfg.blc = !!(isa->isa_en->val & V4L2_IPU_ISA_EN_BLC); + cfg->isa_cfg.cfg.lsc = !!(isa->isa_en->val & V4L2_IPU_ISA_EN_LSC); + cfg->isa_cfg.cfg.dpc = !!(isa->isa_en->val & V4L2_IPU_ISA_EN_DPC); + cfg->isa_cfg.cfg.downscaler = + !!(isa->isa_en->val & V4L2_IPU_ISA_EN_SCALER); + cfg->isa_cfg.cfg.awb = !!(isa->isa_en->val & V4L2_IPU_ISA_EN_AWB); + cfg->isa_cfg.cfg.af = !!(isa->isa_en->val & V4L2_IPU_ISA_EN_AF); + cfg->isa_cfg.cfg.ae = !!(isa->isa_en->val & V4L2_IPU_ISA_EN_AE); + + cfg->isa_cfg.cfg.send_irq_stats_ready = 1; + cfg->isa_cfg.cfg.send_resp_stats_ready = 1; + ipu_isys_video_add_capture_done(ip, isa_capture_done); +} + +static bool is_capture_terminal(struct ia_css_terminal *t) +{ + switch (t->terminal_type) { + case IPU_FW_TERMINAL_TYPE_PARAM_CACHED_OUT: + case IPU_FW_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + case IPU_FW_TERMINAL_TYPE_PARAM_SLICED_OUT: + return true; + default: + return false; + } +} + +/* Return the pointer to the terminal payload's IOVA. */ +static int isa_terminal_get_iova(struct device *dev, struct ia_css_terminal *t, + u32 **iova) +{ + switch (t->terminal_type) { + case IPU_FW_TERMINAL_TYPE_PARAM_CACHED_IN: + case IPU_FW_TERMINAL_TYPE_PARAM_CACHED_OUT:{ + struct ia_css_param_terminal *tpterm = (void *)t; + + *iova = &tpterm->param_payload.buffer; + break; + } + case IPU_FW_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IPU_FW_TERMINAL_TYPE_PARAM_SPATIAL_OUT:{ + struct ia_css_spatial_param_terminal *tpterm = + (void *)t; + + *iova = &tpterm->param_payload.buffer; + break; + } + case IPU_FW_TERMINAL_TYPE_PARAM_SLICED_IN: + case IPU_FW_TERMINAL_TYPE_PARAM_SLICED_OUT:{ + struct ia_css_sliced_param_terminal *tpterm = (void *)t; + + *iova = &tpterm->param_payload.buffer; + break; + } + case IPU_FW_TERMINAL_TYPE_PROGRAM:{ + struct ia_css_program_terminal *tpterm = (void *)t; + + *iova = &tpterm->param_payload.buffer; + break; + } + default: + dev_dbg(dev, "unhandled terminal type %u\n", t->terminal_type); + return -EINVAL; + } + + return 0; +} + +/* + * Validate a process group, and add the IOVA of the data plane to the + * offsets related to the start of the data plane. + */ +static int isa_import_pg(struct vb2_buffer *vb) +{ + void *__pg = vb2_plane_vaddr(vb, ISA_CFG_BUF_PLANE_PG); + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct ipu_isys_isa_buffer *isa_buf = + vb2_buffer_to_ipu_isys_isa_buffer(vb); + struct ia_css_process_group_light *pg = isa_buf->pgl.pg; + bool capture = aq->vbq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + u32 addr = vb2_dma_contig_plane_dma_addr(vb, + ISA_CFG_BUF_PLANE_DATA); + unsigned int i; + + if (!__pg) { + dev_warn(&av->isys->adev->dev, + "virtual mapping of the buffer failed\n"); + return -EINVAL; + } + + if (vb2_plane_size(vb, ISA_CFG_BUF_PLANE_PG) > PGL_SIZE) { + dev_dbg(&av->isys->adev->dev, + "too large process group, max %lu\n", PGL_SIZE); + return -EINVAL; + } + + /* + * Copy the light process group to a kernel buffer so that it + * cannot be modified by the user space. + */ + memcpy(pg, __pg, vb2_plane_size(vb, ISA_CFG_BUF_PLANE_PG)); + + if (pg->size > vb2_plane_size(vb, ISA_CFG_BUF_PLANE_PG)) { + dev_dbg(&av->isys->adev->dev, + "process group size too large (%u bytes, %lu bytes available)\n", + pg->size, vb2_plane_size(vb, ISA_CFG_BUF_PLANE_PG)); + return -EINVAL; + } + + if (!pg->terminal_count) { + dev_dbg(&av->isys->adev->dev, "no terminals defined\n"); + return -EINVAL; + } + + if ((void *)(ia_css_terminal_offsets(pg) + + pg->terminal_count * sizeof(uint16_t)) - (void *)pg + > pg->size) { + dev_dbg(&av->isys->adev->dev, + "terminal offsets do not fit in the buffer\n"); + return -EINVAL; + } + + for (i = 0; i < pg->terminal_count; i++) { + struct ia_css_terminal *t = to_ia_css_terminal(pg, i); + u32 *iova; + int rval; + + if ((void *)t + sizeof(*t) - (void *)pg > pg->size) { + dev_dbg(&av->isys->adev->dev, + "terminal %u does not fit in the buffer\n", i); + return -EINVAL; + } + + dev_dbg(&av->isys->adev->dev, + "terminal: terminal %u, size %u, capture %u / %u\n", + i, t->size, capture, is_capture_terminal(t)); + + if (capture != is_capture_terminal(t)) + continue; + + dev_dbg(&av->isys->adev->dev, "terminal: %u offset %u\n", i, + ia_css_terminal_offsets(pg)[i]); + + rval = isa_terminal_get_iova(&av->isys->adev->dev, t, &iova); + if (rval) + return rval; + + dev_dbg(&av->isys->adev->dev, + "terminal: offset 0x%x, address 0x%8.8x\n", + *iova, (u32) addr + *iova); + + if (addr + *iova < addr) { + dev_dbg(&av->isys->adev->dev, + "address space overflow\n"); + return -EINVAL; + } + + if (*iova > vb2_plane_size(vb, ISA_CFG_BUF_PLANE_DATA)) { + dev_dbg(&av->isys->adev->dev, + "offset outside the buffer\n"); + return -EINVAL; + } + + /* + * Add the IOVA of the data plane to the terminal + * payload's offset. + */ + *iova += addr; + } + + return 0; +} + +static int isa_terminal_buf_prepare(struct vb2_buffer *vb) +{ + struct ipu_isys_queue *aq = vb2_queue_to_ipu_isys_queue(vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + unsigned int i; + + for (i = 0; i < ISA_CFG_BUF_PLANES; i++) { + vb2_set_plane_payload(vb, i, av->mpix.plane_fmt[i].sizeimage); + vb->planes[i].data_offset = 0; + } + + return isa_import_pg(vb); +} + +/* + * Count relevant terminals in a light process group and add the + * number of found to the common light process group. + */ +static void +isa_config_count_valid_terminals(struct device *dev, + struct ia_css_process_group_light *cpg, + struct ia_css_process_group_light *pg, + bool capture) +{ + unsigned int i; + + for (i = 0; i < pg->terminal_count; i++) + if (capture == is_capture_terminal(to_ia_css_terminal(pg, i))) + cpg->terminal_count++; +} + +static void +isa_config_prepare_frame_buff_set_one(struct device *dev, + struct ia_css_process_group_light *cpg, + struct ia_css_process_group_light *pg, + dma_addr_t addr, bool capture, + unsigned int *terminal_count) +{ + unsigned int i; + + dev_dbg(dev, "terminal: size %u, count %u, offset %u\n", + pg->size, pg->terminal_count, pg->terminals_offset_offset); + + dev_dbg(dev, "terminal: copying %u terminal offsets to %p from %p\n", + pg->terminal_count, ia_css_terminal_offsets(cpg), + ia_css_terminal_offsets(pg)); + + for (i = 0; i < pg->terminal_count; i++) { + struct ia_css_terminal *t = to_ia_css_terminal(pg, i), *ct; + + dev_dbg(dev, + "terminal: parsing %u, size %u, capture %u / %u\n", + i, t->size, capture, is_capture_terminal(t)); + + if (capture != is_capture_terminal(t)) + continue; + + ia_css_terminal_offsets(cpg)[*terminal_count] = + ia_css_terminal_offset(cpg, *terminal_count); + + dev_dbg(dev, "terminal: %u offset %u\n", *terminal_count, + ia_css_terminal_offsets(cpg)[*terminal_count]); + + ct = to_ia_css_terminal(cpg, *terminal_count); + + dev_dbg(dev, + "terminal: copying terminal %p to %p (%u bytes)\n", + t, ct, t->size); + memcpy(ct, t, t->size); + + (*terminal_count)++; + } +} + +/* + * Move the terminals from a read-only or write-only light process + * group to a common process group. + */ +static void isa_config_prepare_frame_buff_set(struct vb2_buffer *__vb) +{ + struct ipu_isys_queue *aq = + vb2_queue_to_ipu_isys_queue(__vb->vb2_queue); + struct ipu_isys_video *av = ipu_isys_queue_to_video(aq); + struct ipu_isys_isa *isa = &av->isys->isa; + struct vb2_buffer *vb[ISA_PARAM_QUEUES]; + struct ia_css_process_group_light *pg[ISA_PARAM_QUEUES]; + dma_addr_t addr[ISA_PARAM_QUEUES]; + struct ia_css_process_group_light *cpg; + struct ipu_isys_isa_buffer *__isa_buf; + unsigned int terminal_count = 0, i; + bool capture = &av->isys->isa.av_3a.aq == aq; + + dev_dbg(&av->isys->adev->dev, "%s: capture %u\n", av->vdev.name, + capture); + + isa->next_param[capture] = __vb; + + /* Proceed only when both cfg and stats buffers are available. */ + if (!isa->next_param[!capture]) + return; + + /* Obtain common process group light buffer from config buffer */ + __isa_buf = vb2_buffer_to_ipu_isys_isa_buffer( + isa->next_param[ISA_CFG_BUF_PLANE_PG]); + + for (i = 0; i < ISA_PARAM_QUEUES; i++) { + struct ipu_isys_isa_buffer *isa_buf; + + vb[i] = isa->next_param[i]; + isa_buf = vb2_buffer_to_ipu_isys_isa_buffer(vb[i]); + pg[i] = isa_buf->pgl.pg; + addr[i] = vb2_dma_contig_plane_dma_addr(vb[i], + ISA_CFG_BUF_PLANE_DATA); + + dma_sync_single_for_device(&av->isys->adev->dev, + addr[i], vb2_plane_size(vb[i], + ISA_CFG_BUF_PLANE_DATA), + DMA_TO_DEVICE); + + dev_dbg(&av->isys->adev->dev, + "terminal: queue %u, plane 0: vaddr %p, dma_addr %pad program group size %u program group terminals %u\n", + i, pg[i], &addr[i], pg[i]->size, pg[i]->terminal_count); + } + + cpg = __isa_buf->pgl.common_pg; + cpg->terminal_count = 0; + cpg->terminals_offset_offset = sizeof(*cpg); + + if (cpg->size > PGL_SIZE << 1) { + dev_err(&av->isys->adev->dev, + "not enough room for terms, %lu found, %u needed\n", + PGL_SIZE << 1, cpg->size); + return; + } + + for (i = 0; i < ISA_PARAM_QUEUES; i++) + isa_config_count_valid_terminals(&av->isys->adev->dev, + cpg, pg[i], i); + + for (i = 0; i < ISA_PARAM_QUEUES; i++) { + isa_config_prepare_frame_buff_set_one(&av->isys->adev->dev, cpg, + pg[i], addr[i], i, + &terminal_count); + + isa->next_param[i] = NULL; + } + + cpg->size = ia_css_terminal_offset(cpg, cpg->terminal_count); + + dev_dbg(&av->isys->adev->dev, "common pg size 0x%x count %d\n", + cpg->size, cpg->terminal_count); + + dma_sync_single_for_device(&av->isys->adev->dev, __isa_buf->pgl.iova, + PGL_SIZE << 1, DMA_TO_DEVICE); +} + +static void +isa_config_fill_frame_buff_set_pin(struct vb2_buffer *vb, + struct ipu_fw_isys_frame_buff_set_abi *set) +{ + struct ipu_isys_isa_buffer *isa_buf = + vb2_buffer_to_ipu_isys_isa_buffer(vb); + + set->process_group_light.addr = isa_buf->pgl.iova; + set->process_group_light.param_buf_id = vb->index + 1; +} + +static void isa_ctrl_init(struct v4l2_subdev *sd) +{ + struct ipu_isys_isa *isa = to_ipu_isys_isa(sd); + static const struct v4l2_ctrl_config cfg = { + .ops = &isa_ctrl_ops, + .id = V4L2_CID_IPU_ISA_EN, + .name = "ISA enable", + .type = V4L2_CTRL_TYPE_BITMASK, + .max = V4L2_IPU_ISA_EN_BLC + | V4L2_IPU_ISA_EN_LSC + | V4L2_IPU_ISA_EN_DPC + | V4L2_IPU_ISA_EN_SCALER + | V4L2_IPU_ISA_EN_AWB + | V4L2_IPU_ISA_EN_AF | V4L2_IPU_ISA_EN_AE, + }; + + isa->isa_en = v4l2_ctrl_new_custom(&isa->asd.ctrl_handler, &cfg, NULL); +} + +int ipu_isys_isa_init(struct ipu_isys_isa *isa, + struct ipu_isys *isys, void __iomem *base) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = ISA_PAD_SINK, + .format = { + .width = 4096, + .height = 3072, + }, + }; + struct v4l2_subdev_format fmt_config = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = ISA_PAD_CONFIG, + }; + struct v4l2_subdev_format fmt_3a = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = ISA_PAD_3A, + }; + int rval; + + isa->base = base; + + isa->asd.sd.entity.ops = &isa_entity_ops; + isa->asd.ctrl_init = isa_ctrl_init; + isa->asd.isys = isys; + + rval = ipu_isys_subdev_init(&isa->asd, &isa_sd_ops, 1, + NR_OF_ISA_PADS, +#ifdef IPU_VC_SUPPORT + NR_OF_ISA_STREAMS, +#endif + NR_OF_ISA_SOURCE_PADS, + NR_OF_ISA_SINK_PADS, + V4L2_SUBDEV_FL_HAS_EVENTS); + if (rval) + goto fail; + + isa->asd.pad[ISA_PAD_SINK].flags = MEDIA_PAD_FL_SINK + | MEDIA_PAD_FL_MUST_CONNECT; + isa->asd.pad[ISA_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + isa->asd.valid_tgts[ISA_PAD_SOURCE].crop = true; + isa->asd.pad[ISA_PAD_CONFIG].flags = MEDIA_PAD_FL_SINK + | MEDIA_PAD_FL_MUST_CONNECT; + isa->asd.pad[ISA_PAD_3A].flags = MEDIA_PAD_FL_SOURCE; + isa->asd.pad[ISA_PAD_SOURCE_SCALED].flags = MEDIA_PAD_FL_SOURCE; + isa->asd.valid_tgts[ISA_PAD_SOURCE_SCALED].compose = true; + isa->asd.valid_tgts[ISA_PAD_SOURCE_SCALED].crop = true; + + isa->asd.isl_mode = IPU_ISL_ISA; + isa->asd.supported_codes = isa_supported_codes; + isa->asd.set_ffmt = isa_set_ffmt; + ipu_isys_subdev_set_ffmt(&isa->asd.sd, NULL, &fmt); + ipu_isys_subdev_set_ffmt(&isa->asd.sd, NULL, &fmt_config); + ipu_isys_subdev_set_ffmt(&isa->asd.sd, NULL, &fmt_3a); + + isa->asd.sd.internal_ops = &isa_sd_internal_ops; + snprintf(isa->asd.sd.name, sizeof(isa->asd.sd.name), + IPU_ISYS_ENTITY_PREFIX " ISA"); + v4l2_set_subdevdata(&isa->asd.sd, &isa->asd); + rval = v4l2_device_register_subdev(&isys->v4l2_dev, &isa->asd.sd); + if (rval) { + dev_info(&isys->adev->dev, "can't register v4l2 subdev\n"); + goto fail; + } + + snprintf(isa->av.vdev.name, sizeof(isa->av.vdev.name), + IPU_ISYS_ENTITY_PREFIX " ISA capture"); + isa->av.isys = isys; + isa->av.aq.css_pin_type = IPU_FW_ISYS_PIN_TYPE_RAW_NS; + isa->av.pfmts = ipu_isys_pfmts; + isa->av.try_fmt_vid_mplane = ipu_isys_video_try_fmt_vid_mplane_default; + isa->av.prepare_firmware_stream_cfg = isa_prepare_firmware_stream_cfg; + isa->av.aq.buf_prepare = ipu_isys_buf_prepare; + isa->av.aq.fill_frame_buff_set_pin = + ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set_pin; + isa->av.aq.link_fmt_validate = ipu_isys_link_fmt_validate; + isa->av.aq.vbq.buf_struct_size = sizeof(struct ipu_isys_video_buffer); + + rval = ipu_isys_video_init(&isa->av, &isa->asd.sd.entity, + ISA_PAD_SOURCE, MEDIA_PAD_FL_SINK, 0); + if (rval) { + dev_info(&isys->adev->dev, "can't init video node\n"); + goto fail; + } + + snprintf(isa->av_config.vdev.name, sizeof(isa->av_config.vdev.name), + IPU_ISYS_ENTITY_PREFIX " ISA config"); + isa->av_config.isys = isys; + isa->av_config.pfmts = isa_config_pfmts; + isa->av_config.try_fmt_vid_mplane = isa_config_try_fmt_vid_out_mplane; + isa->av_config.prepare_firmware_stream_cfg = + isa_prepare_firmware_stream_cfg_param; + isa->av_config.vdev.ioctl_ops = &isa_config_ioctl_ops; + isa->av_config.aq.buf_init = isa_config_buf_init; + isa->av_config.aq.buf_cleanup = isa_config_buf_cleanup; + isa->av_config.aq.buf_prepare = isa_terminal_buf_prepare; + isa->av_config.aq.prepare_frame_buff_set = + isa_config_prepare_frame_buff_set; + isa->av_config.aq.fill_frame_buff_set_pin = + isa_config_fill_frame_buff_set_pin; + isa->av_config.aq.link_fmt_validate = ipu_isys_link_fmt_validate; + isa->av_config.aq.vbq.io_modes = VB2_MMAP | VB2_DMABUF; + isa->av_config.aq.vbq.buf_struct_size = + sizeof(struct ipu_isys_isa_buffer); + + rval = ipu_isys_video_init(&isa->av_config, &isa->asd.sd.entity, + ISA_PAD_CONFIG, MEDIA_PAD_FL_SOURCE, 0); + if (rval) { + dev_info(&isys->adev->dev, "can't init video node\n"); + goto fail; + } + + snprintf(isa->av_3a.vdev.name, sizeof(isa->av_3a.vdev.name), + IPU_ISYS_ENTITY_PREFIX " ISA 3A stats"); + isa->av_3a.isys = isys; + isa->av_3a.pfmts = isa_config_pfmts; + isa->av_3a.try_fmt_vid_mplane = isa_config_try_fmt_vid_out_mplane; + isa->av_3a.prepare_firmware_stream_cfg = + isa_prepare_firmware_stream_cfg_param; + isa->av_3a.vdev.ioctl_ops = &isa_config_ioctl_ops; + isa->av_3a.aq.buf_init = isa_3a_buf_init; + isa->av_3a.aq.buf_cleanup = isa_3a_buf_cleanup; + isa->av_3a.aq.buf_prepare = isa_terminal_buf_prepare; + isa->av_3a.aq.prepare_frame_buff_set = + isa_config_prepare_frame_buff_set; + isa->av_3a.aq.link_fmt_validate = ipu_isys_link_fmt_validate; + isa->av_3a.aq.vbq.io_modes = VB2_MMAP | VB2_DMABUF; + isa->av_3a.aq.vbq.buf_struct_size = sizeof(struct ipu_isys_isa_buffer); + isa->av_3a.line_header_length = 4; /* Set to non-zero to force mplane*/ + + rval = ipu_isys_video_init(&isa->av_3a, &isa->asd.sd.entity, + ISA_PAD_3A, MEDIA_PAD_FL_SINK, 0); + if (rval) { + dev_info(&isys->adev->dev, "can't init video node\n"); + goto fail; + } + + snprintf(isa->av_scaled.vdev.name, sizeof(isa->av_scaled.vdev.name), + IPU_ISYS_ENTITY_PREFIX " ISA scaled capture"); + isa->av_scaled.isys = isys; + isa->av_scaled.aq.css_pin_type = IPU_FW_ISYS_PIN_TYPE_RAW_S; + isa->av_scaled.pfmts = isa->av.pfmts; + isa->av_scaled.try_fmt_vid_mplane = + ipu_isys_video_try_fmt_vid_mplane_default; + isa->av_scaled.prepare_firmware_stream_cfg = + isa_prepare_firmware_stream_cfg; + isa->av_scaled.aq.buf_prepare = ipu_isys_buf_prepare; + isa->av_scaled.aq.fill_frame_buff_set_pin = + ipu_isys_buffer_list_to_ipu_fw_isys_frame_buff_set_pin; + isa->av_scaled.aq.link_fmt_validate = ipu_isys_link_fmt_validate; + isa->av_scaled.aq.vbq.buf_struct_size = + sizeof(struct ipu_isys_video_buffer); + + rval = ipu_isys_video_init(&isa->av_scaled, &isa->asd.sd.entity, + ISA_PAD_SOURCE_SCALED, MEDIA_PAD_FL_SINK, 0); + if (rval) { + dev_info(&isys->adev->dev, "can't init video node\n"); + goto fail; + } + + return 0; + +fail: + ipu_isys_isa_cleanup(isa); + + return rval; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-isys-isa.h b/drivers/media/pci/intel/ipu4/ipu4-isys-isa.h new file mode 100644 index 0000000000000..649714dca2f48 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-isys-isa.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2014 - 2018 Intel Corporation */ + +#ifndef IPU_ISYS_ISA_H +#define IPU_ISYS_ISA_H + +#include +#include + +#include "ipu-isys-queue.h" +#include "ipu-isys-subdev.h" +#include "ipu-isys-video.h" + +#define ISA_PAD_SINK 0 +#define ISA_PAD_SOURCE 1 +#define ISA_PAD_CONFIG 2 +#define ISA_PAD_3A 3 +#define ISA_PAD_SOURCE_SCALED 4 + +#define NR_OF_ISA_PADS 5 +#define NR_OF_ISA_SINK_PADS 2 +#define NR_OF_ISA_SOURCE_PADS 3 +#define NR_OF_ISA_STREAMS 1 + +struct ipu_isys; +struct ia_css_process_group_light; + +/* + * struct ipu_isa_buffer + * + * @ivb: Base buffer type which provides inheritance of + * isys buffer and vb2 buffer. + * @pgl: program group light DMA buffer + * @pgl.pg: process group, copy of the buffer's plane 0 + * but not mapped to user space + * @pgl.common_pg: A combined process group from both video buffers + * @pgl.iova: IOVA of common_pg + */ +struct ipu_isys_isa_buffer { + struct ipu_isys_video_buffer ivb; + struct { + struct ia_css_process_group_light *pg; + struct ia_css_process_group_light *common_pg; + dma_addr_t iova; + } pgl; +}; + +/* ISA CFG will use multiplanar buffers */ +#define ISA_CFG_BUF_PLANE_PG 0 +#define ISA_CFG_BUF_PLANE_DATA 1 +#define ISA_CFG_BUF_PLANES 2 + +#define ISA_PARAM_QUEUES 2 + +/* + * struct ipu_isys_isa + */ +struct ipu_isys_isa { + struct ipu_isys_subdev asd; + struct ipu_isys_video av; + struct ipu_isys_video av_config; + struct ipu_isys_video av_3a; + struct ipu_isys_video av_scaled; + + void __iomem *base; + + struct v4l2_ctrl *isa_en; + + struct vb2_buffer *next_param[ISA_PARAM_QUEUES]; /* config and 3a */ +}; + +#define to_ipu_isys_isa(sd) \ + container_of(to_ipu_isys_subdev(sd), \ + struct ipu_isys_isa, asd) + +#define vb2_buffer_to_ipu_isys_isa_buffer(__vb) \ + container_of(vb2_buffer_to_ipu_isys_video_buffer(__vb), \ + struct ipu_isys_isa_buffer, ivb) + +int ipu_isys_isa_init(struct ipu_isys_isa *isa, + struct ipu_isys *isys, void __iomem *base); +void ipu_isys_isa_cleanup(struct ipu_isys_isa *isa); +void ipu_isys_isa_isr(struct ipu_isys_isa *isa); + +#endif /* IPU_ISYS_ISA_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4-isys.c b/drivers/media/pci/intel/ipu4/ipu4-isys.c new file mode 100644 index 0000000000000..514eade03b269 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-isys.c @@ -0,0 +1,400 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Intel Corporation + +#include + +#include "ipu.h" +#include "ipu-platform-regs.h" +#include "ipu-platform-buttress-regs.h" +#include "ipu-platform-isys-csi2-reg.h" +#include "ipu-trace.h" +#include "ipu-isys.h" +#include "ipu-isys-video.h" +#include "ipu-isys-tpg.h" + +struct ipu_trace_block isys_trace_blocks[] = { + { + .offset = TRACE_REG_IS_TRACE_UNIT_BASE, + .type = IPU_TRACE_BLOCK_TUN, + }, + { + .offset = TRACE_REG_IS_SP_EVQ_BASE, + .type = IPU_TRACE_BLOCK_TM, + }, + { + .offset = TRACE_REG_IS_SP_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_IS_ISL_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_IS_MMU_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_CSI2_TM_BASE, + .type = IPU_TRACE_CSI2, + }, + { + .offset = TRACE_REG_CSI2_3PH_TM_BASE, + .type = IPU_TRACE_CSI2_3PH, + }, + { + /* Note! this covers all 9 blocks */ + .offset = TRACE_REG_CSI2_SIG2SIO_GR_BASE(0), + .type = IPU_TRACE_SIG2CIOS, + }, + { + /* Note! this covers all 9 blocks */ + .offset = TRACE_REG_CSI2_PH3_SIG2SIO_GR_BASE(0), + .type = IPU_TRACE_SIG2CIOS, + }, + { + .offset = TRACE_REG_IS_GPREG_TRACE_TIMER_RST_N, + .type = IPU_TRACE_TIMER_RST, + }, + { + .type = IPU_TRACE_BLOCK_END, + } +}; + +#ifdef CONFIG_VIDEO_INTEL_IPU4 +void isys_setup_hw(struct ipu_isys *isys) +{ + void __iomem *base = isys->pdata->base; + const u8 *thd = isys->pdata->ipdata->hw_variant.cdc_fifo_threshold; + u32 irqs; + unsigned int i; + + /* Enable irqs for all MIPI busses */ + irqs = IPU_ISYS_UNISPART_IRQ_CSI2(0) | + IPU_ISYS_UNISPART_IRQ_CSI2(1) | + IPU_ISYS_UNISPART_IRQ_CSI2(2) | + IPU_ISYS_UNISPART_IRQ_CSI2(3) | + IPU_ISYS_UNISPART_IRQ_CSI2(4) | IPU_ISYS_UNISPART_IRQ_CSI2(5); + + irqs |= IPU_ISYS_UNISPART_IRQ_SW; + + writel(irqs, base + IPU_REG_ISYS_UNISPART_IRQ_EDGE); + writel(irqs, base + IPU_REG_ISYS_UNISPART_IRQ_LEVEL_NOT_PULSE); + writel(irqs, base + IPU_REG_ISYS_UNISPART_IRQ_CLEAR); + writel(irqs, base + IPU_REG_ISYS_UNISPART_IRQ_MASK); + writel(irqs, base + IPU_REG_ISYS_UNISPART_IRQ_ENABLE); + + writel(0, base + IPU_REG_ISYS_UNISPART_SW_IRQ_REG); + writel(0, base + IPU_REG_ISYS_UNISPART_SW_IRQ_MUX_REG); + + /* Write CDC FIFO threshold values for isys */ + for (i = 0; i < isys->pdata->ipdata->hw_variant.cdc_fifos; i++) + writel(thd[i], base + IPU_REG_ISYS_CDC_THRESHOLD(i)); +} +#endif + +#ifdef CONFIG_VIDEO_INTEL_IPU4P +/* + * For new HW, extra common register (en_flush_for_idrain)added to the IBufCtrl + * of ISL_IS and CSI that enables the feature to send a DMA command with flush + * when draining. This means that a DMA command is send with the flush bit + * set(read post write check is performed) when a drain request comes in and + * iwake is enabled for that SID proc. + * This results in that all data is moved out of the system when the IDone is + * given back. Default the feature is off, to keep behavior as is when nothing + * is written, writing 0x1 to the register (reg 11 in common reg bank, + * addr ibuf_base + 0x2C) to enable this feature. + */ +static int ipu4p_isys_flush_idrain_en(struct ipu_isys *isys) +{ + void __iomem *base = isys->pdata->base; + + writel(1, base + CSI2_REG_CL0_IBUFCTL_EN_FLUSH_FOR_IDRAIN); + writel(1, base + CSI2_REG_CL1_IBUFCTL_EN_FLUSH_FOR_IDRAIN); + writel(1, base + IPU_REG_ISYS_IBUFCTL_EN_FLUSH_FOR_IDRAIN); + + return 0; +} + +static void ipu4p_isys_irq_cfg(struct ipu_isys *isys) +{ + void __iomem *base = isys->pdata->base; + int i, j; + struct { + u32 base; + u32 mask; + } irq_config[] = { + {IPU_REG_ISYS_UNISPART_IRQ_EDGE, 0x400018}, + {IPU_REG_ISYS_ISA_ACC_IRQ_CTRL_BASE, 0x0}, + {IPU_REG_ISYS_A_IRQ_CTRL_BASE, 0x0}, + {IPU_REG_ISYS_SIP0_IRQ_CTRL_BASE, 0xf}, + {IPU_REG_ISYS_SIP1_IRQ_CTRL_BASE, 0xf}, + }; + unsigned int offsets[4] = { + 0x0, 0x4, 0x10, 0x14 + }; + + for (i = 0; i < ARRAY_SIZE(irq_config); i++) { + for (j = 0; j < ARRAY_SIZE(offsets); j++) + writel(irq_config[i].mask, + base + irq_config[i].base + offsets[j]); + writel(0xffffffff, base + irq_config[i].base + 0xc); + } + + writel(0, base + IPU_REG_ISYS_UNISPART_SW_IRQ_REG); + writel(0, base + IPU_REG_ISYS_UNISPART_SW_IRQ_MUX_REG); +} + +static void ipu4p_isys_bb_cfg(struct ipu_isys *isys) +{ + void __iomem *isp_base = isys->adev->isp->base; + unsigned int i, val; + unsigned int bbconfig[4][4] = { + {4, 13, 32, 0xf}, + {6, 13, 32, 0x15}, + {12, 13, 32, 0xf}, + {14, 13, 32, 0x15}, + }; + + /* Config building block */ + for (i = 0; i < 4; i++) { + unsigned int bb = bbconfig[i][0]; + unsigned int crc = bbconfig[i][1]; + unsigned int drc = bbconfig[i][2]; + unsigned int afe = bbconfig[i][3]; + + val = readl(isp_base + BUTTRESS_REG_CPHYX_DLL_OVRD(bb)); + val &= ~0x7e; + val |= crc << 1; + val |= 1; + writel(val, isp_base + BUTTRESS_REG_CPHYX_DLL_OVRD(bb)); + val = readl(isp_base + BUTTRESS_REG_DPHYX_DLL_OVRD(bb)); + val |= 1; + val |= drc << 1; + writel(val, isp_base + BUTTRESS_REG_DPHYX_DLL_OVRD(bb)); + val = afe | (2 << 29); + writel(val, isp_base + BUTTRESS_REG_BBX_AFE_CONFIG(bb)); + } +} + +static void ipu4p_isys_port_cfg(struct ipu_isys *isys) +{ + void __iomem *base = isys->pdata->base; + void __iomem *isp_base = isys->adev->isp->base; + + /* Port config */ + writel(0x3895, base + IPU_GPOFFSET + 0x14); + writel(0x3895, base + IPU_COMBO_GPOFFSET + 0x14); + writel((0x100 << 1) | (0x100 << 10) | (0x100 << 19), isp_base + + BUTTRESS_REG_CSI_BSCAN_EXCLUDE); +} + +void isys_setup_hw(struct ipu_isys *isys) +{ + ipu4p_isys_irq_cfg(isys); + ipu4p_isys_port_cfg(isys); + ipu4p_isys_bb_cfg(isys); + ipu4p_isys_flush_idrain_en(isys); +} +#endif + +#ifdef CONFIG_VIDEO_INTEL_IPU4 +irqreturn_t isys_isr(struct ipu_bus_device *adev) +{ + struct ipu_isys *isys = ipu_bus_get_drvdata(adev); + void __iomem *base = isys->pdata->base; + u32 status; + + spin_lock(&isys->power_lock); + if (!isys->power) { + spin_unlock(&isys->power_lock); + return IRQ_NONE; + } + + status = readl(isys->pdata->base + + IPU_REG_ISYS_UNISPART_IRQ_STATUS); + do { + writel(status, isys->pdata->base + + IPU_REG_ISYS_UNISPART_IRQ_CLEAR); + + if (isys->isr_csi2_bits & status) { + unsigned int i; + + for (i = 0; i < isys->pdata->ipdata->csi2.nports; i++) { + if (IPU_ISYS_UNISPART_IRQ_CSI2(i) & status) + ipu_isys_csi2_isr(&isys->csi2[i]); + } + } + + writel(0, base + IPU_REG_ISYS_UNISPART_SW_IRQ_REG); + + /* + * Handle a single FW event per checking the CSI-2 + * receiver SOF status. This is done in order to avoid + * the case where events arrive to the event queue and + * one of them is a SOF event which then could be + * handled before the SOF interrupt. This would pose + * issues in sequence numbering which is based on SOF + * interrupts, always assumed to arrive before FW SOF + * events. + */ + if (status & IPU_ISYS_UNISPART_IRQ_SW && !isys_isr_one(adev)) + status = IPU_ISYS_UNISPART_IRQ_SW; + else + status = 0; + + status |= readl(isys->pdata->base + + IPU_REG_ISYS_UNISPART_IRQ_STATUS); + } while (status & (isys->isr_csi2_bits + | IPU_ISYS_UNISPART_IRQ_SW) && + !isys->adev->isp->flr_done); + spin_unlock(&isys->power_lock); + + return IRQ_HANDLED; +} +#endif + +#ifdef CONFIG_VIDEO_INTEL_IPU4P +irqreturn_t isys_isr(struct ipu_bus_device *adev) +{ + struct ipu_isys *isys = ipu_bus_get_drvdata(adev); + void __iomem *base = isys->pdata->base; + u32 status; + unsigned int i; + u32 sip0_status, sip1_status; + struct { + u32 *status; + u32 mask; + } csi2_irq_mask[] = { + {&sip0_status, IPU_ISYS_CSI2_D_IRQ_MASK}, + {&sip1_status, IPU_ISYS_CSI2_A_IRQ_MASK}, + {&sip1_status, IPU_ISYS_CSI2_B_IRQ_MASK}, + {&sip1_status, IPU_ISYS_CSI2_C_IRQ_MASK}, + {&sip1_status, IPU_ISYS_CSI2_D_IRQ_MASK}, + {&sip1_status, IPU_ISYS_CSI2_E_IRQ_MASK}, + {&sip1_status, IPU_ISYS_CSI2_F_IRQ_MASK}, + {&sip1_status, IPU_ISYS_CSI2_G_IRQ_MASK}, + }; + + spin_lock(&isys->power_lock); + if (!isys->power) { + spin_unlock(&isys->power_lock); + return IRQ_NONE; + } + + /* read unis sw irq */ + status = readl(isys->pdata->base + + IPU_REG_ISYS_UNISPART_IRQ_STATUS); + dev_dbg(&adev->dev, "isys irq status - unis sw irq = 0x%x", status); + + do { + /* clear unis sw irqs */ + writel(status, isys->pdata->base + + IPU_REG_ISYS_UNISPART_IRQ_CLEAR); + + /* read and clear sip irq status */ + sip0_status = readl(isys->pdata->base + + IPU_REG_ISYS_SIP0_IRQ_CTRL_STATUS); + sip1_status = readl(isys->pdata->base + + IPU_REG_ISYS_SIP1_IRQ_CTRL_STATUS); + dev_dbg(&adev->dev, "isys irq status - sip0 = 0x%x sip1 = 0x%x", + sip0_status, sip1_status); + writel(sip0_status, isys->pdata->base + + IPU_REG_ISYS_SIP0_IRQ_CTRL_CLEAR); + writel(sip1_status, isys->pdata->base + + IPU_REG_ISYS_SIP1_IRQ_CTRL_CLEAR); + + for (i = 0; i < isys->pdata->ipdata->csi2.nports; i++) { + if (*csi2_irq_mask[i].status & csi2_irq_mask[i].mask) + ipu_isys_csi2_isr(&isys->csi2[i]); + } + + writel(0, base + IPU_REG_ISYS_UNISPART_SW_IRQ_REG); + + /* + * Handle a single FW event per checking the CSI-2 + * receiver SOF status. This is done in order to avoid + * the case where events arrive to the event queue and + * one of them is a SOF event which then could be + * handled before the SOF interrupt. This would pose + * issues in sequence numbering which is based on SOF + * interrupts, always assumed to arrive before FW SOF + * events. + */ + if (status & IPU_ISYS_UNISPART_IRQ_SW && !isys_isr_one(adev)) + status = IPU_ISYS_UNISPART_IRQ_SW; + else + status = 0; + + status |= readl(isys->pdata->base + + IPU_REG_ISYS_UNISPART_IRQ_STATUS); + } while (status & (isys->isr_csi2_bits + | IPU_ISYS_UNISPART_IRQ_SW) && + !isys->adev->isp->flr_done); + spin_unlock(&isys->power_lock); + + return IRQ_HANDLED; +} +#endif + +int tpg_set_stream(struct v4l2_subdev *sd, int enable) +{ + struct ipu_isys_tpg *tpg = to_ipu_isys_tpg(sd); +#ifdef IPU_VC_SUPPORT + __u32 code = tpg->asd.ffmt[TPG_PAD_SOURCE][0].code; +#else + __u32 code = tpg->asd.ffmt[TPG_PAD_SOURCE].code; +#endif + unsigned int bpp = ipu_isys_mbus_code_to_bpp(code); + + /* + * MIPI_GEN block is CSI2 FB. Need to enable/disable TPG selection + * register to control the TPG streaming. + */ + if (tpg->sel) + writel(enable ? 1 : 0, tpg->sel); + + if (!enable) { + writel(0, tpg->base + MIPI_GEN_REG_COM_ENABLE); + return 0; + } + + writel(MIPI_GEN_COM_DTYPE_RAW(bpp), + tpg->base + MIPI_GEN_REG_COM_DTYPE); + writel(ipu_isys_mbus_code_to_mipi(code), + tpg->base + MIPI_GEN_REG_COM_VTYPE); + writel(0, tpg->base + MIPI_GEN_REG_COM_VCHAN); + + writel(0, tpg->base + MIPI_GEN_REG_SYNG_NOF_FRAMES); + +#ifdef IPU_VC_SUPPORT + writel(DIV_ROUND_UP(tpg->asd.ffmt[TPG_PAD_SOURCE][0].width * + bpp, BITS_PER_BYTE), + tpg->base + MIPI_GEN_REG_COM_WCOUNT); + writel(DIV_ROUND_UP(tpg->asd.ffmt[TPG_PAD_SOURCE][0].width, + MIPI_GEN_PPC), + tpg->base + MIPI_GEN_REG_SYNG_NOF_PIXELS); + writel(tpg->asd.ffmt[TPG_PAD_SOURCE][0].height, + tpg->base + MIPI_GEN_REG_SYNG_NOF_LINES); +#else + writel(DIV_ROUND_UP(tpg->asd.ffmt[TPG_PAD_SOURCE].width * + bpp, BITS_PER_BYTE), + tpg->base + MIPI_GEN_REG_COM_WCOUNT); + writel(DIV_ROUND_UP(tpg->asd.ffmt[TPG_PAD_SOURCE].width, + MIPI_GEN_PPC), + tpg->base + MIPI_GEN_REG_SYNG_NOF_PIXELS); + writel(tpg->asd.ffmt[TPG_PAD_SOURCE].height, + tpg->base + MIPI_GEN_REG_SYNG_NOF_LINES); +#endif + + writel(0, tpg->base + MIPI_GEN_REG_TPG_MODE); + writel(-1, tpg->base + MIPI_GEN_REG_TPG_HCNT_MASK); + writel(-1, tpg->base + MIPI_GEN_REG_TPG_VCNT_MASK); + writel(-1, tpg->base + MIPI_GEN_REG_TPG_XYCNT_MASK); + writel(0, tpg->base + MIPI_GEN_REG_TPG_HCNT_DELTA); + writel(0, tpg->base + MIPI_GEN_REG_TPG_VCNT_DELTA); + + v4l2_ctrl_handler_setup(&tpg->asd.ctrl_handler); + + writel(2, tpg->base + MIPI_GEN_REG_COM_ENABLE); + return 0; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-psys.c b/drivers/media/pci/intel/ipu4/ipu4-psys.c new file mode 100644 index 0000000000000..06312ac5bcf93 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-psys.c @@ -0,0 +1,1093 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Intel Corporation + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipu.h" +#include "ipu-psys.h" +#include "ipu-platform-regs.h" +#include "ipu-trace.h" +#define CREATE_TRACE_POINTS +#define IPU_PG_KCMD_TRACE +#include "ipu-trace-event.h" + +static bool early_pg_transfer; +static bool enable_concurrency = true; +module_param(early_pg_transfer, bool, 0664); +module_param(enable_concurrency, bool, 0664); +MODULE_PARM_DESC(early_pg_transfer, + "Copy PGs back to user after resource allocation"); +MODULE_PARM_DESC(enable_concurrency, + "Enable concurrent execution of program groups"); + +struct ipu_trace_block psys_trace_blocks[] = { + { + .offset = TRACE_REG_PS_TRACE_UNIT_BASE, + .type = IPU_TRACE_BLOCK_TUN, + }, + { + .offset = TRACE_REG_PS_SPC_EVQ_BASE, + .type = IPU_TRACE_BLOCK_TM, + }, + { + .offset = TRACE_REG_PS_SPP0_EVQ_BASE, + .type = IPU_TRACE_BLOCK_TM, + }, + { + .offset = TRACE_REG_PS_SPP1_EVQ_BASE, + .type = IPU_TRACE_BLOCK_TM, + }, + { + .offset = TRACE_REG_PS_ISP0_EVQ_BASE, + .type = IPU_TRACE_BLOCK_TM, + }, + { + .offset = TRACE_REG_PS_ISP1_EVQ_BASE, + .type = IPU_TRACE_BLOCK_TM, + }, + { + .offset = TRACE_REG_PS_ISP2_EVQ_BASE, + .type = IPU_TRACE_BLOCK_TM, + }, + { + .offset = TRACE_REG_PS_ISP3_EVQ_BASE, + .type = IPU_TRACE_BLOCK_TM, + }, + { + .offset = TRACE_REG_PS_SPC_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_PS_SPP0_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_PS_SPP1_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_PS_MMU_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_PS_ISL_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_PS_ISP0_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_PS_ISP1_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_PS_ISP2_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_PS_ISP3_GPC_BASE, + .type = IPU_TRACE_BLOCK_GPC, + }, + { + .offset = TRACE_REG_PS_GPREG_TRACE_TIMER_RST_N, + .type = IPU_TRACE_TIMER_RST, + }, + { + .type = IPU_TRACE_BLOCK_END, + } +}; + +static int ipu_psys_kcmd_abort(struct ipu_psys *psys, + struct ipu_psys_kcmd *kcmd); +static int ipu_psys_kcmd_queue(struct ipu_psys *psys, + struct ipu_psys_kcmd *kcmd); + +static void set_sp_info_bits(void *base) +{ + int i; + + writel(IPU_INFO_REQUEST_DESTINATION_PRIMARY, + base + IPU_REG_PSYS_INFO_SEG_0_CONFIG_ICACHE_MASTER); + + for (i = 0; i < 4; i++) + writel(IPU_INFO_REQUEST_DESTINATION_PRIMARY, + base + IPU_REG_PSYS_INFO_SEG_CMEM_MASTER(i)); + for (i = 0; i < 4; i++) + writel(IPU_INFO_REQUEST_DESTINATION_PRIMARY, + base + IPU_REG_PSYS_INFO_SEG_XMEM_MASTER(i)); +} + +static void set_isp_info_bits(void *base) +{ + int i; + + writel(IPU_INFO_REQUEST_DESTINATION_PRIMARY, + base + IPU_REG_PSYS_INFO_SEG_0_CONFIG_ICACHE_MASTER); + + for (i = 0; i < 4; i++) + writel(IPU_INFO_REQUEST_DESTINATION_PRIMARY, + base + IPU_REG_PSYS_INFO_SEG_DATA_MASTER(i)); +} + +void ipu_psys_setup_hw(struct ipu_psys *psys) +{ + void __iomem *base = psys->pdata->base; + void __iomem *spc_regs_base = + base + psys->pdata->ipdata->hw_variant.spc_offset; + void *psys_iommu0_ctrl = base + + psys->pdata->ipdata->hw_variant.mmu_hw[0].offset + + IPU_PSYS_MMU0_CTRL_OFFSET; + const u8 *thd = psys->pdata->ipdata->hw_variant.cdc_fifo_threshold; + u32 irqs; + unsigned int i; + + /* Configure PSYS info bits */ + writel(IPU_INFO_REQUEST_DESTINATION_PRIMARY, psys_iommu0_ctrl); + + set_sp_info_bits(spc_regs_base + IPU_PSYS_REG_SPC_STATUS_CTRL); + set_sp_info_bits(spc_regs_base + IPU_PSYS_REG_SPP0_STATUS_CTRL); + set_sp_info_bits(spc_regs_base + IPU_PSYS_REG_SPP1_STATUS_CTRL); + set_isp_info_bits(spc_regs_base + IPU_PSYS_REG_ISP0_STATUS_CTRL); + set_isp_info_bits(spc_regs_base + IPU_PSYS_REG_ISP1_STATUS_CTRL); + set_isp_info_bits(spc_regs_base + IPU_PSYS_REG_ISP2_STATUS_CTRL); + set_isp_info_bits(spc_regs_base + IPU_PSYS_REG_ISP3_STATUS_CTRL); + + /* Enable FW interrupt #0 */ + writel(0, base + IPU_REG_PSYS_GPDEV_FWIRQ(0)); + irqs = IPU_PSYS_GPDEV_IRQ_FWIRQ(0); + writel(irqs, base + IPU_REG_PSYS_GPDEV_IRQ_EDGE); + /* + * With pulse setting, driver misses interrupts. IUNIT integration + * HAS(v1.26) suggests to use pulse, but this seem to be error in + * documentation. + */ + writel(irqs, base + IPU_REG_PSYS_GPDEV_IRQ_LEVEL_NOT_PULSE); + writel(irqs, base + IPU_REG_PSYS_GPDEV_IRQ_CLEAR); + writel(irqs, base + IPU_REG_PSYS_GPDEV_IRQ_MASK); + writel(irqs, base + IPU_REG_PSYS_GPDEV_IRQ_ENABLE); + + /* Write CDC FIFO threshold values for psys */ + for (i = 0; i < psys->pdata->ipdata->hw_variant.cdc_fifos; i++) + writel(thd[i], base + IPU_REG_PSYS_CDC_THRESHOLD(i)); +} + +/* + * Called to free up all resources associated with a kcmd. + * After this the kcmd doesn't anymore exist in the driver. + */ +void ipu_psys_kcmd_free(struct ipu_psys_kcmd *kcmd) +{ + struct ipu_psys *psys; + unsigned long flags; + + if (!kcmd) + return; + + psys = kcmd->fh->psys; + + if (!list_empty(&kcmd->list)) + list_del(&kcmd->list); + + spin_lock_irqsave(&psys->pgs_lock, flags); + if (kcmd->kpg) + kcmd->kpg->pg_size = 0; + spin_unlock_irqrestore(&psys->pgs_lock, flags); + + kfree(kcmd->pg_manifest); + kfree(kcmd->kbufs); + kfree(kcmd->buffers); + kfree(kcmd); +} + +static struct ipu_psys_kcmd *ipu_psys_copy_cmd(struct ipu_psys_command *cmd, + struct ipu_psys_fh *fh) +{ + struct ipu_psys *psys = fh->psys; + struct ipu_psys_kcmd *kcmd; + struct ipu_psys_kbuffer *kpgbuf; + unsigned int i; + int ret, prevfd = 0; + + if (cmd->bufcount > IPU_MAX_PSYS_CMD_BUFFERS) + return NULL; + + if (!cmd->pg_manifest_size || + cmd->pg_manifest_size > KMALLOC_MAX_CACHE_SIZE) + return NULL; + + kcmd = kzalloc(sizeof(*kcmd), GFP_KERNEL); + if (!kcmd) + return NULL; + + kcmd->state = KCMD_STATE_NEW; + kcmd->fh = fh; + INIT_LIST_HEAD(&kcmd->list); + INIT_LIST_HEAD(&kcmd->started_list); + + mutex_lock(&fh->mutex); + kpgbuf = ipu_psys_lookup_kbuffer(fh, cmd->pg); + mutex_unlock(&fh->mutex); + if (!kpgbuf || !kpgbuf->sgt) + goto error; + + kcmd->pg_user = kpgbuf->kaddr; + kcmd->kpg = __get_pg_buf(psys, kpgbuf->len); + if (!kcmd->kpg) + goto error; + + memcpy(kcmd->kpg->pg, kcmd->pg_user, kcmd->kpg->pg_size); + + kcmd->pg_manifest = kzalloc(cmd->pg_manifest_size, GFP_KERNEL); + if (!kcmd->pg_manifest) + goto error; + + ret = copy_from_user(kcmd->pg_manifest, cmd->pg_manifest, + cmd->pg_manifest_size); + if (ret) + goto error; + + kcmd->pg_manifest_size = cmd->pg_manifest_size; + + kcmd->user_token = cmd->user_token; + kcmd->issue_id = cmd->issue_id; + kcmd->priority = cmd->priority; + if (kcmd->priority >= IPU_PSYS_CMD_PRIORITY_NUM) + goto error; + + kcmd->nbuffers = ipu_fw_psys_pg_get_terminal_count(kcmd); + kcmd->buffers = kcalloc(kcmd->nbuffers, sizeof(*kcmd->buffers), + GFP_KERNEL); + if (!kcmd->buffers) + goto error; + + kcmd->kbufs = kcalloc(kcmd->nbuffers, sizeof(kcmd->kbufs[0]), + GFP_KERNEL); + if (!kcmd->kbufs) + goto error; + + + if (!cmd->bufcount || kcmd->nbuffers > cmd->bufcount) + goto error; + + ret = copy_from_user(kcmd->buffers, cmd->buffers, + kcmd->nbuffers * sizeof(*kcmd->buffers)); + if (ret) + goto error; + + for (i = 0; i < kcmd->nbuffers; i++) { + struct ipu_fw_psys_terminal *terminal; + + terminal = ipu_fw_psys_pg_get_terminal(kcmd, i); + if (!terminal) + continue; + + + mutex_lock(&fh->mutex); + kcmd->kbufs[i] = ipu_psys_lookup_kbuffer(fh, + kcmd->buffers[i].base.fd); + mutex_unlock(&fh->mutex); + if (!kcmd->kbufs[i] || !kcmd->kbufs[i]->sgt || + kcmd->kbufs[i]->len < kcmd->buffers[i].bytes_used) + goto error; + if ((kcmd->kbufs[i]->flags & + IPU_BUFFER_FLAG_NO_FLUSH) || + (kcmd->buffers[i].flags & + IPU_BUFFER_FLAG_NO_FLUSH) || + prevfd == kcmd->buffers[i].base.fd) + continue; + + prevfd = kcmd->buffers[i].base.fd; + dma_sync_sg_for_device(&psys->adev->dev, + kcmd->kbufs[i]->sgt->sgl, + kcmd->kbufs[i]->sgt->orig_nents, + DMA_BIDIRECTIONAL); + } + + + return kcmd; +error: + ipu_psys_kcmd_free(kcmd); + + dev_dbg(&psys->adev->dev, "failed to copy cmd\n"); + + return NULL; +} + +static void ipu_psys_kcmd_run(struct ipu_psys *psys) +{ + struct ipu_psys_kcmd *kcmd = list_first_entry(&psys->started_kcmds_list, + struct ipu_psys_kcmd, + started_list); + int ret; + + ret = ipu_psys_move_resources(&psys->adev->dev, + &kcmd->kpg->resource_alloc, + &psys->resource_pool_started, + &psys->resource_pool_running); + if (!ret) { + psys->started_kcmds--; + psys->active_kcmds++; + kcmd->state = KCMD_STATE_RUNNING; + list_del(&kcmd->started_list); + kcmd->watchdog.expires = jiffies + + msecs_to_jiffies(psys->timeout); + add_timer(&kcmd->watchdog); + return; + } + + if (ret != -ENOSPC || !psys->active_kcmds) { + dev_err(&psys->adev->dev, + "kcmd %p failed to alloc resources %d, active_kcmds %d\n", + kcmd, ret, psys->active_kcmds); + ipu_psys_kcmd_abort(psys, kcmd); + return; + } +} + +/* + * Move kcmd into completed state (due to running finished or failure). + * Fill up the event struct and notify waiters. + */ +void ipu_psys_kcmd_complete(struct ipu_psys *psys, + struct ipu_psys_kcmd *kcmd, int error) +{ + struct ipu_psys_fh *fh = kcmd->fh; + + trace_ipu_pg_kcmd(__func__, kcmd->user_token, kcmd->issue_id, + kcmd->priority, + ipu_fw_psys_pg_get_id(kcmd), + ipu_fw_psys_pg_load_cycles(kcmd), + ipu_fw_psys_pg_init_cycles(kcmd), + ipu_fw_psys_pg_processing_cycles(kcmd)); + + switch (kcmd->state) { + case KCMD_STATE_RUNNING: + if (timer_delete_sync_try(&kcmd->watchdog) < 0) { + dev_err(&psys->adev->dev, + "could not cancel kcmd timer\n"); + return; + } + /* Fall through on purpose */ + case KCMD_STATE_RUN_PREPARED: + ipu_psys_free_resources(&kcmd->kpg->resource_alloc, + &psys->resource_pool_running); + if (psys->started_kcmds) + ipu_psys_kcmd_run(psys); + if (kcmd->state == KCMD_STATE_RUNNING) + psys->active_kcmds--; + break; + case KCMD_STATE_STARTED: + psys->started_kcmds--; + list_del(&kcmd->started_list); + /* Fall through on purpose */ + case KCMD_STATE_START_PREPARED: + ipu_psys_free_resources(&kcmd->kpg->resource_alloc, + &psys->resource_pool_started); + break; + default: + break; + } + + kcmd->ev.type = IPU_PSYS_EVENT_TYPE_CMD_COMPLETE; + kcmd->ev.user_token = kcmd->user_token; + kcmd->ev.issue_id = kcmd->issue_id; + kcmd->ev.error = error; + + if (kcmd->constraint.min_freq) + ipu_buttress_remove_psys_constraint(psys->adev->isp, + &kcmd->constraint); + + if (!early_pg_transfer && kcmd->pg_user && kcmd->kpg->pg) { + struct ipu_psys_kbuffer *kbuf; + + kbuf = ipu_psys_lookup_kbuffer_by_kaddr(kcmd->fh, + kcmd->pg_user); + + if (kbuf && kbuf->valid) + memcpy(kcmd->pg_user, + kcmd->kpg->pg, kcmd->kpg->pg_size); + else + dev_dbg(&psys->adev->dev, + "Skipping already unmapped buffer\n"); + } + + if (kcmd->state == KCMD_STATE_RUNNING || + kcmd->state == KCMD_STATE_STARTED) { + pm_runtime_mark_last_busy(&psys->adev->dev); + pm_runtime_put_autosuspend(&psys->adev->dev); + } + + kcmd->state = KCMD_STATE_COMPLETE; + + wake_up_interruptible(&fh->wait); +} + +/* + * Schedule next kcmd by finding a runnable kcmd from the highest + * priority queue in a round-robin fashion versus the client + * queues and running it. + * Any kcmds which fail to start are completed with an error. + */ +void ipu_psys_run_next(struct ipu_psys *psys) +{ + int p; + + /* + * Code below will crash if fhs is empty. Normally this + * shouldn't happen. + */ + if (list_empty(&psys->fhs)) { + WARN_ON(1); + return; + } + + for (p = 0; p < IPU_PSYS_CMD_PRIORITY_NUM; p++) { + int removed; + + do { + struct ipu_psys_fh *fh = list_first_entry(&psys->fhs, + struct + ipu_psys_fh, + list); + struct ipu_psys_fh *fh_last = + list_last_entry(&psys->fhs, + struct ipu_psys_fh, + list); + /* + * When a kcmd is scheduled from a fh, it might expose + * more runnable kcmds behind it in the same queue. + * Therefore loop running kcmds as long as some were + * scheduled. + */ + removed = 0; + do { + struct ipu_psys_fh *fh_next = + list_next_entry(fh, list); + struct ipu_psys_kcmd *kcmd; + int ret; + + mutex_lock(&fh->mutex); + + kcmd = fh->sched.new_kcmd_tail[p]; + /* + * If concurrency is disabled and there are + * already commands running on the PSYS, do not + * run new commands. + */ + if (!enable_concurrency && + psys->active_kcmds > 0) { + mutex_unlock(&fh->mutex); + return; + } + + /* Are there new kcmds available for running? */ + if (!kcmd) + goto next; + + ret = ipu_psys_kcmd_queue(psys, kcmd); + if (ret == -ENOSPC) + goto next; + + /* Update pointer to the first new kcmd */ + fh->sched.new_kcmd_tail[p] = NULL; + while (kcmd != list_last_entry( + &fh->sched.kcmds[p], + struct ipu_psys_kcmd, + list)) { + kcmd = list_next_entry(kcmd, list); + if (kcmd->state == KCMD_STATE_NEW) { + fh->sched.new_kcmd_tail[p] = + kcmd; + break; + } + } + + list_move_tail(&fh->list, &psys->fhs); + removed++; +next: + mutex_unlock(&fh->mutex); + if (fh == fh_last) + break; + fh = fh_next; + } while (1); + } while (removed > 0); + } +} + +/* + * Move kcmd into completed state. If kcmd is currently running, + * abort it. + */ +int ipu_psys_kcmd_abort(struct ipu_psys *psys, struct ipu_psys_kcmd *kcmd) +{ + int ret = 0; + + if (kcmd->state == KCMD_STATE_COMPLETE) + return 0; + + if ((kcmd->state == KCMD_STATE_RUNNING || + kcmd->state == KCMD_STATE_STARTED)) { + ret = ipu_fw_psys_pg_abort(kcmd); + if (ret) { + dev_err(&psys->adev->dev, "failed to abort kcmd!\n"); + goto out; + } + } + +out: + ipu_psys_kcmd_complete(psys, kcmd, ret); + + return ret; +} + +/* + * Submit kcmd into psys queue. If running fails, complete the kcmd + * with an error. + */ +static int ipu_psys_kcmd_start(struct ipu_psys *psys, + struct ipu_psys_kcmd *kcmd) +{ + /* + * Found a runnable PG. Move queue to the list tail for round-robin + * scheduling and run the PG. Start the watchdog timer if the PG was + * started successfully. Enable PSYS power if requested. + */ + int ret; + + if (psys->adev->isp->flr_done) { + ipu_psys_kcmd_complete(psys, kcmd, -EIO); + return -EIO; + } + + ret = pm_runtime_get_sync(&psys->adev->dev); + if (ret < 0) { + dev_err(&psys->adev->dev, "failed to power on PSYS\n"); + ipu_psys_kcmd_complete(psys, kcmd, -EIO); + pm_runtime_put_noidle(&psys->adev->dev); + return ret; + } + + if (early_pg_transfer && kcmd->pg_user && kcmd->kpg->pg) + memcpy(kcmd->pg_user, kcmd->kpg->pg, kcmd->kpg->pg_size); + + ret = ipu_fw_psys_pg_start(kcmd); + if (ret) { + dev_err(&psys->adev->dev, "failed to start kcmd!\n"); + goto error; + } + + ipu_fw_psys_pg_dump(psys, kcmd, "run"); + + /* + * Starting from scci_master_20151228_1800, pg start api is split into + * two different calls, making driver responsible to flush pg between + * start and disown library calls. + */ + clflush_cache_range(kcmd->kpg->pg, kcmd->kpg->pg_size); + ret = ipu_fw_psys_pg_disown(kcmd); + if (ret) { + dev_err(&psys->adev->dev, "failed to start kcmd!\n"); + goto error; + } + + trace_ipu_pg_kcmd(__func__, kcmd->user_token, kcmd->issue_id, + kcmd->priority, + ipu_fw_psys_pg_get_id(kcmd), + ipu_fw_psys_pg_load_cycles(kcmd), + ipu_fw_psys_pg_init_cycles(kcmd), + ipu_fw_psys_pg_processing_cycles(kcmd)); + + switch (kcmd->state) { + case KCMD_STATE_RUN_PREPARED: + kcmd->state = KCMD_STATE_RUNNING; + psys->active_kcmds++; + kcmd->watchdog.expires = jiffies + + msecs_to_jiffies(psys->timeout); + add_timer(&kcmd->watchdog); + break; + case KCMD_STATE_START_PREPARED: + kcmd->state = KCMD_STATE_STARTED; + psys->started_kcmds++; + list_add_tail(&kcmd->started_list, &psys->started_kcmds_list); + break; + default: + WARN_ON(1); + ret = -EINVAL; + goto error; + } + return 0; + +error: + dev_err(&psys->adev->dev, "failed to start process group\n"); + ipu_psys_kcmd_complete(psys, kcmd, -EIO); + return ret; +} + +/* + * Move all kcmds in all queues forcily into completed state. + */ +static void ipu_psys_flush_kcmds(struct ipu_psys *psys, int error) +{ + struct ipu_psys_fh *fh; + struct ipu_psys_kcmd *kcmd; + int p; + + dev_err(&psys->dev, "flushing all commands with error: %d\n", error); + + list_for_each_entry(fh, &psys->fhs, list) { + mutex_lock(&fh->mutex); + for (p = 0; p < IPU_PSYS_CMD_PRIORITY_NUM; p++) { + fh->sched.new_kcmd_tail[p] = NULL; + list_for_each_entry(kcmd, &fh->sched.kcmds[p], list) { + if (kcmd->state == KCMD_STATE_COMPLETE) + continue; + ipu_psys_kcmd_complete(psys, kcmd, error); + } + } + mutex_unlock(&fh->mutex); + } +} + +/* + * Abort all currently running process groups and reset PSYS + * by power cycling it. PSYS power must not be acquired + * except by running kcmds when calling this. + */ +static void ipu_psys_reset(struct ipu_psys *psys) +{ +#ifdef CONFIG_PM + struct device *d = &psys->adev->isp->psys_iommu->dev; + int r; + + pm_runtime_dont_use_autosuspend(&psys->adev->dev); + r = pm_runtime_get_sync(d); + if (r < 0) { + pm_runtime_put_noidle(d); + dev_err(&psys->adev->dev, "power management failed\n"); + return; + } + + ipu_psys_flush_kcmds(psys, -EIO); + flush_workqueue(pm_wq); + r = pm_runtime_put_sync(d); /* Turn big red power knob off here */ + /* Power was successfully turned off if and only if zero was returned */ + if (r) + dev_warn(&psys->adev->dev, + "power management failed, PSYS reset may be incomplete\n"); + pm_runtime_use_autosuspend(&psys->adev->dev); + ipu_psys_run_next(psys); +#else + dev_err(&psys->adev->dev, + "power management disabled, can not reset PSYS\n"); +#endif +} + +void ipu_psys_watchdog_work(struct work_struct *work) +{ + struct ipu_psys *psys = container_of(work, + struct ipu_psys, watchdog_work); + struct ipu_psys_fh *fh; + + mutex_lock(&psys->mutex); + + /* Loop over all running kcmds */ + list_for_each_entry(fh, &psys->fhs, list) { + int p, r; + + mutex_lock(&fh->mutex); + for (p = 0; p < IPU_PSYS_CMD_PRIORITY_NUM; p++) { + struct ipu_psys_kcmd *kcmd; + + list_for_each_entry(kcmd, &fh->sched.kcmds[p], list) { + if (fh->sched.new_kcmd_tail[p] == kcmd) + break; + if (kcmd->state != KCMD_STATE_RUNNING) + continue; + + if (timer_pending(&kcmd->watchdog)) + continue; + /* Found an expired but running command */ + dev_err(&psys->adev->dev, + "kcmd:0x%llx[0x%llx] taking too long\n", + kcmd->user_token, kcmd->issue_id); + r = ipu_psys_kcmd_abort(psys, kcmd); + if (r) + goto stop_failed; + } + } + mutex_unlock(&fh->mutex); + } + + /* Kick command scheduler thread */ + atomic_set(&psys->wakeup_sched_thread_count, 1); + wake_up_interruptible(&psys->sched_cmd_wq); + mutex_unlock(&psys->mutex); + return; + +stop_failed: + mutex_unlock(&fh->mutex); + ipu_psys_reset(psys); + mutex_unlock(&psys->mutex); +} + +static void ipu_psys_watchdog(struct timer_list *t) +{ + struct ipu_psys_kcmd *kcmd = timer_container_of(kcmd, t, watchdog); + struct ipu_psys *psys = kcmd->fh->psys; + + queue_work(IPU_PSYS_WORK_QUEUE, &psys->watchdog_work); +} + +static int ipu_psys_config_legacy_pg(struct ipu_psys_kcmd *kcmd) +{ + struct ipu_psys *psys = kcmd->fh->psys; + unsigned int i; + int ret; + + ret = ipu_fw_psys_pg_set_ipu_vaddress(kcmd, kcmd->kpg->pg_dma_addr); + if (ret) { + ret = -EIO; + goto error; + } + + for (i = 0; i < kcmd->nbuffers; i++) { + struct ipu_fw_psys_terminal *terminal; + u32 buffer; + + terminal = ipu_fw_psys_pg_get_terminal(kcmd, i); + if (!terminal) + continue; + + buffer = (u32) kcmd->kbufs[i]->dma_addr + + kcmd->buffers[i].data_offset; + + ret = ipu_fw_psys_terminal_set(terminal, i, kcmd, + buffer, kcmd->kbufs[i]->len); + if (ret == -EAGAIN) + continue; + + if (ret) { + dev_err(&psys->adev->dev, "Unable to set terminal\n"); + goto error; + } + } + + ipu_fw_psys_pg_set_token(kcmd, (uintptr_t) kcmd); + + ret = ipu_fw_psys_pg_submit(kcmd); + if (ret) { + dev_err(&psys->adev->dev, "failed to submit kcmd!\n"); + goto error; + } + + return 0; + +error: + dev_err(&psys->adev->dev, "failed to config legacy pg\n"); + return ret; +} + +static bool ipu_psys_kcmd_is_valid(struct ipu_psys *psys, + struct ipu_psys_kcmd *kcmd) +{ + struct ipu_psys_fh *fh; + struct ipu_psys_kcmd *kcmd0; + int p; + + list_for_each_entry(fh, &psys->fhs, list) { + mutex_lock(&fh->mutex); + for (p = 0; p < IPU_PSYS_CMD_PRIORITY_NUM; p++) { + list_for_each_entry(kcmd0, &fh->sched.kcmds[p], list) { + if (kcmd0 == kcmd) { + mutex_unlock(&fh->mutex); + return true; + } + } + } + mutex_unlock(&fh->mutex); + } + + return false; +} + +static int ipu_psys_kcmd_queue(struct ipu_psys *psys, + struct ipu_psys_kcmd *kcmd) +{ + int ret; + + if (kcmd->state != KCMD_STATE_NEW) { + WARN_ON(1); + return -EINVAL; + } + + if (!psys->started_kcmds) { + ret = ipu_psys_allocate_resources(&psys->adev->dev, + kcmd->kpg->pg, + kcmd->pg_manifest, + &kcmd->kpg->resource_alloc, + &psys->resource_pool_running); + if (!ret) { + if (kcmd->state == KCMD_STATE_NEW) + kcmd->state = KCMD_STATE_RUN_PREPARED; + return ipu_psys_kcmd_start(psys, kcmd); + } + + if (ret != -ENOSPC || !psys->active_kcmds) { + dev_err(&psys->adev->dev, + "kcmd %p failed to alloc resources (running)\n", + kcmd); + ipu_psys_kcmd_complete(psys, kcmd, ret); + /* kcmd_complete doesn't handle PM for KCMD_STATE_NEW */ + pm_runtime_put(&psys->adev->dev); + return -EINVAL; + } + } + + ret = ipu_psys_allocate_resources(&psys->adev->dev, + kcmd->kpg->pg, + kcmd->pg_manifest, + &kcmd->kpg->resource_alloc, + &psys->resource_pool_started); + if (!ret) { + kcmd->state = KCMD_STATE_START_PREPARED; + return ipu_psys_kcmd_start(psys, kcmd); + } + + if (ret != -ENOSPC || !psys->started_kcmds) { + dev_err(&psys->adev->dev, + "kcmd %p failed to alloc resources (started)\n", kcmd); + ipu_psys_kcmd_complete(psys, kcmd, ret); + /* kcmd_complete doesn't handle PM for KCMD_STATE_NEW */ + pm_runtime_put(&psys->adev->dev); + ret = -EINVAL; + } + return ret; +} + +int ipu_psys_kcmd_new(struct ipu_psys_command *cmd, struct ipu_psys_fh *fh) +{ + struct ipu_psys *psys = fh->psys; + struct ipu_psys_kcmd *kcmd; + size_t pg_size; + int ret; + + if (psys->adev->isp->flr_done) + return -EIO; + + kcmd = ipu_psys_copy_cmd(cmd, fh); + if (!kcmd) + return -EINVAL; + + timer_setup(&kcmd->watchdog, ipu_psys_watchdog, 0); + + if (cmd->min_psys_freq) { + kcmd->constraint.min_freq = cmd->min_psys_freq; + ipu_buttress_add_psys_constraint(psys->adev->isp, + &kcmd->constraint); + } + + pg_size = ipu_fw_psys_pg_get_size(kcmd); + if (pg_size > kcmd->kpg->pg_size) { + dev_dbg(&psys->adev->dev, "pg size mismatch %zu %zu\n", + pg_size, kcmd->kpg->pg_size); + ret = -EINVAL; + goto error; + } + + ret = ipu_psys_config_legacy_pg(kcmd); + if (ret) + goto error; + + mutex_lock(&fh->mutex); + list_add_tail(&kcmd->list, &fh->sched.kcmds[cmd->priority]); + if (!fh->sched.new_kcmd_tail[cmd->priority] && + kcmd->state == KCMD_STATE_NEW) { + fh->sched.new_kcmd_tail[cmd->priority] = kcmd; + /* Kick command scheduler thread */ + atomic_set(&psys->wakeup_sched_thread_count, 1); + wake_up_interruptible(&psys->sched_cmd_wq); + } + mutex_unlock(&fh->mutex); + + dev_dbg(&psys->adev->dev, + "IOC_QCMD: user_token:%llx issue_id:0x%llx pri:%d\n", + cmd->user_token, cmd->issue_id, cmd->priority); + + return 0; + +error: + ipu_psys_kcmd_free(kcmd); + + return ret; +} + +void ipu_psys_handle_events(struct ipu_psys *psys) +{ + struct ipu_psys_kcmd *kcmd = NULL; + struct ipu_fw_psys_event event; + bool error; + + do { + memset(&event, 0, sizeof(event)); + if (!ipu_fw_psys_rcv_event(psys, &event)) + break; + + error = false; + kcmd = (struct ipu_psys_kcmd *)(unsigned long)event.token; + error = IS_ERR_OR_NULL(kcmd) ? true : false; + + dev_dbg(&psys->adev->dev, "psys received event status:%d\n", + event.status); + + if (error) { + dev_err(&psys->adev->dev, + "no token received, command unknown\n"); + pm_runtime_put(&psys->adev->dev); + ipu_psys_reset(psys); + pm_runtime_get(&psys->adev->dev); + break; + } + + if (ipu_psys_kcmd_is_valid(psys, kcmd)) + ipu_psys_kcmd_complete(psys, kcmd, + event.status == + IPU_PSYS_EVENT_CMD_COMPLETE || + event.status == + IPU_PSYS_EVENT_FRAGMENT_COMPLETE + ? 0 : -EIO); + /* Kick command scheduler thread */ + atomic_set(&psys->wakeup_sched_thread_count, 1); + wake_up_interruptible(&psys->sched_cmd_wq); + } while (1); +} + +int ipu_psys_fh_init(struct ipu_psys_fh *fh) +{ + struct ipu_psys *psys = fh->psys; + int p; + + pm_runtime_use_autosuspend(&psys->adev->dev); + for (p = 0; p < IPU_PSYS_CMD_PRIORITY_NUM; p++) + INIT_LIST_HEAD(&fh->sched.kcmds[p]); + + return 0; +} + +int ipu_psys_fh_deinit(struct ipu_psys_fh *fh) +{ + struct ipu_psys *psys = fh->psys; + struct ipu_psys_kcmd *kcmd, *kcmd0; + int p; + + mutex_lock(&psys->mutex); + mutex_lock(&fh->mutex); + + /* + * Set pg_user to NULL so that completed kcmds don't write + * their result to user space anymore. + */ + for (p = 0; p < IPU_PSYS_CMD_PRIORITY_NUM; p++) + list_for_each_entry(kcmd, &fh->sched.kcmds[p], list) + kcmd->pg_user = NULL; + + /* Prevent scheduler from running more kcmds */ + memset(fh->sched.new_kcmd_tail, 0, + sizeof(fh->sched.new_kcmd_tail)); + + /* Wait until kcmds are completed in this queue and free them */ + for (p = 0; p < IPU_PSYS_CMD_PRIORITY_NUM; p++) { + fh->sched.new_kcmd_tail[p] = NULL; + list_for_each_entry_safe( + kcmd, kcmd0, &fh->sched.kcmds[p], list) { + ipu_psys_kcmd_abort(psys, kcmd); + ipu_psys_kcmd_free(kcmd); + } + } + + /* disable runtime autosuspend for the last fh */ + if (list_empty(&psys->fhs)) + pm_runtime_dont_use_autosuspend(&psys->adev->dev); + + mutex_unlock(&fh->mutex); + mutex_unlock(&psys->mutex); + + return 0; +} + +static struct ipu_psys_kcmd *__ipu_get_completed_kcmd(struct ipu_psys_fh *fh) +{ + int p; + + for (p = 0; p < IPU_PSYS_CMD_PRIORITY_NUM; p++) { + struct ipu_psys_kcmd *kcmd; + + if (list_empty(&fh->sched.kcmds[p])) + continue; + + kcmd = list_first_entry(&fh->sched.kcmds[p], + struct ipu_psys_kcmd, list); + if (kcmd->state != KCMD_STATE_COMPLETE) + continue; + /* Found a kcmd in completed state */ + return kcmd; + + } + + return NULL; +} + +struct ipu_psys_kcmd *ipu_get_completed_kcmd(struct ipu_psys_fh *fh) +{ + struct ipu_psys_kcmd *kcmd; + + mutex_lock(&fh->mutex); + kcmd = __ipu_get_completed_kcmd(fh); + mutex_unlock(&fh->mutex); + + return kcmd; +} + +long ipu_ioctl_dqevent(struct ipu_psys_event *event, + struct ipu_psys_fh *fh, unsigned int f_flags) +{ + struct ipu_psys *psys = fh->psys; + struct ipu_psys_kcmd *kcmd = NULL; + int rval; + + dev_dbg(&psys->adev->dev, "IOC_DQEVENT\n"); + + if (!(f_flags & O_NONBLOCK)) { + rval = wait_event_interruptible(fh->wait, + (kcmd = + ipu_get_completed_kcmd(fh))); + if (rval == -ERESTARTSYS) + return rval; + } + + mutex_lock(&fh->mutex); + if (!kcmd) { + kcmd = __ipu_get_completed_kcmd(fh); + if (!kcmd) { + mutex_unlock(&fh->mutex); + return -ENODATA; + } + } + + *event = kcmd->ev; + ipu_psys_kcmd_free(kcmd); + mutex_unlock(&fh->mutex); + + return 0; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4-resources.c b/drivers/media/pci/intel/ipu4/ipu4-resources.c new file mode 100644 index 0000000000000..097ea1bb7ed91 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4-resources.c @@ -0,0 +1,461 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2015 - 2018 Intel Corporation + +#include +#include +#include +#include +#include + +#include + +#include "ipu-fw-psys.h" +#include "ipu-psys.h" + +static int ipu_resource_init(struct ipu_resource *res, u32 id, int elements) +{ + if (elements <= 0) { + res->bitmap = NULL; + return 0; + } + + res->bitmap = kcalloc(BITS_TO_LONGS(elements), sizeof(long), + GFP_KERNEL); + if (!res->bitmap) + return -ENOMEM; + res->elements = elements; + res->id = id; + return 0; +} + +static unsigned long +ipu_resource_alloc(struct ipu_resource *res, int n, + struct ipu_resource_alloc *alloc, + enum ipu_resource_type type) +{ + unsigned long p; + + if (n <= 0) { + alloc->elements = 0; + return 0; + } + + if (!res->bitmap) + return (unsigned long)(-ENOSPC); + + p = bitmap_find_next_zero_area(res->bitmap, res->elements, 0, n, 0); + alloc->resource = NULL; + + if (p >= res->elements) + return (unsigned long)(-ENOSPC); + bitmap_set(res->bitmap, p, n); + alloc->resource = res; + alloc->elements = n; + alloc->pos = p; + alloc->type = type; + + return p; +} + +static void ipu_resource_free(struct ipu_resource_alloc *alloc) +{ + if (alloc->elements <= 0) + return; + + if (alloc->type == IPU_RESOURCE_DFM) + *alloc->resource->bitmap &= ~(unsigned long)(alloc->elements); + else + bitmap_clear(alloc->resource->bitmap, alloc->pos, + alloc->elements); + alloc->resource = NULL; +} + +static void ipu_resource_cleanup(struct ipu_resource *res) +{ + kfree(res->bitmap); + res->bitmap = NULL; +} + +/********** IPU PSYS-specific resource handling **********/ + +int ipu_psys_resource_pool_init(struct ipu_psys_resource_pool + *pool) +{ + int i, j, k, ret; + + pool->cells = 0; + + for (i = 0; i < res_defs->num_dev_channels; i++) { + ret = ipu_resource_init(&pool->dev_channels[i], i, + res_defs->dev_channels[i]); + if (ret) + goto error; + } + + for (j = 0; j < res_defs->num_ext_mem_ids; j++) { + ret = ipu_resource_init(&pool->ext_memory[j], j, + res_defs->ext_mem_ids[j]); + if (ret) + goto memory_error; + } + + for (k = 0; k < res_defs->num_dfm_ids; k++) { + ret = ipu_resource_init(&pool->dfms[k], k, res_defs->dfms[k]); + if (ret) + goto dfm_error; + } + + return 0; + +dfm_error: + for (k--; k >= 0; k--) + ipu_resource_cleanup(&pool->dfms[k]); + +memory_error: + for (j--; j >= 0; j--) + ipu_resource_cleanup(&pool->ext_memory[j]); + +error: + for (i--; i >= 0; i--) + ipu_resource_cleanup(&pool->dev_channels[i]); + return ret; +} + + +void ipu_psys_resource_pool_cleanup(struct ipu_psys_resource_pool + *pool) +{ + u32 i; + + for (i = 0; i < res_defs->num_dev_channels; i++) + ipu_resource_cleanup(&pool->dev_channels[i]); + + for (i = 0; i < res_defs->num_ext_mem_ids; i++) + ipu_resource_cleanup(&pool->ext_memory[i]); + + for (i = 0; i < res_defs->num_dfm_ids; i++) + ipu_resource_cleanup(&pool->dfms[i]); +} + +static int ipu_psys_allocate_one_resource(const struct device *dev, + struct ipu_fw_psys_process *process, + struct ipu_resource *resource, + struct ipu_fw_generic_program_manifest *pm, + u32 resource_id, + struct ipu_psys_resource_alloc *alloc) +{ + const u16 resource_req = pm->dev_chn_size[resource_id]; + unsigned long retl; + + if (resource_req <= 0) + return 0; + + if (alloc->resources >= IPU_MAX_RESOURCES) { + dev_err(dev, "out of resource handles\n"); + return -ENOSPC; + } + retl = ipu_resource_alloc + (resource, resource_req, + &alloc->resource_alloc[alloc->resources], + IPU_RESOURCE_DEV_CHN); + if (IS_ERR_VALUE(retl)) { + dev_dbg(dev, "out of device channel resources\n"); + return (int)retl; + } + alloc->resources++; + + return 0; +} + +/* + * ext_mem_type_id is a generic type id for memory (like DMEM, VMEM) + * ext_mem_bank_id is detailed type id for memory (like DMEM0, DMEM1 etc.) + */ +static int ipu_psys_allocate_memory_resource( + const struct device *dev, + struct ipu_fw_psys_process *process, + struct ipu_resource *resource, + struct ipu_fw_generic_program_manifest *pm, + u32 ext_mem_type_id, u32 ext_mem_bank_id, + struct ipu_psys_resource_alloc *alloc) +{ + const u16 memory_resource_req = pm->ext_mem_size[ext_mem_type_id]; + + unsigned long retl; + + if (memory_resource_req <= 0) + return 0; + + if (alloc->resources >= IPU_MAX_RESOURCES) { + dev_err(dev, "out of resource handles\n"); + return -ENOSPC; + } + retl = ipu_resource_alloc + (resource, memory_resource_req, + &alloc->resource_alloc[alloc->resources], + IPU_RESOURCE_EXT_MEM); + if (IS_ERR_VALUE(retl)) { + dev_dbg(dev, "out of memory resources\n"); + return (int)retl; + } + + alloc->resources++; + + return 0; +} + +/* + * Allocate resources for pg from `pool'. Mark the allocated + * resources into `alloc'. Returns 0 on success, -ENOSPC + * if there are no enough resources, in which cases resources + * are not allocated at all, or some other error on other conditions. + */ +int ipu_psys_allocate_resources(const struct device *dev, + struct ipu_fw_psys_process_group *pg, + void *pg_manifest, + struct ipu_psys_resource_alloc + *alloc, struct ipu_psys_resource_pool + *pool) +{ + u32 resid; + u32 mem_type_id; + int ret, i; + u16 *process_offset_table; + u8 processes; + u32 cells = 0; + + if (!pg) + return -EINVAL; + process_offset_table = (u16 *)((u8 *) pg + pg->processes_offset); + processes = pg->process_count; + + for (i = 0; i < processes; i++) { + u32 cell; + struct ipu_fw_psys_process *process = + (struct ipu_fw_psys_process *) + ((char *)pg + process_offset_table[i]); + struct ipu_fw_generic_program_manifest pm; + + memset(&pm, 0, sizeof(pm)); + if (!process) { + dev_err(dev, "can not get process\n"); + ret = -ENOENT; + goto free_out; + } + + ret = ipu_fw_psys_get_program_manifest_by_process(&pm, + pg_manifest, + process); + if (ret < 0) { + dev_err(dev, "can not get manifest\n"); + goto free_out; + } + + if (pm.cell_id == res_defs->num_cells && + pm.cell_type_id == res_defs->num_cells_type) { + dev_dbg(dev, "ignore the cell requirement\n"); + cell = res_defs->num_cells; + } else if ((pm.cell_id != res_defs->num_cells && + pm.cell_type_id == res_defs->num_cells_type)) { + cell = ipu_fw_psys_get_process_cell_id(process, 0); + } else { + /* Find a free cell of desired type */ + u32 type = pm.cell_type_id; + + for (cell = 0; cell < res_defs->num_cells; cell++) + if (res_defs->cells[cell] == type && + ((pool->cells | cells) & (1 << cell)) == 0) + break; + if (cell >= res_defs->num_cells) { + dev_dbg(dev, "no free cells of right type\n"); + ret = -ENOSPC; + goto free_out; + } + ret = ipu_fw_psys_set_process_cell_id(process, 0, cell); + if (ret) + goto free_out; + } + if (cell < res_defs->num_cells) + cells |= 1 << cell; + if (pool->cells & cells) { + dev_dbg(dev, "out of cell resources\n"); + ret = -ENOSPC; + goto free_out; + } + if (pm.dev_chn_size) { + for (resid = 0; resid < res_defs->num_dev_channels; resid++) { + ret = ipu_psys_allocate_one_resource + (dev, process, + &pool->dev_channels[resid], &pm, resid, alloc); + if (ret) + goto free_out; + ret = ipu_fw_psys_set_process_dev_chn_offset(process, resid, + alloc->resource_alloc[alloc->resources - 1].pos); + if (ret) + goto free_out; + } + } + + if (pm.ext_mem_size) { + for (mem_type_id = 0; + mem_type_id < res_defs->num_ext_mem_types; mem_type_id++) { + u32 mem_bank_id = res_defs->num_ext_mem_ids; + + if (cell != res_defs->num_cells) + mem_bank_id = + res_defs->cell_mem[res_defs->cell_mem_row * + cell + mem_type_id]; + if (mem_bank_id == res_defs->num_ext_mem_ids) + continue; + + ret = ipu_psys_allocate_memory_resource + (dev, process, + &pool->ext_memory[mem_bank_id], + &pm, mem_type_id, mem_bank_id, alloc); + if (ret) + goto free_out; + /* no return value check here because fw api will + * do some checks, and would return non-zero + * except mem_type_id == 0. This may be caused by that + * above flow if allocating mem_bank_id is improper + */ + ipu_fw_psys_set_process_ext_mem + (process, mem_type_id, mem_bank_id, + alloc->resource_alloc[alloc->resources - 1].pos); + } + } + } + alloc->cells |= cells; + pool->cells |= cells; + return 0; + +free_out: + for (; i >= 0; i--) { + struct ipu_fw_psys_process *process = + (struct ipu_fw_psys_process *) + ((char *)pg + process_offset_table[i]); + struct ipu_fw_generic_program_manifest pm; + int retval; + + if (!process) + break; + + retval = ipu_fw_psys_get_program_manifest_by_process + (&pm, pg_manifest, process); + if (retval < 0) + break; + if ((pm.cell_id != res_defs->num_cells && + pm.cell_type_id == res_defs->num_cells_type)) + continue; + /* no return value check here because if finding free cell + * failed, process cell would not set then calling clear_cell + * will return non-zero. + */ + ipu_fw_psys_clear_process_cell(process); + } + dev_dbg(dev, "failed to allocate resources, ret %d\n", ret); + ipu_psys_free_resources(alloc, pool); + return ret; +} + +int ipu_psys_move_resources(const struct device *dev, + struct ipu_psys_resource_alloc *alloc, + struct ipu_psys_resource_pool + *source_pool, struct ipu_psys_resource_pool + *target_pool) +{ + int i; + + if (target_pool->cells & alloc->cells) { + dev_dbg(dev, "out of cell resources\n"); + return -ENOSPC; + } + + for (i = 0; i < alloc->resources; i++) { + unsigned long bitmap = 0; + unsigned int id = alloc->resource_alloc[i].resource->id; + unsigned long fbit, end; + + switch (alloc->resource_alloc[i].type) { + case IPU_RESOURCE_DEV_CHN: + bitmap_set(&bitmap, alloc->resource_alloc[i].pos, + alloc->resource_alloc[i].elements); + if (*target_pool->dev_channels[id].bitmap & bitmap) + return -ENOSPC; + break; + case IPU_RESOURCE_EXT_MEM: + end = alloc->resource_alloc[i].elements + + alloc->resource_alloc[i].pos; + + fbit = find_next_bit(target_pool->ext_memory[id].bitmap, + end, alloc->resource_alloc[i].pos); + /* if find_next_bit returns "end" it didn't find 1bit */ + if (end != fbit) + return -ENOSPC; + break; + case IPU_RESOURCE_DFM: + bitmap = alloc->resource_alloc[i].elements; + if (*target_pool->dfms[id].bitmap & bitmap) + return -ENOSPC; + break; + default: + dev_err(dev, "Illegal resource type\n"); + return -EINVAL; + } + } + + for (i = 0; i < alloc->resources; i++) { + u32 id = alloc->resource_alloc[i].resource->id; + + switch (alloc->resource_alloc[i].type) { + case IPU_RESOURCE_DEV_CHN: + bitmap_set(target_pool->dev_channels[id].bitmap, + alloc->resource_alloc[i].pos, + alloc->resource_alloc[i].elements); + ipu_resource_free(&alloc->resource_alloc[i]); + alloc->resource_alloc[i].resource = + &target_pool->dev_channels[id]; + break; + case IPU_RESOURCE_EXT_MEM: + bitmap_set(target_pool->ext_memory[id].bitmap, + alloc->resource_alloc[i].pos, + alloc->resource_alloc[i].elements); + ipu_resource_free(&alloc->resource_alloc[i]); + alloc->resource_alloc[i].resource = + &target_pool->ext_memory[id]; + break; + case IPU_RESOURCE_DFM: + *target_pool->dfms[id].bitmap |= + alloc->resource_alloc[i].elements; + *alloc->resource_alloc[i].resource->bitmap &= + ~(alloc->resource_alloc[i].elements); + alloc->resource_alloc[i].resource = + &target_pool->dfms[id]; + break; + default: + /* + * Just keep compiler happy. This case failed already + * in above loop. + */ + break; + } + } + + target_pool->cells |= alloc->cells; + source_pool->cells &= ~alloc->cells; + + return 0; +} + +/* Free resources marked in `alloc' from `resources' */ +void ipu_psys_free_resources(struct ipu_psys_resource_alloc + *alloc, struct ipu_psys_resource_pool *pool) +{ + unsigned int i; + + pool->cells &= ~alloc->cells; + alloc->cells = 0; + for (i = 0; i < alloc->resources; i++) + ipu_resource_free(&alloc->resource_alloc[i]); + alloc->resources = 0; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4.c b/drivers/media/pci/intel/ipu4/ipu4.c new file mode 100644 index 0000000000000..fe1ddcbad22f3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4.c @@ -0,0 +1,572 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Intel Corporation + +#include +#include +#include +#include +#include + +#include "ipu.h" +#include "ipu-cpd.h" +#include "ipu-isys.h" +#include "ipu-buttress.h" +#include "ipu-psys.h" +#include "ipu-platform.h" +#include "ipu-platform-regs.h" +#include "ipu-platform-buttress-regs.h" + +#ifdef CONFIG_VIDEO_INTEL_IPU4 +static struct ipu_receiver_electrical_params ipu4_ev_params[] = { + {0, 1500000000ul / 2, IPU_PCI_ID, IPU_HW_BXT_P_B1_REV, + .rcomp_val_combo = 11, + .rcomp_val_legacy = 11, + .ports[0].crc_val = 18, + .ports[0].drc_val = 29, + .ports[0].drc_val_combined = 29, + .ports[0].ctle_val = 4, + .ports[1].crc_val = 18, + .ports[1].drc_val = 29, + .ports[1].drc_val_combined = 31, + .ports[1].ctle_val = 4 + }, + {0, 1500000000ul / 2, IPU_PCI_ID, IPU_HW_BXT_P_D0_REV, + .rcomp_val_combo = 11, + .rcomp_val_legacy = 11, + .ports[0].crc_val = 18, + .ports[0].drc_val = 29, + .ports[0].drc_val_combined = 29, + .ports[0].ctle_val = 4, + .ports[1].crc_val = 18, + .ports[1].drc_val = 29, + .ports[1].drc_val_combined = 31, + .ports[1].ctle_val = 4 + }, + {0, 1500000000ul / 2, IPU_PCI_ID, IPU_HW_BXT_P_E0_REV, + .rcomp_val_combo = 11, + .rcomp_val_legacy = 11, + .ports[0].crc_val = 18, + .ports[0].drc_val = 29, + .ports[0].drc_val_combined = 29, + .ports[0].ctle_val = 4, + .ports[1].crc_val = 18, + .ports[1].drc_val = 29, + .ports[1].drc_val_combined = 31, + .ports[1].ctle_val = 4 + }, + {}, +}; + +static unsigned int ipu4_csi_offsets[] = { + 0x64000, 0x65000, 0x66000, 0x67000, 0x6C000, 0x6C800 +}; + +static unsigned char ipu4_csi_evlanecombine[] = { + 0, 0, 0, 0, 2, 0 +}; + +static unsigned int ipu4_tpg_offsets[] = { + IPU_TPG0_ADDR_OFFSET, + IPU_TPG1_ADDR_OFFSET +}; + +static unsigned int ipu4_tpg_sels[] = { + IPU_GPOFFSET + IPU_GPREG_MIPI_PKT_GEN0_SEL, + IPU_COMBO_GPOFFSET + IPU_GPREG_MIPI_PKT_GEN1_SEL +}; + +const struct ipu_isys_internal_pdata isys_ipdata = { + .csi2 = { + .nports = ARRAY_SIZE(ipu4_csi_offsets), + .offsets = ipu4_csi_offsets, + .evparams = ipu4_ev_params, + .evlanecombine = ipu4_csi_evlanecombine, + .evsetmask0 = 1 << 4, /* CSI port 4 */ + .evsetmask1 = 1 << 5, /* CSI port 5 */ + }, + .tpg = { + .ntpgs = ARRAY_SIZE(ipu4_tpg_offsets), + .offsets = ipu4_tpg_offsets, + .sels = ipu4_tpg_sels, + }, + .hw_variant = { + .offset = IPU_ISYS_OFFSET, + .nr_mmus = 2, + .mmu_hw = { + { + .offset = IPU_ISYS_IOMMU0_OFFSET, + .info_bits = + IPU_INFO_REQUEST_DESTINATION_PRIMARY, + .nr_l1streams = 0, + .nr_l2streams = 0, + .insert_read_before_invalidate = true, + }, + { + .offset = IPU_ISYS_IOMMU1_OFFSET, + .info_bits = IPU_INFO_STREAM_ID_SET(0), + .nr_l1streams = IPU_MMU_MAX_TLB_L1_STREAMS, + .l1_block_sz = { + 8, 16, 16, 16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 8 + }, + .l1_zlw_en = { + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 + }, + .l1_zlw_1d_mode = { + 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }, + .l1_ins_zlw_ahead_pages = { + 0, 3, 3, 3, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 + }, + .l1_zlw_2d_mode = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + }, + .nr_l2streams = IPU_MMU_MAX_TLB_L2_STREAMS, + .l2_block_sz = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2 + }, + .insert_read_before_invalidate = false, + .zlw_invalidate = true, + .l1_stream_id_reg_offset = + IPU_MMU_L1_STREAM_ID_REG_OFFSET, + .l2_stream_id_reg_offset = + IPU_MMU_L2_STREAM_ID_REG_OFFSET, + }, + }, + .dmem_offset = IPU_ISYS_DMEM_OFFSET, + .spc_offset = IPU_ISYS_SPC_OFFSET, + }, + .num_parallel_streams = IPU_ISYS_NUM_STREAMS, + .isys_dma_overshoot = IPU_ISYS_OVERALLOC_MIN, +}; + +const struct ipu_psys_internal_pdata psys_ipdata = { + .hw_variant = { + .offset = IPU_PSYS_OFFSET, + .nr_mmus = 3, + .mmu_hw = { + { + .offset = IPU_PSYS_IOMMU0_OFFSET, + .info_bits = + IPU_INFO_REQUEST_DESTINATION_PRIMARY, + .nr_l1streams = 0, + .nr_l2streams = 0, + .insert_read_before_invalidate = true, + }, + { + .offset = IPU_PSYS_IOMMU1_OFFSET, + .info_bits = IPU_INFO_STREAM_ID_SET(0), + .nr_l1streams = IPU_MMU_MAX_TLB_L1_STREAMS, + .l1_block_sz = { + 0, 0, 0, 0, 10, 8, 10, 8, 0, + 4, 4, 12, 0, 0, 0, 8 + }, + .l1_zlw_en = { + 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, + 1, 1, 0, 0, 0, 0 + }, + .l1_zlw_1d_mode = { + 0, 0, 0, 0, 1, 1, 1, 1, 0, + 1, 1, 1, 0, 0, 0, 0 + }, + .l1_ins_zlw_ahead_pages = { + 0, 0, 0, 0, 3, 3, + 3, 3, 0, 3, 1, 3, + 0, 0, 0, 0 + }, + .l1_zlw_2d_mode = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + }, + .nr_l2streams = IPU_MMU_MAX_TLB_L2_STREAMS, + .l2_block_sz = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2 + }, + .insert_read_before_invalidate = false, + .zlw_invalidate = true, + .l1_stream_id_reg_offset = + IPU_MMU_L1_STREAM_ID_REG_OFFSET, + .l2_stream_id_reg_offset = + IPU_MMU_L2_STREAM_ID_REG_OFFSET, + }, + { + .offset = IPU_PSYS_IOMMU1R_OFFSET, + .info_bits = IPU_INFO_STREAM_ID_SET(0), + .nr_l1streams = IPU_MMU_MAX_TLB_L1_STREAMS, + .l1_block_sz = { + 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 16, 12, 12, 16 + }, + .l1_zlw_en = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 1, 1 + }, + .l1_zlw_1d_mode = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 1, 1 + }, + .l1_ins_zlw_ahead_pages = { + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0 + }, + .l1_zlw_2d_mode = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1 + }, + .nr_l2streams = IPU_MMU_MAX_TLB_L2_STREAMS, + .l2_block_sz = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2 + }, + .insert_read_before_invalidate = false, + .zlw_invalidate = true, + .l1_stream_id_reg_offset = + IPU_MMU_L1_STREAM_ID_REG_OFFSET, + .l2_stream_id_reg_offset = + IPU_MMU_L2_STREAM_ID_REG_OFFSET, + }, + }, + .dmem_offset = IPU_PSYS_DMEM_OFFSET, + .spc_offset = IPU_PSYS_SPC_OFFSET, + }, +}; + +/* + * This is meant only as reference for initialising the buttress control, + * because the different HW stepping can have different initial values + * + * There is a HW bug and IS_PWR and PS_PWR fields cannot be used to + * detect if power on/off is ready. Using IS_PWR_FSM and PS_PWR_FSM + * fields instead. + */ +const struct ipu_buttress_ctrl isys_buttress_ctrl = { + .divisor = IS_FREQ_CTL_DIVISOR, + .qos_floor = 0, + .freq_ctl = BUTTRESS_REG_IS_FREQ_CTL, + .pwr_sts_shift = BUTTRESS_PWR_STATE_IS_PWR_FSM_SHIFT, + .pwr_sts_mask = BUTTRESS_PWR_STATE_IS_PWR_FSM_MASK, + .pwr_sts_on = BUTTRESS_PWR_STATE_IS_PWR_FSM_IS_RDY, + .pwr_sts_off = BUTTRESS_PWR_STATE_IS_PWR_FSM_IDLE, +}; + +/* + * This is meant only as reference for initialising the buttress control, + * because the different HW stepping can have different initial values + */ + +const struct ipu_buttress_ctrl psys_buttress_ctrl = { + .divisor = PS_FREQ_CTL_DEFAULT_RATIO, + .qos_floor = PS_FREQ_CTL_DEFAULT_RATIO, + .freq_ctl = BUTTRESS_REG_PS_FREQ_CTL, + .pwr_sts_shift = BUTTRESS_PWR_STATE_PS_PWR_FSM_SHIFT, + .pwr_sts_mask = BUTTRESS_PWR_STATE_PS_PWR_FSM_MASK, + .pwr_sts_on = BUTTRESS_PWR_STATE_PS_PWR_FSM_PS_PWR_UP, + .pwr_sts_off = BUTTRESS_PWR_STATE_PS_PWR_FSM_IDLE, +}; +#endif + +#ifdef CONFIG_VIDEO_INTEL_IPU4P + +/* + * ipu4p available hw ports start from sip0 port3 + * available ports are: + * s0p3, s1p0, s1p1, s1p2, s1p3 + */ +static unsigned int ipu4p_csi_offsets[] = { + 0x64300, 0x6c000, 0x6c100, 0x6c200, 0x6c300, 0x6c400, 0x6c500, 0x6c600 +}; + +static unsigned char ipu4p_csi_evlanecombine[] = { + 0, 0, 0, 0, 0, 0 +}; + +static unsigned int ipu4p_tpg_offsets[] = { + IPU_TPG0_ADDR_OFFSET, + IPU_TPG1_ADDR_OFFSET +}; + +static unsigned int ipu4p_tpg_sels[] = { + IPU_GPOFFSET + IPU_GPREG_MIPI_PKT_GEN0_SEL, + IPU_COMBO_GPOFFSET + IPU_GPREG_MIPI_PKT_GEN1_SEL +}; + +const struct ipu_isys_internal_pdata isys_ipdata = { + .csi2 = { + .nports = ARRAY_SIZE(ipu4p_csi_offsets), + .offsets = ipu4p_csi_offsets, + .evlanecombine = ipu4p_csi_evlanecombine, + }, + .tpg = { + .ntpgs = ARRAY_SIZE(ipu4p_tpg_offsets), + .offsets = ipu4p_tpg_offsets, + .sels = ipu4p_tpg_sels, + }, + .hw_variant = { + .offset = IPU_ISYS_OFFSET, + .nr_mmus = 2, + .mmu_hw = { + { + .offset = IPU_ISYS_IOMMU0_OFFSET, + .info_bits = + IPU_INFO_REQUEST_DESTINATION_PRIMARY, + .nr_l1streams = 0, + .nr_l2streams = 0, + .insert_read_before_invalidate = true, + }, + { + .offset = IPU_ISYS_IOMMU1_OFFSET, + .info_bits = IPU_INFO_STREAM_ID_SET(0), + .nr_l1streams = IPU_MMU_MAX_TLB_L1_STREAMS, + .l1_block_sz = { + 5, 16, 6, 6, 6, 6, 6, 8, 0, + 0, 0, 0, 0, 0, 0, 5 + }, + .l1_zlw_en = { + 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0 + }, + .l1_zlw_1d_mode = { + 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0 + }, + .l1_ins_zlw_ahead_pages = { + 0, 3, 3, 3, 3, 3, + 3, 3, 0, 0, 0, 0, + 0, 0, 0, 0 + }, + .l1_zlw_2d_mode = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + }, + .nr_l2streams = IPU_MMU_MAX_TLB_L2_STREAMS, + .l2_block_sz = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2 + }, + .insert_read_before_invalidate = false, + .zlw_invalidate = true, + .l1_stream_id_reg_offset = + IPU_MMU_L1_STREAM_ID_REG_OFFSET, + .l2_stream_id_reg_offset = + IPU_MMU_L2_STREAM_ID_REG_OFFSET, + }, + }, + .dmem_offset = IPU_ISYS_DMEM_OFFSET, + .spc_offset = IPU_ISYS_SPC_OFFSET, + }, + .num_parallel_streams = IPU_ISYS_NUM_STREAMS, + .isys_dma_overshoot = IPU_ISYS_OVERALLOC_MIN, +}; + +const struct ipu_psys_internal_pdata psys_ipdata = { + .hw_variant = { + .offset = IPU_PSYS_OFFSET, + .nr_mmus = 3, + .mmu_hw = { + { + .offset = IPU_PSYS_IOMMU0_OFFSET, + .info_bits = + IPU_INFO_REQUEST_DESTINATION_PRIMARY, + .nr_l1streams = 0, + .nr_l2streams = 0, + .insert_read_before_invalidate = true, + }, + { + .offset = IPU_PSYS_IOMMU1_OFFSET, + .info_bits = IPU_INFO_STREAM_ID_SET(0), + .nr_l1streams = IPU_MMU_MAX_TLB_L1_STREAMS, + .l1_block_sz = { + 2, 5, 4, 2, 2, 10, 5, 16, 10, + 5, 0, 0, 0, 0, 0, 3 + }, + .l1_zlw_en = { + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0 + }, + .l1_zlw_1d_mode = { + 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0 + }, + .l1_ins_zlw_ahead_pages = { + 0, 0, 3, 3, 3, 3, + 3, 3, 3, 3, 0, 0, + 0, 0, 0, 0 + }, + .l1_zlw_2d_mode = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + }, + .nr_l2streams = IPU_MMU_MAX_TLB_L2_STREAMS, + .l2_block_sz = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2 + }, + .insert_read_before_invalidate = false, + .zlw_invalidate = true, + .l1_stream_id_reg_offset = + IPU_MMU_L1_STREAM_ID_REG_OFFSET, + .l2_stream_id_reg_offset = + IPU_MMU_L2_STREAM_ID_REG_OFFSET, + }, + { + .offset = IPU_PSYS_IOMMU1R_OFFSET, + .info_bits = IPU_INFO_STREAM_ID_SET(0), + .nr_l1streams = IPU_MMU_MAX_TLB_L1_STREAMS, + .l1_block_sz = { + 2, 6, 5, 16, 16, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 3 + }, + .l1_zlw_en = { + 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 + }, + .l1_zlw_1d_mode = { + 0, 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + }, + .l1_ins_zlw_ahead_pages = { + 0, 0, 3, 3, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 + }, + .l1_zlw_2d_mode = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + }, + .nr_l2streams = IPU_MMU_MAX_TLB_L2_STREAMS, + .l2_block_sz = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2 + }, + .insert_read_before_invalidate = false, + .zlw_invalidate = true, + .l1_stream_id_reg_offset = + IPU_MMU_L1_STREAM_ID_REG_OFFSET, + .l2_stream_id_reg_offset = + IPU_MMU_L2_STREAM_ID_REG_OFFSET, + }, + }, + .dmem_offset = IPU_PSYS_DMEM_OFFSET, + .spc_offset = IPU_PSYS_SPC_OFFSET, + }, +}; + +const struct ipu_buttress_ctrl isys_buttress_ctrl = { + .divisor = IS_FREQ_CTL_DIVISOR, + .qos_floor = 0, + .ovrd = 0, + .freq_ctl = BUTTRESS_REG_IS_FREQ_CTL, + .divisor_shift = BUTTRESS_REG_IS_FREQ_CTL_RATIO_SHIFT, + .pwr_sts_shift = BUTTRESS_PWR_STATE_IS_PWR_FSM_SHIFT, + .pwr_sts_mask = BUTTRESS_PWR_STATE_IS_PWR_FSM_MASK, + .pwr_sts_on = BUTTRESS_PWR_STATE_IS_PWR_FSM_IS_RDY, + .pwr_sts_off = BUTTRESS_PWR_STATE_IS_PWR_FSM_IDLE, +}; + +const struct ipu_buttress_ctrl psys_buttress_ctrl = { + .divisor = PS_FREQ_CTL_DEFAULT_RATIO, + .qos_floor = PS_FREQ_CTL_DEFAULT_RATIO, + .ovrd = 1, + .freq_ctl = BUTTRESS_REG_PS_FREQ_CTL, + .divisor_shift = BUTTRESS_REG_PS_FREQ_CTL_RATIO_SHIFT, + .ovrd_shift = BUTTRESS_REG_PS_FREQ_CTL_OVRD_SHIFT, + .pwr_sts_shift = BUTTRESS_PWR_STATE_PS_PWR_FSM_SHIFT, + .pwr_sts_mask = BUTTRESS_PWR_STATE_PS_PWR_FSM_MASK, + .pwr_sts_on = BUTTRESS_PWR_STATE_PS_PWR_FSM_PS_PWR_UP, + .pwr_sts_off = BUTTRESS_PWR_STATE_PS_PWR_FSM_IDLE, +}; +#endif + +void ipu_configure_spc(struct ipu_device *isp, + const struct ipu_hw_variants *hw_variant, + int pkg_dir_idx, void __iomem *base, u64 *pkg_dir, + dma_addr_t pkg_dir_dma_addr) +{ + u32 val; + void __iomem *dmem_base = base + hw_variant->dmem_offset; + void __iomem *spc_regs_base = base + hw_variant->spc_offset; + + val = readl(spc_regs_base + IPU_PSYS_REG_SPC_STATUS_CTRL); + val |= IPU_PSYS_SPC_STATUS_CTRL_ICACHE_INVALIDATE; + writel(val, spc_regs_base + IPU_PSYS_REG_SPC_STATUS_CTRL); + + if (isp->secure_mode) { + writel(IPU_PKG_DIR_IMR_OFFSET, dmem_base); + } else { + u32 server_addr; + + server_addr = ipu_cpd_pkg_dir_get_address(pkg_dir, pkg_dir_idx); + + writel(server_addr + + ipu_cpd_get_pg_icache_base(isp, pkg_dir_idx, + isp->cpd_fw->data, + isp->cpd_fw->size), + spc_regs_base + IPU_PSYS_REG_SPC_ICACHE_BASE); + writel(ipu_cpd_get_pg_entry_point(isp, pkg_dir_idx, + isp->cpd_fw->data, + isp->cpd_fw->size), + spc_regs_base + IPU_PSYS_REG_SPC_START_PC); + writel(IPU_INFO_REQUEST_DESTINATION_PRIMARY, + spc_regs_base + + IPU_REG_PSYS_INFO_SEG_0_CONFIG_ICACHE_MASTER); + writel(pkg_dir_dma_addr, dmem_base); + } +} +EXPORT_SYMBOL(ipu_configure_spc); + +int ipu_buttress_psys_freq_get(void *data, u64 *val) +{ + struct ipu_device *isp = data; + u32 reg_val, ratio; + int rval; + + rval = pm_runtime_get_sync(&isp->psys->dev); + if (rval < 0) { + pm_runtime_put(&isp->psys->dev); + dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n", rval); + return rval; + } + + reg_val = readl(isp->base + BUTTRESS_REG_PS_FREQ_CAPABILITIES); + + pm_runtime_put(&isp->psys->dev); + + ratio = (reg_val & + BUTTRESS_PS_FREQ_CAPABILITIES_LAST_RESOLVED_RATIO_MASK) >> + BUTTRESS_PS_FREQ_CAPABILITIES_LAST_RESOLVED_RATIO_SHIFT; + + *val = BUTTRESS_PS_FREQ_STEP * ratio; + + return 0; +} + +int ipu_buttress_isys_freq_get(void *data, u64 *val) +{ + struct ipu_device *isp = data; + u32 reg_val; + int rval; + + rval = pm_runtime_get_sync(&isp->isys->dev); + if (rval < 0) { + pm_runtime_put(&isp->isys->dev); + dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n", rval); + return rval; + } + + reg_val = readl(isp->base + BUTTRESS_REG_IS_FREQ_CTL); + + pm_runtime_put(&isp->isys->dev); + + /* Input system frequency specified as 1600MHz/divisor */ + *val = 1600 / (reg_val & BUTTRESS_IS_FREQ_CTL_DIVISOR_MASK); + + return 0; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4pisys_inc b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4pisys_inc new file mode 100644 index 0000000000000..90a2ab46510c3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4pisys_inc @@ -0,0 +1,26 @@ +IPU_ISYSLIB_INC = \ + -I$(IPU_ISYSLIB_ROOT)/buffer/interface \ + -I$(IPU_ISYSLIB_ROOT)/cell/interface \ + -I$(IPU_ISYSLIB_ROOT)/cell/src \ + -I$(IPU_ISYSLIB_ROOT)/device_access/interface \ + -I$(IPU_ISYSLIB_ROOT)/device_access/src \ + -I$(IPU_ISYSLIB_ROOT)/devices \ + -I$(IPU_ISYSLIB_ROOT)/devices/interface \ + -I$(IPU_ISYSLIB_ROOT)/devices/isys/cnlB0 \ + -I$(IPU_ISYSLIB_ROOT)/devices/src \ + -I$(IPU_ISYSLIB_ROOT)/fw_abi_common_types \ + -I$(IPU_ISYSLIB_ROOT)/fw_abi_common_types/cpu \ + -I$(IPU_ISYSLIB_ROOT)/isysapi/interface \ + -I$(IPU_ISYSLIB_ROOT)/pkg_dir/interface \ + -I$(IPU_ISYSLIB_ROOT)/pkg_dir/src \ + -I$(IPU_ISYSLIB_ROOT)/port/interface \ + -I$(IPU_ISYSLIB_ROOT)/reg_dump/src/isys/cnlB0_gen_reg_dump \ + -I$(IPU_ISYSLIB_ROOT)/regmem/interface \ + -I$(IPU_ISYSLIB_ROOT)/regmem/src \ + -I$(IPU_ISYSLIB_ROOT)/support \ + -I$(IPU_ISYSLIB_ROOT)/syscom/interface \ + -I$(IPU_ISYSLIB_ROOT)/syscom/src \ + -I$(IPU_ISYSLIB_ROOT)/trace/interface \ + -I$(IPU_ISYSLIB_ROOT)/utils/system_defs/ \ + -I$(IPU_ISYSLIB_ROOT)/vied \ + -I$(IPU_ISYSLIB_ROOT)/vied/vied/ \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4pisys_src b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4pisys_src new file mode 100644 index 0000000000000..c20760bdb5f1d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4pisys_src @@ -0,0 +1,19 @@ +IPU_ISYSLIB_SRC = \ + $(IPU_ISYSLIB_ROOT_REL)/isysapi/src/ia_css_isys_private.o \ + $(IPU_ISYSLIB_ROOT_REL)/isysapi/src/ia_css_isys_public.o \ + $(IPU_ISYSLIB_ROOT_REL)/isysapi/src/ia_css_isys_public_trace.o + +ifeq ($(CONFIG_VIDEO_INTEL_IPU), m) +IPU_ISYSLIB_SRC += \ + $(IPU_ISYSLIB_ROOT_REL)/buffer/src/cpu/buffer_access.o \ + $(IPU_ISYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_buffer.o \ + $(IPU_ISYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_input_buffer.o \ + $(IPU_ISYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_output_buffer.o \ + $(IPU_ISYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_shared_buffer.o \ + $(IPU_ISYSLIB_ROOT_REL)/pkg_dir/src/ia_css_pkg_dir.o \ + $(IPU_ISYSLIB_ROOT_REL)/port/src/queue.o \ + $(IPU_ISYSLIB_ROOT_REL)/port/src/recv_port.o \ + $(IPU_ISYSLIB_ROOT_REL)/port/src/send_port.o \ + $(IPU_ISYSLIB_ROOT_REL)/reg_dump/src/reg_dump_generic_bridge.o \ + $(IPU_ISYSLIB_ROOT_REL)/syscom/src/ia_css_syscom.o +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4ppsys_inc b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4ppsys_inc new file mode 100644 index 0000000000000..fb01678242eec --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4ppsys_inc @@ -0,0 +1,52 @@ +IPU_PSYSLIB_INC = \ + -I$(IPU_PSYSLIB_ROOT)/buffer/interface \ + -I$(IPU_PSYSLIB_ROOT)/cell/interface \ + -I$(IPU_PSYSLIB_ROOT)/cell/src \ + -I$(IPU_PSYSLIB_ROOT)/client_pkg/interface \ + -I$(IPU_PSYSLIB_ROOT)/client_pkg/src \ + -I$(IPU_PSYSLIB_ROOT)/cpd/ \ + -I$(IPU_PSYSLIB_ROOT)/cpd/cpd_component/interface \ + -I$(IPU_PSYSLIB_ROOT)/cpd/cpd_metadata/interface \ + -I$(IPU_PSYSLIB_ROOT)/device_access/interface \ + -I$(IPU_PSYSLIB_ROOT)/device_access/src \ + -I$(IPU_PSYSLIB_ROOT)/devices \ + -I$(IPU_PSYSLIB_ROOT)/devices/interface \ + -I$(IPU_PSYSLIB_ROOT)/devices/psys/cnlB0 \ + -I$(IPU_PSYSLIB_ROOT)/devices/src \ + -I$(IPU_PSYSLIB_ROOT)/fw_abi_common_types \ + -I$(IPU_PSYSLIB_ROOT)/fw_abi_common_types/cpu \ + -I$(IPU_PSYSLIB_ROOT)/pkg_dir/interface \ + -I$(IPU_PSYSLIB_ROOT)/pkg_dir/src \ + -I$(IPU_PSYSLIB_ROOT)/port/interface \ + -I$(IPU_PSYSLIB_ROOT)/psys_private_pg/interface \ + -I$(IPU_PSYSLIB_ROOT)/psys_server/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/data/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/data/src \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/device/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/device/interface/cnlB0 \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/dynamic/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/dynamic/src \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/kernel/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/param/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/param/src \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/psys_server_manifest/cnlB0 \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/resource_model/cnlB0 \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/sim/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/sim/src \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/static/interface \ + -I$(IPU_PSYSLIB_ROOT)/psysapi/static/src \ + -I$(IPU_PSYSLIB_ROOT)/reg_dump/src/psys/cnlB0_gen_reg_dump \ + -I$(IPU_PSYSLIB_ROOT)/regmem/interface \ + -I$(IPU_PSYSLIB_ROOT)/regmem/src \ + -I$(IPU_PSYSLIB_ROOT)/routing_bitmap/interface \ + -I$(IPU_PSYSLIB_ROOT)/routing_bitmap/src \ + -I$(IPU_PSYSLIB_ROOT)/support \ + -I$(IPU_PSYSLIB_ROOT)/syscom/interface \ + -I$(IPU_PSYSLIB_ROOT)/syscom/src \ + -I$(IPU_PSYSLIB_ROOT)/trace/interface \ + -I$(IPU_PSYSLIB_ROOT)/vied \ + -I$(IPU_PSYSLIB_ROOT)/vied/vied/ \ + -I$(IPU_PSYSLIB_ROOT)/vied_nci_acb/interface \ + -I$(IPU_PSYSLIB_ROOT)/vied_parameters/interface \ + -I$(IPU_PSYSLIB_ROOT)/vied_parameters/src \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4ppsys_src b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4ppsys_src new file mode 100644 index 0000000000000..3ed88d455baba --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.ipu4ppsys_src @@ -0,0 +1,32 @@ +IPU_PSYSLIB_SRC = \ + $(IPU_PSYSLIB_ROOT_REL)/buffer/src/cpu/buffer_access.o \ + $(IPU_PSYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_buffer.o \ + $(IPU_PSYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_input_buffer.o \ + $(IPU_PSYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_output_buffer.o \ + $(IPU_PSYSLIB_ROOT_REL)/buffer/src/cpu/ia_css_shared_buffer.o \ + $(IPU_PSYSLIB_ROOT_REL)/client_pkg/src/ia_css_client_pkg.o \ + $(IPU_PSYSLIB_ROOT_REL)/pkg_dir/src/ia_css_pkg_dir.o \ + $(IPU_PSYSLIB_ROOT_REL)/port/src/queue.o \ + $(IPU_PSYSLIB_ROOT_REL)/port/src/recv_port.o \ + $(IPU_PSYSLIB_ROOT_REL)/port/src/send_port.o \ + $(IPU_PSYSLIB_ROOT_REL)/psys_server/src/bxt_spctrl_process_group_cmd_impl.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/data/src/ia_css_program_group_data.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/device/src/ia_css_psys_device.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/dynamic/src/ia_css_psys_buffer_set.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/dynamic/src/ia_css_psys_process.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/dynamic/src/ia_css_psys_process_group.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/dynamic/src/ia_css_psys_terminal.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/kernel/src/ia_css_kernel_bitmap.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/param/src/ia_css_program_group_param.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/psys_server_manifest/cnlB0/ia_css_psys_server_manifest.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/resource_model/cnlB0/vied_nci_psys_resource_model.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/sim/src/vied_nci_psys_system.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/static/src/ia_css_psys_program_group_manifest.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/static/src/ia_css_psys_program_manifest.o \ + $(IPU_PSYSLIB_ROOT_REL)/psysapi/static/src/ia_css_psys_terminal_manifest.o \ + $(IPU_PSYSLIB_ROOT_REL)/reg_dump/src/reg_dump_generic_bridge.o \ + $(IPU_PSYSLIB_ROOT_REL)/routing_bitmap/src/ia_css_rbm.o \ + $(IPU_PSYSLIB_ROOT_REL)/routing_bitmap/src/ia_css_rbm_manifest.o \ + $(IPU_PSYSLIB_ROOT_REL)/syscom/src/ia_css_syscom.o \ + $(IPU_PSYSLIB_ROOT_REL)/vied_parameters/src/ia_css_terminal.o \ + $(IPU_PSYSLIB_ROOT_REL)/vied_parameters/src/ia_css_terminal_manifest.o \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.isyslib b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.isyslib new file mode 100644 index 0000000000000..d0816c508ed93 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.isyslib @@ -0,0 +1,42 @@ +ifneq ($(EXTERNAL_BUILD), 1) +srcpath := $(srctree) +endif + +PROGRAMS = isys_fw +SYSTEM = input_system_system +IPU_ISYSLIB_ROOT_REL = ipu4p-css/lib2600 +IPU_ISYSLIB_ROOT = $(srcpath)/$(src)/$(IPU_ISYSLIB_ROOT_REL) + +include $(srcpath)/$(src)/ipu4p-css/Makefile.ipu4pisys_inc +include $(srcpath)/$(src)/ipu4p-css/Makefile.ipu4pisys_src + +intel-ipu4p-isys-csslib-objs := \ + ipu4p-css/libintel-ipu4p.o \ + $(IPU_ISYSLIB_SRC) + +ifeq ($(CONFIG_VIDEO_INTEL_IPU), m) +intel-ipu4p-isys-csslib-objs += ipu4p-css/ipu-wrapper.o +endif +obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu4p-isys-csslib.o + +INCLUDES := -I$(srcpath)/$(src)/$(IPU_ISYSLIB_ROOT_REL) \ + -I$(srcpath)/$(src) \ + $(IPU_ISYSLIB_INC) + +DEFINES:= -D__HOST__ -D__KERNEL__ -DISYS_FPGA -DPSYS_FPGA + +DEFINES += -DSSID=1 +DEFINES += -DMMID=1 +DEFINES += -DPROGNAME=isys_fw +DEFINES += -DPROGMAP=\"isys_fw.map.h\" +DEFINES += -DSUBSYSTEM_INCLUDE=\ +DEFINES += -DCELL=input_system_unis_logic_sp_control_tile_sp +DEFINES += -DSPMAIN=isys_fw +DEFINES += -DRUN_INTEGRATION +DEFINES += -DDEBUG_SP_NCI +DEFINES += -DCFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL=1 +DEFINES += -DHRT_ON_VIED_SUBSYSTEM_ACCESS=0 +DEFINES += -DHRT_USE_VIR_ADDRS +DEFINES += -DHRT_HW + +ccflags-y += $(INCLUDES) $(DEFINES) -fno-common diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.psyslib b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.psyslib new file mode 100644 index 0000000000000..fe954d8e2e623 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/Makefile.psyslib @@ -0,0 +1,14 @@ +ifneq ($(EXTERNAL_BUILD), 1) +srcpath := $(srctree) +endif + +# note: this file only defines INCLUDES paths for lib2600psys +include $(srcpath)/$(src)/ipu4p-css/Makefile.ipu4ppsys_inc + +IPU_PSYSLIB_ROOT = $(srcpath)/$(src)/ipu4p-css/lib2600psys/lib +HOST_DEFINES += -DPSYS_SERVER_ON_SPC +HOST_DEFINES += -DCFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL=1 + +ccflags-y += $(IPU_PSYSLIB_INC) $(HOST_DEFINES) + +obj-$(CONFIG_VIDEO_INTEL_IPU) += ipu4p-css/lib2600psys/ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/ia_css_fw_pkg_release.h b/drivers/media/pci/intel/ipu4/ipu4p-css/ia_css_fw_pkg_release.h new file mode 100644 index 0000000000000..408726c817146 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/ia_css_fw_pkg_release.h @@ -0,0 +1,14 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#define IA_CSS_FW_PKG_RELEASE 0x20181222 diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/ipu-wrapper.c b/drivers/media/pci/intel/ipu4/ipu4p-css/ipu-wrapper.c new file mode 120000 index 0000000000000..3167dda06f067 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/ipu-wrapper.c @@ -0,0 +1 @@ +../../ipu-wrapper.c \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/buffer.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/buffer.mk new file mode 100644 index 0000000000000..c00a1133b440f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/buffer.mk @@ -0,0 +1,43 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is BUFFER + +ifdef _H_BUFFER_MK +$(error ERROR: buffer.mk included multiple times, please check makefile) +else +_H_BUFFER_MK=1 +endif + +BUFFER_DIR=$${MODULES_DIR}/buffer + +BUFFER_INTERFACE=$(BUFFER_DIR)/interface +BUFFER_SOURCES_CPU=$(BUFFER_DIR)/src/cpu +BUFFER_SOURCES_CSS=$(BUFFER_DIR)/src/css + +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_output_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_input_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_shared_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/buffer_access.c +BUFFER_HOST_CPPFLAGS += -I$(BUFFER_INTERFACE) +BUFFER_HOST_CPPFLAGS += -I$${MODULES_DIR}/support + +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_input_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_output_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_shared_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/buffer_access.c + +BUFFER_FW_CPPFLAGS += -I$(BUFFER_INTERFACE) +BUFFER_FW_CPPFLAGS += -I$${MODULES_DIR}/support diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/buffer_access.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/buffer_access.h new file mode 100644 index 0000000000000..e5fe647742c9f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/buffer_access.h @@ -0,0 +1,36 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __BUFFER_ACCESS_H +#define __BUFFER_ACCESS_H + +#include "buffer_type.h" +/* #def to keep consistent the buffer load interfaces for host and css */ +#define IDM 0 + +void +buffer_load( + buffer_address address, + void *data, + unsigned int size, + unsigned int mm_id); + +void +buffer_store( + buffer_address address, + const void *data, + unsigned int size, + unsigned int mm_id); + +#endif /* __BUFFER_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/buffer_type.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/buffer_type.h new file mode 100644 index 0000000000000..de51f23941582 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/buffer_type.h @@ -0,0 +1,29 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __BUFFER_TYPE_H +#define __BUFFER_TYPE_H + +/* portable access to buffers in DDR */ + +#ifdef __VIED_CELL +typedef unsigned int buffer_address; +#else +/* workaround needed because shared_memory_access.h uses size_t */ +#include "type_support.h" +#include "vied/shared_memory_access.h" +typedef host_virtual_address_t buffer_address; +#endif + +#endif /* __BUFFER_TYPE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_buffer_address.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_buffer_address.h new file mode 100644 index 0000000000000..137bfb1fda166 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_buffer_address.h @@ -0,0 +1,24 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BUFFER_ADDRESS_H +#define __IA_CSS_BUFFER_ADDRESS_H + +#include "type_support.h" + +typedef uint32_t ia_css_buffer_address; /* CSS virtual address */ + +#define ia_css_buffer_address_null ((ia_css_buffer_address)0) + +#endif /* __IA_CSS_BUFFER_ADDRESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_input_buffer.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_input_buffer.h new file mode 100644 index 0000000000000..4e92e35b61843 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_input_buffer.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_INPUT_BUFFER_H +#define __IA_CSS_INPUT_BUFFER_H + + +/* Input Buffers */ + +/* A CSS input buffer is a buffer in DDR that can be written by the CPU, + * and that can be read by CSS hardware, after the buffer has been handed over. + * Examples: command buffer, input frame buffer, parameter buffer + * An input buffer must be mapped into the CPU address space before it can be + * written by the CPU. + * After mapping, writing, and unmapping, the buffer can be handed over to the + * firmware. An input buffer is handed over to the CSS by mapping it to the + * CSS address space (by the CPU), and by passing the resulting CSS (virtial) + * address of the input buffer to the DA CSS hardware. + * The firmware can read from an input buffer as soon as it has been received + * CSS virtual address. + * The firmware should not write into an input buffer. + * The firmware hands over the input buffer (back to the CPU) by sending the + * buffer handle via a response. The host should unmap the buffer, + * before reusing it. + * The firmware should not read from the input buffer after returning the + * buffer handle to the CPU. + * + * A buffer may be pre-mapped to the CPU and/or to the CSS upon allocation, + * depending on the allocator's preference. In case of pre-mapped buffers, + * the map and unmap functions will only manage read and write access. + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_input_buffer; /* input buffer handle */ +typedef void *ia_css_input_buffer_cpu_address; /* CPU virtual address */ +/* CSS virtual address */ +typedef ia_css_buffer_address ia_css_input_buffer_css_address; + +#endif /* __IA_CSS_INPUT_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_input_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_input_buffer_cpu.h new file mode 100644 index 0000000000000..d3d01353ce431 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_input_buffer_cpu.h @@ -0,0 +1,49 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_INPUT_BUFFER_CPU_H +#define __IA_CSS_INPUT_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_input_buffer.h" + +ia_css_input_buffer +ia_css_input_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_input_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_input_buffer b); + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_map(ia_css_input_buffer b); + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_unmap(ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map(vied_memory_t mid, ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map_no_invalidate(vied_memory_t mid, ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_unmap(ia_css_input_buffer b); + + +#endif /* __IA_CSS_INPUT_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_output_buffer.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_output_buffer.h new file mode 100644 index 0000000000000..2c310ea92c6af --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_output_buffer.h @@ -0,0 +1,30 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_OUTPUT_BUFFER_H +#define __IA_CSS_OUTPUT_BUFFER_H + +/* Output Buffers */ +/* A CSS output buffer a buffer in DDR that can be written by CSS hardware + * and that can be read by the host, after the buffer has been handed over + * Examples: output frame buffer + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_output_buffer; +typedef void *ia_css_output_buffer_cpu_address; +typedef ia_css_buffer_address ia_css_output_buffer_css_address; + +#endif /* __IA_CSS_OUTPUT_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_output_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_output_buffer_cpu.h new file mode 100644 index 0000000000000..0299fc3b7eb66 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_output_buffer_cpu.h @@ -0,0 +1,48 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_OUTPUT_BUFFER_CPU_H +#define __IA_CSS_OUTPUT_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_output_buffer.h" + +ia_css_output_buffer +ia_css_output_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_output_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_output_buffer b); + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_map(ia_css_output_buffer b); + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_unmap(ia_css_output_buffer b); + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map(vied_memory_t mid, ia_css_output_buffer b); +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map_no_invalidate(vied_memory_t mid, ia_css_output_buffer b); + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_unmap(ia_css_output_buffer b); + + +#endif /* __IA_CSS_OUTPUT_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_return_token.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_return_token.h new file mode 100644 index 0000000000000..440161d2f32b3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_return_token.h @@ -0,0 +1,54 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RETURN_TOKEN_H +#define __IA_CSS_RETURN_TOKEN_H + +#include "storage_class.h" +#include "assert_support.h" /* For CT_ASSERT */ + +/* ia_css_return_token: data item of exacly 8 bytes (64 bits) + * which can be used to pass a return token back to the host +*/ +typedef unsigned long long ia_css_return_token; + +STORAGE_CLASS_INLINE void +ia_css_return_token_copy(ia_css_return_token *to, + const ia_css_return_token *from) +{ + /* copy a return token on VIED processor */ + int *dst = (int *)to; + int *src = (int *)from; + + dst[0] = src[0]; + dst[1] = src[1]; +} + +STORAGE_CLASS_INLINE void +ia_css_return_token_zero(ia_css_return_token *to) +{ + /* zero return token on VIED processor */ + int *dst = (int *)to; + + dst[0] = 0; + dst[1] = 0; +} + +STORAGE_CLASS_INLINE void _check_return_token_size(void) +{ + CT_ASSERT(sizeof(int) == 4); + CT_ASSERT(sizeof(ia_css_return_token) == 8); +} + +#endif /* __IA_CSS_RETURN_TOKEN_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_shared_buffer.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_shared_buffer.h new file mode 100644 index 0000000000000..558ec679f98a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_shared_buffer.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SHARED_BUFFER_H +#define __IA_CSS_SHARED_BUFFER_H + +/* Shared Buffers */ +/* A CSS shared buffer is a buffer in DDR that can be read and written by the + * CPU and CSS. + * Both the CPU and CSS can have the buffer mapped simultaneously. + * Access rights are not managed by this interface, this could be done by means + * the read and write pointer of a queue, for example. + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_shared_buffer; +typedef void *ia_css_shared_buffer_cpu_address; +typedef ia_css_buffer_address ia_css_shared_buffer_css_address; + +#endif /* __IA_CSS_SHARED_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_shared_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_shared_buffer_cpu.h new file mode 100644 index 0000000000000..ff62914f99dc3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/interface/ia_css_shared_buffer_cpu.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SHARED_BUFFER_CPU_H +#define __IA_CSS_SHARED_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_shared_buffer.h" + +ia_css_shared_buffer +ia_css_shared_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_shared_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_shared_buffer b); + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_map(ia_css_shared_buffer b); + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_unmap(ia_css_shared_buffer b); + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_map(ia_css_shared_buffer b); + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_unmap(ia_css_shared_buffer b); + +ia_css_shared_buffer +ia_css_shared_buffer_css_update(vied_memory_t mid, ia_css_shared_buffer b); + +ia_css_shared_buffer +ia_css_shared_buffer_cpu_update(vied_memory_t mid, ia_css_shared_buffer b); + +#endif /* __IA_CSS_SHARED_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/buffer_access.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/buffer_access.c new file mode 100644 index 0000000000000..f0c617fe501a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/buffer_access.c @@ -0,0 +1,39 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/* implementation of buffer access from the CPU */ +/* using shared_memory interface */ + +#include "buffer_access.h" +#include "vied/shared_memory_access.h" + +void +buffer_load( + buffer_address address, + void *data, + unsigned int bytes, + unsigned int mm_id) +{ + shared_memory_load(mm_id, address, data, bytes); +} + +void +buffer_store( + buffer_address address, + const void *data, + unsigned int bytes, + unsigned int mm_id) +{ + shared_memory_store(mm_id, address, data, bytes); +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_buffer.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_buffer.c new file mode 100644 index 0000000000000..146d4109de440 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_buffer.c @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/* provided interface */ +#include "ia_css_buffer.h" + +/* used interfaces */ +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + +ia_css_buffer_t +ia_css_buffer_alloc(vied_subsystem_t sid, vied_memory_t mid, unsigned int size) +{ + ia_css_buffer_t b; + + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + + b->css_address = shared_memory_map(sid, mid, b->mem); + b->size = size; + return b; +} + + +void +ia_css_buffer_free(vied_subsystem_t sid, vied_memory_t mid, ia_css_buffer_t b) +{ + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_buffer.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_buffer.h new file mode 100644 index 0000000000000..a8959fdcd04ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_buffer.h @@ -0,0 +1,58 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BUFFER_H +#define __IA_CSS_BUFFER_H + +/* workaround: needed because uses size_t */ +#include "type_support.h" +#include "vied/shared_memory_map.h" + +typedef enum { + buffer_unmapped, /* buffer is not accessible by cpu, nor css */ + buffer_write, /* output buffer: css has write access */ + /* input buffer: cpu has write access */ + buffer_read, /* input buffer: css has read access */ + /* output buffer: cpu has read access */ + buffer_cpu, /* shared buffer: cpu has read/write access */ + buffer_css /* shared buffer: css has read/write access */ +} buffer_state; + +struct ia_css_buffer_s { + /* number of bytes allocated */ + unsigned int size; + /* allocated virtual memory object */ + host_virtual_address_t mem; + /* virtual address to be used on css/firmware */ + vied_virtual_address_t css_address; + /* virtual address to be used on cpu/host */ + void *cpu_address; + buffer_state state; +}; + +typedef struct ia_css_buffer_s *ia_css_buffer_t; + +ia_css_buffer_t +ia_css_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_buffer_t b); + +#endif /* __IA_CSS_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_input_buffer.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_input_buffer.c new file mode 100644 index 0000000000000..2a128795d03e2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_input_buffer.c @@ -0,0 +1,184 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_input_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_input_buffer +ia_css_input_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_input_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_input_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_input_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_map(ia_css_input_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map input buffer to CPU address space, acquire write access */ + b->state = buffer_write; + + /* return pre-mapped buffer */ + return b->cpu_address; +} + + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_unmap(ia_css_input_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_write) + return NULL; + + /* unmap input buffer from CPU address space, release write access */ + b->state = buffer_unmapped; + + /* return pre-mapped buffer */ + return b->cpu_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map(vied_memory_t mid, ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map input buffer to CSS address space, acquire read access */ + b->state = buffer_read; + + /* now flush the cache */ + ia_css_cpu_mem_cache_flush(b->cpu_address, b->size); +#ifndef HRT_HW + /* only copy in case of simulation, otherwise it should just work */ + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return (ia_css_input_buffer_css_address)b->css_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map_no_invalidate(vied_memory_t mid, ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map input buffer to CSS address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only copy in case of simulation, otherwise it should just work */ + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return (ia_css_input_buffer_css_address)b->css_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_unmap(ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_read) + return 0; + + /* unmap input buffer from CSS address space, release read access */ + b->state = buffer_unmapped; + + /* input buffer only, no need to invalidate cache */ + + return (ia_css_input_buffer_css_address)b->css_address; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_output_buffer.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_output_buffer.c new file mode 100644 index 0000000000000..30bc8d52a5a9e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_output_buffer.c @@ -0,0 +1,181 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_output_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_output_buffer +ia_css_output_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_output_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_output_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_output_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_map(ia_css_output_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map output buffer to CSS address space, acquire write access */ + b->state = buffer_write; + + return (ia_css_output_buffer_css_address)b->css_address; +} + + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_unmap(ia_css_output_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_write) + return 0; + + /* unmap output buffer from CSS address space, release write access */ + b->state = buffer_unmapped; + + return (ia_css_output_buffer_css_address)b->css_address; +} + + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map(vied_memory_t mid, ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map output buffer to CPU address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only in simulation */ + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + /* now invalidate the cache */ + ia_css_cpu_mem_cache_invalidate(b->cpu_address, b->size); + + return b->cpu_address; +} + + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map_no_invalidate(vied_memory_t mid, ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map output buffer to CPU address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only in simulation */ + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return b->cpu_address; +} + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_unmap(ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_read) + return NULL; + + /* unmap output buffer from CPU address space, release read access */ + b->state = buffer_unmapped; + + /* output only, no need to flush cache */ + + return b->cpu_address; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_shared_buffer.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_shared_buffer.c new file mode 100644 index 0000000000000..92b7110644fe3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/buffer/src/cpu/ia_css_shared_buffer.c @@ -0,0 +1,187 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_shared_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_shared_buffer +ia_css_shared_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_shared_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_shared_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_shared_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_map(ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map shared buffer to CPU address space */ + b->state = buffer_cpu; + + return b->cpu_address; +} + + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_unmap(ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_cpu) + return NULL; + + /* unmap shared buffer from CPU address space */ + b->state = buffer_unmapped; + + return b->cpu_address; +} + + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_map(ia_css_shared_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map shared buffer to CSS address space */ + b->state = buffer_css; + + return (ia_css_shared_buffer_css_address)b->css_address; +} + + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_unmap(ia_css_shared_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_css) + return 0; + + /* unmap shared buffer from CSS address space */ + b->state = buffer_unmapped; + + return (ia_css_shared_buffer_css_address)b->css_address; +} + + +ia_css_shared_buffer +ia_css_shared_buffer_css_update(vied_memory_t mid, ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + + /* flush the buffer to CSS after it was modified by the CPU */ + /* flush cache to ddr */ + ia_css_cpu_mem_cache_flush(b->cpu_address, b->size); +#ifndef HRT_HW + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return b; +} + + +ia_css_shared_buffer +ia_css_shared_buffer_cpu_update(vied_memory_t mid, ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + + /* flush the buffer to the CPU after it has been modified by CSS */ +#ifndef HRT_HW + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + /* flush cache to ddr */ + ia_css_cpu_mem_cache_invalidate(b->cpu_address, b->size); + + return b; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cell/cell.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cell/cell.mk new file mode 100644 index 0000000000000..fa5e650226017 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cell/cell.mk @@ -0,0 +1,43 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +ifndef _CELL_MK_ +_CELL_MK_ = 1 + + +CELL_DIR=$${MODULES_DIR}/cell +CELL_INTERFACE=$(CELL_DIR)/interface +CELL_SOURCES=$(CELL_DIR)/src + +CELL_HOST_FILES = +CELL_FW_FILES = + +CELL_HOST_CPPFLAGS = \ + -I$(CELL_INTERFACE) \ + -I$(CELL_SOURCES) + +CELL_FW_CPPFLAGS = \ + -I$(CELL_INTERFACE) \ + -I$(CELL_SOURCES) + +ifdef 0 +# Disabled until it is decided to go this way or not +include $(MODULES_DIR)/device_access/device_access.mk +CELL_HOST_FILES += $(DEVICE_ACCESS_HOST_FILES) +CELL_FW_FILES += $(DEVICE_ACCESS_FW_FILES) +CELL_HOST_CPPFLAGS += $(DEVICE_ACCESS_HOST_CPPFLAGS) +CELL_FW_CPPFLAGS += $(DEVICE_ACCESS_FW_CPPFLAGS) +endif + +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cell/interface/ia_css_cell.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cell/interface/ia_css_cell.h new file mode 100644 index 0000000000000..3fac3c791b6e6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cell/interface/ia_css_cell.h @@ -0,0 +1,112 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_H +#define __IA_CSS_CELL_H + +#include "storage_class.h" +#include "type_support.h" + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stat_ctrl(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_stat_ctrl(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_pc(unsigned int ssid, unsigned int cell_id, + unsigned int pc); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +#if 0 /* To be implemented after completing cell device properties */ +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_info_bits(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_debug_pc(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stall_bits(unsigned int ssid, unsigned int cell_id); +#endif + +/* configure master ports */ + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_base_address(unsigned int ssid, + unsigned int cell_id, + unsigned int master, unsigned int segment, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_bits(unsigned int ssid, unsigned int cell_id, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_bits(unsigned int ssid, + unsigned int cell_id, + unsigned int master, unsigned int segment, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_override_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_override_bits(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value); + +/* Access memories */ + +STORAGE_CLASS_INLINE void +ia_css_cell_mem_store_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr, unsigned int value); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_mem_load_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr); + +/***********************************************************************/ + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_is_ready(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_bit(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_run_bit(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_start(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_start_prefetch(unsigned int ssid, unsigned int cell_id, + bool prefetch); + +STORAGE_CLASS_INLINE void +ia_css_cell_wait(unsigned int ssid, unsigned int cell_id); + +/* include inline implementation */ +#include "ia_css_cell_impl.h" + +#endif /* __IA_CSS_CELL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cell/src/ia_css_cell_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cell/src/ia_css_cell_impl.h new file mode 100644 index 0000000000000..60b2e234da1a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cell/src/ia_css_cell_impl.h @@ -0,0 +1,272 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_IMPL_H +#define __IA_CSS_CELL_IMPL_H + +#include "ia_css_cell.h" + +#include "ia_css_cmem.h" +#include "ipu_device_cell_properties.h" +#include "storage_class.h" +#include "assert_support.h" +#include "platform_support.h" +#include "misc_support.h" + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_regs_addr(unsigned int cell_id) +{ + /* mem_id 0 is for registers */ + return ipu_device_cell_memory_address(cell_id, 0); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_dmem_addr(unsigned int cell_id) +{ + /* mem_id 1 is for DMEM */ + return ipu_device_cell_memory_address(cell_id, 1); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_mem_store_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr, unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ipu_device_cell_memory_address( + cell_id, mem_id) + addr, value); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_mem_load_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr) +{ + return ia_css_cmem_load_32( + ssid, ipu_device_cell_memory_address(cell_id, mem_id) + addr); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stat_ctrl(unsigned int ssid, unsigned int cell_id) +{ + return ia_css_cmem_load_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_stat_ctrl(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS, value); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_is_ready(unsigned int ssid, unsigned int cell_id) +{ + unsigned int reg; + + reg = ia_css_cell_get_stat_ctrl(ssid, cell_id); + /* READY must be 1, START must be 0 */ + return (reg & (1 << IPU_DEVICE_CELL_STAT_CTRL_READY_BIT)) && + ((~reg) & (1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT)); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_pc(unsigned int ssid, unsigned int cell_id, + unsigned int pc) +{ + /* set start PC */ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_START_PC_REG_ADDRESS, pc); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_bit(unsigned int ssid, unsigned int cell_id) +{ + unsigned int reg; + + reg = 1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT; + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_run_bit(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + unsigned int reg; + + reg = value << IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT; + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_start(unsigned int ssid, unsigned int cell_id) +{ + ia_css_cell_start_prefetch(ssid, cell_id, 0); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_start_prefetch(unsigned int ssid, unsigned int cell_id, + bool prefetch) +{ + unsigned int reg = 0; + + /* Set run bit and start bit */ + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT); + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT); + /* Invalidate the icache */ + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_INVALIDATE_ICACHE_BIT); + /* Optionally enable prefetching */ + reg |= ((prefetch == 1) ? + (1 << IPU_DEVICE_CELL_STAT_CTRL_ICACHE_ENABLE_PREFETCH_BIT) : + 0); + + /* store into register */ + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_wait(unsigned int ssid, unsigned int cell_id) +{ + do { + ia_css_sleep(); + } while (!ia_css_cell_is_ready(ssid, cell_id)); +}; + +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_ICACHE_BASE_REG_ADDRESS, value); +} + +/* master port configuration */ + + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_override_bits(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_override_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_base_address(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) + +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_base_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_override_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_override_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_base_address(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments, segment_size; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_base_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + segment_size = ipu_device_cell_master_segment_size(cell, master); + + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + value += segment_size; + } +} + +#endif /* __IA_CSS_CELL_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/config/isys/subsystem_cnlB0.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/config/isys/subsystem_cnlB0.mk new file mode 100644 index 0000000000000..4a7ef4f324f34 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/config/isys/subsystem_cnlB0.mk @@ -0,0 +1,75 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +############################################################################ +# This file is used to specify versions and properties of ISYS firmware +# components. Please note that these are subsystem specific. System specific +# properties should go to system_$IPU_SYSVER.mk. Also the device versions +# should be defined under "devices" or should be taken from the SDK. +############################################################################ + +############################################################################ +# FIRMWARE RELATED VARIABLES +############################################################################ + +# Activate loading params and storing stats DDR<->REGs with DMA +ISYS_USE_ISA_DMA = 1 +#DMA does not work with AF due to a known bug +DISABLE_AF_STAT_DMA = 1 +# Used in ISA module +ISYS_ISL_DPC_DPC_V2 = 1 + +# Specification for Isys server's fixed globals' locations +REGMEM_OFFSET = 0 # Starting from 0 +REGMEM_SECURE_OFFSET = 4096 +REGMEM_SIZE = 36 +REGMEM_WORD_BYTES = 4 +FW_LOAD_NO_OF_REQUEST_OFFSET = 144 # Taken from REGMEM_OFFSET + REGMEM_SIZE*REGMEM_WORD_BYTES +FW_LOAD_NO_OF_REQUEST_SIZE_BYTES = 4 +# Total Used (@ REGMEM_OFFSET) = 148 # FW_LOAD_NO_OF_REQUEST_OFFSET + FW_LOAD_NO_OF_REQUEST_SIZE_BYTES +# Total Used (@ REGMEM_SECURE_OFFSET) = 144 # FW_LOAD_NO_OF_REQUEST_OFFSET + +# Workarounds: + +# This WA is not to pipeline store frame commands for SID processors that control a Str2Vec (ISA output) +WA_HSD1304553438 = 1 + +# FW workaround for HSD 1404347241. Disable clock gating for CSI2 DPHY Receiver ports +DISABLE_CSI2_RX_DPHY_CLK_GATE = 1 + +# Larger than specified frames that complete mid-line +WA_HSD1209062354 = 0 + +# WA to disable clock gating for the devices in the CSI receivers needed for using the mipi_pkt_gen device +WA_HSD1805168877 = 0 + +# Support IBUF soft-reset at stream start +SOFT_RESET_IBUF_STREAM_START_SUPPORT = 0 + +############################################################################ +# TESTING RELATED VARIABLES +############################################################################ + +# Cannot remove this define +# Used in mipi_capture, isys_utils.mk, and stream_controller.mk +ISYS_DISABLE_VERIFY_RECEIVED_SOF_EOF = 0 + +ISYS_ACCESS_BLOCKER_VERSION = v1 + +HAS_SPC = 1 + +# Support dual command context for VTIO - concurrent secure and non-secure streams +ISYS_HAS_DUAL_CMD_CTX_SUPPORT = 1 + +AB_CONFIG_ARRAY_SIZE = 50 diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/config/system_cnlB0.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/config/system_cnlB0.mk new file mode 100644 index 0000000000000..667282b519c4c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/config/system_cnlB0.mk @@ -0,0 +1,96 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +#--- DEFINES REQUIRED TO COMPILE USING LLVM --- +# Enable LLVM/Volcano for IPU4P, SPs only. +VOLCANO_IPU4P = 1 +VOLCANO_SP2601 = 1 +#---------------------------------------------- + +# enable NO_ALIAS for LLVM +ENABLE_NO_ALIAS_FOR_LLVM = 1 + +LOGICAL_FW_INPUT_SYSTEM = input_system_system +LOGICAL_FW_PROCESSING_SYSTEM = processing_system_system +LOGICAL_FW_IPU_SYSTEM = ipu_system +LOGICAL_FW_ISP_SYSTEM = isp2601_default_system +SP_CONTROL_CELL = sp2601_control +SP_PROXY_CELL = sp2601_proxy +ISP_CELL = isp2601 +# The non-capital define isp2601 is used in the sdk, in order to distinguish +# between different isp versions the ISP_CELL_IDENTIFIER define is added. +ISP_CELL_IDENTIFIER = ISP2601 +HAS_IPFD = 1 +HAS_S2M_IN_ISYS_ISL_NONSOC_PATH = 0 +HAS_S2V_IN_ISYS_ISL_NONSOC_PATH = 1 +# ISL-IS non-SoC path has ISA with PAF and DPC-Pext support for IPU4P-B0 +HAS_ISA_IN_ISYS_ISL = 1 +HAS_PAF_IN_ISYS_ISL = 1 +HAS_DPC_PEXT_IN_ISYS_ISL = 1 +HAS_PMA_IF = 1 + +HAS_MIPIBE_IN_PSYS_ISL = 1 + +HAS_VPLESS_SUPPORT = 0 + +DLI_SYSTEM = hive_isp_css_2600_system +RESOURCE_MANAGER_VERSION = v2 +MEM_RESOURCE_VALIDATION_ERROR = 0 +OFS_SCALER_1_4K_TILEY_422_SUPPORT= 1 +PROGDESC_ACC_SYMBOLS_VERSION = v1 +DEVPROXY_INTERFACE_VERSION = v1 +FW_ABI_IPU_TYPES_VERSION = v1 + +HAS_ONLINE_MODE_SUPPORT_IN_ISYS_PSYS = 0 + +MMU_INTERFACE_VERSION = v2 +DEVICE_ACCESS_VERSION = v2 +PSYS_SERVER_VERSION = v3 +PSYS_SERVER_LOADER_VERSION = v1 +PSYS_HW_VERSION = CNL_B0_HW + +# Enable FW_DMA for loading firmware +PSYS_SERVER_ENABLE_FW_LOAD_DMA = 1 + +NCI_SPA_VERSION = v1 +MANIFEST_TOOL_VERSION = v2 +PSYS_CON_MGR_TOOL_VERSION = v1 +# TODO: Should be removed after performance issues OTF are solved +PSYS_PROC_MGR_VERSION = v1 +IPU_RESOURCES_VERSION = v2 + +HAS_ACC_CLUSTER_PAF_PAL = 1 +HAS_ACC_CLUSTER_PEXT_PAL = 1 +HAS_ACC_CLUSTER_GBL_PAL = 1 + +# TODO use version naming scheme "v#" to decouple +# IPU_SYSVER from version. +PARAMBINTOOL_ISA_INIT_VERSION = cnlB0 + +# Select EQC2EQ version +# Version 1: uniform address space, equal EQ addresses regardless of EQC device +# Version 2: multiple addresses per EQ, depending on location of EQC device +EQC2EQ_VERSION = v1 + +# Select DMA instance for fw_load +FW_LOAD_DMA_INSTANCE = NCI_DMA_FW + +HAS_DMA_FW = 1 + +HAS_SIS = 0 +HAS_IDS = 1 + +PSYS_SERVER_ENABLE_TPROXY = 1 +PSYS_SERVER_ENABLE_DEVPROXY = 1 +NCI_OFS_VERSION = v1 diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cpd_binary/ia_css_fw_pkg_release.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cpd_binary/ia_css_fw_pkg_release.h new file mode 100644 index 0000000000000..408726c817146 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/cpd_binary/ia_css_fw_pkg_release.h @@ -0,0 +1,14 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#define IA_CSS_FW_PKG_RELEASE 0x20181222 diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/device_access.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/device_access.mk new file mode 100644 index 0000000000000..1629d9af803b6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/device_access.mk @@ -0,0 +1,40 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# + +ifndef _DEVICE_ACCESS_MK_ +_DEVICE_ACCESS_MK_ = 1 + +# DEVICE_ACCESS_VERSION= +include $(MODULES_DIR)/config/system_$(IPU_SYSVER).mk + +DEVICE_ACCESS_DIR=$${MODULES_DIR}/device_access +DEVICE_ACCESS_INTERFACE=$(DEVICE_ACCESS_DIR)/interface +DEVICE_ACCESS_SOURCES=$(DEVICE_ACCESS_DIR)/src + +DEVICE_ACCESS_HOST_FILES = + +DEVICE_ACCESS_FW_FILES = + +DEVICE_ACCESS_HOST_CPPFLAGS = \ + -I$(DEVICE_ACCESS_INTERFACE) \ + -I$(DEVICE_ACCESS_SOURCES) + +DEVICE_ACCESS_FW_CPPFLAGS = \ + -I$(DEVICE_ACCESS_INTERFACE) \ + -I$(DEVICE_ACCESS_SOURCES) + +DEVICE_ACCESS_FW_CPPFLAGS += \ + -I$(DEVICE_ACCESS_SOURCES)/$(DEVICE_ACCESS_VERSION) +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/interface/ia_css_cmem.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/interface/ia_css_cmem.h new file mode 100644 index 0000000000000..3dc47c29fcab7 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/interface/ia_css_cmem.h @@ -0,0 +1,58 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CMEM_H +#define __IA_CSS_CMEM_H + +#include "type_support.h" +#include "storage_class.h" + +#ifdef __VIED_CELL +typedef unsigned int ia_css_cmem_address_t; +#else +#include +typedef vied_subsystem_address_t ia_css_cmem_address_t; +#endif + +STORAGE_CLASS_INLINE uint32_t +ia_css_cmem_load_32(unsigned int ssid, ia_css_cmem_address_t address); + +STORAGE_CLASS_INLINE void +ia_css_cmem_store_32(unsigned int ssid, ia_css_cmem_address_t address, + uint32_t value); + +STORAGE_CLASS_INLINE void +ia_css_cmem_load(unsigned int ssid, ia_css_cmem_address_t address, void *data, + unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_cmem_store(unsigned int ssid, ia_css_cmem_address_t address, + const void *data, unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_cmem_zero(unsigned int ssid, ia_css_cmem_address_t address, + unsigned int size); + +STORAGE_CLASS_INLINE ia_css_cmem_address_t +ia_css_cmem_get_cmem_addr_from_dmem(unsigned int base_addr, void *p); + +/* Include inline implementation */ + +#ifdef __VIED_CELL +#include "ia_css_cmem_cell.h" +#else +#include "ia_css_cmem_host.h" +#endif + +#endif /* __IA_CSS_CMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/interface/ia_css_xmem.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/interface/ia_css_xmem.h new file mode 100644 index 0000000000000..de2b94d8af541 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/interface/ia_css_xmem.h @@ -0,0 +1,65 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_H +#define __IA_CSS_XMEM_H + +#include "type_support.h" +#include "storage_class.h" + +#ifdef __VIED_CELL +typedef unsigned int ia_css_xmem_address_t; +#else +#include +typedef host_virtual_address_t ia_css_xmem_address_t; +#endif + +STORAGE_CLASS_INLINE uint8_t +ia_css_xmem_load_8(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE uint16_t +ia_css_xmem_load_16(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE uint32_t +ia_css_xmem_load_32(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE void +ia_css_xmem_load(unsigned int mmid, ia_css_xmem_address_t address, void *data, + unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_8(unsigned int mmid, ia_css_xmem_address_t address, + uint8_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_16(unsigned int mmid, ia_css_xmem_address_t address, + uint16_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_32(unsigned int mmid, ia_css_xmem_address_t address, + uint32_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store(unsigned int mmid, ia_css_xmem_address_t address, + const void *data, unsigned int bytes); + +/* Include inline implementation */ + +#ifdef __VIED_CELL +#include "ia_css_xmem_cell.h" +#else +#include "ia_css_xmem_host.h" +#endif + +#endif /* __IA_CSS_XMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/interface/ia_css_xmem_cmem.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/interface/ia_css_xmem_cmem.h new file mode 100644 index 0000000000000..57aab3323c739 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/interface/ia_css_xmem_cmem.h @@ -0,0 +1,35 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_CMEM_H +#define __IA_CSS_XMEM_CMEM_H + +#include "ia_css_cmem.h" +#include "ia_css_xmem.h" + +/* Copy data from xmem to cmem, e.g., from a program in DDR to a cell's DMEM */ +/* This may also be implemented using DMA */ + +STORAGE_CLASS_INLINE void +ia_css_xmem_to_cmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size); + +/* include inline implementation */ +#include "ia_css_xmem_cmem_impl.h" + +#endif /* __IA_CSS_XMEM_CMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/src/ia_css_cmem_host.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/src/ia_css_cmem_host.h new file mode 100644 index 0000000000000..22799e67214c1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/src/ia_css_cmem_host.h @@ -0,0 +1,121 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CMEM_HOST_H +#define __IA_CSS_CMEM_HOST_H + +/* This file is an inline implementation for the interface ia_css_cmem.h + * and should only be included there. */ + +#include "assert_support.h" +#include "misc_support.h" + +STORAGE_CLASS_INLINE uint32_t +ia_css_cmem_load_32(unsigned int ssid, ia_css_cmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + return vied_subsystem_load_32(ssid, address); +} + +STORAGE_CLASS_INLINE uint32_t +ia_css_cond_cmem_load_32(bool cond, unsigned int ssid, + ia_css_cmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + if (cond) + return vied_subsystem_load_32(ssid, address); + else + return 0; +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_store_32(unsigned int ssid, ia_css_cmem_address_t address, + uint32_t data) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + vied_subsystem_store_32(ssid, address, data); +} + +STORAGE_CLASS_INLINE void +ia_css_cond_cmem_store_32(bool cond, unsigned int ssid, + ia_css_cmem_address_t address, uint32_t data) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + if (cond) + vied_subsystem_store_32(ssid, address, data); +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_load(unsigned int ssid, ia_css_cmem_address_t address, void *data, + unsigned int size) +{ + uint32_t *data32 = (uint32_t *)data; + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + assert((long)data % 4 == 0); + + while (address != end) { + *data32 = ia_css_cmem_load_32(ssid, address); + address += 4; + data32 += 1; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_store(unsigned int ssid, ia_css_cmem_address_t address, + const void *data, unsigned int size) +{ + uint32_t *data32 = (uint32_t *)data; + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + assert((long)data % 4 == 0); + + while (address != end) { + ia_css_cmem_store_32(ssid, address, *data32); + address += 4; + data32 += 1; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_zero(unsigned int ssid, ia_css_cmem_address_t address, + unsigned int size) +{ + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + + while (address != end) { + ia_css_cmem_store_32(ssid, address, 0); + address += 4; + } +} + +STORAGE_CLASS_INLINE ia_css_cmem_address_t +ia_css_cmem_get_cmem_addr_from_dmem(unsigned int base_addr, void *p) +{ + NOT_USED(base_addr); + return (ia_css_cmem_address_t)(uintptr_t)p; +} + +#endif /* __IA_CSS_CMEM_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/src/ia_css_xmem_cmem_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/src/ia_css_xmem_cmem_impl.h new file mode 100644 index 0000000000000..adc178b75059a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/src/ia_css_xmem_cmem_impl.h @@ -0,0 +1,79 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_CMEM_IMPL_H +#define __IA_CSS_XMEM_CMEM_IMPL_H + +#include "ia_css_xmem_cmem.h" + +#include "ia_css_cmem.h" +#include "ia_css_xmem.h" + +/* Copy data from xmem to cmem, e.g., from a program in DDR to a cell's DMEM */ +/* This may also be implemented using DMA */ + +STORAGE_CLASS_INLINE void +ia_css_xmem_to_cmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size) +{ + /* copy from ddr to subsystem, e.g., cell dmem */ + ia_css_cmem_address_t end = dst + size; + + assert(size % 4 == 0); + assert((uintptr_t) dst % 4 == 0); + assert((uintptr_t) src % 4 == 0); + + while (dst != end) { + uint32_t data; + + data = ia_css_xmem_load_32(mmid, src); + ia_css_cmem_store_32(ssid, dst, data); + dst += 4; + src += 4; + } +} + +/* Copy data from cmem to xmem */ + +STORAGE_CLASS_INLINE void +ia_css_cmem_to_xmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_cmem_address_t src, + ia_css_xmem_address_t dst, + unsigned int size) +{ + /* copy from ddr to subsystem, e.g., cell dmem */ + ia_css_xmem_address_t end = dst + size; + + assert(size % 4 == 0); + assert((uintptr_t) dst % 4 == 0); + assert((uintptr_t) src % 4 == 0); + + while (dst != end) { + uint32_t data; + + data = ia_css_cmem_load_32(mmid, src); + ia_css_xmem_store_32(ssid, dst, data); + dst += 4; + src += 4; + } +} + + +#endif /* __IA_CSS_XMEM_CMEM_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/src/ia_css_xmem_host.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/src/ia_css_xmem_host.h new file mode 100644 index 0000000000000..d94991fc11143 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/device_access/src/ia_css_xmem_host.h @@ -0,0 +1,84 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_HOST_H +#define __IA_CSS_XMEM_HOST_H + +#include "ia_css_xmem.h" +#include +#include "assert_support.h" +#include + +STORAGE_CLASS_INLINE uint8_t +ia_css_xmem_load_8(unsigned int mmid, ia_css_xmem_address_t address) +{ + return shared_memory_load_8(mmid, address); +} + +STORAGE_CLASS_INLINE uint16_t +ia_css_xmem_load_16(unsigned int mmid, ia_css_xmem_address_t address) +{ + /* Address has to be half-word aligned */ + assert(0 == (uintptr_t) address % 2); + return shared_memory_load_16(mmid, address); +} + +STORAGE_CLASS_INLINE uint32_t +ia_css_xmem_load_32(unsigned int mmid, ia_css_xmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == (uintptr_t) address % 4); + return shared_memory_load_32(mmid, address); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_load(unsigned int mmid, ia_css_xmem_address_t address, void *data, + unsigned int size) +{ + shared_memory_load(mmid, address, data, size); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_8(unsigned int mmid, ia_css_xmem_address_t address, + uint8_t value) +{ + shared_memory_store_8(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_16(unsigned int mmid, ia_css_xmem_address_t address, + uint16_t value) +{ + /* Address has to be half-word aligned */ + assert(0 == (uintptr_t) address % 2); + shared_memory_store_16(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_32(unsigned int mmid, ia_css_xmem_address_t address, + uint32_t value) +{ + /* Address has to be word aligned */ + assert(0 == (uintptr_t) address % 4); + shared_memory_store_32(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store(unsigned int mmid, ia_css_xmem_address_t address, + const void *data, unsigned int bytes) +{ + shared_memory_store(mmid, address, data, bytes); +} + +#endif /* __IA_CSS_XMEM_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/cnlB0/ipu_device_buttress_properties_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/cnlB0/ipu_device_buttress_properties_struct.h new file mode 100644 index 0000000000000..5102f6e44d2f6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/cnlB0/ipu_device_buttress_properties_struct.h @@ -0,0 +1,68 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H +#define __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H + +/* Destination values for master port 0 and bitfield "request_dest" */ +enum cio_M0_btrs_dest { + DEST_IS_BUT_REGS = 0, + DEST_IS_DDR, + RESERVED, + DEST_IS_SUBSYSTEM, + N_BTRS_DEST +}; + +/* Bit-field positions for M0 info bits */ +enum ia_css_info_bits_m0_pos { + IA_CSS_INFO_BITS_M0_SNOOPABLE_POS = 0, + IA_CSS_INFO_BITS_M0_IMR_DESTINED_POS = 1, + IA_CSS_INFO_BITS_M0_REQUEST_DEST_POS = 4 +}; + +#define IA_CSS_INFO_BITS_M0_DDR \ + (DEST_IS_DDR << IA_CSS_INFO_BITS_M0_REQUEST_DEST_POS) +#define IA_CSS_INFO_BITS_M0_SNOOPABLE (1 << IA_CSS_INFO_BITS_M0_SNOOPABLE_POS) + +/* Info bits as expected by the buttress */ +/* Deprecated because bit fields are not portable */ + +/* For master port 0*/ +union cio_M0_t { + struct { + unsigned int snoopable : 1; + unsigned int imr_destined : 1; + unsigned int spare0 : 2; + unsigned int request_dest : 2; + unsigned int spare1 : 26; + } as_bitfield; + unsigned int as_word; +}; + +/* For master port 1*/ +union cio_M1_t { + struct { + unsigned int spare0 : 1; + unsigned int deadline_pointer : 1; + unsigned int reserved : 1; + unsigned int zlw : 1; + unsigned int stream_id : 4; + unsigned int address_swizzling : 1; + unsigned int spare1 : 23; + } as_bitfield; + unsigned int as_word; +}; + + +#endif /* __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_properties.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_properties.h new file mode 100644 index 0000000000000..e6e1e9dcbe80c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_properties.h @@ -0,0 +1,76 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_H +#define __IPU_DEVICE_CELL_PROPERTIES_H + +#include "storage_class.h" +#include "ipu_device_cell_type_properties.h" + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_devices(void); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_memories(const unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_size(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_address(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_databus_memory_address(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_masters(const unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_bits(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_num_segments(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_size(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_stride(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_base_reg(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_reg(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_icache_align(unsigned int cell_id); + +#ifdef C_RUN +STORAGE_CLASS_INLINE int +ipu_device_cell_id_crun(int cell_id); +#endif + +#include "ipu_device_cell_properties_func.h" + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_properties_func.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_properties_func.h new file mode 100644 index 0000000000000..481b0504a2378 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_properties_func.h @@ -0,0 +1,164 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_FUNC_H +#define __IPU_DEVICE_CELL_PROPERTIES_FUNC_H + +/* define properties for all cells uses in ISYS */ + +#include "ipu_device_cell_properties_impl.h" +#include "ipu_device_cell_devices.h" +#include "assert_support.h" +#include "storage_class.h" + +enum {IA_CSS_CELL_MASTER_ADDRESS_WIDTH = 32}; + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_devices(void) +{ + return NUM_CELLS; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_memories(const unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + num_memories; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_size(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + return ipu_device_cell_properties[cell_id].type_properties-> + mem_size[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_address(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + return ipu_device_cell_properties[cell_id].mem_address[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_databus_memory_address(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + assert(mem_id != 0); + return ipu_device_cell_properties[cell_id].mem_databus_address[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_masters(const unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + num_master_ports; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_bits(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].segment_bits; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_num_segments(const unsigned int cell_id, + const unsigned int master_id) +{ + return 1u << ipu_device_cell_master_segment_bits(cell_id, master_id); +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_size(const unsigned int cell_id, + const unsigned int master_id) +{ + return 1u << (IA_CSS_CELL_MASTER_ADDRESS_WIDTH - + ipu_device_cell_master_segment_bits(cell_id, master_id)); +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_stride(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].stride; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_base_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].base_address_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].info_bits_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_override_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].info_override_bits_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_icache_align(unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + icache_align; +} + +#ifdef C_RUN +STORAGE_CLASS_INLINE int +ipu_device_cell_id_crun(int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_map_cell_id_to_crun_proc_id[cell_id]; +} +#endif + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_FUNC_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_properties_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_properties_struct.h new file mode 100644 index 0000000000000..63397dc0b7fe6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_properties_struct.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H +#define __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H + +/* definitions for all cell types */ + +struct ipu_device_cell_count_s { + unsigned int num_memories; + unsigned int num_master_ports; + unsigned int num_stall_bits; + unsigned int icache_align; +}; + +struct ipu_device_cell_master_properties_s { + unsigned int segment_bits; + unsigned int stride; /* offset to register of next segment */ + unsigned int base_address_register; /* address of first base address + register */ + unsigned int info_bits_register; + unsigned int info_override_bits_register; +}; + +struct ipu_device_cell_type_properties_s { + const struct ipu_device_cell_count_s *count; + const struct ipu_device_cell_master_properties_s *master; + const unsigned int *reg_offset; /* offsets of registers, some depend + on cell type */ + const unsigned int *mem_size; +}; + +struct ipu_device_cell_properties_s { + const struct ipu_device_cell_type_properties_s *type_properties; + const unsigned int *mem_address; + const unsigned int *mem_databus_address; + /* const cell_master_port_properties_s* master_port_properties; */ +}; + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_type_properties.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_type_properties.h new file mode 100644 index 0000000000000..72caed3eef0c9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/interface/ipu_device_cell_type_properties.h @@ -0,0 +1,69 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_TYPE_PROPERTIES_H +#define __IPU_DEVICE_CELL_TYPE_PROPERTIES_H + +#define IPU_DEVICE_INVALID_MEM_ADDRESS 0xFFFFFFFF + +enum ipu_device_cell_stat_ctrl_bit { + IPU_DEVICE_CELL_STAT_CTRL_RESET_BIT = 0, + IPU_DEVICE_CELL_STAT_CTRL_START_BIT = 1, + IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT = 3, + IPU_DEVICE_CELL_STAT_CTRL_READY_BIT = 5, + IPU_DEVICE_CELL_STAT_CTRL_SLEEP_BIT = 6, + IPU_DEVICE_CELL_STAT_CTRL_STALL_BIT = 7, + IPU_DEVICE_CELL_STAT_CTRL_CLEAR_IRQ_MASK_FLAG_BIT = 8, + IPU_DEVICE_CELL_STAT_CTRL_BROKEN_IRQ_MASK_FLAG_BIT = 9, + IPU_DEVICE_CELL_STAT_CTRL_READY_IRQ_MASK_FLAG_BIT = 10, + IPU_DEVICE_CELL_STAT_CTRL_SLEEP_IRQ_MASK_FLAG_BIT = 11, + IPU_DEVICE_CELL_STAT_CTRL_INVALIDATE_ICACHE_BIT = 12, + IPU_DEVICE_CELL_STAT_CTRL_ICACHE_ENABLE_PREFETCH_BIT = 13 +}; + +enum ipu_device_cell_reg_addr { + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS = 0x0, + IPU_DEVICE_CELL_START_PC_REG_ADDRESS = 0x4, + IPU_DEVICE_CELL_ICACHE_BASE_REG_ADDRESS = 0x10, + IPU_DEVICE_CELL_ICACHE_INFO_BITS_REG_ADDRESS = 0x14 +}; + +enum ipu_device_cell_reg { + IPU_DEVICE_CELL_STAT_CTRL_REG, + IPU_DEVICE_CELL_START_PC_REG, + IPU_DEVICE_CELL_ICACHE_BASE_REG, + IPU_DEVICE_CELL_DEBUG_PC_REG, + IPU_DEVICE_CELL_STALL_REG, + IPU_DEVICE_CELL_NUM_REGS +}; + +enum ipu_device_cell_mem { + IPU_DEVICE_CELL_REGS, /* memory id of registers */ + IPU_DEVICE_CELL_PMEM, /* memory id of pmem */ + IPU_DEVICE_CELL_DMEM, /* memory id of dmem */ + IPU_DEVICE_CELL_BAMEM, /* memory id of bamem */ + IPU_DEVICE_CELL_VMEM /* memory id of vmem */ +}; +#define IPU_DEVICE_CELL_NUM_MEMORIES (IPU_DEVICE_CELL_VMEM + 1) + +enum ipu_device_cell_master { + IPU_DEVICE_CELL_MASTER_ICACHE, /* master port id of icache */ + IPU_DEVICE_CELL_MASTER_QMEM, + IPU_DEVICE_CELL_MASTER_CMEM, + IPU_DEVICE_CELL_MASTER_XMEM, + IPU_DEVICE_CELL_MASTER_XVMEM +}; +#define IPU_DEVICE_CELL_MASTER_NUM_MASTERS (IPU_DEVICE_CELL_MASTER_XVMEM + 1) + +#endif /* __IPU_DEVICE_CELL_TYPE_PROPERTIES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/isys/cnlB0/ipu_device_cell_devices.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/isys/cnlB0/ipu_device_cell_devices.h new file mode 100644 index 0000000000000..274c9518fd3de --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/isys/cnlB0/ipu_device_cell_devices.h @@ -0,0 +1,27 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_DEVICES_H +#define __IPU_DEVICE_CELL_DEVICES_H + +/* define cell instances in ISYS */ + +#define SPC0_CELL input_system_unis_logic_sp_control_tile_sp + +enum ipu_device_isys_cell_id { + SPC0 +}; +#define NUM_CELLS (SPC0 + 1) + +#endif /* __IPU_DEVICE_CELL_DEVICES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/isys/cnlB0/ipu_device_cell_properties_defs.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/isys/cnlB0/ipu_device_cell_properties_defs.h new file mode 100644 index 0000000000000..e811478b7d0f4 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/isys/cnlB0/ipu_device_cell_properties_defs.h @@ -0,0 +1,22 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +/* Generated file - please do not edit. */ + +#ifndef _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ +#define _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ +#define SPC0_REGS_CBUS_ADDRESS 0x0 +#define SPC0_DMEM_CBUS_ADDRESS 0x8000 +#define SPC0_DMEM_DBUS_ADDRESS 0x8000 +#define SPC0_DMEM_DMA_M0_ADDRESS 0x1010000 +#endif /* _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/isys/cnlB0/ipu_device_cell_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/isys/cnlB0/ipu_device_cell_properties_impl.h new file mode 100644 index 0000000000000..f350ae74b94d6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/isys/cnlB0/ipu_device_cell_properties_impl.h @@ -0,0 +1,57 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_IMPL_H +#define __IPU_DEVICE_CELL_PROPERTIES_IMPL_H + +/* define properties for all cells uses in ISYS */ + +#include "ipu_device_sp2600_control_properties_impl.h" +#include "ipu_device_cell_properties_defs.h" +#include "ipu_device_cell_devices.h" +#include "ipu_device_cell_type_properties.h"/* IPU_DEVICE_INVALID_MEM_ADDRESS */ + +static const unsigned int +ipu_device_spc0_mem_address[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + SPC0_REGS_CBUS_ADDRESS, + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPC0_DMEM_CBUS_ADDRESS +}; + +static const unsigned int +ipu_device_spc0_databus_mem_address[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* regs not accessible from DBUS */ + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPC0_DMEM_DBUS_ADDRESS +}; + +static const struct ipu_device_cell_properties_s +ipu_device_cell_properties[NUM_CELLS] = { + { + &ipu_device_sp2600_control_properties, + ipu_device_spc0_mem_address, + ipu_device_spc0_databus_mem_address + } +}; + +#ifdef C_RUN + +/* Mapping between hrt_hive_processors enum and cell_id's used in FW */ +static const int ipu_device_map_cell_id_to_crun_proc_id[NUM_CELLS] = { + 0 /* SPC0 */ +}; + +#endif + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/src/ipu_device_sp2600_control_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/src/ipu_device_sp2600_control_properties_impl.h new file mode 100644 index 0000000000000..430295cd9d949 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/devices/src/ipu_device_sp2600_control_properties_impl.h @@ -0,0 +1,136 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H +#define __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H + +/* sp2600_control definition */ + +#include "ipu_device_cell_properties_struct.h" + +enum ipu_device_sp2600_control_registers { + /* control registers */ + IPU_DEVICE_SP2600_CONTROL_STAT_CTRL = 0x0, + IPU_DEVICE_SP2600_CONTROL_START_PC = 0x4, + + /* master port registers */ + IPU_DEVICE_SP2600_CONTROL_ICACHE_BASE = 0x10, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO = 0x14, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO_OVERRIDE = 0x18, + + IPU_DEVICE_SP2600_CONTROL_QMEM_BASE = 0x1C, + + IPU_DEVICE_SP2600_CONTROL_CMEM_BASE = 0x28, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO = 0x2C, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO_OVERRIDE = 0x30, + + IPU_DEVICE_SP2600_CONTROL_XMEM_BASE = 0x58, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO = 0x5C, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO_OVERRIDE = 0x60, + + /* debug registers */ + IPU_DEVICE_SP2600_CONTROL_DEBUG_PC = 0x9C, + IPU_DEVICE_SP2600_CONTROL_STALL = 0xA0 +}; + +enum ipu_device_sp2600_control_mems { + IPU_DEVICE_SP2600_CONTROL_REGS, + IPU_DEVICE_SP2600_CONTROL_PMEM, + IPU_DEVICE_SP2600_CONTROL_DMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES +}; + +static const unsigned int +ipu_device_sp2600_control_mem_size[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + 0x000AC, + 0x00000, + 0x10000 +}; + +enum ipu_device_sp2600_control_masters { + IPU_DEVICE_SP2600_CONTROL_ICACHE, + IPU_DEVICE_SP2600_CONTROL_QMEM, + IPU_DEVICE_SP2600_CONTROL_CMEM, + IPU_DEVICE_SP2600_CONTROL_XMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS +}; + +static const struct ipu_device_cell_master_properties_s +ipu_device_sp2600_control_masters[IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS] = { + { + 0, + 0xC, + IPU_DEVICE_SP2600_CONTROL_ICACHE_BASE, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO_OVERRIDE + }, + { + 0, + 0xC, + IPU_DEVICE_SP2600_CONTROL_QMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_CONTROL_CMEM_BASE, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO_OVERRIDE + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_CONTROL_XMEM_BASE, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO_OVERRIDE + } +}; + +enum ipu_device_sp2600_control_stall_bits { + IPU_DEVICE_SP2600_CONTROL_STALL_ICACHE, + IPU_DEVICE_SP2600_CONTROL_STALL_DMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_QMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_CMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_XMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_STALL_BITS +}; + +/* 32 bits per instruction */ +#define IPU_DEVICE_SP2600_CONTROL_ICACHE_WORD_SIZE 4 +/* 32 instructions per burst */ +#define IPU_DEVICE_SP2600_CONTROL_ICACHE_BURST_SIZE 32 + +static const struct ipu_device_cell_count_s ipu_device_sp2600_control_count = { + IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES, + IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS, + IPU_DEVICE_SP2600_CONTROL_NUM_STALL_BITS, + IPU_DEVICE_SP2600_CONTROL_ICACHE_WORD_SIZE * + IPU_DEVICE_SP2600_CONTROL_ICACHE_BURST_SIZE +}; + +static const unsigned int +ipu_device_sp2600_control_reg_offset[/* CELL_NUM_REGS */] = { + 0x0, 0x4, 0x10, 0x9C, 0xA0 +}; + +static const struct ipu_device_cell_type_properties_s +ipu_device_sp2600_control_properties = { + &ipu_device_sp2600_control_count, + ipu_device_sp2600_control_masters, + ipu_device_sp2600_control_reg_offset, + ipu_device_sp2600_control_mem_size +}; + +#endif /* __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/cpu/fw_abi_cpu_types.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/cpu/fw_abi_cpu_types.mk new file mode 100644 index 0000000000000..b1ffbf7ea21ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/cpu/fw_abi_cpu_types.mk @@ -0,0 +1,24 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +# MODULE is FW ABI COMMON TYPES + +FW_ABI_COMMON_TYPES_DIRS = -I$${MODULES_DIR}/fw_abi_common_types +FW_ABI_COMMON_TYPES_DIRS += -I$${MODULES_DIR}/fw_abi_common_types/cpu + +FW_ABI_COMMON_TYPES_HOST_FILES = +FW_ABI_COMMON_TYPES_HOST_CPPFLAGS = $(FW_ABI_COMMON_TYPES_DIRS) + +FW_ABI_COMMON_TYPES_FW_FILES = +FW_ABI_COMMON_TYPES_FW_CPPFLAGS = $(FW_ABI_COMMON_TYPES_DIRS) diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_base_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_base_types.h new file mode 100644 index 0000000000000..21cc3f43f485e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_base_types.h @@ -0,0 +1,42 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_BASE_TYPES_H +#define __IA_CSS_TERMINAL_BASE_TYPES_H + + +#include "type_support.h" +#include "ia_css_terminal_defs.h" + +#define N_UINT16_IN_TERMINAL_STRUCT 3 +#define N_PADDING_UINT8_IN_TERMINAL_STRUCT 5 + +#define SIZE_OF_TERMINAL_STRUCT_BITS \ + (IA_CSS_TERMINAL_TYPE_BITS \ + + IA_CSS_TERMINAL_ID_BITS \ + + N_UINT16_IN_TERMINAL_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_IN_TERMINAL_STRUCT * IA_CSS_UINT8_T_BITS) + +/* ==================== Base Terminal - START ==================== */ +struct ia_css_terminal_s { /**< Base terminal */ + ia_css_terminal_type_t terminal_type; /**< Type ia_css_terminal_type_t */ + int16_t parent_offset; /**< Offset to the process group */ + uint16_t size; /**< Size of this whole terminal layout-structure */ + uint16_t tm_index; /**< Index of the terminal manifest object */ + ia_css_terminal_ID_t ID; /**< Absolute referal ID for this terminal, valid ID's != 0 */ + uint8_t padding[N_PADDING_UINT8_IN_TERMINAL_STRUCT]; +}; +/* ==================== Base Terminal - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h new file mode 100644 index 0000000000000..056e1b6d5d4bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h @@ -0,0 +1,42 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H +#define __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H + +#include "ia_css_terminal_defs.h" + +#define N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT 5 +#define SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + (IA_CSS_UINT16_T_BITS \ + + IA_CSS_TERMINAL_ID_BITS \ + + IA_CSS_TERMINAL_TYPE_BITS \ + + IA_CSS_UINT32_T_BITS \ + + (N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT*IA_CSS_UINT8_T_BITS)) + +/* ==================== Base Terminal Manifest - START ==================== */ +struct ia_css_terminal_manifest_s { + ia_css_terminal_type_t terminal_type; /**< Type ia_css_terminal_type_t */ + int16_t parent_offset; /**< Offset to the program group manifest */ + uint16_t size; /**< Size of this whole terminal-manifest layout-structure */ + ia_css_terminal_ID_t ID; + uint8_t padding[N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT]; +}; + +typedef struct ia_css_terminal_manifest_s + ia_css_terminal_manifest_t; + +/* ==================== Base Terminal Manifest - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/ia_css_base_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/ia_css_base_types.h new file mode 100644 index 0000000000000..3b80a17a6ad38 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/ia_css_base_types.h @@ -0,0 +1,38 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BASE_TYPES_H +#define __IA_CSS_BASE_TYPES_H + +#include "type_support.h" + +#define VIED_VADDRESS_BITS 32 +typedef uint32_t vied_vaddress_t; + +#define DEVICE_DESCRIPTOR_ID_BITS 32 +typedef struct { + uint8_t device_id; + uint8_t instance_id; + uint8_t channel_id; + uint8_t section_id; +} device_descriptor_fields_t; + +typedef union { + device_descriptor_fields_t fields; + uint32_t data; +} device_descriptor_id_t; + +typedef uint16_t ia_css_process_id_t; + +#endif /* __IA_CSS_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/ia_css_terminal_defs.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/ia_css_terminal_defs.h new file mode 100644 index 0000000000000..dbf1cf93756ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/fw_abi_common_types/ia_css_terminal_defs.h @@ -0,0 +1,105 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_DEFS_H +#define __IA_CSS_TERMINAL_DEFS_H + + +#include "type_support.h" + +#define IA_CSS_TERMINAL_ID_BITS 8 +typedef uint8_t ia_css_terminal_ID_t; +#define IA_CSS_TERMINAL_INVALID_ID ((ia_css_terminal_ID_t)(-1)) + +/* + * Terminal Base Type + */ +typedef enum ia_css_terminal_type { + /**< Data input */ + IA_CSS_TERMINAL_TYPE_DATA_IN = 0, + /**< Data output */ + IA_CSS_TERMINAL_TYPE_DATA_OUT, + /**< Type 6 parameter input */ + IA_CSS_TERMINAL_TYPE_PARAM_STREAM, + /**< Type 1-5 parameter input */ + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN, + /**< Type 1-5 parameter output */ + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT, + /**< Represent the new type of terminal for the + * "spatial dependent parameters", when params go in + */ + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN, + /**< Represent the new type of terminal for the + * "spatial dependent parameters", when params go out + */ + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT, + /**< Represent the new type of terminal for the + * explicit slicing, when params go in + */ + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN, + /**< Represent the new type of terminal for the + * explicit slicing, when params go out + */ + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT, + /**< State (private data) input */ + IA_CSS_TERMINAL_TYPE_STATE_IN, + /**< State (private data) output */ + IA_CSS_TERMINAL_TYPE_STATE_OUT, + IA_CSS_TERMINAL_TYPE_PROGRAM, + IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT, + IA_CSS_N_TERMINAL_TYPES +} ia_css_terminal_type_t; + +#define IA_CSS_TERMINAL_TYPE_BITS 32 + +/* Temporary redirection needed to facilicate merging with the drivers + in a backwards compatible manner */ +#define IA_CSS_TERMINAL_TYPE_PARAM_CACHED IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN + +/* + * Dimensions of the data objects. Note that a C-style + * data order is assumed. Data stored by row. + */ +typedef enum ia_css_dimension { + /**< The number of columns, i.e. the size of the row */ + IA_CSS_COL_DIMENSION = 0, + /**< The number of rows, i.e. the size of the column */ + IA_CSS_ROW_DIMENSION = 1, + IA_CSS_N_DATA_DIMENSION = 2 +} ia_css_dimension_t; + +#define IA_CSS_N_COMMAND_COUNT (4) + +#ifndef PIPE_GENERATION +/* Don't include these complex enum structures in Genpipe, it can't handle and it does not need them */ +/* + * enum ia_css_isys_link_id. Lists the link IDs used by the FW for On The Fly feature + */ +typedef enum ia_css_isys_link_id { + IA_CSS_ISYS_LINK_OFFLINE = 0, + IA_CSS_ISYS_LINK_MAIN_OUTPUT = 1, + IA_CSS_ISYS_LINK_PDAF_OUTPUT = 2 +} ia_css_isys_link_id_t; +#define N_IA_CSS_ISYS_LINK_ID (IA_CSS_ISYS_LINK_PDAF_OUTPUT + 1) + +/* + * enum ia_css_data_barrier_link_id. Lists the link IDs used by the FW for data barrier feature + */ +typedef enum ia_css_data_barrier_link_id { + IA_CSS_DATA_BARRIER_LINK_MEMORY = N_IA_CSS_ISYS_LINK_ID, + N_IA_CSS_DATA_BARRIER_LINK_ID +} ia_css_data_barrier_link_id_t; + +#endif /* #ifndef PIPE_GENERATION */ +#endif /* __IA_CSS_TERMINAL_DEFS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isys_fw_bridged_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isys_fw_bridged_types.h new file mode 100644 index 0000000000000..5d85c0f2de14f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isys_fw_bridged_types.h @@ -0,0 +1,402 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYS_FW_BRIDGED_TYPES_H +#define __IA_CSS_ISYS_FW_BRIDGED_TYPES_H + +#include "platform_support.h" + +#include "ia_css_isysapi_fw_types.h" + +/** + * struct ia_css_isys_buffer_partition_comm - buffer partition information + * @num_gda_pages: Number of virtual gda pages available for each + * virtual stream + */ +struct ia_css_isys_buffer_partition_comm { + aligned_uint32(unsigned int, num_gda_pages[STREAM_ID_MAX]); +}; + +/** + * struct ia_css_isys_fw_config - contains the parts from + * ia_css_isys_device_cfg_data + * we need to transfer to the cell + * @num_send_queues: Number of send queues per queue + * type(N_IA_CSS_ISYS_QUEUE_TYPE) + * @num_recv_queues: Number of receive queues per queue + * type(N_IA_CSS_ISYS_QUEUE_TYPE) + */ +struct ia_css_isys_fw_config { + aligned_struct(struct ia_css_isys_buffer_partition_comm, + buffer_partition); + aligned_uint32(unsigned int, + num_send_queues[N_IA_CSS_ISYS_QUEUE_TYPE]); + aligned_uint32(unsigned int, + num_recv_queues[N_IA_CSS_ISYS_QUEUE_TYPE]); +}; + +/** + * struct ia_css_isys_resolution_comm: Generic resolution structure. + * @Width + * @Height + */ +struct ia_css_isys_resolution_comm { + aligned_uint32(unsigned int, width); + aligned_uint32(unsigned int, height); +}; + +/** + * struct ia_css_isys_output_pin_payload_comm + * @out_buf_id: Points to output pin buffer - buffer identifier + * @addr: Points to output pin buffer - CSS Virtual Address + * @compress: Request frame compression (1), or not (0) + * This must be the same as ia_css_isys_output_pin_info_comm::reserve_compression + */ +struct ia_css_isys_output_pin_payload_comm { + aligned_uint64(ia_css_return_token, out_buf_id); + aligned_uint32(ia_css_output_buffer_css_address, addr); + aligned_uint32(unsigned int, compress); +}; + +/** + * struct ia_css_isys_output_pin_info_comm + * @input_pin_id: input pin id/index which is source of + * the data for this output pin + * @output_res: output pin resolution + * @stride: output stride in Bytes (not valid for statistics) + * @watermark_in_lines: pin watermark level in lines + * @payload_buf_size: Size in Bytes of all buffers that will be supplied for capture + * on this pin (i.e. addressed by ia_css_isys_output_pin_payload::addr) + * @send_irq: assert if pin event should trigger irq + * @pt: pin type + * @ft: frame format type + * @link_id: identifies PPG to connect to, link_id = 0 implies offline + * while link_id > 0 implies buffer_chasing or online mode + * can be entered. + * @reserve_compression: Reserve compression resources for pin. + */ +struct ia_css_isys_output_pin_info_comm { + aligned_struct(struct ia_css_isys_resolution_comm, output_res); + aligned_uint32(unsigned int, stride); + aligned_uint32(unsigned int, watermark_in_lines); + aligned_uint32(unsigned int, payload_buf_size); + aligned_uint8(unsigned int, send_irq); + aligned_uint8(unsigned int, input_pin_id); + aligned_uint8(enum ia_css_isys_pin_type, pt); + aligned_uint8(enum ia_css_isys_frame_format_type, ft); + aligned_uint8(enum ia_css_isys_link_id, link_id); + aligned_uint8(unsigned int, reserve_compression); +}; + +/** + * struct ia_css_isys_param_pin_comm + * @param_buf_id: Points to param port buffer - buffer identifier + * @addr: Points to param pin buffer - CSS Virtual Address + */ +struct ia_css_isys_param_pin_comm { + aligned_uint64(ia_css_return_token, param_buf_id); + aligned_uint32(ia_css_input_buffer_css_address, addr); +}; + +/** + * struct ia_css_isys_input_pin_info_comm + * @input_res: input resolution + * @dt: mipi data type + * @mipi_store_mode: defines if legacy long packet header will be stored or + * hdiscarded if discarded, output pin pin type for this + * input pin can only be MIPI + * @bits_per_pix: native bits per pixel + * @dt_rename: mapped_dt + */ +struct ia_css_isys_input_pin_info_comm { + aligned_struct(struct ia_css_isys_resolution_comm, input_res); + aligned_uint8(enum ia_css_isys_mipi_data_type, dt); + aligned_uint8(enum ia_css_isys_mipi_store_mode, mipi_store_mode); + aligned_uint8(unsigned int, bits_per_pix); + aligned_uint8(unsigned int, mapped_dt); +}; + +/** + * ISA configuration fields, definition and macros + */ +#define ISA_CFG_FIELD_BLC_EN_LEN 1 +#define ISA_CFG_FIELD_BLC_EN_SHIFT 0 + +#define ISA_CFG_FIELD_LSC_EN_LEN 1 +#define ISA_CFG_FIELD_LSC_EN_SHIFT 1 + +#define ISA_CFG_FIELD_DPC_EN_LEN 1 +#define ISA_CFG_FIELD_DPC_EN_SHIFT 2 + +#define ISA_CFG_FIELD_DOWNSCALER_EN_LEN 1 +#define ISA_CFG_FIELD_DOWNSCALER_EN_SHIFT 3 + +#define ISA_CFG_FIELD_AWB_EN_LEN 1 +#define ISA_CFG_FIELD_AWB_EN_SHIFT 4 + +#define ISA_CFG_FIELD_AF_EN_LEN 1 +#define ISA_CFG_FIELD_AF_EN_SHIFT 5 + +#define ISA_CFG_FIELD_AE_EN_LEN 1 +#define ISA_CFG_FIELD_AE_EN_SHIFT 6 + +#define ISA_CFG_FIELD_PAF_TYPE_LEN 8 +#define ISA_CFG_FIELD_PAF_TYPE_SHIFT 7 + +#define ISA_CFG_FIELD_SEND_IRQ_STATS_READY_LEN 1 +#define ISA_CFG_FIELD_SEND_IRQ_STATS_READY_SHIFT 15 + +#define ISA_CFG_FIELD_SEND_RESP_STATS_READY_LEN 1 +#define ISA_CFG_FIELD_SEND_RESP_STATS_READY_SHIFT 16 + +/* Helper macros */ +#define ISA_CFG_GET_MASK_FROM_LEN(len) ((1 << (len)) - 1) +#define ISA_CFG_GET_MASK_FROM_TAG(tag) \ + (ISA_CFG_GET_MASK_FROM_LEN(ISA_CFG_FIELD_##tag##_LEN)) +#define ISA_CFG_GET_SHIFT_FROM_TAG(tag) \ + (ISA_CFG_FIELD_##tag##_SHIFT) +/* Get/Set macros */ +#define ISA_CFG_FIELD_GET(tag, word) \ + ( \ + ((word) >> (ISA_CFG_GET_SHIFT_FROM_TAG(tag))) &\ + ISA_CFG_GET_MASK_FROM_TAG(tag) \ + ) +#define ISA_CFG_FIELD_SET(tag, word, value) \ + (word |= ( \ + ((value) & ISA_CFG_GET_MASK_FROM_TAG(tag)) << \ + ISA_CFG_GET_SHIFT_FROM_TAG(tag) \ + )) + +/** + * struct ia_css_isys_isa_cfg_comm. Describes the ISA cfg + */ +struct ia_css_isys_isa_cfg_comm { + aligned_struct(struct ia_css_isys_resolution_comm, + isa_res[N_IA_CSS_ISYS_RESOLUTION_INFO]); + aligned_uint32(/* multi-field packing */, cfg_fields); +}; + + /** + * struct ia_css_isys_cropping_comm - cropping coordinates + */ +struct ia_css_isys_cropping_comm { + aligned_int32(int, top_offset); + aligned_int32(int, left_offset); + aligned_int32(int, bottom_offset); + aligned_int32(int, right_offset); +}; + + /** + * struct ia_css_isys_stream_cfg_data_comm + * ISYS stream configuration data structure + * @isa_cfg: details about what ACCs are active if ISA is used + * @crop: defines cropping resolution for the + * maximum number of input pins which can be cropped, + * it is directly mapped to the HW devices + * @input_pins: input pin descriptors + * @output_pins: output pin descriptors + * @compfmt: de-compression setting for User Defined Data + * @nof_input_pins: number of input pins + * @nof_output_pins: number of output pins + * @send_irq_sof_discarded: send irq on discarded frame sof response + * - if '1' it will override the send_resp_sof_discarded and send + * the response + * - if '0' the send_resp_sof_discarded will determine whether to + * send the response + * @send_irq_eof_discarded: send irq on discarded frame eof response + * - if '1' it will override the send_resp_eof_discarded and send + * the response + * - if '0' the send_resp_eof_discarded will determine whether to + * send the response + * @send_resp_sof_discarded: send response for discarded frame sof detected, + * used only when send_irq_sof_discarded is '0' + * @send_resp_eof_discarded: send response for discarded frame eof detected, + * used only when send_irq_eof_discarded is '0' + * @src: Stream source index e.g. MIPI_generator_0, CSI2-rx_1 + * @vc: MIPI Virtual Channel (up to 4 virtual per physical channel) + * @isl_use: indicates whether stream requires ISL and how + */ +struct ia_css_isys_stream_cfg_data_comm { + aligned_struct(struct ia_css_isys_isa_cfg_comm, isa_cfg); + aligned_struct(struct ia_css_isys_cropping_comm, + crop[N_IA_CSS_ISYS_CROPPING_LOCATION]); + aligned_struct(struct ia_css_isys_input_pin_info_comm, + input_pins[MAX_IPINS]); + aligned_struct(struct ia_css_isys_output_pin_info_comm, + output_pins[MAX_OPINS]); + aligned_uint32(unsigned int, compfmt); + aligned_uint8(unsigned int, nof_input_pins); + aligned_uint8(unsigned int, nof_output_pins); + aligned_uint8(unsigned int, send_irq_sof_discarded); + aligned_uint8(unsigned int, send_irq_eof_discarded); + aligned_uint8(unsigned int, send_resp_sof_discarded); + aligned_uint8(unsigned int, send_resp_eof_discarded); + aligned_uint8(enum ia_css_isys_stream_source, src); + aligned_uint8(enum ia_css_isys_mipi_vc, vc); + aligned_uint8(enum ia_css_isys_isl_use, isl_use); +}; + +/** + * struct ia_css_isys_frame_buff_set - frame buffer set + * @output_pins: output pin addresses + * @process_group_light: process_group_light buffer address + * @send_irq_sof: send irq on frame sof response + * - if '1' it will override the send_resp_sof and send the + * response + * - if '0' the send_resp_sof will determine whether to send the + * response + * @send_irq_eof: send irq on frame eof response + * - if '1' it will override the send_resp_eof and send the + * response + * - if '0' the send_resp_eof will determine whether to send the + * response + * @send_resp_sof: send response for frame sof detected, used only when + * send_irq_sof is '0' + * @send_resp_eof: send response for frame eof detected, used only when + * send_irq_eof is '0' + * @frame_counter: frame number associated with this buffer set. + */ +struct ia_css_isys_frame_buff_set_comm { + aligned_struct(struct ia_css_isys_output_pin_payload_comm, + output_pins[MAX_OPINS]); + aligned_struct(struct ia_css_isys_param_pin_comm, process_group_light); + aligned_uint8(unsigned int, send_irq_sof); + aligned_uint8(unsigned int, send_irq_eof); + aligned_uint8(unsigned int, send_irq_capture_ack); + aligned_uint8(unsigned int, send_irq_capture_done); + aligned_uint8(unsigned int, send_resp_sof); + aligned_uint8(unsigned int, send_resp_eof); + aligned_uint8(unsigned int, frame_counter); +}; + +/** + * struct ia_css_isys_error_info_comm + * @error: error code if something went wrong + * @error_details: depending on error code, it may contain additional + * error info + */ +struct ia_css_isys_error_info_comm { + aligned_enum(enum ia_css_isys_error, error); + aligned_uint32(unsigned int, error_details); +}; + +/** + * struct ia_css_isys_resp_info_comm + * @pin: this var is only valid for pin event related responses, + * contains pin addresses + * @process_group_light: this var is valid for stats ready related responses, + * contains process group addresses + * @error_info: error information from the FW + * @timestamp: Time information for event if available + * @stream_handle: stream id the response corresponds to + * @type: response type + * @pin_id: pin id that the pin payload corresponds to + * @acc_id: this var is valid for stats ready related responses, + * contains accelerator id that finished producing + * all related statistics + * @frame_counter: valid for STREAM_START_AND_CAPTURE_DONE, + * STREAM_CAPTURE_DONE and STREAM_CAPTURE_DISCARDED, + * @written_direct: indicates if frame was written direct (online mode) or not. + * + */ + +struct ia_css_isys_resp_info_comm { + aligned_uint64(ia_css_return_token, buf_id); /* Used internally only */ + aligned_struct(struct ia_css_isys_output_pin_payload_comm, pin); + aligned_struct(struct ia_css_isys_param_pin_comm, process_group_light); + aligned_struct(struct ia_css_isys_error_info_comm, error_info); + aligned_uint32(unsigned int, timestamp[2]); + aligned_uint8(unsigned int, stream_handle); + aligned_uint8(enum ia_css_isys_resp_type, type); + aligned_uint8(unsigned int, pin_id); + aligned_uint8(unsigned int, acc_id); + aligned_uint8(unsigned int, frame_counter); + aligned_uint8(unsigned int, written_direct); +}; + +/** + * struct ia_css_isys_proxy_error_info_comm + * @proxy_error: error code if something went wrong + * @proxy_error_details: depending on error code, it may contain additional + * error info + */ +struct ia_css_isys_proxy_error_info_comm { + aligned_enum(enum ia_css_proxy_error, error); + aligned_uint32(unsigned int, error_details); +}; + +/** + * struct ia_css_isys_proxy_resp_info_comm + * @request_id: Unique identifier for the write request + * (in case multiple write requests are issued for same register) + * @error_info: details in struct definition + */ +struct ia_css_isys_proxy_resp_info_comm { + aligned_uint32(uint32_t, request_id); + aligned_struct(struct ia_css_isys_proxy_error_info_comm, error_info); +}; + +/** + * struct ia_css_proxy_write_queue_token + * @request_id: update id for the specific proxy write request + * @region_index: Region id for the proxy write request + * @offset: Offset of the write request according to the base address of the + * region + * @value: Value that is requested to be written with the proxy write request + */ +struct ia_css_proxy_write_queue_token { + aligned_uint32(uint32_t, request_id); + aligned_uint32(uint32_t, region_index); + aligned_uint32(uint32_t, offset); + aligned_uint32(uint32_t, value); +}; + +/* From here on type defines not coming from the ISYSAPI interface */ + +/** + * struct resp_queue_token + */ +struct resp_queue_token { + aligned_struct(struct ia_css_isys_resp_info_comm, resp_info); +}; + +/** + * struct send_queue_token + */ +struct send_queue_token { + aligned_uint64(ia_css_return_token, buf_handle); + aligned_uint32(ia_css_input_buffer_css_address, payload); + aligned_uint16(enum ia_css_isys_send_type, send_type); + aligned_uint16(unsigned int, stream_id); +}; + +/** + * struct proxy_resp_queue_token + */ +struct proxy_resp_queue_token { + aligned_struct(struct ia_css_isys_proxy_resp_info_comm, + proxy_resp_info); +}; + +/** + * struct proxy_send_queue_token + */ +struct proxy_send_queue_token { + aligned_uint32(uint32_t, request_id); + aligned_uint32(uint32_t, region_index); + aligned_uint32(uint32_t, offset); + aligned_uint32(uint32_t, value); +}; + +#endif /* __IA_CSS_ISYS_FW_BRIDGED_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi.h new file mode 100644 index 0000000000000..514cbcda69099 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi.h @@ -0,0 +1,321 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_H +#define __IA_CSS_ISYSAPI_H + + +/* The following is needed for the function arguments */ +#include "ia_css_isysapi_types.h" + +/* To define the HANDLE */ +#include "type_support.h" + + +/** + * ia_css_isys_device_open() - configure ISYS device + * @ context : device handle output parameter + * @config: device configuration data struct ptr as input parameter, + * read only by css fw until function return + * Ownership, ISYS will only access read my_device during fct call + * Prepares and Sends to PG server (SP) the syscom and isys context + * Executes the host level 0 and 1 boot sequence and starts the PG server (SP) + * All streams must be stopped when calling ia_css_isys_device_open() + * + * Return: int type error code (errno.h) + */ +#if HAS_DUAL_CMD_CTX_SUPPORT +extern int ia_css_isys_context_create( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config +); +extern int ia_css_isys_context_store_dmem( + const HANDLE *context, + const struct ia_css_isys_device_cfg_data *config +); +extern bool ia_css_isys_ab_spc_ready( + HANDLE *context +); +extern int ia_css_isys_device_open( + const struct ia_css_isys_device_cfg_data *config +); +#else +extern int ia_css_isys_device_open( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config +); +#endif + +/** + * ia_css_isys_device_open_ready() - Complete ISYS device configuration + * @ context : device handle output parameter + * read only by css fw until function return + * Requires the boot failure to be completed before it can return + * successfully (includes syscom and isys context) + * Initialise Host/ISYS messaging queues + * Must be called multiple times until it succeeds or it is determined by + * the driver that the boot seuqence has failed. + * All streams must be stopped when calling ia_css_isys_device_open() + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_device_open_ready( + HANDLE context +); + + /** + * ia_css_isys_stream_open() - open and configure a virtual stream + * @ stream_handle: stream handle + * @ stream_cfg: stream configuration data struct pointer, which is + * "read only" by ISYS until function return + * ownership, ISYS will only read access stream_cfg during fct call + * Pre-conditions: + * Any Isys/Ssys interface changes must call ia_css_isys_stream_open() + * Post-condition: + * On successful call, ISYS hardware resource (IBFctrl, ISL, DMAs) + * are acquired and ISYS server is able to handle stream specific commands + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_open( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_stream_cfg_data *stream_cfg +); + +/** + * ia_css_isys_stream_close() - close virtual stream + * @ stream_handle: stream identifier + * release ISYS resources by freeing up stream HW resources + * output pin buffers ownership is returned to the driver + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_close( + HANDLE context, + const unsigned int stream_handle +); + +/** + * ia_css_isys_stream_start() - starts handling a mipi virtual stream + * @ stream_handle: stream identifier + * @next_frame: + * if next_frame != NULL: apply next_frame + * settings asynchronously and start stream + * This mode ensures that the first frame is captured + * and thus a minimal start up latency + * (preconditions: sensor streaming must be switched off) + * + * if next_frame == NULL: sensor can be in a streaming state, + * all capture indicates commands will be + * processed synchronously (e.g. on mipi SOF events) + * + * To be called once ia_css_isys_stream_open() successly called + * On success, the stream's HW resources are in active state + * + * Object ownership: During this function call, + * next_frame struct must be read but not modified by the ISYS, + * and in addition the driver is not allowed to modify it + * on function exit next_frame ownership is returned to + * the driver and is no longer accesses by iSYS + * next_frame contains a collection of + * ia_css_isys_output_pin * and ia_css_isys_input_pin * + * which point to the frame's "output/input pin info & data buffers", + * + * Upon the ia_css_isys_stream_start() call, + * ia_css_isys_output_pin* or ia_css_isys_input_pin* + * will now be owned by the ISYS + * these ptr will enable runtime/dynamic ISYS configuration and also + * to store and write captured payload data + * at the address specified in ia_css_isys_output_pin_payload + * These ptrs should no longer be accessed by any other + * code until (ia_css_isys_output_pin) gets handed + * back to the driver via the response mechansim + * ia_css_isys_stream_handle_response() + * the driver is responsible for providing valid + * ia_css_isys_output_pin* or ia_css_isys_output_pin* + * Pointers set to NULL will simply not be used by the ISYS + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_start( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_frame_buff_set *next_frame +); + +/** + * ia_css_isys_stream_stop() - Stops a mipi virtual stream + * @ stream_handle: stream identifier + * stop both accepting new commands and processing + * submitted capture indication commands + * Support for Secure Touch + * Precondition: stream must be started + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_stop( + HANDLE context, + const unsigned int stream_handle +); + +/** + * ia_css_isys_stream_flush() - stops a mipi virtual stream but + * completes processing cmd backlog + * @ stream_handle: stream identifier + * stop accepting commands, but process + * the already submitted capture indicates + * Precondition: stream must be started + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_flush( + HANDLE context, + const unsigned int stream_handle +); + +/** + * ia_css_isys_stream_capture_indication() + * captures "next frame" on stream_handle + * @ stream_handle: stream identifier + * @ next_frame: frame pin payloads are provided atomically + * purpose: stream capture new frame command, Successfull calls will + * result in frame output pins being captured + * + * To be called once ia_css_isys_stream_start() is successly called + * On success, the stream's HW resources are in active state + * + * Object ownership: During this function call, + * next_frame struct must be read but not modified by the ISYS, + * and in addition the driver is not allowed to modify it + * on function exit next_frame ownership is returned to + * the driver and is no longer accesses by iSYS + * next_frame contains a collection of + * ia_css_isys_output_pin * and ia_css_isys_input_pin * + * which point to the frame's "output/input pin info & data buffers", + * + * Upon the ia_css_isys_stream_capture_indication() call, + * ia_css_isys_output_pin* or ia_css_isys_input_pin* + * will now be owned by the ISYS + * these ptr will enable runtime/dynamic ISYS configuration and also + * to store and write captured payload data + * at the address specified in ia_css_isys_output_pin_payload + * These ptrs should no longer be accessed by any other + * code until (ia_css_isys_output_pin) gets handed + * back to the driver via the response mechanism + * ia_css_isys_stream_handle_response() + * the driver is responsible for providing valid + * ia_css_isys_output_pin* or ia_css_isys_output_pin* + * Pointers set to NULL will simply not be used by the ISYS, and this + * refers specifically the following cases: + * - output pins from SOC path if the same datatype is also passed into ISAPF + * path or it has active MIPI output (not NULL) + * - full resolution pin from ISA (but not when bypassing ISA) + * - scaled pin from ISA (bypassing ISA for scaled pin is impossible) + * - output pins from MIPI path but only when the same datatype is also + * either forwarded to the ISAPF path based on the stream configuration + * (it is ok if the second output pin of this datatype is also skipped) + * or it has an active SOC output (not NULL) + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_capture_indication( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_frame_buff_set *next_frame +); + +/** + * ia_css_isys_stream_handle_response() - handle ISYS responses + * @received_response: provides response info from the + * "next response element" from ISYS server + * received_response will be written to during the fct call and + * can be read by the drv once fct is returned + * + * purpose: Allows the client to handle received ISYS responses + * Upon an IRQ event, the driver will call ia_css_isys_stream_handle_response() + * until the queue is emptied + * Responses returning IA_CSS_ISYS_RESP_TYPE_PIN_DATA_READY to the driver will + * hand back ia_css_isys_output_pin ownership to the drv + * ISYS FW will not write/read access ia_css_isys_output_pin + * once it belongs to the driver + * Pre-conditions: ISYS client must have sent a CMDs to ISYS srv + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_stream_handle_response( + HANDLE context, + struct ia_css_isys_resp_info *received_response +); + +/** + * ia_css_isys_device_close() - close ISYS device + * @context : device handle output parameter + * Purpose: Request for the cell to close + * All streams must be stopped when calling ia_css_isys_device_close() + * + * Return: int type error code (errno.h) + */ +#if HAS_DUAL_CMD_CTX_SUPPORT +extern int ia_css_isys_context_destroy( + HANDLE context +); +extern void ia_css_isys_device_close( + void +); +#else +extern int ia_css_isys_device_close( + HANDLE context +); +#endif + +/** + * ia_css_isys_device_release() - release ISYS device + * @context : device handle output parameter + * @force: forces release or verifies the state before releasing + * Purpose: Free context forcibly or not + * Must be called after ia_css_isys_device_close() + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_device_release( + HANDLE context, + unsigned int force +); + +/** + * ia_css_isys_proxy_write_req() - issue a isys proxy write request + * @context : device handle output parameter + * Purpose: Issues a write request for the regions that are exposed + * by proxy interface + * Can be called any time between ia_css_isys_device_open + * ia_css_isys_device_close + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_proxy_write_req( + HANDLE context, + const struct ia_css_proxy_write_req_val *write_req_val +); + +/** + * ia_css_isys_proxy_handle_write_response() + * - Handles isys proxy write request responses + * @context : device handle output parameter + * Purpose: Handling the responses that are created by FW upon the completion + * proxy interface write request + * + * Return: int type error code (errno.h) + */ +extern int ia_css_isys_proxy_handle_write_response( + HANDLE context, + struct ia_css_proxy_write_req_resp *received_response +); + +#endif /* __IA_CSS_ISYSAPI_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_fw_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_fw_types.h new file mode 100644 index 0000000000000..938f726d1cfb8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_fw_types.h @@ -0,0 +1,512 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_FW_TYPES_H +#define __IA_CSS_ISYSAPI_FW_TYPES_H + + +/* Max number of Input/Output Pins */ +#define MAX_IPINS (4) +/* worst case is ISA use where a single input pin produces: +* Mipi output, NS Pixel Output, and Scaled Pixel Output. +* This is how the 2 is calculated +*/ +#define MAX_OPINS ((MAX_IPINS) + 2) + +/* Max number of supported virtual streams */ +#define STREAM_ID_MAX (8) + +/* Aligned with the approach of having one dedicated per stream */ +#define N_MAX_MSG_SEND_QUEUES (STREAM_ID_MAX) +/* Single return queue for all streams/commands type */ +#define N_MAX_MSG_RECV_QUEUES (1) +/* Single device queue for high priority commands (bypass in-order queue) */ +#define N_MAX_DEV_SEND_QUEUES (1) +/* Single dedicated send queue for proxy interface */ +#define N_MAX_PROXY_SEND_QUEUES (1) +/* Single dedicated recv queue for proxy interface */ +#define N_MAX_PROXY_RECV_QUEUES (1) +/* Send queues layout */ +#define BASE_PROXY_SEND_QUEUES (0) +#define BASE_DEV_SEND_QUEUES (BASE_PROXY_SEND_QUEUES + N_MAX_PROXY_SEND_QUEUES) +#define BASE_MSG_SEND_QUEUES (BASE_DEV_SEND_QUEUES + N_MAX_DEV_SEND_QUEUES) +#define N_MAX_SEND_QUEUES (BASE_MSG_SEND_QUEUES + N_MAX_MSG_SEND_QUEUES) +/* Recv queues layout */ +#define BASE_PROXY_RECV_QUEUES (0) +#define BASE_MSG_RECV_QUEUES (BASE_PROXY_RECV_QUEUES + N_MAX_PROXY_RECV_QUEUES) +#define N_MAX_RECV_QUEUES (BASE_MSG_RECV_QUEUES + N_MAX_MSG_RECV_QUEUES) + +#define MAX_QUEUE_SIZE (256) +#define MIN_QUEUE_SIZE (1) + +/* Consider 1 slot per stream since driver is not expected to pipeline + * device commands for the same stream */ +#define DEV_SEND_QUEUE_SIZE (STREAM_ID_MAX) + +/* Max number of supported SRAM buffer partitions */ +/* It refers to the size of stream partitions */ +/* These partitions are further subpartitioned internally */ +/* by the FW, but by declaring statically the stream */ +/* partitions we solve the buffer fragmentation issue */ +#define NOF_SRAM_BLOCKS_MAX (STREAM_ID_MAX) + +/* Max number of supported input pins routed in ISL */ +#define MAX_IPINS_IN_ISL (2) + +/* Max number of planes for frame formats supported by the FW */ +#define PIN_PLANES_MAX (4) + +/** + * enum ia_css_isys_resp_type + */ +enum ia_css_isys_resp_type { + IA_CSS_ISYS_RESP_TYPE_STREAM_OPEN_DONE = 0, + IA_CSS_ISYS_RESP_TYPE_STREAM_START_ACK, + IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK, + IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK, + IA_CSS_ISYS_RESP_TYPE_STREAM_STOP_ACK, + IA_CSS_ISYS_RESP_TYPE_STREAM_FLUSH_ACK, + IA_CSS_ISYS_RESP_TYPE_STREAM_CLOSE_ACK, + IA_CSS_ISYS_RESP_TYPE_PIN_DATA_READY, + IA_CSS_ISYS_RESP_TYPE_PIN_DATA_WATERMARK, + IA_CSS_ISYS_RESP_TYPE_FRAME_SOF, + IA_CSS_ISYS_RESP_TYPE_FRAME_EOF, + IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE, + IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_DONE, + IA_CSS_ISYS_RESP_TYPE_PIN_DATA_SKIPPED, + IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_SKIPPED, + IA_CSS_ISYS_RESP_TYPE_FRAME_SOF_DISCARDED, + IA_CSS_ISYS_RESP_TYPE_FRAME_EOF_DISCARDED, + IA_CSS_ISYS_RESP_TYPE_STATS_DATA_READY, + N_IA_CSS_ISYS_RESP_TYPE +}; + +/** + * enum ia_css_isys_send_type + */ +enum ia_css_isys_send_type { + IA_CSS_ISYS_SEND_TYPE_STREAM_OPEN = 0, + IA_CSS_ISYS_SEND_TYPE_STREAM_START, + IA_CSS_ISYS_SEND_TYPE_STREAM_START_AND_CAPTURE, + IA_CSS_ISYS_SEND_TYPE_STREAM_CAPTURE, + IA_CSS_ISYS_SEND_TYPE_STREAM_STOP, + IA_CSS_ISYS_SEND_TYPE_STREAM_FLUSH, + IA_CSS_ISYS_SEND_TYPE_STREAM_CLOSE, + N_IA_CSS_ISYS_SEND_TYPE +}; + +/** + * enum ia_css_isys_queue_type + */ +enum ia_css_isys_queue_type { + IA_CSS_ISYS_QUEUE_TYPE_PROXY = 0, + IA_CSS_ISYS_QUEUE_TYPE_DEV, + IA_CSS_ISYS_QUEUE_TYPE_MSG, + N_IA_CSS_ISYS_QUEUE_TYPE +}; + +/** + * enum ia_css_isys_stream_source: Specifies a source for a stream + */ +enum ia_css_isys_stream_source { + IA_CSS_ISYS_STREAM_SRC_PORT_0 = 0, + IA_CSS_ISYS_STREAM_SRC_PORT_1, + IA_CSS_ISYS_STREAM_SRC_PORT_2, + IA_CSS_ISYS_STREAM_SRC_PORT_3, + IA_CSS_ISYS_STREAM_SRC_PORT_4, + IA_CSS_ISYS_STREAM_SRC_PORT_5, + IA_CSS_ISYS_STREAM_SRC_PORT_6, + IA_CSS_ISYS_STREAM_SRC_PORT_7, + IA_CSS_ISYS_STREAM_SRC_PORT_8, + IA_CSS_ISYS_STREAM_SRC_PORT_9, + IA_CSS_ISYS_STREAM_SRC_PORT_10, + IA_CSS_ISYS_STREAM_SRC_PORT_11, + IA_CSS_ISYS_STREAM_SRC_PORT_12, + IA_CSS_ISYS_STREAM_SRC_PORT_13, + IA_CSS_ISYS_STREAM_SRC_PORT_14, + IA_CSS_ISYS_STREAM_SRC_PORT_15, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_0, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_1, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_2, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_3, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_4, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_5, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_6, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_7, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_8, + IA_CSS_ISYS_STREAM_SRC_MIPIGEN_9, + N_IA_CSS_ISYS_STREAM_SRC +}; + +#define IA_CSS_ISYS_STREAM_SRC_CSI2_PORT0 IA_CSS_ISYS_STREAM_SRC_PORT_0 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_PORT1 IA_CSS_ISYS_STREAM_SRC_PORT_1 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_PORT2 IA_CSS_ISYS_STREAM_SRC_PORT_2 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_PORT3 IA_CSS_ISYS_STREAM_SRC_PORT_3 + +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_PORTA IA_CSS_ISYS_STREAM_SRC_PORT_4 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_PORTB IA_CSS_ISYS_STREAM_SRC_PORT_5 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT0 IA_CSS_ISYS_STREAM_SRC_PORT_6 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT1 IA_CSS_ISYS_STREAM_SRC_PORT_7 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT2 IA_CSS_ISYS_STREAM_SRC_PORT_8 +#define IA_CSS_ISYS_STREAM_SRC_CSI2_3PH_CPHY_PORT3 IA_CSS_ISYS_STREAM_SRC_PORT_9 + +#define IA_CSS_ISYS_STREAM_SRC_MIPIGEN_PORT0 IA_CSS_ISYS_STREAM_SRC_MIPIGEN_0 +#define IA_CSS_ISYS_STREAM_SRC_MIPIGEN_PORT1 IA_CSS_ISYS_STREAM_SRC_MIPIGEN_1 + +/** + * enum ia_css_isys_mipi_vc: MIPI csi2 spec + * supports upto 4 virtual per physical channel + */ +enum ia_css_isys_mipi_vc { + IA_CSS_ISYS_MIPI_VC_0 = 0, + IA_CSS_ISYS_MIPI_VC_1, + IA_CSS_ISYS_MIPI_VC_2, + IA_CSS_ISYS_MIPI_VC_3, + N_IA_CSS_ISYS_MIPI_VC +}; + +/** + * Supported Pixel Frame formats. Expandable if needed + */ +enum ia_css_isys_frame_format_type { + IA_CSS_ISYS_FRAME_FORMAT_NV11 = 0,/* 12 bit YUV 411, Y, UV plane */ + IA_CSS_ISYS_FRAME_FORMAT_NV12,/* 12 bit YUV 420, Y, UV plane */ + IA_CSS_ISYS_FRAME_FORMAT_NV12_16,/* 16 bit YUV 420, Y, UV plane */ + IA_CSS_ISYS_FRAME_FORMAT_NV12_TILEY,/* 12 bit YUV 420, Intel + proprietary tiled format, + TileY + */ + IA_CSS_ISYS_FRAME_FORMAT_NV16,/* 16 bit YUV 422, Y, UV plane */ + IA_CSS_ISYS_FRAME_FORMAT_NV21,/* 12 bit YUV 420, Y, VU plane */ + IA_CSS_ISYS_FRAME_FORMAT_NV61,/* 16 bit YUV 422, Y, VU plane */ + IA_CSS_ISYS_FRAME_FORMAT_YV12,/* 12 bit YUV 420, Y, V, U plane */ + IA_CSS_ISYS_FRAME_FORMAT_YV16,/* 16 bit YUV 422, Y, V, U plane */ + IA_CSS_ISYS_FRAME_FORMAT_YUV420,/* 12 bit YUV 420, Y, U, V plane */ + IA_CSS_ISYS_FRAME_FORMAT_YUV420_10,/* yuv420, 10 bits per subpixel */ + IA_CSS_ISYS_FRAME_FORMAT_YUV420_12,/* yuv420, 12 bits per subpixel */ + IA_CSS_ISYS_FRAME_FORMAT_YUV420_14,/* yuv420, 14 bits per subpixel */ + IA_CSS_ISYS_FRAME_FORMAT_YUV420_16,/* yuv420, 16 bits per subpixel */ + IA_CSS_ISYS_FRAME_FORMAT_YUV422,/* 16 bit YUV 422, Y, U, V plane */ + IA_CSS_ISYS_FRAME_FORMAT_YUV422_16,/* yuv422, 16 bits per subpixel */ + IA_CSS_ISYS_FRAME_FORMAT_UYVY,/* 16 bit YUV 422, UYVY interleaved */ + IA_CSS_ISYS_FRAME_FORMAT_YUYV,/* 16 bit YUV 422, YUYV interleaved */ + IA_CSS_ISYS_FRAME_FORMAT_YUV444,/* 24 bit YUV 444, Y, U, V plane */ + IA_CSS_ISYS_FRAME_FORMAT_YUV_LINE,/* Internal format, 2 y lines + followed by a uvinterleaved line + */ + IA_CSS_ISYS_FRAME_FORMAT_RAW8, /* RAW8, 1 plane */ + IA_CSS_ISYS_FRAME_FORMAT_RAW10, /* RAW10, 1 plane */ + IA_CSS_ISYS_FRAME_FORMAT_RAW12, /* RAW12, 1 plane */ + IA_CSS_ISYS_FRAME_FORMAT_RAW14, /* RAW14, 1 plane */ + IA_CSS_ISYS_FRAME_FORMAT_RAW16, /* RAW16, 1 plane */ + IA_CSS_ISYS_FRAME_FORMAT_RGB565,/* 16 bit RGB, 1 plane. Each 3 sub + pixels are packed into one 16 bit + value, 5 bits for R, 6 bits for G + and 5 bits for B. + */ + IA_CSS_ISYS_FRAME_FORMAT_PLANAR_RGB888, /* 24 bit RGB, 3 planes */ + IA_CSS_ISYS_FRAME_FORMAT_RGBA888,/* 32 bit RGBA, 1 plane, + A=Alpha (alpha is unused) + */ + IA_CSS_ISYS_FRAME_FORMAT_QPLANE6,/* Internal, for advanced ISP */ + IA_CSS_ISYS_FRAME_FORMAT_BINARY_8,/* byte stream, used for jpeg. */ + N_IA_CSS_ISYS_FRAME_FORMAT +}; +/* Temporary for driver compatibility */ +#define IA_CSS_ISYS_FRAME_FORMAT_RAW (IA_CSS_ISYS_FRAME_FORMAT_RAW16) + + +/** + * Supported MIPI data type. Keep in sync array in ia_css_isys_private.c + */ +enum ia_css_isys_mipi_data_type { + /** SYNCHRONIZATION SHORT PACKET DATA TYPES */ + IA_CSS_ISYS_MIPI_DATA_TYPE_FRAME_START_CODE = 0x00, + IA_CSS_ISYS_MIPI_DATA_TYPE_FRAME_END_CODE = 0x01, + IA_CSS_ISYS_MIPI_DATA_TYPE_LINE_START_CODE = 0x02, /* Optional */ + IA_CSS_ISYS_MIPI_DATA_TYPE_LINE_END_CODE = 0x03, /* Optional */ + /** Reserved 0x04-0x07 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x04 = 0x04, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x05 = 0x05, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x06 = 0x06, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x07 = 0x07, + /** GENERIC SHORT PACKET DATA TYPES */ + /** They are used to keep the timing information for the + * opening/closing of shutters, triggering of flashes and etc. + */ + /* Generic Short Packet Code 1 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT1 = 0x08, + /* Generic Short Packet Code 2 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT2 = 0x09, + /* Generic Short Packet Code 3 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT3 = 0x0A, + /* Generic Short Packet Code 4 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT4 = 0x0B, + /* Generic Short Packet Code 5 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT5 = 0x0C, + /* Generic Short Packet Code 6 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT6 = 0x0D, + /* Generic Short Packet Code 7 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT7 = 0x0E, + /* Generic Short Packet Code 8 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_GENERIC_SHORT8 = 0x0F, + /** GENERIC LONG PACKET DATA TYPES */ + IA_CSS_ISYS_MIPI_DATA_TYPE_NULL = 0x10, + IA_CSS_ISYS_MIPI_DATA_TYPE_BLANKING_DATA = 0x11, + /* Embedded 8-bit non Image Data */ + IA_CSS_ISYS_MIPI_DATA_TYPE_EMBEDDED = 0x12, + /** Reserved 0x13-0x17 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x13 = 0x13, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x14 = 0x14, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x15 = 0x15, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x16 = 0x16, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x17 = 0x17, + /** YUV DATA TYPES */ + /* 8 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV420_8 = 0x18, + /* 10 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV420_10 = 0x19, + /* 8 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV420_8_LEGACY = 0x1A, + /** Reserved 0x1B */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x1B = 0x1B, + /* YUV420 8-bit (Chroma Shifted Pixel Sampling) */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV420_8_SHIFT = 0x1C, + /* YUV420 10-bit (Chroma Shifted Pixel Sampling) */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV420_10_SHIFT = 0x1D, + /* UYVY..UVYV, 8 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV422_8 = 0x1E, + /* UYVY..UVYV, 10 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_YUV422_10 = 0x1F, + /** RGB DATA TYPES */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RGB_444 = 0x20, + /* BGR..BGR, 5 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RGB_555 = 0x21, + /* BGR..BGR, 5 bits B and R, 6 bits G */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RGB_565 = 0x22, + /* BGR..BGR, 6 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RGB_666 = 0x23, + /* BGR..BGR, 8 bits per subpixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RGB_888 = 0x24, + /** Reserved 0x25-0x27 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x25 = 0x25, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x26 = 0x26, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x27 = 0x27, + /** RAW DATA TYPES */ + /* RAW data, 6 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_6 = 0x28, + /* RAW data, 7 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_7 = 0x29, + /* RAW data, 8 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_8 = 0x2A, + /* RAW data, 10 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_10 = 0x2B, + /* RAW data, 12 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_12 = 0x2C, + /* RAW data, 14 bits per pixel */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_14 = 0x2D, + /** Reserved 0x2E-2F are used with assigned meaning */ + /* RAW data, 16 bits per pixel, not specified in CSI-MIPI standard */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RAW_16 = 0x2E, + /* Binary byte stream, which is target at JPEG, not specified in + * CSI-MIPI standard + */ + IA_CSS_ISYS_MIPI_DATA_TYPE_BINARY_8 = 0x2F, + /** USER DEFINED 8-BIT DATA TYPES */ + /** For example, the data transmitter (e.g. the SoC sensor) can keep + * the JPEG data as the User Defined Data Type 4 and the MPEG data as + * the User Defined Data Type 7. + */ + /* User defined 8-bit data type 1 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF1 = 0x30, + /* User defined 8-bit data type 2 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF2 = 0x31, + /* User defined 8-bit data type 3 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF3 = 0x32, + /* User defined 8-bit data type 4 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF4 = 0x33, + /* User defined 8-bit data type 5 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF5 = 0x34, + /* User defined 8-bit data type 6 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF6 = 0x35, + /* User defined 8-bit data type 7 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF7 = 0x36, + /* User defined 8-bit data type 8 */ + IA_CSS_ISYS_MIPI_DATA_TYPE_USER_DEF8 = 0x37, + /** Reserved 0x38-0x3F */ + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x38 = 0x38, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x39 = 0x39, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3A = 0x3A, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3B = 0x3B, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3C = 0x3C, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3D = 0x3D, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3E = 0x3E, + IA_CSS_ISYS_MIPI_DATA_TYPE_RESERVED_0x3F = 0x3F, + + /* Keep always last and max value */ + N_IA_CSS_ISYS_MIPI_DATA_TYPE = 0x40 +}; + +/** enum ia_css_isys_pin_type: output pin buffer types. + * Buffers can be queued and de-queued to hand them over between IA and ISYS + */ +enum ia_css_isys_pin_type { + /* Captured as MIPI packets */ + IA_CSS_ISYS_PIN_TYPE_MIPI = 0, + /* Captured through the ISApf (with/without ISA) + * and the non-scaled output path + */ + IA_CSS_ISYS_PIN_TYPE_RAW_NS, + /* Captured through the ISApf + ISA and the scaled output path */ + IA_CSS_ISYS_PIN_TYPE_RAW_S, + /* Captured through the SoC path */ + IA_CSS_ISYS_PIN_TYPE_RAW_SOC, + /* Reserved for future use, maybe short packets */ + IA_CSS_ISYS_PIN_TYPE_METADATA_0, + /* Reserved for future use */ + IA_CSS_ISYS_PIN_TYPE_METADATA_1, + /* Legacy (non-PIV2), used for the AWB stats */ + IA_CSS_ISYS_PIN_TYPE_AWB_STATS, + /* Legacy (non-PIV2), used for the AF stats */ + IA_CSS_ISYS_PIN_TYPE_AF_STATS, + /* Legacy (non-PIV2), used for the AE stats */ + IA_CSS_ISYS_PIN_TYPE_HIST_STATS, + /* Used for the PAF FF*/ + IA_CSS_ISYS_PIN_TYPE_PAF_FF, + /* Keep always last and max value */ + N_IA_CSS_ISYS_PIN_TYPE +}; + +/** + * enum ia_css_isys_isl_use. Describes the ISL/ISA use + * (ISAPF path in after BXT A0) + */ +enum ia_css_isys_isl_use { + IA_CSS_ISYS_USE_NO_ISL_NO_ISA = 0, + IA_CSS_ISYS_USE_SINGLE_DUAL_ISL, + IA_CSS_ISYS_USE_SINGLE_ISA, + N_IA_CSS_ISYS_USE +}; + +/** + * enum ia_css_isys_mipi_store_mode. Describes if long MIPI packets reach MIPI + * SRAM with the long packet header or not. + * if not, then only option is to capture it with pin type MIPI. + */ +enum ia_css_isys_mipi_store_mode { + IA_CSS_ISYS_MIPI_STORE_MODE_NORMAL = 0, + IA_CSS_ISYS_MIPI_STORE_MODE_DISCARD_LONG_HEADER, + N_IA_CSS_ISYS_MIPI_STORE_MODE +}; + +/** + * enum ia_css_isys_mipi_dt_rename_mode. Describes if long MIPI packets have + * DT with some other DT format. + */ +enum ia_css_isys_mipi_dt_rename_mode { + IA_CSS_ISYS_MIPI_DT_NO_RENAME = 0, + IA_CSS_ISYS_MIPI_DT_RENAMED_MODE, + N_IA_CSS_ISYS_MIPI_DT_MODE +}; + +/** + * enum ia_css_isys_type_paf. Describes the Type of PAF enabled + * (PAF path in after cnlB0) + */ +enum ia_css_isys_type_paf { + /* PAF data not present */ + IA_CSS_ISYS_TYPE_NO_PAF = 0, + /* Type 2 sensor types, PAF coming separately from Image Frame */ + /* PAF data in interleaved format(RLRL or LRLR)*/ + IA_CSS_ISYS_TYPE_INTERLEAVED_PAF, + /* PAF data in non-interleaved format(LL/RR or RR/LL) */ + IA_CSS_ISYS_TYPE_NON_INTERLEAVED_PAF, + /* Type 3 sensor types , PAF data embedded in Image Frame*/ + /* Frame Embedded PAF in interleaved format(RLRL or LRLR)*/ + IA_CSS_ISYS_TYPE_FRAME_EMB_INTERLEAVED_PAF, + /* Frame Embedded PAF non-interleaved format(LL/RR or RR/LL)*/ + IA_CSS_ISYS_TYPE_FRAME_EMB_NON_INTERLEAVED_PAF, + N_IA_CSS_ISYS_TYPE_PAF +}; + +/** + * enum ia_css_isys_cropping_location. Enumerates the cropping locations + * in ISYS + */ +enum ia_css_isys_cropping_location { + /* Cropping executed in ISAPF (mainly), ISAPF preproc (odd column) and + * MIPI STR2MMIO (odd row) + */ + IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA = 0, + /* BXT A0 legacy mode which will never be implemented */ + IA_CSS_ISYS_CROPPING_LOCATION_RESERVED_1, + /* Cropping executed in StreamPifConv in the ISA output for + * RAW_NS pin + */ + IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED, + /* Cropping executed in StreamScaledPifConv in the ISA output for + * RAW_S pin + */ + IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_SCALED, + N_IA_CSS_ISYS_CROPPING_LOCATION +}; + +/** + * enum ia_css_isys_resolution_info. Describes the resolution, required to + * setup the various ISA GP registers. + */ +enum ia_css_isys_resolution_info { + /* Scaled ISA output resolution before the + * StreamScaledPifConv cropping + */ + IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED = 0, + /* Non-Scaled ISA output resolution before the + * StreamPifConv cropping + */ + IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED, + N_IA_CSS_ISYS_RESOLUTION_INFO +}; + +/** + * enum ia_css_isys_error. Describes the error type detected by the FW + */ +enum ia_css_isys_error { + IA_CSS_ISYS_ERROR_NONE = 0, /* No details */ + IA_CSS_ISYS_ERROR_FW_INTERNAL_CONSISTENCY, /* enum */ + IA_CSS_ISYS_ERROR_HW_CONSISTENCY, /* enum */ + IA_CSS_ISYS_ERROR_DRIVER_INVALID_COMMAND_SEQUENCE, /* enum */ + IA_CSS_ISYS_ERROR_DRIVER_INVALID_DEVICE_CONFIGURATION, /* enum */ + IA_CSS_ISYS_ERROR_DRIVER_INVALID_STREAM_CONFIGURATION, /* enum */ + IA_CSS_ISYS_ERROR_DRIVER_INVALID_FRAME_CONFIGURATION, /* enum */ + IA_CSS_ISYS_ERROR_INSUFFICIENT_RESOURCES, /* enum */ + IA_CSS_ISYS_ERROR_HW_REPORTED_STR2MMIO, /* HW code */ + IA_CSS_ISYS_ERROR_HW_REPORTED_SIG2CIO, /* HW code */ + IA_CSS_ISYS_ERROR_SENSOR_FW_SYNC, /* enum */ + IA_CSS_ISYS_ERROR_STREAM_IN_SUSPENSION, /* FW code */ + IA_CSS_ISYS_ERROR_RESPONSE_QUEUE_FULL, /* FW code */ + N_IA_CSS_ISYS_ERROR +}; + +/** + * enum ia_css_proxy_error. Describes the error type for the proxy detected by + * the FW + */ +enum ia_css_proxy_error { + IA_CSS_PROXY_ERROR_NONE = 0, + IA_CSS_PROXY_ERROR_INVALID_WRITE_REGION, + IA_CSS_PROXY_ERROR_INVALID_WRITE_OFFSET, + N_IA_CSS_PROXY_ERROR +}; + +#endif /* __IA_CSS_ISYSAPI_FW_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_fw_version.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_fw_version.h new file mode 100644 index 0000000000000..bc056157cedb6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_fw_version.h @@ -0,0 +1,21 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_FW_VERSION_H +#define __IA_CSS_ISYSAPI_FW_VERSION_H + +/* ISYSAPI FW VERSION is taken from Makefile for FW tests */ +#define BXT_FW_RELEASE_VERSION ISYS_FIRMWARE_VERSION + +#endif /* __IA_CSS_ISYSAPI_FW_VERSION_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_defs.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_defs.h new file mode 100644 index 0000000000000..27c930f6cd19c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_defs.h @@ -0,0 +1,113 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_PROXY_REGION_DEFS_H +#define __IA_CSS_ISYSAPI_PROXY_REGION_DEFS_H + +#include "ia_css_isysapi_proxy_region_types.h" + +/* + * Definitions for IPU4_B0_PROXY_INT + */ + +#if defined(IPU4_B0_PROXY_INT) + +/** + * enum ipu4_b0_ia_css_proxy_write_region. Provides the list of regions for ipu4B0 that + * can be accessed (for writing purpose) through the proxy interface + */ +enum ipu4_b0_ia_css_proxy_write_region { + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_0_ERROR_FILL_RATE = 0, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_1_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_2_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_3_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_4_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_5_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_6_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_7_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_8_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_9_ERROR_FILL_RATE, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IRQ_URGENT_THRESHOLD, + IPU4_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IRQ_CRITICAL_THRESHOLD, + N_IPU4_B0_IA_CSS_PROXY_WRITE_REGION +}; + +struct ia_css_proxy_write_region_description ipu4_b0_reg_write_desc[N_IPU4_B0_IA_CSS_PROXY_WRITE_REGION] = { + /* base_addr, offset */ + {0x64128, /*input_system_csi2_logic_s2m_a_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_0_ERROR_FILL_RATE*/ + {0x65128, /*input_system_csi2_logic_s2m_b_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_1_ERROR_FILL_RATE*/ + {0x66128, /*input_system_csi2_logic_s2m_c_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_2_ERROR_FILL_RATE*/ + {0x67128, /*input_system_csi2_logic_s2m_d_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_3_ERROR_FILL_RATE*/ + {0x6C128, /*input_system_csi2_3ph_logic_s2m_a_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_4_ERROR_FILL_RATE*/ + {0x6C928, /*input_system_csi2_3ph_logic_s2m_b_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_5_ERROR_FILL_RATE*/ + {0x6D128, /*input_system_csi2_3ph_logic_s2m_0_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_6_ERROR_FILL_RATE*/ + {0x6D928, /*input_system_csi2_3ph_logic_s2m_1_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_7_ERROR_FILL_RATE*/ + {0x6E128, /*input_system_csi2_3ph_logic_s2m_2_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_8_ERROR_FILL_RATE*/ + {0x6E928, /*input_system_csi2_3ph_logic_s2m_3_stream2mmio_err_mode_dc_ctrl_reg_id*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_STR2MMIO_MIPI_9_ERROR_FILL_RATE*/ + {0x7800C, /*input_system_unis_logic_gda_irq_urgent_threshold*/ 4}, /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IRQ_URGENT_THRESHOLD*/ + {0x78010, /*input_system_unis_logic_gda_irq_critical_threshold*/ 4} /*IPU4_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IRQ_CRITICAL_THRESHOLD*/ +}; + +#endif /*defined(IPU4_B0_PROXY_INT)*/ + +/* + * Definitions for IPU4P_A0_PROXY_INT + */ + +#if defined(IPU4P_A0_PROXY_INT) + +/** + * enum ipu4p_a0_ia_css_proxy_write_region. Provides the list of regions for ipu4pA0 that + * can be accessed (for writing purpose) through the proxy interface + */ +enum ipu4p_a0_ia_css_proxy_write_region { + N_IPU4P_A0_IA_CSS_PROXY_WRITE_REGION +}; + +#define IPU4P_A0_NO_PROXY_WRITE_REGION_AVAILABLE + +#ifndef IPU4P_A0_NO_PROXY_WRITE_REGION_AVAILABLE +struct ia_css_proxy_write_region_description ipu4p_a0_reg_write_desc[N_IPU4P_A0_IA_CSS_PROXY_WRITE_REGION] = { +} +#endif /*IPU4P_A0_NO_PROXY_WRITE_REGION_AVAILABLE*/ + +#endif /*defined(IPU4P_A0_PROXY_INT)*/ + +/* + * Definitions for IPU4P_B0_PROXY_INT + */ + +#if defined(IPU4P_B0_PROXY_INT) + +/** + * enum ipu4p_b0_ia_css_proxy_write_region. Provides the list of regions for ipu4pB0 that + * can be accessed (for writing purpose) through the proxy interface + */ +enum ipu4p_b0_ia_css_proxy_write_region { + IPU4P_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IWAKE_THRESHOLD = 0, + IPU4P_B0_IA_CSS_PROXY_WRITE_REGION_GDA_ENABLE_IWAKE, + N_IPU4P_B0_IA_CSS_PROXY_WRITE_REGION +}; + +struct ia_css_proxy_write_region_description ipu4p_b0_reg_write_desc[N_IPU4P_B0_IA_CSS_PROXY_WRITE_REGION] = { + /* base_addr, max_offset */ + /*input_system_unis_logic_gda_iwake_threshold*/ + {0x78014, 4}, /*IPU4P_B0_IA_CSS_PROXY_WRITE_REGION_GDA_IWAKE_THRESHOLD*/ + /*input_system_unis_logic_gda_enable_iwake*/ + {0x7801C, 4} /*IPU4P_B0_IA_CSS_PROXY_WRITE_REGION_GDA_ENABLE_IWAKE*/ +}; + +#endif /*defined(IPU4P_B0_PROXY_INT)*/ + +#endif /* __IA_CSS_ISYSAPI_PROXY_REGION_DEFS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_types.h new file mode 100644 index 0000000000000..045f089e5a4c8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_proxy_region_types.h @@ -0,0 +1,24 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_PROXY_REGION_TYPES_H +#define __IA_CSS_ISYSAPI_PROXY_REGION_TYPES_H + + +struct ia_css_proxy_write_region_description { + uint32_t base_addr; + uint32_t offset; +}; + +#endif /* __IA_CSS_ISYSAPI_PROXY_REGION_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_types.h new file mode 100644 index 0000000000000..e8b4ad28fbd4b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/interface/ia_css_isysapi_types.h @@ -0,0 +1,349 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_TYPES_H +#define __IA_CSS_ISYSAPI_TYPES_H + +#include "ia_css_isysapi_fw_types.h" +#include "type_support.h" + +#include "ia_css_return_token.h" +#include "ia_css_output_buffer.h" +#include "ia_css_input_buffer.h" +#include "ia_css_terminal_defs.h" + +/** + * struct ia_css_isys_buffer_partition - buffer partition information + * @num_gda_pages: Number of virtual gda pages available for each virtual stream + */ +struct ia_css_isys_buffer_partition { + unsigned int num_gda_pages[STREAM_ID_MAX]; +}; + +/** + * This should contain the driver specified info for sys + */ +struct ia_css_driver_sys_config { + unsigned int ssid; + unsigned int mmid; + unsigned int num_send_queues; /* # of MSG send queues */ + unsigned int num_recv_queues; /* # of MSG recv queues */ + unsigned int send_queue_size; /* max # tokens per queue */ + unsigned int recv_queue_size; /* max # tokens per queue */ + + unsigned int icache_prefetch; /* enable prefetching for SPC */ +}; + +/** + * This should contain the driver specified info for proxy write queues + */ +struct ia_css_driver_proxy_config { + /* max # tokens per PROXY send/recv queue. + * Proxy queues are used for write access purpose + */ + unsigned int proxy_write_queue_size; +}; + + /** + * struct ia_css_isys_device_cfg_data - ISYS device configuration data + * @driver_sys + * @buffer_partition: Information required for the virtual SRAM + * space partition of the streams. + * @driver_proxy + * @secure: Driver needs to set 'secure' to indicate the intention + * when invoking ia_css_isys_context_create() in + * HAS_DUAL_CMD_CTX_SUPPORT case. If 'true', it's for + * secure case. + */ +struct ia_css_isys_device_cfg_data { + struct ia_css_driver_sys_config driver_sys; + struct ia_css_isys_buffer_partition buffer_partition; + struct ia_css_driver_proxy_config driver_proxy; + bool secure; + unsigned int vtl0_addr_mask; /* only applicable in 'secure' case */ +}; + +/** + * struct ia_css_isys_resolution: Generic resolution structure. + * @Width + * @Height + */ +struct ia_css_isys_resolution { + unsigned int width; + unsigned int height; +}; + +/** + * struct ia_css_isys_output_pin_payload + * @out_buf_id: Points to output pin buffer - buffer identifier + * @addr: Points to output pin buffer - CSS Virtual Address + * @compressed: Request frame compression (1), or not (0) + * This must be the same as ia_css_isys_output_pin_info::reserve_compression + */ +struct ia_css_isys_output_pin_payload { + ia_css_return_token out_buf_id; + ia_css_output_buffer_css_address addr; + unsigned int compress; +}; + +/** + * struct ia_css_isys_output_pin_info + * @input_pin_id: input pin id/index which is source of + * the data for this output pin + * @output_res: output pin resolution + * @stride: output stride in Bytes (not valid for statistics) + * @pt: pin type + * @ft: frame format type + * @watermark_in_lines: pin watermark level in lines + * @send_irq: assert if pin event should trigger irq + * @link_id: identifies PPG to connect to, link_id = 0 implies offline + * while link_id > 0 implies buffer_chasing or online mode + * can be entered. + * @reserve_compression: Reserve compression resources for pin. + * @payload_buf_size: Minimum size in Bytes of all buffers that will be supplied for capture + * on this pin (i.e. addressed by ia_css_isys_output_pin_payload::addr) + */ +struct ia_css_isys_output_pin_info { + unsigned int input_pin_id; + struct ia_css_isys_resolution output_res; + unsigned int stride; + enum ia_css_isys_pin_type pt; + enum ia_css_isys_frame_format_type ft; + unsigned int watermark_in_lines; + unsigned int send_irq; + enum ia_css_isys_link_id link_id; + unsigned int reserve_compression; + unsigned int payload_buf_size; +}; + +/** + * struct ia_css_isys_param_pin + * @param_buf_id: Points to param buffer - buffer identifier + * @addr: Points to param buffer - CSS Virtual Address + */ +struct ia_css_isys_param_pin { + ia_css_return_token param_buf_id; + ia_css_input_buffer_css_address addr; +}; + +/** + * struct ia_css_isys_input_pin_info + * @input_res: input resolution + * @dt: mipi data type + * @mipi_store_mode: defines if legacy long packet header will be stored or + * discarded if discarded, output pin pin type for this + * input pin can only be MIPI + * @dt_rename_mode: defines if MIPI data is encapsulated in some other + * data type + * @mapped_dt: Encapsulating in mipi data type(what sensor sends) + */ +struct ia_css_isys_input_pin_info { + struct ia_css_isys_resolution input_res; + enum ia_css_isys_mipi_data_type dt; + enum ia_css_isys_mipi_store_mode mipi_store_mode; + enum ia_css_isys_mipi_dt_rename_mode dt_rename_mode; + enum ia_css_isys_mipi_data_type mapped_dt; +}; + +/** + * struct ia_css_isys_isa_cfg. Describes the ISA cfg + */ +struct ia_css_isys_isa_cfg { + /* Following sets resolution information neeed by the IS GP registers, + * For index IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED, + * it is needed when there is RAW_NS pin + * For index IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED, + * it is needed when there is RAW_S pin + */ + struct ia_css_isys_resolution isa_res[N_IA_CSS_ISYS_RESOLUTION_INFO]; + /* acc id 0, set if process required */ + unsigned int blc_enabled; + /* acc id 1, set if process required */ + unsigned int lsc_enabled; + /* acc id 2, set if process required */ + unsigned int dpc_enabled; + /* acc id 3, set if process required */ + unsigned int downscaler_enabled; + /* acc id 4, set if process required */ + unsigned int awb_enabled; + /* acc id 5, set if process required */ + unsigned int af_enabled; + /* acc id 6, set if process required */ + unsigned int ae_enabled; + /* acc id 7, disabled, or type of paf enabled*/ + enum ia_css_isys_type_paf paf_type; + /* Send irq for any statistics buffers which got completed */ + unsigned int send_irq_stats_ready; + /* Send response for any statistics buffers which got completed */ + unsigned int send_resp_stats_ready; +}; + +/** + * struct ia_css_isys_cropping - cropping coordinates + * Left/Top offsets are INCLUDED + * Right/Bottom offsets are EXCLUDED + * Horizontal: [left_offset,right_offset) + * Vertical: [top_offset,bottom_offset) + * Padding is supported + */ +struct ia_css_isys_cropping { + int top_offset; + int left_offset; + int bottom_offset; + int right_offset; +}; + + /** + * struct ia_css_isys_stream_cfg_data + * ISYS stream configuration data structure + * @src: Stream source index e.g. MIPI_generator_0, CSI2-rx_1 + * @vc: MIPI Virtual Channel (up to 4 virtual per physical channel) + * @isl_use: indicates whether stream requires ISL and how + * @compfmt: de-compression setting for User Defined Data + * @isa_cfg: details about what ACCs are active if ISA is used + * @crop: defines cropping resolution for the + * maximum number of input pins which can be cropped, + * it is directly mapped to the HW devices + * @send_irq_sof_discarded: send irq on discarded frame sof response + * - if '1' it will override the send_resp_sof_discarded and send + * the response + * - if '0' the send_resp_sof_discarded will determine whether to + * send the response + * @send_irq_eof_discarded: send irq on discarded frame eof response + * - if '1' it will override the send_resp_eof_discarded and send + * the response + * - if '0' the send_resp_eof_discarded will determine whether to + * send the response + * @send_resp_sof_discarded: send response for discarded frame sof detected, + * used only when send_irq_sof_discarded is '0' + * @send_resp_eof_discarded: send response for discarded frame eof detected, + * used only when send_irq_eof_discarded is '0' + * @the rest: input/output pin descriptors + */ +struct ia_css_isys_stream_cfg_data { + enum ia_css_isys_stream_source src; + enum ia_css_isys_mipi_vc vc; + enum ia_css_isys_isl_use isl_use; + unsigned int compfmt; + struct ia_css_isys_isa_cfg isa_cfg; + struct ia_css_isys_cropping crop[N_IA_CSS_ISYS_CROPPING_LOCATION]; + unsigned int send_irq_sof_discarded; + unsigned int send_irq_eof_discarded; + unsigned int send_resp_sof_discarded; + unsigned int send_resp_eof_discarded; + unsigned int nof_input_pins; + unsigned int nof_output_pins; + struct ia_css_isys_input_pin_info input_pins[MAX_IPINS]; + struct ia_css_isys_output_pin_info output_pins[MAX_OPINS]; +}; + +/** + * struct ia_css_isys_frame_buff_set - frame buffer set + * @output_pins: output pin addresses + * @process_group_light: process_group_light buffer address + * @send_irq_sof: send irq on frame sof response + * - if '1' it will override the send_resp_sof and send + * the response + * - if '0' the send_resp_sof will determine whether to send + * the response + * @send_irq_eof: send irq on frame eof response + * - if '1' it will override the send_resp_eof and send + * the response + * - if '0' the send_resp_eof will determine whether to send + * the response + * @send_resp_sof: send response for frame sof detected, + * used only when send_irq_sof is '0' + * @send_resp_eof: send response for frame eof detected, + * used only when send_irq_eof is '0' + * @frame_counter: frame number associated with this buffer set. + */ +struct ia_css_isys_frame_buff_set { + struct ia_css_isys_output_pin_payload output_pins[MAX_OPINS]; + struct ia_css_isys_param_pin process_group_light; + unsigned int send_irq_sof; + unsigned int send_irq_eof; + unsigned int send_irq_capture_ack; + unsigned int send_irq_capture_done; + unsigned int send_resp_sof; + unsigned int send_resp_eof; + uint8_t frame_counter; +}; + +/** + * struct ia_css_isys_resp_info + * @type: response type + * @stream_handle: stream id the response corresponds to + * @timestamp: Time information for event if available + * @error: error code if something went wrong + * @error_details: depending on error code, it may contain additional + * error info + * @pin: this var is valid for pin event related responses, + * contains pin addresses + * @pin_id: this var is valid for pin event related responses, + * contains pin id that the pin payload corresponds to + * @process_group_light: this var is valid for stats ready related responses, + * contains process group addresses + * @acc_id: this var is valid for stats ready related responses, + * contains accelerator id that finished producing + * all related statistics + * @frame_counter: valid for STREAM_START_AND_CAPTURE_DONE, + * STREAM_CAPTURE_DONE and STREAM_CAPTURE_DISCARDED + * @written_direct: indicates if frame was written direct (online mode) or to DDR. + */ +struct ia_css_isys_resp_info { + enum ia_css_isys_resp_type type; + unsigned int stream_handle; + unsigned int timestamp[2]; + enum ia_css_isys_error error; + unsigned int error_details; + struct ia_css_isys_output_pin_payload pin; + unsigned int pin_id; + struct ia_css_isys_param_pin process_group_light; + unsigned int acc_id; + uint8_t frame_counter; + uint8_t written_direct; +}; + +/** + * struct ia_css_proxy_write_req_val + * @request_id: Unique identifier for the write request + * (in case multiple write requests are issued for same register) + * @region_index: region id for the write request + * @offset: Offset to the specific register within the region + * @value: Value to be written to register + */ +struct ia_css_proxy_write_req_val { + uint32_t request_id; + uint32_t region_index; + uint32_t offset; + uint32_t value; +}; + +/** + * struct ia_css_proxy_write_req_resp + * @request_id: Unique identifier for the write request + * (in case multiple write requests are issued for same register) + * @error: error code if something went wrong + * @error_details: error detail includes either offset or region index + * information which caused proxy request to be rejected + * (invalid access request) + */ +struct ia_css_proxy_write_req_resp { + uint32_t request_id; + enum ia_css_proxy_error error; + uint32_t error_details; +}; + + +#endif /* __IA_CSS_ISYSAPI_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/isysapi.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/isysapi.mk new file mode 100644 index 0000000000000..0d06298f9acb0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/isysapi.mk @@ -0,0 +1,77 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is ISYSAPI + +include $(MODULES_DIR)/config/isys/subsystem_$(IPU_SYSVER).mk + +ISYSAPI_DIR=$${MODULES_DIR}/isysapi + +ISYSAPI_INTERFACE=$(ISYSAPI_DIR)/interface +ISYSAPI_SOURCES=$(ISYSAPI_DIR)/src +ISYSAPI_EXTINCLUDE=$${MODULES_DIR}/support +ISYSAPI_EXTINTERFACE=$${MODULES_DIR}/syscom/interface + +ISYSAPI_HOST_FILES += $(ISYSAPI_SOURCES)/ia_css_isys_public.c + +ISYSAPI_HOST_FILES += $(ISYSAPI_SOURCES)/ia_css_isys_private.c + +# ISYSAPI Trace Log Level = ISYSAPI_TRACE_LOG_LEVEL_NORMAL +# Other options are [ISYSAPI_TRACE_LOG_LEVEL_OFF, ISYSAPI_TRACE_LOG_LEVEL_DEBUG] +ifndef ISYSAPI_TRACE_CONFIG_HOST + ISYSAPI_TRACE_CONFIG_HOST=ISYSAPI_TRACE_LOG_LEVEL_NORMAL +endif +ifndef ISYSAPI_TRACE_CONFIG_FW + ISYSAPI_TRACE_CONFIG_FW=ISYSAPI_TRACE_LOG_LEVEL_NORMAL +endif + +ISYSAPI_HOST_CPPFLAGS += -DISYSAPI_TRACE_CONFIG=$(ISYSAPI_TRACE_CONFIG_HOST) +ISYSAPI_FW_CPPFLAGS += -DISYSAPI_TRACE_CONFIG=$(ISYSAPI_TRACE_CONFIG_FW) + +ISYSAPI_HOST_FILES += $(ISYSAPI_SOURCES)/ia_css_isys_public_trace.c + +ISYSAPI_HOST_CPPFLAGS += -I$(ISYSAPI_INTERFACE) +ISYSAPI_HOST_CPPFLAGS += -I$(ISYSAPI_EXTINCLUDE) +ISYSAPI_HOST_CPPFLAGS += -I$(ISYSAPI_EXTINTERFACE) +ISYSAPI_HOST_CPPFLAGS += -I$(HIVESDK)/systems/ipu_system/dai/include +ISYSAPI_HOST_CPPFLAGS += -I$(HIVESDK)/systems/ipu_system/dai/include/default_system +ISYSAPI_HOST_CPPFLAGS += -I$(HIVESDK)/include/ipu/dai +ISYSAPI_HOST_CPPFLAGS += -I$(HIVESDK)/include/ipu + +ISYSAPI_FW_FILES += $(ISYSAPI_SOURCES)/isys_fw.c +ISYSAPI_FW_FILES += $(ISYSAPI_SOURCES)/isys_fw_utils.c + +ISYSAPI_FW_CPPFLAGS += -I$(ISYSAPI_INTERFACE) +ISYSAPI_FW_CPPFLAGS += -I$(ISYSAPI_SOURCES)/$(IPU_SYSVER) +ISYSAPI_FW_CPPFLAGS += -I$(ISYSAPI_EXTINCLUDE) +ISYSAPI_FW_CPPFLAGS += -I$(ISYSAPI_EXTINTERFACE) +ISYSAPI_FW_CPPFLAGS += -I$(HIVESDK)/systems/ipu_system/dai/include +ISYSAPI_FW_CPPFLAGS += -I$(HIVESDK)/systems/ipu_system/dai/include/default_system +ISYSAPI_FW_CPPFLAGS += -I$(HIVESDK)/include/ipu/dai +ISYSAPI_FW_CPPFLAGS += -I$(HIVESDK)/include/ipu + +ISYSAPI_FW_CPPFLAGS += -DWA_HSD1805168877=$(WA_HSD1805168877) + +ISYSAPI_HOST_CPPFLAGS += -DREGMEM_OFFSET=$(REGMEM_OFFSET) + +ifeq ($(ISYS_HAS_DUAL_CMD_CTX_SUPPORT), 1) +ISYSAPI_HOST_CPPFLAGS += -DHAS_DUAL_CMD_CTX_SUPPORT=$(ISYS_HAS_DUAL_CMD_CTX_SUPPORT) +ISYSAPI_FW_CPPFLAGS += -DHAS_DUAL_CMD_CTX_SUPPORT=$(ISYS_HAS_DUAL_CMD_CTX_SUPPORT) +endif + +ifdef AB_CONFIG_ARRAY_SIZE +ISYSAPI_FW_CPPFLAGS += -DAB_CONFIG_ARRAY_SIZE=$(AB_CONFIG_ARRAY_SIZE) +else +ISYSAPI_FW_CPPFLAGS += -DAB_CONFIG_ARRAY_SIZE=1 +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_private.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_private.c new file mode 100644 index 0000000000000..4379e20ba058e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_private.c @@ -0,0 +1,979 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_isys_private.h" +/* The following is needed for the contained data types */ +#include "ia_css_isys_fw_bridged_types.h" +#include "ia_css_isysapi_types.h" +#include "ia_css_syscom_config.h" +/* + * The following header file is needed for the + * stddef.h (NULL), + * limits.h (CHAR_BIT definition). + */ +#include "type_support.h" +#include "error_support.h" +#include "ia_css_isysapi_trace.h" +#include "misc_support.h" +#include "cpu_mem_support.h" +#include "storage_class.h" + +#include "ia_css_shared_buffer_cpu.h" + +/* + * defines how many stream cfg host may sent concurrently + * before receiving the stream ack + */ +#define STREAM_CFG_BUFS_PER_MSG_QUEUE (1) +#define NEXT_FRAME_BUFS_PER_MSG_QUEUE \ + (ctx->send_queue_size[IA_CSS_ISYS_QUEUE_TYPE_MSG] + 4 + 1) +/* + * There is an edge case that host has filled the full queue + * with capture requests (ctx->send_queue_size), + * SP reads and HW-queues all of them (4), + * while in the meantime host continues queueing capture requests + * without checking for responses which SP will have sent with each HW-queue + * capture request (if it does then the 4 is much more improbable to appear, + * but still not impossible). + * After this, host tries to queue an extra capture request + * even though there is no space in the msg queue because msg queue + * is checked at a later point, so +1 is needed + */ + +/* + * A DT is supported assuming when the MIPI packets + * have the same size even when even/odd lines are different, + * and the size is the average per line + */ +#define IA_CSS_UNSUPPORTED_DATA_TYPE (0) +static const uint32_t +ia_css_isys_extracted_bits_per_pixel_per_mipi_data_type[ + N_IA_CSS_ISYS_MIPI_DATA_TYPE] = { + /* + * Remove Prefix "IA_CSS_ISYS_MIPI_DATA_TYPE_" in comments + * to align with Checkpatch 80 characters requirements + * For detailed comments of each field, please refer to + * definition of enum ia_css_isys_mipi_data_type{} in + * isysapi/interface/ia_css_isysapi_fw_types.h + */ + 64, /* [0x00] FRAME_START_CODE */ + 64, /* [0x01] FRAME_END_CODE */ + 64, /* [0x02] LINE_START_CODE Optional */ + 64, /* [0x03] LINE_END_CODE Optional */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x04] RESERVED_0x04 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x05] RESERVED_0x05 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x06] RESERVED_0x06 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x07] RESERVED_0x07 */ + 64, /* [0x08] GENERIC_SHORT1 */ + 64, /* [0x09] GENERIC_SHORT2 */ + 64, /* [0x0A] GENERIC_SHORT3 */ + 64, /* [0x0B] GENERIC_SHORT4 */ + 64, /* [0x0C] GENERIC_SHORT5 */ + 64, /* [0x0D] GENERIC_SHORT6 */ + 64, /* [0x0E] GENERIC_SHORT7 */ + 64, /* [0x0F] GENERIC_SHORT8 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x10] NULL To be ignored */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x11] BLANKING_DATA To be ignored */ + 8, /* [0x12] EMBEDDED non Image Data */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x13] RESERVED_0x13 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x14] RESERVED_0x14 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x15] RESERVED_0x15 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x16] RESERVED_0x16 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x17] RESERVED_0x17 */ + 12, /* [0x18] YUV420_8 */ + 15, /* [0x19] YUV420_10 */ + 12, /* [0x1A] YUV420_8_LEGACY */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x1B] RESERVED_0x1B */ + 12, /* [0x1C] YUV420_8_SHIFT */ + 15, /* [0x1D] YUV420_10_SHIFT */ + 16, /* [0x1E] YUV422_8 */ + 20, /* [0x1F] YUV422_10 */ + 16, /* [0x20] RGB_444 */ + 16, /* [0x21] RGB_555 */ + 16, /* [0x22] RGB_565 */ + 18, /* [0x23] RGB_666 */ + 24, /* [0x24] RGB_888 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x25] RESERVED_0x25 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x26] RESERVED_0x26 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x27] RESERVED_0x27 */ + 6, /* [0x28] RAW_6 */ + 7, /* [0x29] RAW_7 */ + 8, /* [0x2A] RAW_8 */ + 10, /* [0x2B] RAW_10 */ + 12, /* [0x2C] RAW_12 */ + 14, /* [0x2D] RAW_14 */ + 16, /* [0x2E] RAW_16 */ + 8, /* [0x2F] BINARY_8 */ + 8, /* [0x30] USER_DEF1 */ + 8, /* [0x31] USER_DEF2 */ + 8, /* [0x32] USER_DEF3 */ + 8, /* [0x33] USER_DEF4 */ + 8, /* [0x34] USER_DEF5 */ + 8, /* [0x35] USER_DEF6 */ + 8, /* [0x36] USER_DEF7 */ + 8, /* [0x37] USER_DEF8 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x38] RESERVED_0x38 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x39] RESERVED_0x39 */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x3A] RESERVED_0x3A */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x3B] RESERVED_0x3B */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x3C] RESERVED_0x3C */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x3D] RESERVED_0x3D */ + IA_CSS_UNSUPPORTED_DATA_TYPE, /* [0x3E] RESERVED_0x3E */ + IA_CSS_UNSUPPORTED_DATA_TYPE /* [0x3F] RESERVED_0x3F */ +}; + +STORAGE_CLASS_INLINE int get_stream_cfg_buff_slot( + struct ia_css_isys_context *ctx, + int stream_handle, + int stream_cfg_buff_counter) +{ + NOT_USED(ctx); + return (stream_handle * STREAM_CFG_BUFS_PER_MSG_QUEUE) + + stream_cfg_buff_counter; +} + +STORAGE_CLASS_INLINE int get_next_frame_buff_slot( + struct ia_css_isys_context *ctx, + int stream_handle, + int next_frame_buff_counter) +{ + NOT_USED(ctx); + return (stream_handle * NEXT_FRAME_BUFS_PER_MSG_QUEUE) + + next_frame_buff_counter; +} + +STORAGE_CLASS_INLINE void free_comm_buff_shared_mem( + struct ia_css_isys_context *ctx, + int stream_handle, + int stream_cfg_buff_counter, + int next_frame_buff_counter) +{ + int buff_slot; + + /* Initialiser is the current value of stream_handle */ + for (; stream_handle >= 0; stream_handle--) { + /* + * Initialiser is the current value of stream_cfg_buff_counter + */ + for (; stream_cfg_buff_counter >= 0; + stream_cfg_buff_counter--) { + buff_slot = get_stream_cfg_buff_slot( + ctx, stream_handle, stream_cfg_buff_counter); + ia_css_shared_buffer_free( + ctx->ssid, ctx->mmid, + ctx->isys_comm_buffer_queue. + pstream_cfg_buff_id[buff_slot]); + } + /* Set for the next iteration */ + stream_cfg_buff_counter = STREAM_CFG_BUFS_PER_MSG_QUEUE - 1; + /* + * Initialiser is the current value of next_frame_buff_counter + */ + for (; next_frame_buff_counter >= 0; + next_frame_buff_counter--) { + buff_slot = get_next_frame_buff_slot( + ctx, stream_handle, next_frame_buff_counter); + ia_css_shared_buffer_free( + ctx->ssid, ctx->mmid, + ctx->isys_comm_buffer_queue. + pnext_frame_buff_id[buff_slot]); + } + next_frame_buff_counter = NEXT_FRAME_BUFS_PER_MSG_QUEUE - 1; + } +} + +/* + * ia_css_isys_constr_comm_buff_queue() + */ +int ia_css_isys_constr_comm_buff_queue( + struct ia_css_isys_context *ctx) +{ + int stream_handle; + int stream_cfg_buff_counter; + int next_frame_buff_counter; + int buff_slot; + + verifret(ctx, EFAULT); /* Host Consistency */ + + ctx->isys_comm_buffer_queue.pstream_cfg_buff_id = + (ia_css_shared_buffer *) + ia_css_cpu_mem_alloc(ctx-> + num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] * + STREAM_CFG_BUFS_PER_MSG_QUEUE * + sizeof(ia_css_shared_buffer)); + verifret(ctx->isys_comm_buffer_queue.pstream_cfg_buff_id != NULL, + EFAULT); + + ctx->isys_comm_buffer_queue.pnext_frame_buff_id = + (ia_css_shared_buffer *) + ia_css_cpu_mem_alloc(ctx-> + num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] * + NEXT_FRAME_BUFS_PER_MSG_QUEUE * + sizeof(ia_css_shared_buffer)); + if (ctx->isys_comm_buffer_queue.pnext_frame_buff_id == NULL) { + ia_css_cpu_mem_free( + ctx->isys_comm_buffer_queue.pstream_cfg_buff_id); + verifret(0, EFAULT); /* return EFAULT; equivalent */ + } + + for (stream_handle = 0; stream_handle < + (int)ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + stream_handle++) { + /* Initialisation needs to happen here for both loops */ + stream_cfg_buff_counter = 0; + next_frame_buff_counter = 0; + + for (; stream_cfg_buff_counter < STREAM_CFG_BUFS_PER_MSG_QUEUE; + stream_cfg_buff_counter++) { + buff_slot = get_stream_cfg_buff_slot( + ctx, stream_handle, stream_cfg_buff_counter); + ctx->isys_comm_buffer_queue. + pstream_cfg_buff_id[buff_slot] = + ia_css_shared_buffer_alloc( + ctx->ssid, ctx->mmid, + sizeof(struct + ia_css_isys_stream_cfg_data_comm)); + if (ctx->isys_comm_buffer_queue.pstream_cfg_buff_id[ + buff_slot] == 0) { + goto SHARED_BUFF_ALLOC_FAILURE; + } + } + ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle] = 0; + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle] = 0; + for (; next_frame_buff_counter < + (int)NEXT_FRAME_BUFS_PER_MSG_QUEUE; + next_frame_buff_counter++) { + buff_slot = get_next_frame_buff_slot( + ctx, stream_handle, + next_frame_buff_counter); + ctx->isys_comm_buffer_queue. + pnext_frame_buff_id[buff_slot] = + ia_css_shared_buffer_alloc( + ctx->ssid, ctx->mmid, + sizeof(struct + ia_css_isys_frame_buff_set_comm)); + if (ctx->isys_comm_buffer_queue. + pnext_frame_buff_id[buff_slot] == 0) { + goto SHARED_BUFF_ALLOC_FAILURE; + } + } + ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle] = 0; + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle] = 0; + } + + return 0; + +SHARED_BUFF_ALLOC_FAILURE: + /* stream_handle has correct value for calling the free function */ + /* prepare stream_cfg_buff_counter for calling the free function */ + stream_cfg_buff_counter--; + /* prepare next_frame_buff_counter for calling the free function */ + next_frame_buff_counter--; + free_comm_buff_shared_mem( + ctx, + stream_handle, + stream_cfg_buff_counter, + next_frame_buff_counter); + + verifret(0, EFAULT); /* return EFAULT; equivalent */ +} + +/* + * ia_css_isys_force_unmap_comm_buff_queue() + */ +int ia_css_isys_force_unmap_comm_buff_queue( + struct ia_css_isys_context *ctx) +{ + int stream_handle; + int buff_slot; + + verifret(ctx, EFAULT); /* Host Consistency */ + + IA_CSS_TRACE_0(ISYSAPI, WARNING, + "ia_css_isys_force_unmap_comm_buff_queue() called\n"); + for (stream_handle = 0; stream_handle < + (int)ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + stream_handle++) { + /* Host-FW Consistency */ + verifret((ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle] - + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle]) <= + STREAM_CFG_BUFS_PER_MSG_QUEUE, EPROTO); + for (; ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle] < + ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle]; + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle]++) { + IA_CSS_TRACE_1(ISYSAPI, WARNING, + "CSS forced unmapping stream_cfg %d\n", + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle]); + buff_slot = get_stream_cfg_buff_slot( + ctx, stream_handle, + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle] % + STREAM_CFG_BUFS_PER_MSG_QUEUE); + ia_css_shared_buffer_css_unmap( + ctx->isys_comm_buffer_queue. + pstream_cfg_buff_id[buff_slot]); + } + /* Host-FW Consistency */ + verifret((ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle] - + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle]) <= + NEXT_FRAME_BUFS_PER_MSG_QUEUE, EPROTO); + for (; ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle] < + ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle]; + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle]++) { + IA_CSS_TRACE_1(ISYSAPI, WARNING, + "CSS forced unmapping next_frame %d\n", + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle]); + buff_slot = get_next_frame_buff_slot( + ctx, stream_handle, + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle] % + NEXT_FRAME_BUFS_PER_MSG_QUEUE); + ia_css_shared_buffer_css_unmap( + ctx->isys_comm_buffer_queue. + pnext_frame_buff_id[buff_slot]); + } + } + + return 0; +} + +/* + * ia_css_isys_destr_comm_buff_queue() + */ +int ia_css_isys_destr_comm_buff_queue( + struct ia_css_isys_context *ctx) +{ + verifret(ctx, EFAULT); /* Host Consistency */ + + free_comm_buff_shared_mem( + ctx, + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] - 1, + STREAM_CFG_BUFS_PER_MSG_QUEUE - 1, + NEXT_FRAME_BUFS_PER_MSG_QUEUE - 1); + + ia_css_cpu_mem_free(ctx->isys_comm_buffer_queue.pnext_frame_buff_id); + ia_css_cpu_mem_free(ctx->isys_comm_buffer_queue.pstream_cfg_buff_id); + + return 0; +} + +STORAGE_CLASS_INLINE void resolution_host_to_css( + const struct ia_css_isys_resolution *resolution_host, + struct ia_css_isys_resolution_comm *resolution_css) +{ + resolution_css->width = resolution_host->width; + resolution_css->height = resolution_host->height; +} + +STORAGE_CLASS_INLINE void output_pin_payload_host_to_css( + const struct ia_css_isys_output_pin_payload *output_pin_payload_host, + struct ia_css_isys_output_pin_payload_comm *output_pin_payload_css) +{ + output_pin_payload_css->out_buf_id = + output_pin_payload_host->out_buf_id; + output_pin_payload_css->addr = output_pin_payload_host->addr; +#ifdef ENABLE_DEC400 + output_pin_payload_css->compress = output_pin_payload_host->compress; +#else + output_pin_payload_css->compress = 0; +#endif /* ENABLE_DEC400 */ +} + +STORAGE_CLASS_INLINE void output_pin_info_host_to_css( + const struct ia_css_isys_output_pin_info *output_pin_info_host, + struct ia_css_isys_output_pin_info_comm *output_pin_info_css) +{ + output_pin_info_css->input_pin_id = output_pin_info_host->input_pin_id; + resolution_host_to_css( + &output_pin_info_host->output_res, + &output_pin_info_css->output_res); + output_pin_info_css->stride = output_pin_info_host->stride; + output_pin_info_css->pt = output_pin_info_host->pt; + output_pin_info_css->watermark_in_lines = + output_pin_info_host->watermark_in_lines; + output_pin_info_css->send_irq = output_pin_info_host->send_irq; + output_pin_info_css->ft = output_pin_info_host->ft; + output_pin_info_css->link_id = output_pin_info_host->link_id; +#ifdef ENABLE_DEC400 + output_pin_info_css->reserve_compression = output_pin_info_host->reserve_compression; + output_pin_info_css->payload_buf_size = output_pin_info_host->payload_buf_size; +#else + output_pin_info_css->reserve_compression = 0; + /* Though payload_buf_size was added for compression, set sane value for + * payload_buf_size, just in case... + */ + output_pin_info_css->payload_buf_size = + output_pin_info_host->stride * output_pin_info_host->output_res.height; +#endif /* ENABLE_DEC400 */ +} + +STORAGE_CLASS_INLINE void param_pin_host_to_css( + const struct ia_css_isys_param_pin *param_pin_host, + struct ia_css_isys_param_pin_comm *param_pin_css) +{ + param_pin_css->param_buf_id = param_pin_host->param_buf_id; + param_pin_css->addr = param_pin_host->addr; +} + +STORAGE_CLASS_INLINE void input_pin_info_host_to_css( + const struct ia_css_isys_input_pin_info *input_pin_info_host, + struct ia_css_isys_input_pin_info_comm *input_pin_info_css) +{ + resolution_host_to_css( + &input_pin_info_host->input_res, + &input_pin_info_css->input_res); + if (input_pin_info_host->dt >= N_IA_CSS_ISYS_MIPI_DATA_TYPE) { + IA_CSS_TRACE_0(ISYSAPI, ERROR, + "input_pin_info_host->dt out of range\n"); + return; + } + if (input_pin_info_host->dt_rename_mode >= N_IA_CSS_ISYS_MIPI_DT_MODE) { + IA_CSS_TRACE_0(ISYSAPI, ERROR, + "input_pin_info_host->dt_rename_mode out of range\n"); + return; + } + /* Mapped DT check if data type renaming is being used*/ + if (input_pin_info_host->dt_rename_mode == IA_CSS_ISYS_MIPI_DT_RENAMED_MODE && + input_pin_info_host->mapped_dt >= N_IA_CSS_ISYS_MIPI_DATA_TYPE) { + IA_CSS_TRACE_0(ISYSAPI, ERROR, + "input_pin_info_host->mapped_dt out of range\n"); + return; + } + input_pin_info_css->dt = input_pin_info_host->dt; + input_pin_info_css->mipi_store_mode = + input_pin_info_host->mipi_store_mode; + input_pin_info_css->bits_per_pix = + ia_css_isys_extracted_bits_per_pixel_per_mipi_data_type[ + input_pin_info_host->dt]; + if (input_pin_info_host->dt_rename_mode == IA_CSS_ISYS_MIPI_DT_RENAMED_MODE) { + input_pin_info_css->mapped_dt = input_pin_info_host->mapped_dt; + } else { + input_pin_info_css->mapped_dt = N_IA_CSS_ISYS_MIPI_DATA_TYPE; + } +} + +STORAGE_CLASS_INLINE void isa_cfg_host_to_css( + const struct ia_css_isys_isa_cfg *isa_cfg_host, + struct ia_css_isys_isa_cfg_comm *isa_cfg_css) +{ + unsigned int i; + + for (i = 0; i < N_IA_CSS_ISYS_RESOLUTION_INFO; i++) { + resolution_host_to_css(&isa_cfg_host->isa_res[i], + &isa_cfg_css->isa_res[i]); + } + isa_cfg_css->cfg_fields = 0; + ISA_CFG_FIELD_SET(BLC_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->blc_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(LSC_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->lsc_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(DPC_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->dpc_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(DOWNSCALER_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->downscaler_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(AWB_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->awb_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(AF_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->af_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(AE_EN, isa_cfg_css->cfg_fields, + isa_cfg_host->ae_enabled ? 1 : 0); + ISA_CFG_FIELD_SET(PAF_TYPE, isa_cfg_css->cfg_fields, + isa_cfg_host->paf_type); + ISA_CFG_FIELD_SET(SEND_IRQ_STATS_READY, isa_cfg_css->cfg_fields, + isa_cfg_host->send_irq_stats_ready ? 1 : 0); + ISA_CFG_FIELD_SET(SEND_RESP_STATS_READY, isa_cfg_css->cfg_fields, + (isa_cfg_host->send_irq_stats_ready || + isa_cfg_host->send_resp_stats_ready) ? 1 : 0); +} + +STORAGE_CLASS_INLINE void cropping_host_to_css( + const struct ia_css_isys_cropping *cropping_host, + struct ia_css_isys_cropping_comm *cropping_css) +{ + cropping_css->top_offset = cropping_host->top_offset; + cropping_css->left_offset = cropping_host->left_offset; + cropping_css->bottom_offset = cropping_host->bottom_offset; + cropping_css->right_offset = cropping_host->right_offset; + +} + +STORAGE_CLASS_INLINE int stream_cfg_data_host_to_css( + const struct ia_css_isys_stream_cfg_data *stream_cfg_data_host, + struct ia_css_isys_stream_cfg_data_comm *stream_cfg_data_css) +{ + unsigned int i; + + stream_cfg_data_css->src = stream_cfg_data_host->src; + stream_cfg_data_css->vc = stream_cfg_data_host->vc; + stream_cfg_data_css->isl_use = stream_cfg_data_host->isl_use; + stream_cfg_data_css->compfmt = stream_cfg_data_host->compfmt; + stream_cfg_data_css->isa_cfg.cfg_fields = 0; + + switch (stream_cfg_data_host->isl_use) { + case IA_CSS_ISYS_USE_SINGLE_ISA: + isa_cfg_host_to_css(&stream_cfg_data_host->isa_cfg, + &stream_cfg_data_css->isa_cfg); + /* deliberate fall-through */ + case IA_CSS_ISYS_USE_SINGLE_DUAL_ISL: + for (i = 0; i < N_IA_CSS_ISYS_CROPPING_LOCATION; i++) { + cropping_host_to_css(&stream_cfg_data_host->crop[i], + &stream_cfg_data_css->crop[i]); + } + break; + case IA_CSS_ISYS_USE_NO_ISL_NO_ISA: + break; + default: + break; + } + + stream_cfg_data_css->send_irq_sof_discarded = + stream_cfg_data_host->send_irq_sof_discarded ? 1 : 0; + stream_cfg_data_css->send_irq_eof_discarded = + stream_cfg_data_host->send_irq_eof_discarded ? 1 : 0; + stream_cfg_data_css->send_resp_sof_discarded = + stream_cfg_data_host->send_irq_sof_discarded ? + 1 : stream_cfg_data_host->send_resp_sof_discarded; + stream_cfg_data_css->send_resp_eof_discarded = + stream_cfg_data_host->send_irq_eof_discarded ? + 1 : stream_cfg_data_host->send_resp_eof_discarded; + stream_cfg_data_css->nof_input_pins = + stream_cfg_data_host->nof_input_pins; + stream_cfg_data_css->nof_output_pins = + stream_cfg_data_host->nof_output_pins; + for (i = 0; i < stream_cfg_data_host->nof_input_pins; i++) { + input_pin_info_host_to_css( + &stream_cfg_data_host->input_pins[i], + &stream_cfg_data_css->input_pins[i]); + verifret(stream_cfg_data_css->input_pins[i].bits_per_pix, + EINVAL); + } + for (i = 0; i < stream_cfg_data_host->nof_output_pins; i++) { + output_pin_info_host_to_css( + &stream_cfg_data_host->output_pins[i], + &stream_cfg_data_css->output_pins[i]); + } + return 0; +} + +STORAGE_CLASS_INLINE void frame_buff_set_host_to_css( + const struct ia_css_isys_frame_buff_set *frame_buff_set_host, + struct ia_css_isys_frame_buff_set_comm *frame_buff_set_css) +{ + int i; + + for (i = 0; i < MAX_OPINS; i++) { + output_pin_payload_host_to_css( + &frame_buff_set_host->output_pins[i], + &frame_buff_set_css->output_pins[i]); + } + + param_pin_host_to_css(&frame_buff_set_host->process_group_light, + &frame_buff_set_css->process_group_light); + frame_buff_set_css->send_irq_sof = + frame_buff_set_host->send_irq_sof ? 1 : 0; + frame_buff_set_css->send_irq_eof = + frame_buff_set_host->send_irq_eof ? 1 : 0; + frame_buff_set_css->send_irq_capture_done = + (uint8_t)frame_buff_set_host->send_irq_capture_done; + frame_buff_set_css->send_irq_capture_ack = + frame_buff_set_host->send_irq_capture_ack ? 1 : 0; + frame_buff_set_css->send_resp_sof = + frame_buff_set_host->send_irq_sof ? + 1 : frame_buff_set_host->send_resp_sof; + frame_buff_set_css->send_resp_eof = + frame_buff_set_host->send_irq_eof ? + 1 : frame_buff_set_host->send_resp_eof; + frame_buff_set_css->frame_counter = + frame_buff_set_host->frame_counter; +} + +STORAGE_CLASS_INLINE void buffer_partition_host_to_css( + const struct ia_css_isys_buffer_partition *buffer_partition_host, + struct ia_css_isys_buffer_partition_comm *buffer_partition_css) +{ + int i; + + for (i = 0; i < STREAM_ID_MAX; i++) { + buffer_partition_css->num_gda_pages[i] = + buffer_partition_host->num_gda_pages[i]; + } +} + +STORAGE_CLASS_INLINE void output_pin_payload_css_to_host( + const struct ia_css_isys_output_pin_payload_comm * + output_pin_payload_css, + struct ia_css_isys_output_pin_payload *output_pin_payload_host) +{ + output_pin_payload_host->out_buf_id = + output_pin_payload_css->out_buf_id; + output_pin_payload_host->addr = output_pin_payload_css->addr; +#ifdef ENABLE_DEC400 + output_pin_payload_host->compress = output_pin_payload_css->compress; +#else + output_pin_payload_host->compress = 0; +#endif /* ENABLE_DEC400 */ +} + +STORAGE_CLASS_INLINE void param_pin_css_to_host( + const struct ia_css_isys_param_pin_comm *param_pin_css, + struct ia_css_isys_param_pin *param_pin_host) +{ + param_pin_host->param_buf_id = param_pin_css->param_buf_id; + param_pin_host->addr = param_pin_css->addr; + +} + +STORAGE_CLASS_INLINE void resp_info_css_to_host( + const struct ia_css_isys_resp_info_comm *resp_info_css, + struct ia_css_isys_resp_info *resp_info_host) +{ + resp_info_host->type = resp_info_css->type; + resp_info_host->timestamp[0] = resp_info_css->timestamp[0]; + resp_info_host->timestamp[1] = resp_info_css->timestamp[1]; + resp_info_host->stream_handle = resp_info_css->stream_handle; + resp_info_host->error = resp_info_css->error_info.error; + resp_info_host->error_details = + resp_info_css->error_info.error_details; + output_pin_payload_css_to_host( + &resp_info_css->pin, &resp_info_host->pin); + resp_info_host->pin_id = resp_info_css->pin_id; + param_pin_css_to_host(&resp_info_css->process_group_light, + &resp_info_host->process_group_light); + resp_info_host->acc_id = resp_info_css->acc_id; + resp_info_host->frame_counter = resp_info_css->frame_counter; + resp_info_host->written_direct = resp_info_css->written_direct; +} + +/* + * ia_css_isys_constr_fw_stream_cfg() + */ +int ia_css_isys_constr_fw_stream_cfg( + struct ia_css_isys_context *ctx, + const unsigned int stream_handle, + ia_css_shared_buffer_css_address *pstream_cfg_fw, + ia_css_shared_buffer *pbuf_stream_cfg_id, + const struct ia_css_isys_stream_cfg_data *stream_cfg) +{ + ia_css_shared_buffer_cpu_address stream_cfg_cpu_addr; + ia_css_shared_buffer_css_address stream_cfg_css_addr; + int buff_slot; + int retval = 0; + unsigned int wrap_compensation; + const unsigned int wrap_condition = 0xFFFFFFFF; + + verifret(ctx, EFAULT); /* Host Consistency */ + verifret(pstream_cfg_fw, EFAULT); /* Host Consistency */ + verifret(pbuf_stream_cfg_id, EFAULT); /* Host Consistency */ + verifret(stream_cfg, EFAULT); /* Host Consistency */ + + /* Host-FW Consistency */ + verifret((ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle] - + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle]) < + STREAM_CFG_BUFS_PER_MSG_QUEUE, EPROTO); + buff_slot = get_stream_cfg_buff_slot(ctx, stream_handle, + ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle] % + STREAM_CFG_BUFS_PER_MSG_QUEUE); + *pbuf_stream_cfg_id = + ctx->isys_comm_buffer_queue.pstream_cfg_buff_id[buff_slot]; + /* Host-FW Consistency */ + verifret(*pbuf_stream_cfg_id, EADDRNOTAVAIL); + + stream_cfg_cpu_addr = + ia_css_shared_buffer_cpu_map(*pbuf_stream_cfg_id); + /* Host-FW Consistency */ + verifret(stream_cfg_cpu_addr, EADDRINUSE); + + retval = stream_cfg_data_host_to_css(stream_cfg, stream_cfg_cpu_addr); + if (retval) + return retval; + + stream_cfg_cpu_addr = + ia_css_shared_buffer_cpu_unmap(*pbuf_stream_cfg_id); + /* Host Consistency */ + verifret(stream_cfg_cpu_addr, EADDRINUSE); + + stream_cfg_css_addr = + ia_css_shared_buffer_css_map(*pbuf_stream_cfg_id); + /* Host Consistency */ + verifret(stream_cfg_css_addr, EADDRINUSE); + + ia_css_shared_buffer_css_update(ctx->mmid, *pbuf_stream_cfg_id); + + *pstream_cfg_fw = stream_cfg_css_addr; + + /* + * cover head wrap around extreme case, + * in which case force tail to wrap around too + * while maintaining diff and modulo + */ + if (ctx->isys_comm_buffer_queue.stream_cfg_queue_head[stream_handle] == + wrap_condition) { + /* Value to be added to both head and tail */ + wrap_compensation = + /* + * Distance of wrap_condition to 0, + * will need to be added for wrapping around head to 0 + */ + (0 - wrap_condition) + + /* + * To force tail to also wrap around, + * since it has to happen concurrently + */ + STREAM_CFG_BUFS_PER_MSG_QUEUE + + /* To preserve the same modulo, + * since the previous will result in head modulo 0 + */ + (wrap_condition % STREAM_CFG_BUFS_PER_MSG_QUEUE); + ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[stream_handle] += + wrap_compensation; + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[stream_handle] += + wrap_compensation; + } + ctx->isys_comm_buffer_queue.stream_cfg_queue_head[stream_handle]++; + + return 0; +} + +/* + * ia_css_isys_constr_fw_next_frame() + */ +int ia_css_isys_constr_fw_next_frame( + struct ia_css_isys_context *ctx, + const unsigned int stream_handle, + ia_css_shared_buffer_css_address *pnext_frame_fw, + ia_css_shared_buffer *pbuf_next_frame_id, + const struct ia_css_isys_frame_buff_set *next_frame) +{ + ia_css_shared_buffer_cpu_address next_frame_cpu_addr; + ia_css_shared_buffer_css_address next_frame_css_addr; + int buff_slot; + unsigned int wrap_compensation; + const unsigned int wrap_condition = 0xFFFFFFFF; + + verifret(ctx, EFAULT); /* Host Consistency */ + verifret(pnext_frame_fw, EFAULT); /* Host Consistency */ + verifret(next_frame, EFAULT); /* Host Consistency */ + verifret(pbuf_next_frame_id, EFAULT); /* Host Consistency */ + + /* For some reason responses are not dequeued in time */ + verifret((ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle] - + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle]) < + NEXT_FRAME_BUFS_PER_MSG_QUEUE, EPERM); + buff_slot = get_next_frame_buff_slot(ctx, stream_handle, + ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle] % + NEXT_FRAME_BUFS_PER_MSG_QUEUE); + *pbuf_next_frame_id = + ctx->isys_comm_buffer_queue.pnext_frame_buff_id[buff_slot]; + /* Host-FW Consistency */ + verifret(*pbuf_next_frame_id, EADDRNOTAVAIL); + + /* map it in cpu */ + next_frame_cpu_addr = + ia_css_shared_buffer_cpu_map(*pbuf_next_frame_id); + /* Host-FW Consistency */ + verifret(next_frame_cpu_addr, EADDRINUSE); + + frame_buff_set_host_to_css(next_frame, next_frame_cpu_addr); + + /* unmap the buffer from cpu */ + next_frame_cpu_addr = + ia_css_shared_buffer_cpu_unmap(*pbuf_next_frame_id); + /* Host Consistency */ + verifret(next_frame_cpu_addr, EADDRINUSE); + + /* map it to css */ + next_frame_css_addr = + ia_css_shared_buffer_css_map(*pbuf_next_frame_id); + /* Host Consistency */ + verifret(next_frame_css_addr, EADDRINUSE); + + ia_css_shared_buffer_css_update(ctx->mmid, *pbuf_next_frame_id); + + *pnext_frame_fw = next_frame_css_addr; + + /* + * cover head wrap around extreme case, + * in which case force tail to wrap around too + * while maintaining diff and modulo + */ + if (ctx->isys_comm_buffer_queue.next_frame_queue_head[stream_handle] == + wrap_condition) { + /* Value to be added to both head and tail */ + wrap_compensation = + /* + * Distance of wrap_condition to 0, + * will need to be added for wrapping around head to 0 + */ + (0 - wrap_condition) + + /* + * To force tail to also wrap around, + * since it has to happen concurrently + */ + NEXT_FRAME_BUFS_PER_MSG_QUEUE + + /* + * To preserve the same modulo, + * since the previous will result in head modulo 0 + */ + (wrap_condition % NEXT_FRAME_BUFS_PER_MSG_QUEUE); + ctx->isys_comm_buffer_queue. + next_frame_queue_head[stream_handle] += + wrap_compensation; + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[stream_handle] += + wrap_compensation; + } + ctx->isys_comm_buffer_queue.next_frame_queue_head[stream_handle]++; + + return 0; +} + +/* + * ia_css_isys_extract_fw_response() + */ +int ia_css_isys_extract_fw_response( + struct ia_css_isys_context *ctx, + const struct resp_queue_token *token, + struct ia_css_isys_resp_info *received_response) +{ + int buff_slot; + unsigned int css_address; + + verifret(ctx, EFAULT); /* Host Consistency */ + verifret(token, EFAULT); /* Host Consistency */ + verifret(received_response, EFAULT); /* Host Consistency */ + + resp_info_css_to_host(&(token->resp_info), received_response); + + switch (token->resp_info.type) { + case IA_CSS_ISYS_RESP_TYPE_STREAM_OPEN_DONE: + /* Host-FW Consistency */ + verifret((ctx->isys_comm_buffer_queue. + stream_cfg_queue_head[token->resp_info.stream_handle] - + ctx->isys_comm_buffer_queue.stream_cfg_queue_tail[ + token->resp_info.stream_handle]) > 0, EPROTO); + buff_slot = get_stream_cfg_buff_slot(ctx, + token->resp_info.stream_handle, + ctx->isys_comm_buffer_queue. + stream_cfg_queue_tail[ + token->resp_info.stream_handle] % + STREAM_CFG_BUFS_PER_MSG_QUEUE); + verifret((ia_css_shared_buffer)HOST_ADDRESS( + token->resp_info.buf_id) == + ctx->isys_comm_buffer_queue. + pstream_cfg_buff_id[buff_slot], EIO); + ctx->isys_comm_buffer_queue.stream_cfg_queue_tail[ + token->resp_info.stream_handle]++; + css_address = ia_css_shared_buffer_css_unmap( + (ia_css_shared_buffer) + HOST_ADDRESS(token->resp_info.buf_id)); + verifret(css_address, EADDRINUSE); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK: + case IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK: + /* Host-FW Consistency */ + verifret((ctx->isys_comm_buffer_queue. + next_frame_queue_head[token->resp_info.stream_handle] - + ctx->isys_comm_buffer_queue.next_frame_queue_tail[ + token->resp_info.stream_handle]) > 0, EPROTO); + buff_slot = get_next_frame_buff_slot(ctx, + token->resp_info.stream_handle, + ctx->isys_comm_buffer_queue. + next_frame_queue_tail[ + token->resp_info.stream_handle] % + NEXT_FRAME_BUFS_PER_MSG_QUEUE); + verifret((ia_css_shared_buffer)HOST_ADDRESS( + token->resp_info.buf_id) == + ctx->isys_comm_buffer_queue. + pnext_frame_buff_id[buff_slot], EIO); + ctx->isys_comm_buffer_queue.next_frame_queue_tail[ + token->resp_info.stream_handle]++; + css_address = ia_css_shared_buffer_css_unmap( + (ia_css_shared_buffer) + HOST_ADDRESS(token->resp_info.buf_id)); + verifret(css_address, EADDRINUSE); + break; + default: + break; + } + + return 0; +} + +/* + * ia_css_isys_extract_proxy_response() + */ +int ia_css_isys_extract_proxy_response( + const struct proxy_resp_queue_token *token, + struct ia_css_proxy_write_req_resp *preceived_response) +{ + verifret(token, EFAULT); /* Host Consistency */ + verifret(preceived_response, EFAULT); /* Host Consistency */ + + preceived_response->request_id = token->proxy_resp_info.request_id; + preceived_response->error = token->proxy_resp_info.error_info.error; + preceived_response->error_details = + token->proxy_resp_info.error_info.error_details; + + return 0; +} + +/* + * ia_css_isys_prepare_param() + */ +int ia_css_isys_prepare_param( + struct ia_css_isys_fw_config *isys_fw_cfg, + const struct ia_css_isys_buffer_partition *buf_partition, + const unsigned int num_send_queues[], + const unsigned int num_recv_queues[]) +{ + unsigned int i; + + verifret(isys_fw_cfg, EFAULT); /* Host Consistency */ + verifret(buf_partition, EFAULT); /* Host Consistency */ + verifret(num_send_queues, EFAULT); /* Host Consistency */ + verifret(num_recv_queues, EFAULT); /* Host Consistency */ + + buffer_partition_host_to_css(buf_partition, + &isys_fw_cfg->buffer_partition); + for (i = 0; i < N_IA_CSS_ISYS_QUEUE_TYPE; i++) { + isys_fw_cfg->num_send_queues[i] = num_send_queues[i]; + isys_fw_cfg->num_recv_queues[i] = num_recv_queues[i]; + } + + return 0; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_private.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_private.h new file mode 100644 index 0000000000000..d53fa53c9a818 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_private.h @@ -0,0 +1,156 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYS_PRIVATE_H +#define __IA_CSS_ISYS_PRIVATE_H + + +#include "type_support.h" +/* Needed for the structure member ia_css_sys_context * sys */ +#include "ia_css_syscom.h" +/* Needed for the definitions of STREAM_ID_MAX */ +#include "ia_css_isysapi.h" +/* The following is needed for the function arguments */ +#include "ia_css_isys_fw_bridged_types.h" + +#include "ia_css_shared_buffer.h" + + +/* Set for the respective error handling */ +#define VERIFY_DEVSTATE 1 + +#if (VERIFY_DEVSTATE != 0) +/** + * enum device_state + */ +enum device_state { + IA_CSS_ISYS_DEVICE_STATE_IDLE = 0, + IA_CSS_ISYS_DEVICE_STATE_CONFIGURED = 1, + IA_CSS_ISYS_DEVICE_STATE_READY = 2 +}; +#endif /* VERIFY_DEVSTATE */ + +/** + * enum stream_state + */ +enum stream_state { + IA_CSS_ISYS_STREAM_STATE_IDLE = 0, + IA_CSS_ISYS_STREAM_STATE_OPENED = 1, + IA_CSS_ISYS_STREAM_STATE_STARTED = 2 +}; + + +/** + * struct ia_css_isys_comm_buffer_queue + */ +struct ia_css_isys_comm_buffer_queue { + ia_css_shared_buffer *pstream_cfg_buff_id; + unsigned int stream_cfg_queue_head[STREAM_ID_MAX]; + unsigned int stream_cfg_queue_tail[STREAM_ID_MAX]; + ia_css_shared_buffer *pnext_frame_buff_id; + unsigned int next_frame_queue_head[STREAM_ID_MAX]; + unsigned int next_frame_queue_tail[STREAM_ID_MAX]; +}; + + +/** + * struct ia_css_isys_context + */ +struct ia_css_isys_context { + struct ia_css_syscom_context *sys; + /* add here any isys specific members that need + to be passed into the isys api functions as input */ + unsigned int ssid; + unsigned int mmid; + unsigned int num_send_queues[N_IA_CSS_ISYS_QUEUE_TYPE]; + unsigned int num_recv_queues[N_IA_CSS_ISYS_QUEUE_TYPE]; + unsigned int send_queue_size[N_IA_CSS_ISYS_QUEUE_TYPE]; + struct ia_css_isys_comm_buffer_queue isys_comm_buffer_queue; + unsigned int stream_nof_output_pins[STREAM_ID_MAX]; +#if (VERIFY_DEVSTATE != 0) + enum device_state dev_state; +#endif /* VERIFY_DEVSTATE */ + enum stream_state stream_state_array[STREAM_ID_MAX]; + /* If true, this context is created based on secure config */ + bool secure; +}; + + +/** + * ia_css_isys_constr_comm_buff_queue() + */ +extern int ia_css_isys_constr_comm_buff_queue( + struct ia_css_isys_context *ctx +); + +/** + * ia_css_isys_force_unmap_comm_buff_queue() + */ +extern int ia_css_isys_force_unmap_comm_buff_queue( + struct ia_css_isys_context *ctx +); + +/** + * ia_css_isys_destr_comm_buff_queue() + */ +extern int ia_css_isys_destr_comm_buff_queue( + struct ia_css_isys_context *ctx +); + +/** + * ia_css_isys_constr_fw_stream_cfg() + */ +extern int ia_css_isys_constr_fw_stream_cfg( + struct ia_css_isys_context *ctx, + const unsigned int stream_handle, + ia_css_shared_buffer_css_address *pstream_cfg_fw, + ia_css_shared_buffer *pbuf_stream_cfg_id, + const struct ia_css_isys_stream_cfg_data *stream_cfg +); + +/** + * ia_css_isys_constr_fw_next_frame() + */ +extern int ia_css_isys_constr_fw_next_frame( + struct ia_css_isys_context *ctx, + const unsigned int stream_handle, + ia_css_shared_buffer_css_address *pnext_frame_fw, + ia_css_shared_buffer *pbuf_next_frame_id, + const struct ia_css_isys_frame_buff_set *next_frame +); + +/** + * ia_css_isys_extract_fw_response() + */ +extern int ia_css_isys_extract_fw_response( + struct ia_css_isys_context *ctx, + const struct resp_queue_token *token, + struct ia_css_isys_resp_info *received_response +); +extern int ia_css_isys_extract_proxy_response( + const struct proxy_resp_queue_token *token, + struct ia_css_proxy_write_req_resp *received_response +); + +/** + * ia_css_isys_prepare_param() + */ +extern int ia_css_isys_prepare_param( + struct ia_css_isys_fw_config *isys_fw_cfg, + const struct ia_css_isys_buffer_partition *buf_partition, + const unsigned int num_send_queues[], + const unsigned int num_recv_queues[] +); + +#endif /* __IA_CSS_ISYS_PRIVATE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_public.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_public.c new file mode 100644 index 0000000000000..0e49af6353e03 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_public.c @@ -0,0 +1,1283 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/* TODO: REMOVE --> START IF EXTERNALLY INCLUDED/DEFINED */ +/* These are temporary, the correct numbers need to be inserted/linked */ +/* Until this happens, the following definitions stay here */ +#define INPUT_MIN_WIDTH 1 +#define INPUT_MAX_WIDTH 16384 +#define INPUT_MIN_HEIGHT 1 +#define INPUT_MAX_HEIGHT 16384 +#define OUTPUT_MIN_WIDTH 1 +#define OUTPUT_MAX_WIDTH 16384 +#define OUTPUT_MIN_HEIGHT 1 +#define OUTPUT_MAX_HEIGHT 16384 +/* REMOVE --> END IF EXTERNALLY INCLUDED/DEFINED */ + + +/* The FW bridged types are included through the following */ +#include "ia_css_isysapi.h" +/* The following provides the isys-sys context */ +#include "ia_css_isys_private.h" +/* The following provides the sys layer functions */ +#include "ia_css_syscom.h" + +#include "ia_css_cell.h" +#include "ipu_device_cell_properties.h" + +/* The following provides the tracing functions */ +#include "ia_css_isysapi_trace.h" +#include "ia_css_isys_public_trace.h" + +#include "ia_css_shared_buffer_cpu.h" +/* The following is needed for the + * stddef.h (NULL), + * limits.h (CHAR_BIT definition). + */ +#include "type_support.h" +#include "error_support.h" +#include "cpu_mem_support.h" +#include "math_support.h" +#include "misc_support.h" +#include "system_const.h" + +static int isys_context_create( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config); +static int isys_start_server( + const struct ia_css_isys_device_cfg_data *config); + +static int isys_context_create( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config) +{ + int retval; + unsigned int stream_handle; + struct ia_css_isys_context *ctx; + struct ia_css_syscom_config sys; + /* Needs to be updated in case new type of queues are introduced */ + struct ia_css_syscom_queue_config input_queue_cfg[N_MAX_SEND_QUEUES]; + /* Needs to be updated in case new type of queues are introduced */ + struct ia_css_syscom_queue_config output_queue_cfg[N_MAX_RECV_QUEUES]; + struct ia_css_isys_fw_config isys_fw_cfg; + unsigned int proxy_write_queue_size; + unsigned int ssid; + unsigned int mmid; + unsigned int i; + + /* Printing "ENTRY isys_context_create" + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY isys_context_create\n"); + + verifret(config != NULL, EFAULT); + + /* Printing configuration information if tracing level = VERBOSE. */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_device_config_data(config); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + + /* Runtime check for # of send and recv MSG queues */ + verifret(config->driver_sys.num_send_queues <= + N_MAX_MSG_SEND_QUEUES/*=STREAM_ID_MAX*/, EINVAL); + verifret(config->driver_sys.num_recv_queues <= + N_MAX_MSG_RECV_QUEUES, EINVAL); + + /* Runtime check for send and recv MSG queue sizes */ + verifret(config->driver_sys.send_queue_size <= MAX_QUEUE_SIZE, EINVAL); + verifret(config->driver_sys.recv_queue_size <= MAX_QUEUE_SIZE, EINVAL); + + /* TODO: return an error in case MAX_QUEUE_SIZE is exceeded + * (Similar to runtime check on MSG queue sizes) + */ + proxy_write_queue_size = uclip( + config->driver_proxy.proxy_write_queue_size, + MIN_QUEUE_SIZE, + MAX_QUEUE_SIZE); + + ctx = (struct ia_css_isys_context *) + ia_css_cpu_mem_alloc(sizeof(struct ia_css_isys_context)); + verifret(ctx != NULL, EFAULT); + *context = (HANDLE)ctx; + + /* Copy to the sys config the driver_sys config, + * and add the internal info (token sizes) + */ + ssid = config->driver_sys.ssid; + mmid = config->driver_sys.mmid; + sys.ssid = ssid; + sys.mmid = mmid; + + ctx->secure = config->secure; + /* Following operations need to be aligned with + * "enum ia_css_isys_queue_type" list (list of queue types) + */ + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] = + N_MAX_PROXY_SEND_QUEUES; + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV] = + N_MAX_DEV_SEND_QUEUES; + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] = + config->driver_sys.num_send_queues; + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] = + N_MAX_PROXY_RECV_QUEUES; + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV] = + 0; /* Common msg/dev return queue */ + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] = + config->driver_sys.num_recv_queues; + + sys.num_input_queues = + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] + + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV] + + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + sys.num_output_queues = + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] + + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV] + + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + + sys.input = input_queue_cfg; + for (i = 0; + i < ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY]; + i++) { + input_queue_cfg[BASE_PROXY_SEND_QUEUES + i].queue_size = + proxy_write_queue_size; + input_queue_cfg[BASE_PROXY_SEND_QUEUES + i].token_size = + sizeof(struct proxy_send_queue_token); + } + for (i = 0; + i < ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV]; + i++) { + input_queue_cfg[BASE_DEV_SEND_QUEUES + i].queue_size = + DEV_SEND_QUEUE_SIZE; + input_queue_cfg[BASE_DEV_SEND_QUEUES + i].token_size = + sizeof(struct send_queue_token); + } + for (i = 0; + i < ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + i++) { + input_queue_cfg[BASE_MSG_SEND_QUEUES + i].queue_size = + config->driver_sys.send_queue_size; + input_queue_cfg[BASE_MSG_SEND_QUEUES + i].token_size = + sizeof(struct send_queue_token); + } + + ctx->send_queue_size[IA_CSS_ISYS_QUEUE_TYPE_PROXY] = + proxy_write_queue_size; + ctx->send_queue_size[IA_CSS_ISYS_QUEUE_TYPE_DEV] = + DEV_SEND_QUEUE_SIZE; + ctx->send_queue_size[IA_CSS_ISYS_QUEUE_TYPE_MSG] = + config->driver_sys.send_queue_size; + + sys.output = output_queue_cfg; + for (i = 0; + i < ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY]; + i++) { + output_queue_cfg[BASE_PROXY_RECV_QUEUES + i].queue_size = + proxy_write_queue_size; + output_queue_cfg[BASE_PROXY_RECV_QUEUES + i].token_size = + sizeof(struct proxy_resp_queue_token); + } + /* There is no recv DEV queue */ + for (i = 0; + i < ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]; + i++) { + output_queue_cfg[BASE_MSG_RECV_QUEUES + i].queue_size = + config->driver_sys.recv_queue_size; + output_queue_cfg[BASE_MSG_RECV_QUEUES + i].token_size = + sizeof(struct resp_queue_token); + } + + sys.regs_addr = ipu_device_cell_memory_address(SPC0, + IPU_DEVICE_SP2600_CONTROL_REGS); + sys.dmem_addr = ipu_device_cell_memory_address(SPC0, + IPU_DEVICE_SP2600_CONTROL_DMEM); + +#if HAS_DUAL_CMD_CTX_SUPPORT + sys.dmem_addr += config->secure ? REGMEM_SECURE_OFFSET : REGMEM_OFFSET; +#endif + + /* Prepare the param */ + ia_css_isys_prepare_param( + &isys_fw_cfg, + &config->buffer_partition, + ctx->num_send_queues, + ctx->num_recv_queues); + + /* parameter struct to be passed to fw */ + sys.specific_addr = &isys_fw_cfg; + /* parameters size */ + sys.specific_size = sizeof(isys_fw_cfg); + sys.secure = config->secure; + if (config->secure) { + sys.vtl0_addr_mask = config->vtl0_addr_mask; + } + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "isys_context_create || call ia_css_syscom_open()\n"); + /* The allocation of the queues will take place within this call and + * info will be stored in sys_context output + */ + ctx->sys = ia_css_syscom_open(&sys, NULL); + if (!ctx->sys) { + ia_css_cpu_mem_free(ctx); + return -EFAULT; + } + + /* Update the context with the id's */ + ctx->ssid = ssid; + ctx->mmid = mmid; + + for (stream_handle = 0; stream_handle < STREAM_ID_MAX; + stream_handle++) { + ctx->stream_state_array[stream_handle] = + IA_CSS_ISYS_STREAM_STATE_IDLE; + } + + retval = ia_css_isys_constr_comm_buff_queue(ctx); + if (retval) { + ia_css_syscom_close(ctx->sys); + ia_css_syscom_release(ctx->sys, 1); + ia_css_cpu_mem_free(ctx); + return retval; + } + +#if (VERIFY_DEVSTATE != 0) + ctx->dev_state = IA_CSS_ISYS_DEVICE_STATE_CONFIGURED; +#endif /* VERIFY_DEVSTATE */ + + /* Printing device configuration and device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + + /* Printing "LEAVE isys_context_create" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE isys_context_create\n"); + return 0; +} + +static int isys_start_server( + const struct ia_css_isys_device_cfg_data *config) +{ + verifret(config != NULL, EFAULT); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "isys_start_server || start SPC\n"); + /* The firmware is loaded and syscom is ready, start the SPC */ + ia_css_cell_start_prefetch(config->driver_sys.ssid, SPC0, + config->driver_sys.icache_prefetch); + IA_CSS_TRACE_1(ISYSAPI, VERBOSE, "SPC prefetch: %d\n", + config->driver_sys.icache_prefetch); + return 0; +} + +/** + * ia_css_isys_device_open() - open and configure ISYS device + */ +#if HAS_DUAL_CMD_CTX_SUPPORT +int ia_css_isys_context_create( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config) +{ + return isys_context_create(context, config); +} + +/* push context information to DMEM for FW to access */ +int ia_css_isys_context_store_dmem( + const HANDLE *context, + const struct ia_css_isys_device_cfg_data *config) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *) *context; + + return ia_css_syscom_store_dmem(ctx->sys, config->driver_sys.ssid, config->vtl0_addr_mask); +} + +bool ia_css_isys_ab_spc_ready( + HANDLE *context) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *) *context; + + return ia_css_syscom_is_ab_spc_ready(ctx->sys); +} + +int ia_css_isys_device_open( + const struct ia_css_isys_device_cfg_data *config) +{ + return isys_start_server(config); +} +#else +int ia_css_isys_device_open( + HANDLE *context, + const struct ia_css_isys_device_cfg_data *config) +{ + int retval; + + retval = isys_context_create(context, config); + if (retval) { + IA_CSS_TRACE_1(ISYSAPI, ERROR, "ia_css_isys_device_open() failed (retval %d)\n", retval); + return retval; + } + + isys_start_server(config); + return 0; +} +#endif + +/** + * ia_css_isys_device_open_ready() - open and configure ISYS device + */ +int ia_css_isys_device_open_ready(HANDLE context) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + unsigned int i; + int retval; + + /* Printing "ENTRY IA_CSS_ISYS_DEVICE_OPEN" + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_DEVICE_OPEN\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_CONFIGURED, EPERM); +#endif /* VERIFY_DEVSTATE */ + + /* Open the ports for all the non-MSG send queues (PROXY + DEV) */ + for (i = 0; + i < ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] + + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV]; + i++) { + retval = ia_css_syscom_send_port_open(ctx->sys, i); + verifret(retval != FW_ERROR_BUSY, EBUSY); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + } + + /* Open the ports for all the recv queues (PROXY + MSG) */ + for (i = 0; + i < (ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] + + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG]); + i++) { + retval = ia_css_syscom_recv_port_open(ctx->sys, i); + verifret(retval != FW_ERROR_BUSY, EBUSY); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + } + +#if (VERIFY_DEVSTATE != 0) + ctx->dev_state = IA_CSS_ISYS_DEVICE_STATE_READY; +#endif /* VERIFY_DEVSTATE */ + + /* Printing "LEAVE IA_CSS_ISYS_DEVICE_OPEN_READY" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "LEAVE IA_CSS_ISYS_DEVICE_OPEN_READY\n"); + return 0; +} + + + /** + * ia_css_isys_stream_open() - open and configure a virtual stream + */ +int ia_css_isys_stream_open( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_stream_cfg_data *stream_cfg) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + unsigned int i; + int retval = 0; + int packets; + struct send_queue_token token; + ia_css_shared_buffer_css_address stream_cfg_fw = 0; + ia_css_shared_buffer buf_stream_cfg_id = (ia_css_shared_buffer)NULL; + /* Printing "ENTRY IA_CSS_ISYS_STREAM_OPEN" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_STREAM_OPEN\n"); + + verifret(ctx, EFAULT); + + /* Printing stream configuration and device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); + print_stream_config_data(stream_cfg); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_IDLE, EPERM); + + verifret(stream_cfg != NULL, EFAULT); + verifret(stream_cfg->src < N_IA_CSS_ISYS_STREAM_SRC, EINVAL); + verifret(stream_cfg->vc < N_IA_CSS_ISYS_MIPI_VC, EINVAL); + verifret(stream_cfg->isl_use < N_IA_CSS_ISYS_USE, EINVAL); + if (stream_cfg->isl_use != IA_CSS_ISYS_USE_NO_ISL_NO_ISA) { + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].bottom_offset >= + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].top_offset + + OUTPUT_MIN_HEIGHT, EINVAL); + + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].bottom_offset <= + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].top_offset + + OUTPUT_MAX_HEIGHT, EINVAL); + + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].right_offset >= + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].left_offset + + OUTPUT_MIN_WIDTH, EINVAL); + + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].right_offset <= + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].left_offset + + OUTPUT_MAX_WIDTH, EINVAL); + } + verifret(stream_cfg->nof_input_pins <= MAX_IPINS, EINVAL); + verifret(stream_cfg->nof_output_pins <= MAX_OPINS, EINVAL); + for (i = 0; i < stream_cfg->nof_input_pins; i++) { + /* Verify input pin */ + verifret( + stream_cfg->input_pins[i].input_res.width >= + INPUT_MIN_WIDTH && + stream_cfg->input_pins[i].input_res.width <= + INPUT_MAX_WIDTH && + stream_cfg->input_pins[i].input_res.height >= + INPUT_MIN_HEIGHT && + stream_cfg->input_pins[i].input_res.height <= + INPUT_MAX_HEIGHT, EINVAL); + verifret(stream_cfg->input_pins[i].dt < + N_IA_CSS_ISYS_MIPI_DATA_TYPE, EINVAL); +/* #ifdef To be removed when driver inits the value */ +#ifdef DRIVER_INIT_MIPI_STORE_MODE + verifret(stream_cfg->input_pins[i].mipi_store_mode < + N_IA_CSS_ISYS_MIPI_STORE_MODE, EINVAL); +#endif /* DRIVER_INIT_MIPI_STORE_MODE */ + } + for (i = 0; i < stream_cfg->nof_output_pins; i++) { + /* Verify output pin */ + verifret(stream_cfg->output_pins[i].input_pin_id < + stream_cfg->nof_input_pins, EINVAL); + verifret(stream_cfg->output_pins[i].pt < + N_IA_CSS_ISYS_PIN_TYPE, EINVAL); + verifret(stream_cfg->output_pins[i].ft < + N_IA_CSS_ISYS_FRAME_FORMAT, EINVAL); + /* Verify that the stride is aligned to 64 bytes: HW spec */ + verifret(stream_cfg->output_pins[i].stride%(XMEM_WIDTH/8) == + 0, EINVAL); + verifret((stream_cfg->output_pins[i].output_res.width >= + OUTPUT_MIN_WIDTH) && + (stream_cfg->output_pins[i].output_res.width <= + OUTPUT_MAX_WIDTH) && + (stream_cfg->output_pins[i].output_res.height >= + OUTPUT_MIN_HEIGHT) && + (stream_cfg->output_pins[i].output_res.height <= + OUTPUT_MAX_HEIGHT), EINVAL); + verifret((stream_cfg->output_pins[i].pt == + IA_CSS_ISYS_PIN_TYPE_MIPI) || + (stream_cfg-> + input_pins[stream_cfg->output_pins[i].input_pin_id].mipi_store_mode != + IA_CSS_ISYS_MIPI_STORE_MODE_DISCARD_LONG_HEADER), EINVAL); + if (stream_cfg->isl_use == IA_CSS_ISYS_USE_SINGLE_ISA) { + switch (stream_cfg->output_pins[i].pt) { + case IA_CSS_ISYS_PIN_TYPE_RAW_NS: + /* Ensure the PIFCONV cropped resolution + * matches the RAW_NS output pin resolution + */ + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED].bottom_offset == + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED].top_offset + + (int)stream_cfg->output_pins[i].output_res.height, EINVAL); + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED].right_offset == + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_NONSCALED].left_offset + + (int)stream_cfg->output_pins[i].output_res.width, EINVAL); + /* Ensure the ISAPF cropped resolution matches + * the Non-scaled ISA output resolution before + * the PIFCONV cropping, since nothing can + * modify the resolution in that part of + * the pipe + */ + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].bottom_offset == + stream_cfg->crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].top_offset + + (int)stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED].height, + EINVAL); + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].right_offset == + stream_cfg->crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].left_offset + + (int)stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED].width, + EINVAL); + /* Ensure the Non-scaled ISA output resolution + * before the PIFCONV cropping bounds the + * RAW_NS pin output resolution since padding + * is not supported + */ + verifret(stream_cfg-> +isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED].height >= +stream_cfg->output_pins[i].output_res.height, EINVAL); + verifret(stream_cfg-> +isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_NONSCALED].width >= +stream_cfg->output_pins[i].output_res.width, EINVAL); + break; + case IA_CSS_ISYS_PIN_TYPE_RAW_S: + /* Ensure the ScaledPIFCONV cropped resolution + * matches the RAW_S output pin resolution + */ + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_SCALED].bottom_offset == + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_SCALED].top_offset + + (int)stream_cfg->output_pins[i].output_res.height, EINVAL); + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_SCALED].right_offset == + stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_POST_ISA_SCALED].left_offset + + (int)stream_cfg->output_pins[i].output_res.width, EINVAL); + /* Ensure the ISAPF cropped resolution bounds + * the Scaled ISA output resolution before the + * ScaledPIFCONV cropping, since only IDS can + * modify the resolution, and this only to + * make it smaller + */ + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].bottom_offset >= + stream_cfg->crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].top_offset + + (int)stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED].height, + EINVAL); + verifret(stream_cfg-> + crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].right_offset >= + stream_cfg->crop[IA_CSS_ISYS_CROPPING_LOCATION_PRE_ISA].left_offset + + (int)stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED].width, + EINVAL); + /* Ensure the Scaled ISA output resolution + * before the ScaledPIFCONV cropping bounds + * the RAW_S pin output resolution since + * padding is not supported + */ + verifret(stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED].height >= + stream_cfg->output_pins[i].output_res.height, EINVAL); + verifret(stream_cfg-> + isa_cfg.isa_res[IA_CSS_ISYS_RESOLUTION_INFO_POST_ISA_SCALED].width >= + stream_cfg->output_pins[i].output_res.width, EINVAL); + break; + default: + break; + } + } + } + + /* open 1 send queue/stream and a single receive queue + * if not existing + */ + retval = ia_css_syscom_send_port_open(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(retval != FW_ERROR_BUSY, EBUSY); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_OPEN; + retval = ia_css_isys_constr_fw_stream_cfg(ctx, stream_handle, + &stream_cfg_fw, &buf_stream_cfg_id, stream_cfg); + verifret(retval == 0, retval); + token.payload = stream_cfg_fw; + token.buf_handle = HOST_ADDRESS(buf_stream_cfg_id); + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + ctx->stream_nof_output_pins[stream_handle] = + stream_cfg->nof_output_pins; + ctx->stream_state_array[stream_handle] = + IA_CSS_ISYS_STREAM_STATE_OPENED; + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_OPEN" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_STREAM_OPEN\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_close() - close virtual stream + */ +int ia_css_isys_stream_close( + HANDLE context, + const unsigned int stream_handle) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct send_queue_token token; + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_CLOSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_STREAM_CLOSE\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_OPENED, EPERM); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_CLOSE; + token.stream_id = stream_handle; + token.payload = 0; + token.buf_handle = 0; + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + /* close 1 send queue/stream and the single receive queue + * if none is using it + */ + retval = ia_css_syscom_send_port_close(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + + ctx->stream_state_array[stream_handle] = IA_CSS_ISYS_STREAM_STATE_IDLE; + /* Printing "LEAVE IA_CSS_ISYS_STREAM_CLOSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_STREAM_CLOSE\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_start() - starts handling a mipi virtual stream + */ +int ia_css_isys_stream_start( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_frame_buff_set *next_frame) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct send_queue_token token; + ia_css_shared_buffer_css_address next_frame_fw = 0; + ia_css_shared_buffer buf_next_frame_id = (ia_css_shared_buffer)NULL; + + /* Printing "ENTRY IA_CSS_ISYS_STREAM_START" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_STREAM_START\n"); + + verifret(ctx, EFAULT); + + /* Printing frame configuration and device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); + print_isys_frame_buff_set(next_frame, + ctx->stream_nof_output_pins[stream_handle]); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_OPENED, EPERM); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + if (next_frame != NULL) { + token.send_type = + IA_CSS_ISYS_SEND_TYPE_STREAM_START_AND_CAPTURE; + retval = ia_css_isys_constr_fw_next_frame(ctx, stream_handle, + &next_frame_fw, &buf_next_frame_id, next_frame); + verifret(retval == 0, retval); + token.payload = next_frame_fw; + token.buf_handle = HOST_ADDRESS(buf_next_frame_id); + } else { + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_START; + token.payload = 0; + token.buf_handle = 0; + } + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + ctx->stream_state_array[stream_handle] = + IA_CSS_ISYS_STREAM_STATE_STARTED; + /* Printing "LEAVE IA_CSS_ISYS_STREAM_START" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_STREAM_START\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_stop() - Stops a mipi virtual stream + */ +int ia_css_isys_stream_stop( + HANDLE context, + const unsigned int stream_handle) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct send_queue_token token; + + /* Printing "ENTRY IA_CSS_ISYS_STREAM_STOP" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_STREAM_STOP\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_STARTED, EPERM); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_DEV_SEND_QUEUES)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_STOP; + token.stream_id = stream_handle; + token.payload = 0; + token.buf_handle = 0; + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_DEV_SEND_QUEUES), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + ctx->stream_state_array[stream_handle] = + IA_CSS_ISYS_STREAM_STATE_OPENED; + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_STOP" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_STREAM_STOP\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_flush() - stops a mipi virtual stream but + * completes processing cmd backlog + */ +int ia_css_isys_stream_flush( + HANDLE context, + const unsigned int stream_handle) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct send_queue_token token; + + /* Printing "ENTRY IA_CSS_ISYS_STREAM_FLUSH" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_STREAM_FLUSH\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_STARTED, EPERM); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_FLUSH; + token.payload = 0; + token.buf_handle = 0; + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + ctx->stream_state_array[stream_handle] = + IA_CSS_ISYS_STREAM_STATE_OPENED; + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_FLUSH" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_STREAM_FLUSH\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_capture_indication() + * - captures "next frame" on stream_handle + */ +int ia_css_isys_stream_capture_indication( + HANDLE context, + const unsigned int stream_handle, + const struct ia_css_isys_frame_buff_set *next_frame) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct send_queue_token token; + ia_css_shared_buffer_css_address next_frame_fw = 0; + ia_css_shared_buffer buf_next_frame_id = (ia_css_shared_buffer)NULL; + + /* Printing "ENTRY IA_CSS_ISYS_STREAM_CAPTURE_INDICATION" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "ENTRY IA_CSS_ISYS_STREAM_CAPTURE_INDICATION\n"); + + verifret(ctx, EFAULT); + + /* Printing frame configuration and device handle context information + *if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); + print_isys_frame_buff_set(next_frame, + ctx->stream_nof_output_pins[stream_handle]); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(stream_handle < STREAM_ID_MAX, EINVAL); + verifret(stream_handle < + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG], EINVAL); + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_STARTED, EPERM); + verifret(next_frame != NULL, EFAULT); + + packets = ia_css_syscom_send_port_available(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle)); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + { + token.send_type = IA_CSS_ISYS_SEND_TYPE_STREAM_CAPTURE; + retval = ia_css_isys_constr_fw_next_frame(ctx, stream_handle, + &next_frame_fw, &buf_next_frame_id, next_frame); + verifret(retval == 0, retval); + token.payload = next_frame_fw; + token.buf_handle = HOST_ADDRESS(buf_next_frame_id); + } + retval = ia_css_syscom_send_port_transfer(ctx->sys, + (BASE_MSG_SEND_QUEUES + stream_handle), &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_CAPTURE_INDICATION" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "LEAVE IA_CSS_ISYS_STREAM_CAPTURE_INDICATION\n"); + + return 0; +} + + +/** + * ia_css_isys_stream_handle_response() - handle ISYS responses + */ +int ia_css_isys_stream_handle_response( + HANDLE context, + struct ia_css_isys_resp_info *received_response) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + int packets; + struct resp_queue_token token; + + /* Printing "ENTRY IA_CSS_ISYS_STREAM_HANDLE_RESPONSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "ENTRY IA_CSS_ISYS_STREAM_HANDLE_RESPONSE\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + verifret(received_response != NULL, EFAULT); + + packets = ia_css_syscom_recv_port_available( + ctx->sys, BASE_MSG_RECV_QUEUES); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + + retval = ia_css_syscom_recv_port_transfer( + ctx->sys, BASE_MSG_RECV_QUEUES, &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + retval = ia_css_isys_extract_fw_response( + ctx, &token, received_response); + verifret(retval == 0, retval); + + /* Printing received response information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_isys_resp_info(received_response); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + + verifret(received_response->type < N_IA_CSS_ISYS_RESP_TYPE, EINVAL); + verifret(received_response->stream_handle < STREAM_ID_MAX, EINVAL); + + if (received_response->type == IA_CSS_ISYS_RESP_TYPE_PIN_DATA_READY || + received_response->type == IA_CSS_ISYS_RESP_TYPE_PIN_DATA_WATERMARK || + received_response->type == IA_CSS_ISYS_RESP_TYPE_PIN_DATA_SKIPPED) { + verifret(received_response->pin.addr != 0, EFAULT); + verifret(received_response->pin.out_buf_id != 0, EFAULT); + verifret(received_response->pin_id < + ctx->stream_nof_output_pins[received_response->stream_handle], + EINVAL); + } + + /* Printing "LEAVE IA_CSS_ISYS_STREAM_HANDLE_RESPONSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "LEAVE IA_CSS_ISYS_STREAM_HANDLE_RESPONSE\n"); + + return 0; +} + + +/** + * ia_css_isys_device_close() - close ISYS device + */ +static int isys_context_destroy(HANDLE context) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + unsigned int stream_handle; + unsigned int queue_id; + unsigned int nof_recv_queues; + int retval = 0; + + /* Printing "ENTRY IA_CSS_ISYS_DEVICE_CLOSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY isys_context_destroy\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_READY, EPERM); +#endif /* VERIFY_DEVSTATE */ + + nof_recv_queues = ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_MSG] + + ctx->num_recv_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY]; + /* Close the ports for all the recv queues (MSG and PROXY) */ + for (queue_id = 0; queue_id < nof_recv_queues; queue_id++) { + retval = ia_css_syscom_recv_port_close( + ctx->sys, queue_id); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + } + + /* Close the ports for PROXY send queue(s) */ + for (queue_id = 0; + queue_id < ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_PROXY] + + ctx->num_send_queues[IA_CSS_ISYS_QUEUE_TYPE_DEV]; + queue_id++) { + retval = ia_css_syscom_send_port_close( + ctx->sys, queue_id); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval == 0, EINVAL); + } + + for (stream_handle = 0; stream_handle < STREAM_ID_MAX; + stream_handle++) { + verifret(ctx->stream_state_array[stream_handle] == + IA_CSS_ISYS_STREAM_STATE_IDLE, EPERM); + } + + retval = ia_css_syscom_close(ctx->sys); + verifret(retval == 0, EBUSY); + +#if (VERIFY_DEVSTATE != 0) + ctx->dev_state = IA_CSS_ISYS_DEVICE_STATE_CONFIGURED; +#endif /* VERIFY_DEVSTATE */ + + /* Printing "LEAVE IA_CSS_ISYS_DEVICE_CLOSE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE isys_context_destroy\n"); + + return 0; +} +/** + * ia_css_isys_device_close() - close ISYS device + */ +#if HAS_DUAL_CMD_CTX_SUPPORT +int ia_css_isys_context_destroy(HANDLE context) +{ + return isys_context_destroy(context); +} + +void ia_css_isys_device_close(void) +{ + /* Created for legacy, nothing to perform here */ +} + +#else +int ia_css_isys_device_close(HANDLE context) +{ + return isys_context_destroy(context); +} +#endif + +/** + * ia_css_isys_device_release() - release ISYS device + */ +int ia_css_isys_device_release(HANDLE context, unsigned int force) +{ + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + int retval = 0; + + /* Printing "ENTRY IA_CSS_ISYS_DEVICE_RELEASE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_DEVICE_RELEASE\n"); + + verifret(ctx, EFAULT); + + /* Printing device handle context information + * if tracing level = VERBOSE. + */ +#if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + print_handle_context(ctx); +#endif /* ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG */ + +#if (VERIFY_DEVSTATE != 0) + verifret(ctx->dev_state == IA_CSS_ISYS_DEVICE_STATE_CONFIGURED, EPERM); +#endif /* VERIFY_DEVSTATE */ + + retval = ia_css_syscom_release(ctx->sys, force); + verifret(retval == 0, EBUSY); + + /* If ia_css_isys_device_release called with force==1, this should + * happen after timeout, so no active transfers + * If ia_css_isys_device_release called with force==0, this should + * happen after SP has gone idle, so no active transfers + */ + ia_css_isys_force_unmap_comm_buff_queue(ctx); + ia_css_isys_destr_comm_buff_queue(ctx); + +#if (VERIFY_DEVSTATE != 0) + ctx->dev_state = IA_CSS_ISYS_DEVICE_STATE_IDLE; +#endif /* VERIFY_DEVSTATE */ + + ia_css_cpu_mem_free(ctx); + + /* Printing "LEAVE IA_CSS_ISYS_DEVICE_RELEASE" message + * if tracing level = VERBOSE. + */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_DEVICE_RELEASE\n"); + + return 0; +} + +/** + * ia_css_isys_proxy_write_req() - send ISYS proxy write requests + */ +int ia_css_isys_proxy_write_req( + HANDLE context, + const struct ia_css_proxy_write_req_val *write_req_val) +{ + + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + struct proxy_send_queue_token token; + int packets; + int retval = 0; + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ENTRY IA_CSS_ISYS_PROXY_WRITE_REQ\n"); + verifret(ctx, EFAULT); + verifret(write_req_val != NULL, EFAULT); + + packets = ia_css_syscom_send_port_available(ctx->sys, 0); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + + token.request_id = write_req_val->request_id; + token.region_index = write_req_val->region_index; + token.offset = write_req_val->offset; + token.value = write_req_val->value; + + retval = ia_css_syscom_send_port_transfer(ctx->sys, 0, &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "LEAVE IA_CSS_ISYS_PROXY_WRITE_REQ\n"); + + return 0; +} + +/** + * ia_css_isys_proxy_handle_write_response() - handle ISYS proxy responses + */ +int ia_css_isys_proxy_handle_write_response( + HANDLE context, + struct ia_css_proxy_write_req_resp *received_response) +{ + + struct ia_css_isys_context *ctx = (struct ia_css_isys_context *)context; + struct proxy_resp_queue_token token; + int retval = 0; + int packets; + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "ENTRY IA_CSS_ISYS_PROXY_HANDLE_WRITE_RESPONSE\n"); + verifret(ctx, EFAULT); + verifret(received_response != NULL, EFAULT); + + packets = ia_css_syscom_recv_port_available(ctx->sys, 0); + verifret(packets != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(packets >= 0, EINVAL); + verifret(packets > 0, EPERM); + + retval = ia_css_syscom_recv_port_transfer(ctx->sys, 0, &token); + verifret(retval != FW_ERROR_BAD_ADDRESS, EFAULT); + verifret(retval >= 0, EINVAL); + + + retval = ia_css_isys_extract_proxy_response(&token, received_response); + verifret(retval == 0, retval); + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "LEAVE IA_CSS_ISYS_PROXY_HANDLE_WRITE_RESPONSE\n"); + + return 0; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_public_trace.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_public_trace.c new file mode 100644 index 0000000000000..660bcc62da3c0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_public_trace.c @@ -0,0 +1,379 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_isysapi_trace.h" +#include "ia_css_isys_public_trace.h" +#include "ia_css_isysapi_types.h" +#include "ia_css_isysapi.h" +#include "ia_css_isys_private.h" +#include "error_support.h" +#include "ia_css_syscom.h" + +/** + * print_handle_context - formatted print function for + * struct ia_css_isys_context *ctx variable + */ +int print_handle_context(struct ia_css_isys_context *ctx) +{ + unsigned int i; + + verifret(ctx != NULL, EFAULT); + /* Print ctx->(ssid, mmid, dev_state) */ + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "Print ia_css_isys_context *ctx\n" + "-------------------------------------------------------\n"); + IA_CSS_TRACE_3(ISYSAPI, VERBOSE, + "\tia_css_isys_context->ssid = %d\n" + "\t\t\tia_css_isys_context->mmid = %d\n" + "\t\t\tia_css_isys_context->device_state = %d\n" + , ctx->ssid + , ctx->mmid + , ctx->dev_state); + /* Print ctx->(stream_state_array, stream_nof_output_pins) */ + for (i = 0; i < STREAM_ID_MAX; i++) { + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_context->stream_state[i = %d] = %d\n" + "\t\t\tia_css_isys_context->stream_nof_output_pins[i = %d] = %d\n" + , i + , ctx->stream_state_array[i] + , i + , ctx->stream_nof_output_pins[i]); + } + /* Print ctx->ia_css_syscom_context */ + IA_CSS_TRACE_1(ISYSAPI, VERBOSE, + "\tia_css_isys_context->ia_css_syscom_context = %p\n" + , (struct ia_css_syscom_context *)(ctx->sys)); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "-------------------------------------------------------\n"); + return 0; +} + +/** + * print_device_config_data - formatted print function for + * struct ia_css_isys_device_cfg_data *config variable + */ +int print_device_config_data(const struct ia_css_isys_device_cfg_data *config) +{ + verifret(config != NULL, EFAULT); + IA_CSS_TRACE_0(ISYSAPI, + VERBOSE, + "Print ia_css_isys_device_cfg_data *config\n" + "-------------------------------------------------------\n"); + IA_CSS_TRACE_7(ISYSAPI, + VERBOSE, + "\tia_css_isys_device_cfg_data->driver_sys.ssid = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_sys.mmid = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_sys.num_send_queues = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_sys.num_recv_queues = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_sys.send_queue_size = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_sys.recv_queue_size = %d\n" + "\t\t\tia_css_isys_device_cfg_data->driver_proxy.proxy_write_queue_size = %d\n", + config->driver_sys.ssid, + config->driver_sys.mmid, + config->driver_sys.num_send_queues, + config->driver_sys.num_recv_queues, + config->driver_sys.send_queue_size, + config->driver_sys.recv_queue_size, + config->driver_proxy.proxy_write_queue_size); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "-------------------------------------------------------\n"); + return 0; +} + +/** + * print_stream_config_data - formatted print function for + * ia_css_isys_stream_cfg_data stream_cfg variable + */ +int print_stream_config_data( + const struct ia_css_isys_stream_cfg_data *stream_cfg) +{ + unsigned int i; + + verifret(stream_cfg != NULL, EFAULT); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "Print ia_css_isys_stream_cfg_data stream_cfg\n" + "-------------------------------------------------------\n"); + IA_CSS_TRACE_5(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_isl_use = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_stream_source = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_mipi_vc = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->nof_input_pins = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->nof_output_pins = %d\n" + , stream_cfg->isl_use + , stream_cfg->src + , stream_cfg->vc + , stream_cfg->nof_input_pins + , stream_cfg->nof_output_pins); + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->send_irq_sof_discarded = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->send_irq_eof_discarded = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->send_resp_sof_discarded = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->send_resp_eof_discarded = %d\n" + , stream_cfg->send_irq_sof_discarded + , stream_cfg->send_irq_eof_discarded + , stream_cfg->send_resp_sof_discarded + , stream_cfg->send_resp_eof_discarded); + for (i = 0; i < stream_cfg->nof_input_pins; i++) { + IA_CSS_TRACE_6(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_input_pin_info[i = %d].ia_css_isys_mipi_data_type = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_input_pin_info[i = %d].ia_css_isys_resolution.width = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_input_pin_info[i = %d].ia_css_isys_resolution.height = %d\n" + , i + , stream_cfg->input_pins[i].dt + , i + , stream_cfg->input_pins[i].input_res.width + , i + , stream_cfg->input_pins[i].input_res.height); + IA_CSS_TRACE_2(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_input_pin_info[i = %d].ia_css_isys_mipi_store_mode = %d\n" + , i + , stream_cfg->input_pins[i].mipi_store_mode); + } + for (i = 0; i < N_IA_CSS_ISYS_CROPPING_LOCATION; i++) { + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_cropping[i = %d].top_offset = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_cropping[i = %d].left_offset = %d\n" + , i + , stream_cfg->crop[i].top_offset + , i + , stream_cfg->crop[i].left_offset); + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_cropping[i = %d].bottom_offset = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_cropping[i = %d].right_offset = %d\n" + , i + , stream_cfg->crop[i].bottom_offset + , i + , stream_cfg->crop[i].right_offset); + } + for (i = 0; i < stream_cfg->nof_output_pins; i++) { + IA_CSS_TRACE_6(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].ia_css_isys_pin_type = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].ia_css_isys_frame_format_type = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].input_pin_id = %d\n" + , i + , stream_cfg->output_pins[i].pt + , i + , stream_cfg->output_pins[i].ft + , i + , stream_cfg->output_pins[i].input_pin_id); + IA_CSS_TRACE_6(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].watermark_in_lines = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].send_irq = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].stride = %d\n" + , i + , stream_cfg->output_pins[i].watermark_in_lines + , i + , stream_cfg->output_pins[i].send_irq + , i + , stream_cfg->output_pins[i].stride); + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].ia_css_isys_resolution.width = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_output_pin_info[i = %d].ia_css_isys_resolution.height = %d\n" + , i + , stream_cfg->output_pins[i].output_res.width + , i + , stream_cfg->output_pins[i].output_res.height); + } + for (i = 0; i < N_IA_CSS_ISYS_RESOLUTION_INFO; i++) { + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.ia_css_isys_resolution[i = %d].width = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.ia_css_isys_resolution[i = %d].height = %d\n" + , i + , stream_cfg->isa_cfg.isa_res[i].width + , i + , stream_cfg->isa_cfg.isa_res[i].height); + } + IA_CSS_TRACE_7(ISYSAPI, VERBOSE, + "\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.blc_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.lsc_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.dpc_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.downscaler_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.awb_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.af_enabled = %d\n" + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.ae_enabled = %d\n" + , stream_cfg->isa_cfg.blc_enabled + , stream_cfg->isa_cfg.lsc_enabled + , stream_cfg->isa_cfg.dpc_enabled + , stream_cfg->isa_cfg.downscaler_enabled + , stream_cfg->isa_cfg.awb_enabled + , stream_cfg->isa_cfg.af_enabled + , stream_cfg->isa_cfg.ae_enabled); + + IA_CSS_TRACE_1(ISYSAPI, VERBOSE, + "\t\t\tia_css_isys_stream_cfg_data->ia_css_isys_isa_cfg.paf_type = %d\n" + , stream_cfg->isa_cfg.paf_type); + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "-------------------------------------------------------\n"); + return 0; +} + +/** + * print_isys_frame_buff_set - formatted print function for + * struct ia_css_isys_frame_buff_set *next_frame variable + */ +int print_isys_frame_buff_set( + const struct ia_css_isys_frame_buff_set *next_frame, + const unsigned int nof_output_pins) +{ + unsigned int i; + + verifret(next_frame != NULL, EFAULT); + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "Print ia_css_isys_frame_buff_set *next_frame\n" + "-------------------------------------------------------\n"); + for (i = 0; i < nof_output_pins; i++) { + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_frame_buff_set->ia_css_isys_output_pin_payload[i = %d].ia_css_return_token = %016lxu\n" + "\t\t\tia_css_isys_frame_buff_set->ia_css_isys_output_pin_payload[i = %d].ia_css_input_buffer_css_address = %08xu\n" + , i + , (unsigned long) + next_frame->output_pins[i].out_buf_id + , i + , next_frame->output_pins[i].addr); + } + IA_CSS_TRACE_2(ISYSAPI, VERBOSE, + "\tia_css_isys_frame_buff_set->process_group_light.ia_css_return_token = %016lxu\n" + "\t\t\tia_css_isys_frame_buff_set->process_group_light.ia_css_input_buffer_css_address = %08xu\n" + , (unsigned long) + next_frame->process_group_light.param_buf_id + , next_frame->process_group_light.addr); + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_frame_buff_set->send_irq_sof = %d\n" + "\t\t\tia_css_isys_frame_buff_set->send_irq_eof = %d\n" + "\t\t\tia_css_isys_frame_buff_set->send_resp_sof = %d\n" + "\t\t\tia_css_isys_frame_buff_set->send_resp_eof = %d\n" + , (int) next_frame->send_irq_sof + , (int) next_frame->send_irq_eof + , (int) next_frame->send_resp_sof + , (int) next_frame->send_resp_eof); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "-------------------------------------------------------\n"); + return 0; +} + +/** + * print_isys_resp_info - formatted print function for + * struct ia_css_isys_frame_buff_set *next_frame variable + */ +int print_isys_resp_info(struct ia_css_isys_resp_info *received_response) +{ + verifret(received_response != NULL, EFAULT); + + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, "ISYS_RESPONSE_INFO\n" + "-------------------------------------------------------\n"); + switch (received_response->type) { + case IA_CSS_ISYS_RESP_TYPE_STREAM_OPEN_DONE: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_OPEN_DONE\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_START_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_START_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_STOP_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_STOP_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_FLUSH_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_FLUSH_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_CLOSE_ACK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_CLOSE_ACK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_PIN_DATA_READY: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_PIN_DATA_READY\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_PIN_DATA_WATERMARK: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_PIN_DATA_WATERMARK\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_FRAME_SOF: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_FRAME_SOF\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_FRAME_EOF: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_FRAME_EOF\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_DONE: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_DONE\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_PIN_DATA_SKIPPED: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_PIN_DATA_SKIPPED\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_SKIPPED: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_STREAM_CAPTURE_SKIPPED\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_FRAME_SOF_DISCARDED: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_FRAME_SOF_DISCARDED\n"); + break; + case IA_CSS_ISYS_RESP_TYPE_FRAME_EOF_DISCARDED: + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = IA_CSS_ISYS_RESP_TYPE_FRAME_EOF_DISCARDED\n"); + break; + default: + IA_CSS_TRACE_0(ISYSAPI, ERROR, + "\tia_css_isys_resp_info.ia_css_isys_resp_type = INVALID\n"); + break; + } + + IA_CSS_TRACE_4(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.type = %d\n" + "\t\t\tia_css_isys_resp_info.stream_handle = %d\n" + "\t\t\tia_css_isys_resp_info.time_stamp[0] = %d\n" + "\t\t\tia_css_isys_resp_info.time_stamp[1] = %d\n", + received_response->type, + received_response->stream_handle, + received_response->timestamp[0], + received_response->timestamp[1]); + IA_CSS_TRACE_7(ISYSAPI, VERBOSE, + "\tia_css_isys_resp_info.error = %d\n" + "\t\t\tia_css_isys_resp_info.error_details = %d\n" + "\t\t\tia_css_isys_resp_info.pin.out_buf_id = %016llxu\n" + "\t\t\tia_css_isys_resp_info.pin.addr = %016llxu\n" + "\t\t\tia_css_isys_resp_info.pin_id = %d\n" + "\t\t\tia_css_isys_resp_info.frame_counter = %d\n," + "\t\t\tia_css_isys_resp_info.written_direct = %d\n", + received_response->error, + received_response->error_details, + (unsigned long long)received_response->pin.out_buf_id, + (unsigned long long)received_response->pin.addr, + received_response->pin_id, + received_response->frame_counter, + received_response->written_direct); + IA_CSS_TRACE_0(ISYSAPI, VERBOSE, + "------------------------------------------------------\n"); + + return 0; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_public_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_public_trace.h new file mode 100644 index 0000000000000..5b6508058fd6e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isys_public_trace.h @@ -0,0 +1,55 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYS_PUBLIC_TRACE_H +#define __IA_CSS_ISYS_PUBLIC_TRACE_H + +#include "ia_css_isysapi_trace.h" + +#include "ia_css_isysapi_types.h" + +#include "ia_css_isysapi.h" + +#include "ia_css_isys_private.h" +/** + * print_handle_context - formatted print function for + * struct ia_css_isys_context *ctx variable + */ +int print_handle_context(struct ia_css_isys_context *ctx); + +/** + * print_device_config_data - formatted print function for + * struct ia_css_isys_device_cfg_data *config variable + */ +int print_device_config_data(const struct ia_css_isys_device_cfg_data *config); +/** + * print_stream_config_data - formatted print function for + * ia_css_isys_stream_cfg_data stream_cfg variable + */ +int print_stream_config_data( + const struct ia_css_isys_stream_cfg_data *stream_cfg); +/** + * print_isys_frame_buff_set - formatted print function for + * struct ia_css_isys_frame_buff_set *next_frame variable + */ +int print_isys_frame_buff_set( + const struct ia_css_isys_frame_buff_set *next_frame, + const unsigned int nof_output_pins); +/** + * print_isys_isys_resp_info - formatted print function for + * struct ia_css_isys_frame_buff_set *next_frame variable + */ +int print_isys_resp_info(struct ia_css_isys_resp_info *received_response); + +#endif /* __IA_CSS_ISYS_PUBLIC_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isysapi_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isysapi_trace.h new file mode 100644 index 0000000000000..c6b944f245b11 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/isysapi/src/ia_css_isysapi_trace.h @@ -0,0 +1,79 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_ISYSAPI_TRACE_H +#define __IA_CSS_ISYSAPI_TRACE_H + +#include "ia_css_trace.h" + +#define ISYSAPI_TRACE_LOG_LEVEL_OFF 0 +#define ISYSAPI_TRACE_LOG_LEVEL_NORMAL 1 +#define ISYSAPI_TRACE_LOG_LEVEL_DEBUG 2 + +/* ISYSAPI and all the submodules in ISYSAPI will have + * the default tracing level set to this level + */ +#define ISYSAPI_TRACE_CONFIG_DEFAULT ISYSAPI_TRACE_LOG_LEVEL_NORMAL + +/* In case ISYSAPI_TRACE_CONFIG is not defined, set it to default level */ +#if !defined(ISYSAPI_TRACE_CONFIG) + #define ISYSAPI_TRACE_CONFIG ISYSAPI_TRACE_CONFIG_DEFAULT +#endif + +/* ISYSAPI Module tracing backend is mapped to + * TUNIT tracing for target platforms + */ +#ifdef IA_CSS_TRACE_PLATFORM_CELL + #ifndef HRT_CSIM + #define ISYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_TRACE + #else + #define ISYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + #endif +#else + #define ISYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#endif + +#if (defined(ISYSAPI_TRACE_CONFIG)) + /* TRACE_OFF */ + #if ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_OFF + #define ISYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED + /* TRACE_NORMAL */ + #elif ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_NORMAL + #define ISYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED + #define ISYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED + /* TRACE_DEBUG */ + #elif ISYSAPI_TRACE_CONFIG == ISYSAPI_TRACE_LOG_LEVEL_DEBUG + #define ISYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_ENABLED + #define ISYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No ISYSAPI_TRACE_CONFIG Tracing level defined" + #endif +#else + #error "ISYSAPI_TRACE_CONFIG not defined" +#endif + +#endif /* __IA_CSS_ISYSAPI_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir.h new file mode 100644 index 0000000000000..a284d74bb4a67 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir.h @@ -0,0 +1,99 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_H +#define __IA_CSS_PKG_DIR_H + +#include "ia_css_pkg_dir_storage_class.h" +#include "ia_css_pkg_dir_types.h" +#include "type_support.h" + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +const ia_css_pkg_dir_entry_t *ia_css_pkg_dir_get_entry( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index +); + +/* User is expected to call the verify function manually, + * other functions do not call it internally + */ +IA_CSS_PKG_DIR_STORAGE_CLASS_H +int ia_css_pkg_dir_verify_header( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_get_num_entries( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_get_size_in_bytes( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +enum ia_css_pkg_dir_version ia_css_pkg_dir_get_version( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint16_t ia_css_pkg_dir_set_version( + ia_css_pkg_dir_entry_t *pkg_dir_header, + enum ia_css_pkg_dir_version version +); + + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_address_lo( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_address_hi( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_size( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint16_t ia_css_pkg_dir_entry_get_version( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint8_t ia_css_pkg_dir_entry_get_type( + const ia_css_pkg_dir_entry_t *entry +); + +/* Get the address of the specified entry in the PKG_DIR + * Note: This function expects the complete PKG_DIR in the same memory space + * and the entries contains offsets and not addresses. + */ +IA_CSS_PKG_DIR_STORAGE_CLASS_H +void *ia_css_pkg_dir_get_entry_address( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index +); + +#ifdef __IA_CSS_PKG_DIR_INLINE__ + +#include "ia_css_pkg_dir_impl.h" + +#endif + +#endif /* __IA_CSS_PKG_DIR_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_iunit.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_iunit.h new file mode 100644 index 0000000000000..ad194b0389eb7 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_iunit.h @@ -0,0 +1,46 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_IUNIT_H +#define __IA_CSS_PKG_DIR_IUNIT_H + +/* In bootflow, pkg_dir only supports upto 16 entries in pkg_dir + * pkg_dir_header + Psys_server pg + Isys_server pg + 13 Client pg + */ + +enum { + IA_CSS_PKG_DIR_SIZE = 16, + IA_CSS_PKG_DIR_ENTRIES = IA_CSS_PKG_DIR_SIZE - 1 +}; + +#define IUNIT_MAX_CLIENT_PKG_ENTRIES 13 + +/* Example assignment of unique identifiers for the FW components + * This should match the identifiers in the manifest + */ +enum ia_css_pkg_dir_entry_type { + IA_CSS_PKG_DIR_HEADER = 0, + IA_CSS_PKG_DIR_PSYS_SERVER_PG, + IA_CSS_PKG_DIR_ISYS_SERVER_PG, + IA_CSS_PKG_DIR_CLIENT_PG +}; + +/* Fixed entries in the package directory */ +enum ia_css_pkg_dir_index { + IA_CSS_PKG_DIR_PSYS_INDEX = 0, + IA_CSS_PKG_DIR_ISYS_INDEX = 1, + IA_CSS_PKG_DIR_CLIENT_0 = 2 +}; + +#endif /* __IA_CSS_PKG_DIR_IUNIT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_storage_class.h new file mode 100644 index 0000000000000..cb64172151f92 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_storage_class.h @@ -0,0 +1,29 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_STORAGE_CLASS_H +#define __IA_CSS_PKG_DIR_STORAGE_CLASS_H + + +#include "storage_class.h" + +#ifndef __IA_CSS_PKG_DIR_INLINE__ +#define IA_CSS_PKG_DIR_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PKG_DIR_STORAGE_CLASS_C +#else +#define IA_CSS_PKG_DIR_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PKG_DIR_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PKG_DIR_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_types.h new file mode 100644 index 0000000000000..b024b3da2f9e6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/interface/ia_css_pkg_dir_types.h @@ -0,0 +1,41 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_TYPES_H +#define __IA_CSS_PKG_DIR_TYPES_H + +#include "type_support.h" + +struct ia_css_pkg_dir_entry { + uint32_t address[2]; + uint32_t size; + uint16_t version; + uint8_t type; + uint8_t unused; +}; + +typedef void ia_css_pkg_dir_t; +typedef struct ia_css_pkg_dir_entry ia_css_pkg_dir_entry_t; + +/* The version field of the pkg_dir header defines + * if entries contain offsets or pointers + */ +/* This is temporary, until all pkg_dirs use pointers */ +enum ia_css_pkg_dir_version { + IA_CSS_PKG_DIR_POINTER, + IA_CSS_PKG_DIR_OFFSET +}; + + +#endif /* __IA_CSS_PKG_DIR_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/pkg_dir.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/pkg_dir.mk new file mode 100644 index 0000000000000..32c8a68f3653c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/pkg_dir.mk @@ -0,0 +1,29 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PKG DIR + +PKG_DIR_DIR = $${MODULES_DIR}/pkg_dir +PKG_DIR_INTERFACE = $(PKG_DIR_DIR)/interface +PKG_DIR_SOURCES = $(PKG_DIR_DIR)/src + +PKG_DIR_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir.c +PKG_DIR_CPPFLAGS = -I$(PKG_DIR_INTERFACE) +PKG_DIR_CPPFLAGS += -I$(PKG_DIR_SOURCES) +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/../isp/kernels/io_ls/common +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/fw_abi_common_types/ipu +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/fw_abi_common_types/ipu/$(FW_ABI_IPU_TYPES_VERSION) + +PKG_DIR_CREATE_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir_create.c +PKG_DIR_UPDATE_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir_update.c diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/src/ia_css_pkg_dir.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/src/ia_css_pkg_dir.c new file mode 100644 index 0000000000000..348b56833e060 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/src/ia_css_pkg_dir.c @@ -0,0 +1,27 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifdef __IA_CSS_PKG_DIR_INLINE__ + +#include "storage_class.h" + +STORAGE_CLASS_INLINE int __ia_css_pkg_dir_avoid_warning_on_empty_file(void) +{ + return 0; +} + +#else +#include "ia_css_pkg_dir_impl.h" + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/src/ia_css_pkg_dir_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/src/ia_css_pkg_dir_impl.h new file mode 100644 index 0000000000000..d5067d21398f9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/src/ia_css_pkg_dir_impl.h @@ -0,0 +1,201 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_IMPL_H +#define __IA_CSS_PKG_DIR_IMPL_H + +#include "ia_css_pkg_dir.h" +#include "ia_css_pkg_dir_int.h" +#include "error_support.h" +#include "type_support.h" +#include "assert_support.h" + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +const ia_css_pkg_dir_entry_t *ia_css_pkg_dir_get_entry( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index) +{ + DECLARE_ERRVAL + struct ia_css_pkg_dir_entry *pkg_dir_header = NULL; + + verifexitval(pkg_dir != NULL, EFAULT); + + pkg_dir_header = (struct ia_css_pkg_dir_entry *)pkg_dir; + + /* First entry of the structure is the header, skip that */ + index++; + verifexitval(index < pkg_dir_header->size, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + return NULL; + } + return &(pkg_dir_header[index]); +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +int ia_css_pkg_dir_verify_header(const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + verifexitval(pkg_dir_header != NULL, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + return -1; + } + return ((pkg_dir_header->address[0] == PKG_DIR_MAGIC_VAL_0) + && (pkg_dir_header->address[1] == PKG_DIR_MAGIC_VAL_1)) ? + 0 : -1; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_get_num_entries( + const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + uint32_t size = 0; + + verifexitval(pkg_dir_header != NULL, EFAULT); + size = pkg_dir_header->size; + verifexitval(size > 0, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return size - 1; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +enum ia_css_pkg_dir_version +ia_css_pkg_dir_get_version(const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + assert(pkg_dir_header != NULL); + return pkg_dir_header->version; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint16_t ia_css_pkg_dir_set_version(ia_css_pkg_dir_entry_t *pkg_dir_header, + enum ia_css_pkg_dir_version version) +{ + DECLARE_ERRVAL + + verifexitval(pkg_dir_header != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 1; + } + pkg_dir_header->version = version; + return 0; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_get_size_in_bytes( + const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + + verifexitval(pkg_dir_header != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return sizeof(struct ia_css_pkg_dir_entry) * pkg_dir_header->size; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_address_lo( + const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->address[0]; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_address_hi( + const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->address[1]; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_size(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->size; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint16_t ia_css_pkg_dir_entry_get_version(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->version; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint8_t ia_css_pkg_dir_entry_get_type(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->type; +} + + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +void *ia_css_pkg_dir_get_entry_address(const ia_css_pkg_dir_t *pkg_dir, + uint32_t index) +{ + void *entry_blob = NULL; + const ia_css_pkg_dir_entry_t *pkg_dir_entry = + ia_css_pkg_dir_get_entry(pkg_dir, index-1); + + if ((pkg_dir_entry != NULL) && + (ia_css_pkg_dir_entry_get_size(pkg_dir_entry) > 0)) { + assert(ia_css_pkg_dir_entry_get_address_hi(pkg_dir_entry) == 0); + entry_blob = (void *)((char *)pkg_dir + + ia_css_pkg_dir_entry_get_address_lo(pkg_dir_entry)); + } + return entry_blob; +} + +#endif /* __IA_CSS_PKG_DIR_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/src/ia_css_pkg_dir_int.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/src/ia_css_pkg_dir_int.h new file mode 100644 index 0000000000000..203505fbee54e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/pkg_dir/src/ia_css_pkg_dir_int.h @@ -0,0 +1,49 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_INT_H +#define __IA_CSS_PKG_DIR_INT_H + +/* + * Package Dir structure as specified in CSE FAS + * + * PKG DIR Header + * Qword 63:56 55 54:48 47:32 31:24 23:0 + * 0 "_IUPKDR_" + * 1 Rsvd Rsvd Type Version Rsvd Size + * + * Version: Version of the Structure + * Size: Size of the entire table (including header) in 16 byte chunks + * Type: Must be 0 for header + * + * Figure 13: PKG DIR Header + * + * + * PKG DIR Entry + * Qword 63:56 55 54:48 47:32 31:24 23:0 + * N Address/Offset + * N+1 Rsvd Rsvd Type Version Rsvd Size + * + * Version: Version # of the Component + * Size: Size of the component in bytes + * Type: Component Identifier + */ + +#define PKG_DIR_SIZE_BITS 24 +#define PKG_DIR_TYPE_BITS 7 + +#define PKG_DIR_MAGIC_VAL_1 (('_' << 24) | ('I' << 16) | ('U' << 8) | 'P') +#define PKG_DIR_MAGIC_VAL_0 (('K' << 24) | ('D' << 16) | ('R' << 8) | '_') + +#endif /* __IA_CSS_PKG_DIR_INT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/port_env_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/port_env_struct.h new file mode 100644 index 0000000000000..4d39a4739a8b0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/port_env_struct.h @@ -0,0 +1,24 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PORT_ENV_STRUCT_H +#define __PORT_ENV_STRUCT_H + +struct port_env { + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; +}; + +#endif /* __PORT_ENV_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/queue.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/queue.h new file mode 100644 index 0000000000000..b233ab3baf014 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/queue.h @@ -0,0 +1,40 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __QUEUE_H +#define __QUEUE_H + +#include "queue_struct.h" +#include "port_env_struct.h" + +/* + * SYS queues are created by the host + * SYS queues cannot be accessed through the queue interface + * To send data into a queue a send_port must be opened. + * To receive data from a queue, a recv_port must be opened. + */ + +/* return required buffer size for queue */ +unsigned int +sys_queue_buf_size(unsigned int size, unsigned int token_size); + +/* + * initialize a queue that can hold at least 'size' tokens of + * 'token_size' bytes. + */ +void +sys_queue_init(struct sys_queue *q, unsigned int size, + unsigned int token_size, struct sys_queue_res *res); + +#endif /* __QUEUE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/queue_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/queue_struct.h new file mode 100644 index 0000000000000..ef48fcfded2b6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/queue_struct.h @@ -0,0 +1,47 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __QUEUE_STRUCT_H +#define __QUEUE_STRUCT_H + +/* queue description, shared between sender and receiver */ + +#include "type_support.h" + +#ifdef __VIED_CELL +typedef struct {uint32_t v[2]; } host_buffer_address_t; +#else +typedef uint64_t host_buffer_address_t; +#endif + +typedef uint32_t vied_buffer_address_t; + + +struct sys_queue { + host_buffer_address_t host_address; + vied_buffer_address_t vied_address; + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* reg no in subsystem's regmem */ + unsigned int rd_reg; + unsigned int _align; +}; + +struct sys_queue_res { + host_buffer_address_t host_address; + vied_buffer_address_t vied_address; + unsigned int reg; +}; + +#endif /* __QUEUE_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/recv_port.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/recv_port.h new file mode 100644 index 0000000000000..cce253b266687 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/recv_port.h @@ -0,0 +1,34 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __RECV_PORT_H +#define __RECV_PORT_H + + +struct recv_port; +struct sys_queue; +struct port_env; + +void +recv_port_open(struct recv_port *p, const struct sys_queue *q, + const struct port_env *env); + +unsigned int +recv_port_available(const struct recv_port *p); + +unsigned int +recv_port_transfer(const struct recv_port *p, void *data); + + +#endif /* __RECV_PORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/recv_port_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/recv_port_struct.h new file mode 100644 index 0000000000000..52ec563b13cf5 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/recv_port_struct.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __RECV_PORT_STRUCT_H +#define __RECV_PORT_STRUCT_H + +#include "buffer_type.h" + +struct recv_port { + buffer_address buffer; /* address of buffer in DDR */ + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* index of write pointer located in regmem */ + unsigned int rd_reg; /* index read pointer located in regmem */ + + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; /* address of memory containing regmem */ +}; + +#endif /* __RECV_PORT_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/send_port.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/send_port.h new file mode 100644 index 0000000000000..04a160f3f0199 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/send_port.h @@ -0,0 +1,52 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __SEND_PORT_H +#define __SEND_PORT_H + + +/* + * A send port can be used to send tokens into a queue. + * The interface can be used on any type of processor (host, SP, ...) + */ + +struct send_port; +struct sys_queue; +struct port_env; + +/* + * Open a send port on a queue. After the port is opened, tokens can be sent + */ +void +send_port_open(struct send_port *p, const struct sys_queue *q, + const struct port_env *env); + +/* + * Determine how many tokens can be sent + */ +unsigned int +send_port_available(const struct send_port *p); + +/* + * Send a token via a send port. The function returns the number of + * tokens that have been sent: + * 1: the token was accepted + * 0: the token was not accepted (full queue) + * The size of a token is determined at initialization. + */ +unsigned int +send_port_transfer(const struct send_port *p, const void *data); + + +#endif /* __SEND_PORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/send_port_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/send_port_struct.h new file mode 100644 index 0000000000000..f834c62bc3db6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/interface/send_port_struct.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __SEND_PORT_STRUCT_H +#define __SEND_PORT_STRUCT_H + +#include "buffer_type.h" + +struct send_port { + buffer_address buffer; + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* index of write pointer in regmem */ + unsigned int rd_reg; /* index of read pointer in regmem */ + + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; +}; + +#endif /* __SEND_PORT_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/port.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/port.mk new file mode 100644 index 0000000000000..b3801247802e9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/port.mk @@ -0,0 +1,31 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PORT + +PORT_DIR=$${MODULES_DIR}/port + +PORT_INTERFACE=$(PORT_DIR)/interface +PORT_SOURCES1=$(PORT_DIR)/src + +PORT_HOST_FILES += $(PORT_SOURCES1)/send_port.c +PORT_HOST_FILES += $(PORT_SOURCES1)/recv_port.c +PORT_HOST_FILES += $(PORT_SOURCES1)/queue.c + +PORT_HOST_CPPFLAGS += -I$(PORT_INTERFACE) + +PORT_FW_FILES += $(PORT_SOURCES1)/send_port.c +PORT_FW_FILES += $(PORT_SOURCES1)/recv_port.c + +PORT_FW_CPPFLAGS += -I$(PORT_INTERFACE) diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/src/queue.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/src/queue.c new file mode 100644 index 0000000000000..eeec99dfe2d0d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/src/queue.c @@ -0,0 +1,47 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "queue.h" + +#include "regmem_access.h" +#include "port_env_struct.h" + +unsigned int sys_queue_buf_size(unsigned int size, unsigned int token_size) +{ + return (size + 1) * token_size; +} + +void +sys_queue_init(struct sys_queue *q, unsigned int size, unsigned int token_size, + struct sys_queue_res *res) +{ + unsigned int buf_size; + + q->size = size + 1; + q->token_size = token_size; + buf_size = sys_queue_buf_size(size, token_size); + + /* acquire the shared buffer space */ + q->host_address = res->host_address; + res->host_address += buf_size; + q->vied_address = res->vied_address; + res->vied_address += buf_size; + + /* acquire the shared read and writer pointers */ + q->wr_reg = res->reg; + res->reg++; + q->rd_reg = res->reg; + res->reg++; + +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/src/recv_port.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/src/recv_port.c new file mode 100644 index 0000000000000..31b36e9ceafbb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/src/recv_port.c @@ -0,0 +1,95 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "recv_port.h" +#include "port_env_struct.h" /* for port_env */ +#include "queue_struct.h" /* for sys_queue */ +#include "recv_port_struct.h" /* for recv_port */ +#include "buffer_access.h" /* for buffer_load, buffer_address */ +#include "regmem_access.h" /* for regmem_load_32, regmem_store_32 */ +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "math_support.h" /* for OP_std_modadd */ +#include "type_support.h" /* for HOST_ADDRESS */ + +#ifndef __VIED_CELL +#include "cpu_mem_support.h" /* for ia_css_cpu_mem_cache_invalidate */ +#endif + +void +recv_port_open(struct recv_port *p, const struct sys_queue *q, + const struct port_env *env) +{ + p->mmid = env->mmid; + p->ssid = env->ssid; + p->mem_addr = env->mem_addr; + + p->size = q->size; + p->token_size = q->token_size; + p->wr_reg = q->wr_reg; + p->rd_reg = q->rd_reg; + +#ifdef __VIED_CELL + p->buffer = q->vied_address; +#else + p->buffer = q->host_address; +#endif +} + +STORAGE_CLASS_INLINE unsigned int +recv_port_index(const struct recv_port *p, unsigned int i) +{ + unsigned int rd = regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + + return OP_std_modadd(rd, i, p->size); +} + +unsigned int +recv_port_available(const struct recv_port *p) +{ + int wr = (int)regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + int rd = (int)regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + + return OP_std_modadd(wr, -rd, p->size); +} + +STORAGE_CLASS_INLINE void +recv_port_copy(const struct recv_port *p, unsigned int i, void *data) +{ + unsigned int rd = recv_port_index(p, i); + unsigned int token_size = p->token_size; + buffer_address addr = p->buffer + (rd * token_size); +#ifndef __VIED_CELL + ia_css_cpu_mem_cache_invalidate((void *)HOST_ADDRESS(p->buffer), + token_size*p->size); +#endif + buffer_load(addr, data, token_size, p->mmid); +} + +STORAGE_CLASS_INLINE void +recv_port_release(const struct recv_port *p, unsigned int i) +{ + unsigned int rd = recv_port_index(p, i); + + regmem_store_32(p->mem_addr, p->rd_reg, rd, p->ssid); +} + +unsigned int +recv_port_transfer(const struct recv_port *p, void *data) +{ + if (!recv_port_available(p)) + return 0; + recv_port_copy(p, 0, data); + recv_port_release(p, 1); + return 1; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/src/send_port.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/src/send_port.c new file mode 100644 index 0000000000000..8d1fba08c5d58 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/port/src/send_port.c @@ -0,0 +1,94 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "send_port.h" +#include "queue_struct.h" /* for sys_queue */ +#include "send_port_struct.h" /* for send_port */ +#include "port_env_struct.h" /* for port_env */ +#include "regmem_access.h" /* for regmem_load_32, regmem_store_32 */ +#include "buffer_access.h" /* for buffer_store, buffer_address */ +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "math_support.h" /* for OP_std_modadd */ +#include "type_support.h" /* for HOST_ADDRESS */ + +#ifndef __VIED_CELL +#include "cpu_mem_support.h" /* for ia_css_cpu_mem_cache_flush */ +#endif + +void +send_port_open(struct send_port *p, const struct sys_queue *q, + const struct port_env *env) +{ + p->mmid = env->mmid; + p->ssid = env->ssid; + p->mem_addr = env->mem_addr; + + p->size = q->size; + p->token_size = q->token_size; + p->wr_reg = q->wr_reg; + p->rd_reg = q->rd_reg; +#ifdef __VIED_CELL + p->buffer = q->vied_address; +#else + p->buffer = q->host_address; +#endif +} + +STORAGE_CLASS_INLINE unsigned int +send_port_index(const struct send_port *p, unsigned int i) +{ + unsigned int wr = regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + + return OP_std_modadd(wr, i, p->size); +} + +unsigned int +send_port_available(const struct send_port *p) +{ + int rd = (int)regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + int wr = (int)regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + + return OP_std_modadd(rd, -(wr+1), p->size); +} + +STORAGE_CLASS_INLINE void +send_port_copy(const struct send_port *p, unsigned int i, const void *data) +{ + unsigned int wr = send_port_index(p, i); + unsigned int token_size = p->token_size; + buffer_address addr = p->buffer + (wr * token_size); + + buffer_store(addr, data, token_size, p->mmid); +#ifndef __VIED_CELL + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(addr), token_size); +#endif +} + +STORAGE_CLASS_INLINE void +send_port_release(const struct send_port *p, unsigned int i) +{ + unsigned int wr = send_port_index(p, i); + + regmem_store_32(p->mem_addr, p->wr_reg, wr, p->ssid); +} + +unsigned int +send_port_transfer(const struct send_port *p, const void *data) +{ + if (!send_port_available(p)) + return 0; + send_port_copy(p, 0, data); + send_port_release(p, 1); + return 1; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/reg_dump/src/isys/cnlB0_gen_reg_dump/ia_css_debug_dump.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/reg_dump/src/isys/cnlB0_gen_reg_dump/ia_css_debug_dump.c new file mode 100644 index 0000000000000..c51d65c8cb647 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/reg_dump/src/isys/cnlB0_gen_reg_dump/ia_css_debug_dump.c @@ -0,0 +1,15 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#include "ia_css_debug_dump.h" + void ia_css_debug_dump(void) {} \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/reg_dump/src/isys/cnlB0_gen_reg_dump/ia_css_debug_dump.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/reg_dump/src/isys/cnlB0_gen_reg_dump/ia_css_debug_dump.h new file mode 100644 index 0000000000000..5dd23ddbd180b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/reg_dump/src/isys/cnlB0_gen_reg_dump/ia_css_debug_dump.h @@ -0,0 +1,17 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#ifndef __IA_CSS_DEBUG_DUMP_H_ + #define __IA_CSS_DEBUG_DUMP_H_ + void ia_css_debug_dump(void); + #endif /* __IA_CSS_DEBUG_DUMP_H_ */ \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/reg_dump/src/reg_dump_generic_bridge.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/reg_dump/src/reg_dump_generic_bridge.c new file mode 100644 index 0000000000000..9b9161ae78cf2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/reg_dump/src/reg_dump_generic_bridge.c @@ -0,0 +1,39 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include +#include "ia_css_trace.h" +#ifdef USE_LOGICAL_SSIDS +/* + Logical names can be used to define the SSID + In order to resolve these names the following include file should be provided + and the define above should be enabled +*/ +#include +#endif + +#define REG_DUMP_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#define REG_DUMP_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED + +/* SSID value is defined in test makefiles as either isys0 or psys0 */ +#define REG_DUMP_READ_REGISTER(addr) vied_subsystem_load_32(SSID, addr) + +#define REG_DUMP_PRINT_0(...) \ +EXPAND_VA_ARGS(IA_CSS_TRACE_0(REG_DUMP, VERBOSE, __VA_ARGS__)) +#define REG_DUMP_PRINT_1(...) \ +EXPAND_VA_ARGS(IA_CSS_TRACE_1(REG_DUMP, VERBOSE, __VA_ARGS__)) +#define EXPAND_VA_ARGS(x) x + +/* Including generated source code for reg_dump */ +#include "ia_css_debug_dump.c" diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/interface/regmem_access.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/interface/regmem_access.h new file mode 100644 index 0000000000000..d4576af936f6d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/interface/regmem_access.h @@ -0,0 +1,67 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_ACCESS_H +#define __REGMEM_ACCESS_H + +#include "storage_class.h" + +enum regmem_id { + /* pass pkg_dir address to SPC in non-secure mode */ + PKG_DIR_ADDR_REG = 0, + /* pass syscom configuration to SPC */ + SYSCOM_CONFIG_REG = 1, + /* syscom state - modified by SP */ + SYSCOM_STATE_REG = 2, + /* syscom commands - modified by the host */ + SYSCOM_COMMAND_REG = 3, + /* Store interrupt status - updated by SP */ + SYSCOM_IRQ_REG = 4, + /* Store VTL0_ADDR_MASK in trusted secure regision - provided by host.*/ + SYSCOM_VTL0_ADDR_MASK = 5, +#if HAS_DUAL_CMD_CTX_SUPPORT + /* Initialized if trustlet exists - updated by host */ + TRUSTLET_STATUS = 6, + /* identify if SPC access blocker programming is completed - updated by SP */ + AB_SPC_STATUS = 7, + /* first syscom queue pointer register */ + SYSCOM_QPR_BASE_REG = 8 +#else + /* first syscom queue pointer register */ + SYSCOM_QPR_BASE_REG = 6 +#endif +}; + +#if HAS_DUAL_CMD_CTX_SUPPORT +/* Bit 0: for untrusted non-secure DRV driver on VTL0 + * Bit 1: for trusted secure TEE driver on VTL1 + */ +#define SYSCOM_IRQ_VTL0_MASK 0x1 +#define SYSCOM_IRQ_VTL1_MASK 0x2 +#endif + +STORAGE_CLASS_INLINE unsigned int +regmem_load_32(unsigned int mem_address, unsigned int reg, unsigned int ssid); + +STORAGE_CLASS_INLINE void +regmem_store_32(unsigned int mem_address, unsigned int reg, unsigned int value, + unsigned int ssid); + +#ifdef __VIED_CELL +#include "regmem_access_cell.h" +#else +#include "regmem_access_host.h" +#endif + +#endif /* __REGMEM_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/regmem.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/regmem.mk new file mode 100644 index 0000000000000..24ebc1c325d8e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/regmem.mk @@ -0,0 +1,32 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +ifndef REGMEM_MK +REGMEM_MK=1 + +# MODULE is REGMEM + +REGMEM_DIR=$${MODULES_DIR}/regmem + +REGMEM_INTERFACE=$(REGMEM_DIR)/interface +REGMEM_SOURCES=$(REGMEM_DIR)/src + +REGMEM_HOST_FILES = +REGMEM_FW_FILES = $(REGMEM_SOURCES)/regmem.c + +REGMEM_CPPFLAGS = -I$(REGMEM_INTERFACE) -I$(REGMEM_SOURCES) +REGMEM_HOST_CPPFLAGS = $(REGMEM_CPPFLAGS) +REGMEM_FW_CPPFLAGS = $(REGMEM_CPPFLAGS) + +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/src/regmem_access_host.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/src/regmem_access_host.h new file mode 100644 index 0000000000000..8878d7074fabb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/src/regmem_access_host.h @@ -0,0 +1,41 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_ACCESS_HOST_H +#define __REGMEM_ACCESS_HOST_H + +#include "regmem_access.h" /* implemented interface */ + +#include "storage_class.h" +#include "regmem_const.h" +#include +#include "ia_css_cmem.h" + +STORAGE_CLASS_INLINE unsigned int +regmem_load_32(unsigned int mem_addr, unsigned int reg, unsigned int ssid) +{ + /* No need to add REGMEM_OFFSET, it is already included in mem_addr. */ + return ia_css_cmem_load_32(ssid, mem_addr + (REGMEM_WORD_BYTES*reg)); +} + +STORAGE_CLASS_INLINE void +regmem_store_32(unsigned int mem_addr, unsigned int reg, + unsigned int value, unsigned int ssid) +{ + /* No need to add REGMEM_OFFSET, it is already included in mem_addr. */ + ia_css_cmem_store_32(ssid, mem_addr + (REGMEM_WORD_BYTES*reg), + value); +} + +#endif /* __REGMEM_ACCESS_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/src/regmem_const.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/src/regmem_const.h new file mode 100644 index 0000000000000..ac7e3a98a434f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/regmem/src/regmem_const.h @@ -0,0 +1,28 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_CONST_H +#define __REGMEM_CONST_H + +#ifndef REGMEM_SIZE +#define REGMEM_SIZE (16) +#endif /* REGMEM_SIZE */ +#ifndef REGMEM_OFFSET +#define REGMEM_OFFSET (0) +#endif /* REGMEM_OFFSET */ +#ifndef REGMEM_WORD_BYTES +#define REGMEM_WORD_BYTES (4) +#endif + +#endif /* __REGMEM_CONST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/assert_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/assert_support.h new file mode 100644 index 0000000000000..ec24488bf6b11 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/assert_support.h @@ -0,0 +1,197 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __ASSERT_SUPPORT_H +#define __ASSERT_SUPPORT_H + +/* This file provides support for run-time assertions + * and compile-time assertions. + * + * Run-time asstions are provided via the following syntax: + * assert(condition) + * Run-time assertions are disabled using the NDEBUG flag. + * + * Compile time assertions are provided via the following syntax: + * COMPILATION_ERROR_IF(condition); + * A compile-time assertion will fail to compile if the condition is false. + * The condition must be constant, such that it can be evaluated + * at compile time. + * + * OP___assert is deprecated. + */ + +#define IA_CSS_ASSERT(expr) assert(expr) + +#ifdef __KLOCWORK__ +/* Klocwork does not see that assert will lead to abortion + * as there is no good way to tell this to KW and the code + * should not depend on assert to function (actually the assert + * could be disabled in a release build) it was decided to + * disable the assert for KW scans (by defining NDEBUG) + */ +#define NDEBUG +#endif /* __KLOCWORK__ */ + +/** + * The following macro can help to test the size of a struct at compile + * time rather than at run-time. It does not work for all compilers; see + * below. + * + * Depending on the value of 'condition', the following macro is expanded to: + * - condition==true: + * an expression containing an array declaration with negative size, + * usually resulting in a compilation error + * - condition==false: + * (void) 1; // C statement with no effect + * + * example: + * COMPILATION_ERROR_IF( sizeof(struct host_sp_queues) != + * SIZE_OF_HOST_SP_QUEUES_STRUCT); + * + * verify that the macro indeed triggers a compilation error with your compiler: + * COMPILATION_ERROR_IF( sizeof(struct host_sp_queues) != + * (sizeof(struct host_sp_queues)+1) ); + * + * Not all compilers will trigger an error with this macro; + * use a search engine to search for BUILD_BUG_ON to find other methods. + */ +#define COMPILATION_ERROR_IF(condition) \ +((void)sizeof(char[1 - 2*!!(condition)])) + +/* Compile time assertion */ +#ifndef CT_ASSERT +#define CT_ASSERT(cnd) ((void)sizeof(char[(cnd)?1 : -1])) +#endif /* CT_ASSERT */ + +#ifdef NDEBUG + +#define assert(cnd) ((void)0) + +#else + +#include "storage_class.h" + +#if defined(_MSC_VER) +#ifdef _KERNEL_MODE +/* Windows kernel mode compilation */ +#include +#define assert(cnd) ASSERT(cnd) +#else +/* Windows usermode compilation */ +#include +#endif + +#elif defined(__HIVECC) + +/* + * target: assert disabled + * sched: assert enabled only when SCHED_DEBUG is defined + * unsched: assert enabled + */ +#if defined(HRT_HW) +#define assert(cnd) ((void)0) +#elif defined(HRT_SCHED) && !defined(DEBUG_SCHED) +#define assert(cnd) ((void)0) +#elif defined(PIPE_GENERATION) +#define assert(cnd) ((void)0) +#else +#include +#define assert(cnd) OP___csim_assert(cnd) +#endif + +#elif defined(__KERNEL__) +#include + +#ifndef KERNEL_ASSERT_TO_BUG +#ifndef KERNEL_ASSERT_TO_BUG_ON +#ifndef KERNEL_ASSERT_TO_WARN_ON +#ifndef KERNEL_ASSERT_TO_WARN_ON_INF_LOOP +#ifndef KERNEL_ASSERT_UNDEFINED +/* Default */ +#define KERNEL_ASSERT_TO_BUG +#endif /*KERNEL_ASSERT_UNDEFINED*/ +#endif /*KERNEL_ASSERT_TO_WARN_ON_INF_LOOP*/ +#endif /*KERNEL_ASSERT_TO_WARN_ON*/ +#endif /*KERNEL_ASSERT_TO_BUG_ON*/ +#endif /*KERNEL_ASSERT_TO_BUG*/ + +#ifdef KERNEL_ASSERT_TO_BUG +/* TODO: it would be cleaner to use this: + * #define assert(cnd) BUG_ON(cnd) + * but that causes many compiler warnings (==errors) under Android + * because it seems that the BUG_ON() macro is not seen as a check by + * gcc like the BUG() macro is. */ +#define assert(cnd) \ + do { \ + if (!(cnd)) { \ + BUG(); \ + } \ + } while (0) +#endif /*KERNEL_ASSERT_TO_BUG*/ + +#ifdef KERNEL_ASSERT_TO_BUG_ON +#define assert(cnd) BUG_ON(!(cnd)) +#endif /*KERNEL_ASSERT_TO_BUG_ON*/ + +#ifdef KERNEL_ASSERT_TO_WARN_ON +#define assert(cnd) WARN_ON(!(cnd)) +#endif /*KERNEL_ASSERT_TO_WARN_ON*/ + +#ifdef KERNEL_ASSERT_TO_WARN_ON_INF_LOOP +#define assert(cnd) \ + do { \ + int not_cnd = !(cnd); \ + WARN_ON(not_cnd); \ + if (not_cnd) { \ + for (;;) { \ + } \ + } \ + } while (0) +#endif /*KERNEL_ASSERT_TO_WARN_ON_INF_LOOP*/ + +#ifdef KERNEL_ASSERT_UNDEFINED +#include KERNEL_ASSERT_DEFINITION_FILESTRING +#endif /*KERNEL_ASSERT_UNDEFINED*/ + +#elif defined(__FIST__) || defined(__GNUC__) + +#include "assert.h" + +#else /* default is for unknown environments */ +#define assert(cnd) ((void)0) +#endif + +#endif /* NDEBUG */ + +#ifndef PIPE_GENERATION +/* Deprecated OP___assert, this is still used in ~1000 places + * in the code. This will be removed over time. + * The implementation for the pipe generation tool is in see support.isp.h */ +#define OP___assert(cnd) assert(cnd) + +#ifdef C_RUN +#define compile_time_assert(cond) OP___assert(cond) +#else +#include "storage_class.h" +extern void _compile_time_assert(void); +STORAGE_CLASS_INLINE void compile_time_assert(unsigned int cond) +{ + /* Call undefined function if cond is false */ + if (!cond) + _compile_time_assert(); +} +#endif +#endif /* PIPE_GENERATION */ + +#endif /* __ASSERT_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/cpu_mem_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/cpu_mem_support.h new file mode 100644 index 0000000000000..defea068429ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/cpu_mem_support.h @@ -0,0 +1,233 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __CPU_MEM_SUPPORT_H +#define __CPU_MEM_SUPPORT_H + +#include "storage_class.h" +#include "assert_support.h" +#include "type_support.h" + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_copy(void *dst, const void *src, unsigned int size) +{ + /* memcpy cannot be used in Windows (function is not allowed), + * and the safer function memcpy_s is not available on other platforms. + * Because usage of ia_css_cpu_mem_copy is minimal, we implement it here in an easy, + * but sub-optimal way. + */ + unsigned int i; + + assert(dst != NULL && src != NULL); + + if (!(dst != NULL && src != NULL)) { + return NULL; + } + for (i = 0; i < size; i++) { + ((char *)dst)[i] = ((char *)src)[i]; + } + return dst; +} + +#if defined(__KERNEL__) + +#include +#include +#include +#include + +/* TODO: remove, workaround for issue in hrt file ibuf_ctrl_2600_config.c + * error checking code added to SDK that uses calls to exit function + */ +#define exit(a) return + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return kmalloc(size, GFP_KERNEL); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + return ia_css_cpu_mem_alloc(size); /* todo: align to page size */ +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_protect(void *ptr, unsigned int size, int prot) +{ + /* nothing here yet */ +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); /* available in kernel in linux/string.h */ +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + kfree(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ + /* parameter check here */ + if (ptr == NULL) + return; + + clflush_cache_range(ptr, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ + /* for now same as flush */ + ia_css_cpu_mem_cache_flush(ptr, size); +} + +#elif defined(_MSC_VER) + +#include +#include +#include + +extern void *hrt_malloc(size_t bytes, int zero_mem); +extern void *hrt_free(void *ptr); +extern void hrt_mem_cache_flush(void *ptr, unsigned int size); +extern void hrt_mem_cache_invalidate(void *ptr, unsigned int size); + +#define malloc(a) hrt_malloc(a, 1) +#define free(a) hrt_free(a) + +#define CSS_PAGE_SIZE (1<<12) + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return malloc(size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + unsigned int buffer_size = size; + + /* Currently hrt_malloc calls Windows ExAllocatePoolWithTag() routine + * to request system memory. If the number of bytes is equal or bigger + * than the page size, then the returned address is page aligned, + * but if it's smaller it's not necessarily page-aligned We agreed + * with Windows team that we allocate a full page + * if it's less than page size + */ + if (buffer_size < CSS_PAGE_SIZE) + buffer_size = CSS_PAGE_SIZE; + + return ia_css_cpu_mem_alloc(buffer_size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + free(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ +#ifdef _KERNEL_MODE + hrt_mem_cache_flush(ptr, size); +#else + (void)ptr; + (void)size; +#endif +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ +#ifdef _KERNEL_MODE + hrt_mem_cache_invalidate(ptr, size); +#else + (void)ptr; + (void)size; +#endif +} + +#else + +#include +#include +#include +/* Needed for the MPROTECT */ +#include +#include +#include +#include + + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return malloc(size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + int pagesize; + + pagesize = sysconf(_SC_PAGE_SIZE); + return memalign(pagesize, size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + free(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ + /* not needed in simulation */ + (void)ptr; + (void)size; +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ + /* not needed in simulation */ + (void)ptr; + (void)size; +} + +#endif + +#endif /* __CPU_MEM_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/error_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/error_support.h new file mode 100644 index 0000000000000..9fe1f65125e6c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/error_support.h @@ -0,0 +1,110 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __ERROR_SUPPORT_H +#define __ERROR_SUPPORT_H + +#if defined(__KERNEL__) +#include +#else +#include +#endif +#include + +/* OS-independent definition of IA_CSS errno values */ +/* #define IA_CSS_EINVAL 1 */ +/* #define IA_CSS_EFAULT 2 */ + +#ifdef __HIVECC +#define ERR_EMBEDDED 1 +#else +#define ERR_EMBEDDED 0 +#endif + +#if ERR_EMBEDDED +#define DECLARE_ERRVAL +#else +#define DECLARE_ERRVAL \ + int _errval = 0; +#endif + +/* Use "owl" in while to prevent compiler warnings in Windows */ +#define ALWAYS_FALSE ((void)0, 0) + +#define verifret(cond, error_type) \ +do { \ + if (!(cond)) { \ + return error_type; \ + } \ +} while (ALWAYS_FALSE) + +#define verifjmp(cond, error_tag) \ +do { \ + if (!(cond)) { \ + goto error_tag; \ + } \ +} while (ALWAYS_FALSE) + +#define verifexit(cond) \ +do { \ + if (!(cond)) { \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#if ERR_EMBEDDED +#define verifexitval(cond, error_tag) \ +do { \ + assert(cond); \ +} while (ALWAYS_FALSE) +#else +#define verifexitval(cond, error_tag) \ +do { \ + if (!(cond)) { \ + _errval = (error_tag); \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) +#endif + +#if ERR_EMBEDDED +#define haserror(error_tag) (0) +#else +#define haserror(error_tag) \ + (_errval == (error_tag)) +#endif + +#if ERR_EMBEDDED +#define noerror() (1) +#else +#define noerror() \ + (_errval == 0) +#endif + +#define verifjmpexit(cond) \ +do { \ + if (!(cond)) { \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#define verifjmpexitsetretval(cond, retval) \ +do { \ + if (!(cond)) { \ + retval = -1; \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#endif /* __ERROR_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/math_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/math_support.h new file mode 100644 index 0000000000000..651e310a420c2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/math_support.h @@ -0,0 +1,314 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __MATH_SUPPORT_H +#define __MATH_SUPPORT_H + +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "type_support.h" +#include "assert_support.h" + +/* in case we have min/max/MIN/MAX macro's undefine them */ +#ifdef min +#undef min +#endif +#ifdef max +#undef max +#endif +#ifdef MIN /* also defined in include/hrt/numeric.h from SDK */ +#undef MIN +#endif +#ifdef MAX +#undef MAX +#endif + +#ifndef UINT16_MAX +#define UINT16_MAX (0xffffUL) +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX (0xffffffffUL) +#endif + +#define IS_ODD(a) ((a) & 0x1) +#define IS_EVEN(a) (!IS_ODD(a)) +#define IS_POWER2(a) (!((a)&((a)-1))) +#define IS_MASK_BITS_SET(a, b) ((a & b) != 0) + +/*To Find next power of 2 number from x */ +#define bit2(x) ((x) | ((x) >> 1)) +#define bit4(x) (bit2(x) | (bit2(x) >> 2)) +#define bit8(x) (bit4(x) | (bit4(x) >> 4)) +#define bit16(x) (bit8(x) | (bit8(x) >> 8)) +#define bit32(x) (bit16(x) | (bit16(x) >> 16)) +#define NEXT_POWER_OF_2(x) (bit32(x-1) + 1) + +/* force a value to a lower even value */ +#define EVEN_FLOOR(x) ((x) & ~1UL) + +/* A => B */ +#define IMPLIES(a, b) (!(a) || (b)) + +/* The ORIG_BITS th bit is the sign bit */ +/* Sign extends a ORIG_BITS bits long signed number to a 64-bit signed number */ +/* By type casting it can relimited to any valid type-size + * (32-bit signed or 16-bit or 8-bit) + */ +/* By masking it can be transformed to any arbitrary bit size */ +#define SIGN_EXTEND(VAL, ORIG_BITS) \ +((~(((VAL)&(1ULL<<((ORIG_BITS)-1)))-1))|(VAL)) + +#define EXTRACT_BIT(a, b) ((a >> b) & 1) + +/* for preprocessor and array sizing use MIN and MAX + otherwise use min and max */ +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define CLIP(a, b, c) MIN((MAX((a), (b))), (c)) +/* Integer round-down division of a with b */ +#define FLOOR_DIV(a, b) ((b) ? ((a) / (b)) : 0) +/* Align a to the lower multiple of b */ +#define FLOOR_MUL(a, b) (FLOOR_DIV(a, b) * (b)) +/* Integer round-up division of a with b */ +#define CEIL_DIV(a, b) ((b) ? (((a) + (b) - 1) / (b)) : 0) +/* Align a to the upper multiple of b */ +#define CEIL_MUL(a, b) (CEIL_DIV(a, b) * (b)) +/* Align a to the upper multiple of b - fast implementation + * for cases when b=pow(2,n) + */ +#define CEIL_MUL2(a, b) (((a) + (b) - 1) & ~((b) - 1)) +/* integer round-up division of a with pow(2,b) */ +#define CEIL_SHIFT(a, b) (((a) + (1UL << (b)) - 1) >> (b)) +/* Align a to the upper multiple of pow(2,b) */ +#define CEIL_SHIFT_MUL(a, b) (CEIL_SHIFT(a, b) << (b)) +/* Absolute difference of a and b */ +#define ABS_DIF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a))) +#define ABS(a) ABS_DIF(a, 0) +/* Square of x */ +#define SQR(x) ((x)*(x)) +/* Integer round-half-down division of a nad b */ +#define ROUND_HALF_DOWN_DIV(a, b) ((b) ? ((a) + (b / 2) - 1) / (b) : 0) +/* Align a to the round-half-down multiple of b */ +#define ROUND_HALF_DOWN_MUL(a, b) (ROUND_HALF_DOWN_DIV(a, b) * (b)) + +#define MAX3(a, b, c) MAX((a), MAX((b), (c))) +#define MIN3(a, b, c) MIN((a), MIN((b), (c))) +#define MAX4(a, b, c, d) MAX((MAX((a), (b))), (MAX((c), (d)))) +#define MIN4(a, b, c, d) MIN((MIN((a), (b))), (MIN((c), (d)))) + +/* min and max should not be macros as they will evaluate their arguments twice. + if you really need a macro (e.g. for CPP or for initializing an array) + use MIN() and MAX(), otherwise use min() and max() */ + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) ((sizeof(a) / sizeof(*(a)))) +#endif + +#ifndef BYTES +#define BYTES(bit) (((bit)+7)/8) +#endif + +#if !defined(PIPE_GENERATION) +STORAGE_CLASS_INLINE unsigned int max_value_bits(unsigned int bits) +{ + return (bits == 0) ? 0 : ((2 * ((1 << ((bits) - 1)) - 1)) + 1); +} +STORAGE_CLASS_INLINE unsigned int max_value_bytes(unsigned int bytes) +{ + return max_value_bits(IA_CSS_UINT8_T_BITS * bytes); +} +STORAGE_CLASS_INLINE int max(int a, int b) +{ + return MAX(a, b); +} + +STORAGE_CLASS_INLINE int min(int a, int b) +{ + return MIN(a, b); +} + +STORAGE_CLASS_INLINE int clip(int a, int b, int c) +{ + return min(max(a, b), c); +} + +STORAGE_CLASS_INLINE unsigned int ipu4_umax(unsigned int a, unsigned int b) +{ + return MAX(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ipu4_umin(unsigned int a, unsigned int b) +{ + return MIN(a, b); +} + +STORAGE_CLASS_INLINE unsigned int uclip(unsigned int a, unsigned int b, + unsigned int c) +{ + return ipu4_umin(ipu4_umax(a, b), c); +} + +STORAGE_CLASS_INLINE unsigned int ceil_div(unsigned int a, unsigned int b) +{ + return CEIL_DIV(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_mul(unsigned int a, unsigned int b) +{ + return CEIL_MUL(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_mul2(unsigned int a, unsigned int b) +{ + return CEIL_MUL2(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_shift(unsigned int a, unsigned int b) +{ + return CEIL_SHIFT(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_shift_mul(unsigned int a, unsigned int b) +{ + return CEIL_SHIFT_MUL(a, b); +} + +STORAGE_CLASS_INLINE int abs_dif(int a, int b) +{ + return ABS_DIF(a, b); +} + +STORAGE_CLASS_INLINE unsigned int uabs_dif(unsigned int a, unsigned int b) +{ + return ABS_DIF(a, b); +} + +STORAGE_CLASS_INLINE unsigned int round_half_down_div(unsigned int a, + unsigned int b) +{ + return ROUND_HALF_DOWN_DIV(a, b); +} + +STORAGE_CLASS_INLINE unsigned int round_half_down_mul(unsigned int a, + unsigned int b) +{ + return ROUND_HALF_DOWN_MUL(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_pow2(uint32_t a) +{ + unsigned int retval = 0; + + if (IS_POWER2(a)) { + retval = (unsigned int)a; + } else { + unsigned int v = a; + + v |= v>>1; + v |= v>>2; + v |= v>>4; + v |= v>>8; + v |= v>>16; + retval = (unsigned int)(v+1); + } + return retval; +} + +STORAGE_CLASS_INLINE unsigned int floor_log2(uint32_t a) +{ + static const uint8_t de_bruijn[] = { + 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 + }; + uint32_t v = a; + + v |= v>>1; + v |= v>>2; + v |= v>>4; + v |= v>>8; + v |= v>>16; + return (unsigned int)de_bruijn[(v*0x07C4ACDDU)>>27]; +} + +/* Divide by small power of two */ +STORAGE_CLASS_INLINE unsigned int +udiv2_small_i(uint32_t a, uint32_t b) +{ + assert(b <= 2); + return a >> (b-1); +} + +/* optimized divide for small results + * a will be divided by b + * outbits is the number of bits needed for the result + * the smaller the cheaper the function will be. + * if the result doesn't fit in the number of output bits + * the result is incorrect and the function will assert + */ +STORAGE_CLASS_INLINE unsigned int +udiv_medium(uint32_t a, uint32_t b, unsigned int outbits) +{ + int bit; + unsigned int res = 0; + unsigned int mask; + +#ifdef VOLCANO +#pragma ipu unroll +#endif + for (bit = outbits-1 ; bit >= 0; bit--) { + mask = 1<= (b<= c ? a+b-c : a+b); +} + +/* + * For SP and ISP, SDK provides the definition of OP_asp_slor. + * We need it only for host + */ +STORAGE_CLASS_INLINE unsigned int OP_asp_slor(int a, int b, int c) +{ + return ((a << c) | b); +} +#else +#include "hive/customops.h" +#endif /* !defined(__VIED_CELL) */ + +#endif /* !defined(PIPE_GENERATION) */ + +#if !defined(__KERNEL__) +#define clamp(a, min_val, max_val) MIN(MAX((a), (min_val)), (max_val)) +#endif /* !defined(__KERNEL__) */ + +#endif /* __MATH_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/misc_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/misc_support.h new file mode 100644 index 0000000000000..a2c2729e946d2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/misc_support.h @@ -0,0 +1,76 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __MISC_SUPPORT_H +#define __MISC_SUPPORT_H + +/* suppress compiler warnings on unused variables */ +#ifndef NOT_USED +#define NOT_USED(a) ((void)(a)) +#endif + +/* Calculate the total bytes for pow(2) byte alignment */ +#define tot_bytes_for_pow2_align(pow2, cur_bytes) \ + ((cur_bytes + (pow2 - 1)) & ~(pow2 - 1)) + +/* Display the macro value given a string */ +#define _STR(x) #x +#define STR(x) _STR(x) + +/* Concatenate */ +#ifndef CAT /* also defined in */ +#define _CAT(a, b) a ## b +#define CAT(a, b) _CAT(a, b) +#endif + +#define _CAT3(a, b, c) a ## b ## c +#define CAT3(a, b, c) _CAT3(a, b, c) + +/* NO_HOIST, NO_CSE, NO_ALIAS attributes must be ignored for host code */ +#ifndef __HIVECC +#ifndef NO_HOIST +#define NO_HOIST +#endif +#ifndef NO_CSE +#define NO_CSE +#endif +#ifndef NO_ALIAS +#define NO_ALIAS +#endif +#endif + +enum hive_method_id { + HIVE_METHOD_ID_CRUN, + HIVE_METHOD_ID_UNSCHED, + HIVE_METHOD_ID_SCHED, + HIVE_METHOD_ID_TARGET +}; + +/* Derive METHOD */ +#if defined(C_RUN) + #define HIVE_METHOD "crun" + #define HIVE_METHOD_ID HIVE_METHOD_ID_CRUN +#elif defined(HRT_UNSCHED) + #define HIVE_METHOD "unsched" + #define HIVE_METHOD_ID HIVE_METHOD_ID_UNSCHED +#elif defined(HRT_SCHED) + #define HIVE_METHOD "sched" + #define HIVE_METHOD_ID HIVE_METHOD_ID_SCHED +#else + #define HIVE_METHOD "target" + #define HIVE_METHOD_ID HIVE_METHOD_ID_TARGET + #define HRT_TARGET 1 +#endif + +#endif /* __MISC_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/platform_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/platform_support.h new file mode 100644 index 0000000000000..d281d841e1c33 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/platform_support.h @@ -0,0 +1,146 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PLATFORM_SUPPORT_H +#define __PLATFORM_SUPPORT_H + +#include "storage_class.h" + +#define MSEC_IN_SEC 1000 +#define NSEC_IN_MSEC 1000000 + +#if defined(_MSC_VER) +#include + +#define IA_CSS_EXTERN +#define SYNC_WITH(x) +#define CSS_ALIGN(d, a) _declspec(align(a)) d + +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + /* Placeholder for driver team*/ +} + +STORAGE_CLASS_INLINE void ia_css_sleep_msec(unsigned long delay_time_ms) +{ + /* Placeholder for driver team*/ + (void)delay_time_ms; +} + +#elif defined(__HIVECC) +#include +#include + +#define IA_CSS_EXTERN extern +#define CSS_ALIGN(d, a) d __aligned(a) +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + OP___schedule(); +} + +#elif defined(__KERNEL__) +#include +#include + +#define IA_CSS_EXTERN +#define CSS_ALIGN(d, a) d __aligned(a) + +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + usleep_range(1, 50); +} + +#elif defined(__GNUC__) +#include + +#define IA_CSS_EXTERN +#define CSS_ALIGN(d, a) d __aligned(a) + +/* Define some __HIVECC specific macros to nothing to allow host code compilation */ +#ifndef NO_ALIAS +#define NO_ALIAS +#endif + +#ifndef SYNC_WITH +#define SYNC_WITH(x) +#endif + +#if defined(HRT_CSIM) +#include "hrt/host.h" /* Using hrt_sleep from hrt/host.h */ +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + /* For the SDK still using hrt_sleep */ + hrt_sleep(); +} +STORAGE_CLASS_INLINE void ia_css_sleep_msec(long unsigned int delay_time_ms) +{ + /* For the SDK still using hrt_sleep */ + long unsigned int i = 0; + for (i = 0; i < delay_time_ms; i++) { + hrt_sleep(); + } +} +#else +#include +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + struct timespec delay_time; + + delay_time.tv_sec = 0; + delay_time.tv_nsec = 10; + nanosleep(&delay_time, NULL); +} +STORAGE_CLASS_INLINE void ia_css_sleep_msec(long unsigned int delay_time_ms) +{ + struct timespec delay_time; + + if (delay_time_ms >= MSEC_IN_SEC) { + delay_time.tv_sec = delay_time_ms / MSEC_IN_SEC; + delay_time.tv_nsec = (delay_time_ms % MSEC_IN_SEC) * NSEC_IN_MSEC; + } else { + delay_time.tv_sec = 0; + delay_time.tv_nsec = delay_time_ms * NSEC_IN_MSEC; + } + nanosleep(&delay_time, NULL); +} +#endif + +#else +#include +#endif + +/*needed for the include in stdint.h for various environments */ +#include "type_support.h" +#include "storage_class.h" + +#define MAX_ALIGNMENT 8 +#define aligned_uint8(type, obj) CSS_ALIGN(uint8_t obj, 1) +#define aligned_int8(type, obj) CSS_ALIGN(int8_t obj, 1) +#define aligned_uint16(type, obj) CSS_ALIGN(uint16_t obj, 2) +#define aligned_int16(type, obj) CSS_ALIGN(int16_t obj, 2) +#define aligned_uint32(type, obj) CSS_ALIGN(uint32_t obj, 4) +#define aligned_int32(type, obj) CSS_ALIGN(int32_t obj, 4) + +/* needed as long as hivecc does not define the type (u)int64_t */ +#if defined(__HIVECC) +#define aligned_uint64(type, obj) CSS_ALIGN(unsigned long long obj, 8) +#define aligned_int64(type, obj) CSS_ALIGN(signed long long obj, 8) +#else +#define aligned_uint64(type, obj) CSS_ALIGN(uint64_t obj, 8) +#define aligned_int64(type, obj) CSS_ALIGN(int64_t obj, 8) +#endif +#define aligned_enum(enum_type, obj) CSS_ALIGN(uint32_t obj, 4) +#define aligned_struct(struct_type, obj) struct_type obj + +#endif /* __PLATFORM_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/print_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/print_support.h new file mode 100644 index 0000000000000..0b614f7ef12d8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/print_support.h @@ -0,0 +1,90 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PRINT_SUPPORT_H +#define __PRINT_SUPPORT_H + +#if defined(_MSC_VER) +#ifdef _KERNEL_MODE + +/* TODO: Windows driver team to provide tracing mechanism for kernel mode + * e.g. DbgPrint and DbgPrintEx + */ +extern void FwTracePrintPWARN(const char *fmt, ...); +extern void FwTracePrintPRINT(const char *fmt, ...); +extern void FwTracePrintPERROR(const char *fmt, ...); +extern void FwTracePrintPDEBUG(const char *fmt, ...); + +#define PWARN(format, ...) FwTracePrintPWARN(format, __VA_ARGS__) +#define PRINT(format, ...) FwTracePrintPRINT(format, __VA_ARGS__) +#define PERROR(format, ...) FwTracePrintPERROR(format, __VA_ARGS__) +#define PDEBUG(format, ...) FwTracePrintPDEBUG(format, __VA_ARGS__) + +#else +/* Windows usermode compilation */ +#include + +/* To change the defines below, communicate with Windows team first + * to ensure they will not get flooded with prints + */ +/* This is temporary workaround to avoid flooding userspace + * Windows driver with prints + */ + +#define PWARN(format, ...) +#define PRINT(format, ...) +#define PERROR(format, ...) printf("error: " format, __VA_ARGS__) +#define PDEBUG(format, ...) + +#endif /* _KERNEL_MODE */ + +#elif defined(__HIVECC) +#include +/* To be revised + +#define PWARN(format) +#define PRINT(format) OP___printstring(format) +#define PERROR(variable) OP___dump(9999, arguments) +#define PDEBUG(variable) OP___dump(__LINE__, arguments) + +*/ + +#define PRINTSTRING(str) OP___printstring(str) + +#elif defined(__KERNEL__) +#include +#include + + +#define PWARN(format, arguments...) pr_debug(format, ##arguments) +#define PRINT(format, arguments...) pr_debug(format, ##arguments) +#define PERROR(format, arguments...) pr_debug(format, ##arguments) +#define PDEBUG(format, arguments...) pr_debug(format, ##arguments) + +#else +#include + +#define PRINT_HELPER(prefix, format, ...) printf(prefix format "%s", __VA_ARGS__) + +/* The trailing "" allows the edge case of printing single string */ +#define PWARN(...) PRINT_HELPER("warning: ", __VA_ARGS__, "") +#define PRINT(...) PRINT_HELPER("", __VA_ARGS__, "") +#define PERROR(...) PRINT_HELPER("error: ", __VA_ARGS__, "") +#define PDEBUG(...) PRINT_HELPER("debug: ", __VA_ARGS__, "") + +#define PRINTSTRING(str) PRINT(str) + +#endif + +#endif /* __PRINT_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/storage_class.h new file mode 100644 index 0000000000000..58932a6b3ec76 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/storage_class.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __STORAGE_CLASS_H +#define __STORAGE_CLASS_H + +#define STORAGE_CLASS_EXTERN \ +extern + +#if defined(_MSC_VER) +#define STORAGE_CLASS_INLINE \ +static inline +#elif defined(__HIVECC) +#define STORAGE_CLASS_INLINE \ +static inline +#else +#define STORAGE_CLASS_INLINE \ +static inline +#endif + +/* Register struct */ +#ifndef __register +#if defined(__HIVECC) && !defined(PIPE_GENERATION) +#define __register register +#else +#define __register +#endif +#endif + +/* Memory attribute */ +#ifndef MEM +#ifdef PIPE_GENERATION +#elif defined(__HIVECC) +#include +#else +#define MEM(any_mem) +#endif +#endif + +#endif /* __STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/type_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/type_support.h new file mode 100644 index 0000000000000..7d8e00fdd95e1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/support/type_support.h @@ -0,0 +1,80 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __TYPE_SUPPORT_H +#define __TYPE_SUPPORT_H + +/* Per the DLI spec, types are in "type_support.h" and + * "platform_support.h" is for unclassified/to be refactored + * platform specific definitions. + */ +#define IA_CSS_UINT8_T_BITS 8 +#define IA_CSS_UINT16_T_BITS 16 +#define IA_CSS_UINT32_T_BITS 32 +#define IA_CSS_INT32_T_BITS 32 +#define IA_CSS_UINT64_T_BITS 64 + + +#if defined(_MSC_VER) +#include +#include +#include +#include +#if defined(_M_X64) +#define HOST_ADDRESS(x) ((unsigned long long)(x)) +#else +#define HOST_ADDRESS(x) ((unsigned long)(x)) +#endif + +#elif defined(PARAM_GENERATION) +/* Nothing */ +#elif defined(__HIVECC) +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#elif defined(__KERNEL__) +#include +#include + +#define CHAR_BIT (8) +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#elif defined(__GNUC__) +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#else /* default is for the FIST environment */ +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#endif + +#if !defined(PIPE_GENERATION) && !defined(IO_GENERATION) +/* genpipe cannot handle the void* syntax */ +typedef void *HANDLE; +#endif + +#endif /* __TYPE_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/interface/ia_css_syscom.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/interface/ia_css_syscom.h new file mode 100644 index 0000000000000..5426d6d18e0bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/interface/ia_css_syscom.h @@ -0,0 +1,247 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_H +#define __IA_CSS_SYSCOM_H + + +/* + * The CSS Subsystem Communication Interface - Host side + * + * It provides subsystem initialzation, send ports and receive ports + * The PSYS and ISYS interfaces are implemented on top of this interface. + */ + +#include "ia_css_syscom_config.h" + +#define FW_ERROR_INVALID_PARAMETER (-1) +#define FW_ERROR_BAD_ADDRESS (-2) +#define FW_ERROR_BUSY (-3) +#define FW_ERROR_NO_MEMORY (-4) + +struct ia_css_syscom_context; + +/** + * ia_css_syscom_size() - provide syscom external buffer requirements + * @config: pointer to the configuration data (read) + * @size: pointer to the buffer size (write) + * + * Purpose: + * - Provide external buffer requirements + * - To be used for external buffer allocation + * + */ +extern void +ia_css_syscom_size( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size *size +); + +/** + * ia_css_syscom_open() - initialize a subsystem context + * @config: pointer to the configuration data (read) + * @buf: pointer to externally allocated buffers (read) + * @returns: struct ia_css_syscom_context* on success, 0 otherwise. + * + * Purpose: + * - initialize host side data structures + * - boot the subsystem? + * + */ +extern struct ia_css_syscom_context* +ia_css_syscom_open( + struct ia_css_syscom_config *config, + struct ia_css_syscom_buf *buf +); + +/** + * ia_css_syscom_close() - signal close to cell + * @context: pointer to the subsystem context + * @returns: 0 on success, -2 (FW_ERROR_BUSY) if SPC is not ready yet. + * + * Purpose: + * Request from the Cell to terminate + */ +extern int +ia_css_syscom_close( + struct ia_css_syscom_context *context +); + +/** + * ia_css_syscom_release() - free context + * @context: pointer to the subsystem context + * @force: flag which specifies whether cell + * state will be checked before freeing the + * context. + * @returns: 0 on success, -2 (FW_ERROR_BUSY) if cell + * is busy and call was not forced. + * + * Purpose: + * 2 modes, with first (force==true) immediately + * free context, and second (force==false) verifying + * that the cell state is ok and freeing context if so, + * returning error otherwise. + */ +extern int +ia_css_syscom_release( + struct ia_css_syscom_context *context, + unsigned int force +); + +/** + * Open a port for sending tokens to the subsystem + * @context: pointer to the subsystem context + * @port: send port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_open( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Closes a port for sending tokens to the subsystem + * @context: pointer to the subsystem context + * @port: send port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_close( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Get the number of tokens that can be sent to a port without error. + * @context: pointer to the subsystem context + * @port: send port index + * @returns: number of available tokens on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_available( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Send a token to the subsystem port + * The token size is determined during initialization + * @context: pointer to the subsystem context + * @port: send port index + * @token: pointer to the token value that is transferred to the subsystem + * @returns: number of tokens sent on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_transfer( + struct ia_css_syscom_context *context, + unsigned int port, + const void *token +); + +/** + * Open a port for receiving tokens to the subsystem + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_open( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Closes a port for receiving tokens to the subsystem + * Returns 0 on success, otherwise negative value of error code + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_close( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Get the number of tokens that can be received from a port without errors. + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: number of available tokens on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_available( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Receive a token from the subsystem port + * The token size is determined during initialization + * @context: pointer to the subsystem context + * @port: receive port index + * @token (output): pointer to (space for) the token to be received + * @returns: number of tokens received on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_transfer( + struct ia_css_syscom_context *context, + unsigned int port, + void *token +); + +#if HAS_DUAL_CMD_CTX_SUPPORT +/** + * ia_css_syscom_store_dmem() - store subsystem context information in DMEM + * @context: pointer to the subsystem context + * @ssid: subsystem id + * @vtl0_addr_mask: VTL0 address mask; only applicable when the passed in context is secure + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_store_dmem( + struct ia_css_syscom_context *context, + unsigned int ssid, + unsigned int vtl0_addr_mask +); + +/** + * ia_css_syscom_set_trustlet_status() - store truslet configuration setting + * @context: pointer to the subsystem context + * @trustlet_exist: 1 if trustlet exists + */ +extern void +ia_css_syscom_set_trustlet_status( + unsigned int dmem_addr, + unsigned int ssid, + bool trustlet_exist +); + +/** + * ia_css_syscom_is_ab_spc_ready() - check if SPC access blocker programming is completed + * @context: pointer to the subsystem context + * @returns: 1 when status is ready. 0 otherwise + */ +bool +ia_css_syscom_is_ab_spc_ready( + struct ia_css_syscom_context *ctx +); +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +#endif /* __IA_CSS_SYSCOM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/interface/ia_css_syscom_config.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/interface/ia_css_syscom_config.h new file mode 100644 index 0000000000000..2f5eb309df94e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/interface/ia_css_syscom_config.h @@ -0,0 +1,97 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONFIG_H +#define __IA_CSS_SYSCOM_CONFIG_H + +#include +#include + +/* syscom size struct, output of ia_css_syscom_size, + * input for (external) allocation + */ +struct ia_css_syscom_size { + /* Size of host buffer */ + unsigned int cpu; + /* Size of shared config buffer (host to cell) */ + unsigned int shm; + /* Size of shared input queue buffers (host to cell) */ + unsigned int ibuf; + /* Size of shared output queue buffers (cell to host) */ + unsigned int obuf; +}; + +/* syscom buffer struct, output of (external) allocation, + * input for ia_css_syscom_open + */ +struct ia_css_syscom_buf { + char *cpu; /* host buffer */ + + /* shared memory buffer host address */ + host_virtual_address_t shm_host; + /* shared memory buffer cell address */ + vied_virtual_address_t shm_cell; + + /* input queue shared buffer host address */ + host_virtual_address_t ibuf_host; + /* input queue shared buffer cell address */ + vied_virtual_address_t ibuf_cell; + + /* output queue shared buffer host address */ + host_virtual_address_t obuf_host; + /* output queue shared buffer cell address */ + vied_virtual_address_t obuf_cell; +}; + +struct ia_css_syscom_queue_config { + unsigned int queue_size; /* tokens per queue */ + unsigned int token_size; /* bytes per token */ +}; + +/** + * Parameter struct for ia_css_syscom_open + */ +struct ia_css_syscom_config { + /* This member in no longer used in syscom. + It is kept to not break any driver builds, and will be removed when + all assignments have been removed from driver code */ + /* address of firmware in DDR/IMR */ + unsigned long long host_firmware_address; + + /* address of firmware in DDR, seen from SPC */ + unsigned int vied_firmware_address; + + unsigned int ssid; + unsigned int mmid; + + unsigned int num_input_queues; + unsigned int num_output_queues; + struct ia_css_syscom_queue_config *input; + struct ia_css_syscom_queue_config *output; + + unsigned int regs_addr; + unsigned int dmem_addr; + + /* firmware-specific configuration data */ + void *specific_addr; + unsigned int specific_size; + + /* if true; secure syscom in VTIO Case + * if false, non-secure syscom + */ + bool secure; + unsigned int vtl0_addr_mask; /* only applicable in 'secure' case */ +}; + +#endif /* __IA_CSS_SYSCOM_CONFIG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/interface/ia_css_syscom_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/interface/ia_css_syscom_trace.h new file mode 100644 index 0000000000000..2c32693c2a82e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/interface/ia_css_syscom_trace.h @@ -0,0 +1,51 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_SYSCOM_TRACE_H +#define __IA_CSS_SYSCOM_TRACE_H + +#include "ia_css_trace.h" + +#define SYSCOM_TRACE_LEVEL_DEFAULT 1 +#define SYSCOM_TRACE_LEVEL_DEBUG 2 + +/* Set to default level if no level is defined */ +#ifndef SYSCOM_TRACE_LEVEL +#define SYSCOM_TRACE_LEVEL SYSCOM_TRACE_LEVEL_DEFAULT +#endif /* SYSCOM_TRACE_LEVEL */ + +/* SYSCOM Module tracing backend is mapped to TUNIT tracing for target platforms */ +#ifdef __HIVECC +# ifndef HRT_CSIM +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_TRACE +# else +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +# endif +#else +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#endif + +#define SYSCOM_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED +#define SYSCOM_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED +#define SYSCOM_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + +#if (SYSCOM_TRACE_LEVEL == SYSCOM_TRACE_LEVEL_DEFAULT) +# define SYSCOM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED +#elif (SYSCOM_TRACE_LEVEL == SYSCOM_TRACE_LEVEL_DEBUG) +# define SYSCOM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED +#else +# error "Connection manager trace level not defined!" +#endif /* SYSCOM_TRACE_LEVEL */ + +#endif /* __IA_CSS_SYSCOM_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/src/ia_css_syscom.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/src/ia_css_syscom.c new file mode 100644 index 0000000000000..dffbf581eb2b3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/src/ia_css_syscom.c @@ -0,0 +1,652 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_syscom.h" + +#include "ia_css_syscom_context.h" +#include "ia_css_syscom_config_fw.h" +#include "ia_css_syscom_trace.h" + +#include "queue.h" +#include "send_port.h" +#include "recv_port.h" +#include "regmem_access.h" + +#include "error_support.h" +#include "cpu_mem_support.h" + +#include "queue_struct.h" +#include "send_port_struct.h" +#include "recv_port_struct.h" + +#include "type_support.h" +#include +#include +#include "platform_support.h" + +#include "ia_css_cell.h" + +/* struct of internal buffer sizes */ +struct ia_css_syscom_size_intern { + unsigned int context; + unsigned int input_queue; + unsigned int output_queue; + unsigned int input_port; + unsigned int output_port; + + unsigned int fw_config; + unsigned int specific; + + unsigned int input_buffer; + unsigned int output_buffer; +}; + +/* Allocate buffers internally, when no buffers are provided */ +static int +ia_css_syscom_alloc( + unsigned int ssid, + unsigned int mmid, + const struct ia_css_syscom_size *size, + struct ia_css_syscom_buf *buf) +{ + /* zero the buffer to set all pointers to zero */ + memset(buf, 0, sizeof(*buf)); + + /* allocate cpu_mem */ + buf->cpu = (char *)ia_css_cpu_mem_alloc(size->cpu); + if (!buf->cpu) + goto EXIT7; + + /* allocate and map shared config buffer */ + buf->shm_host = shared_memory_alloc(mmid, size->shm); + if (!buf->shm_host) + goto EXIT6; + buf->shm_cell = shared_memory_map(ssid, mmid, buf->shm_host); + if (!buf->shm_cell) + goto EXIT5; + + /* allocate and map input queue buffer */ + buf->ibuf_host = shared_memory_alloc(mmid, size->ibuf); + if (!buf->ibuf_host) + goto EXIT4; + buf->ibuf_cell = shared_memory_map(ssid, mmid, buf->ibuf_host); + if (!buf->ibuf_cell) + goto EXIT3; + + /* allocate and map output queue buffer */ + buf->obuf_host = shared_memory_alloc(mmid, size->obuf); + if (!buf->obuf_host) + goto EXIT2; + buf->obuf_cell = shared_memory_map(ssid, mmid, buf->obuf_host); + if (!buf->obuf_cell) + goto EXIT1; + + return 0; + +EXIT1: shared_memory_free(mmid, buf->obuf_host); +EXIT2: shared_memory_unmap(ssid, mmid, buf->ibuf_cell); +EXIT3: shared_memory_free(mmid, buf->ibuf_host); +EXIT4: shared_memory_unmap(ssid, mmid, buf->shm_cell); +EXIT5: shared_memory_free(mmid, buf->shm_host); +EXIT6: ia_css_cpu_mem_free(buf->cpu); +EXIT7: return FW_ERROR_NO_MEMORY; +} + +static void +ia_css_syscom_size_intern( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size_intern *size) +{ + /* convert syscom config into syscom internal size struct */ + + unsigned int i; + + size->context = sizeof(struct ia_css_syscom_context); + size->input_queue = cfg->num_input_queues * sizeof(struct sys_queue); + size->output_queue = cfg->num_output_queues * sizeof(struct sys_queue); + size->input_port = cfg->num_input_queues * sizeof(struct send_port); + size->output_port = cfg->num_output_queues * sizeof(struct recv_port); + + size->fw_config = sizeof(struct ia_css_syscom_config_fw); + size->specific = cfg->specific_size; + + /* accumulate input queue buffer sizes */ + size->input_buffer = 0; + for (i = 0; i < cfg->num_input_queues; i++) { + size->input_buffer += + sys_queue_buf_size(cfg->input[i].queue_size, + cfg->input[i].token_size); + } + + /* accumulate outut queue buffer sizes */ + size->output_buffer = 0; + for (i = 0; i < cfg->num_output_queues; i++) { + size->output_buffer += + sys_queue_buf_size(cfg->output[i].queue_size, + cfg->output[i].token_size); + } +} + +static void +ia_css_syscom_size_extern( + const struct ia_css_syscom_size_intern *i, + struct ia_css_syscom_size *e) +{ + /* convert syscom internal size struct into external size struct */ + + e->cpu = i->context + i->input_queue + i->output_queue + + i->input_port + i->output_port; + e->shm = i->fw_config + i->input_queue + i->output_queue + i->specific; + e->ibuf = i->input_buffer; + e->obuf = i->output_buffer; +} + +/* Function that provides buffer sizes to be allocated */ +void +ia_css_syscom_size( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size *size) +{ + struct ia_css_syscom_size_intern i; + + ia_css_syscom_size_intern(cfg, &i); + ia_css_syscom_size_extern(&i, size); +} + +static struct ia_css_syscom_context* +ia_css_syscom_assign_buf( + const struct ia_css_syscom_size_intern *i, + const struct ia_css_syscom_buf *buf) +{ + struct ia_css_syscom_context *ctx; + char *cpu_mem_buf; + host_virtual_address_t shm_buf_host; + vied_virtual_address_t shm_buf_cell; + + /* host context */ + cpu_mem_buf = buf->cpu; + + ctx = (struct ia_css_syscom_context *)cpu_mem_buf; + ia_css_cpu_mem_set_zero(ctx, i->context); + cpu_mem_buf += i->context; + + ctx->input_queue = (struct sys_queue *) cpu_mem_buf; + cpu_mem_buf += i->input_queue; + + ctx->output_queue = (struct sys_queue *) cpu_mem_buf; + cpu_mem_buf += i->output_queue; + + ctx->send_port = (struct send_port *) cpu_mem_buf; + cpu_mem_buf += i->input_port; + + ctx->recv_port = (struct recv_port *) cpu_mem_buf; + + + /* cell config */ + shm_buf_host = buf->shm_host; + shm_buf_cell = buf->shm_cell; + + ctx->config_host_addr = shm_buf_host; + shm_buf_host += i->fw_config; + ctx->config_vied_addr = shm_buf_cell; + shm_buf_cell += i->fw_config; + + ctx->input_queue_host_addr = shm_buf_host; + shm_buf_host += i->input_queue; + ctx->input_queue_vied_addr = shm_buf_cell; + shm_buf_cell += i->input_queue; + + ctx->output_queue_host_addr = shm_buf_host; + shm_buf_host += i->output_queue; + ctx->output_queue_vied_addr = shm_buf_cell; + shm_buf_cell += i->output_queue; + + ctx->specific_host_addr = shm_buf_host; + ctx->specific_vied_addr = shm_buf_cell; + + ctx->ibuf_host_addr = buf->ibuf_host; + ctx->ibuf_vied_addr = buf->ibuf_cell; + + ctx->obuf_host_addr = buf->obuf_host; + ctx->obuf_vied_addr = buf->obuf_cell; + + return ctx; +} + +struct ia_css_syscom_context* +ia_css_syscom_open( + struct ia_css_syscom_config *cfg, + struct ia_css_syscom_buf *buf_extern +) +{ + struct ia_css_syscom_size_intern size_intern; + struct ia_css_syscom_size size; + struct ia_css_syscom_buf buf_intern; + struct ia_css_syscom_buf *buf; + struct ia_css_syscom_context *ctx; + struct ia_css_syscom_config_fw fw_cfg; + unsigned int i; + struct sys_queue_res res; + + IA_CSS_TRACE_0(SYSCOM, INFO, "Entered: ia_css_syscom_open\n"); + + /* error handling */ + if (cfg == NULL) + return NULL; + + IA_CSS_TRACE_1(SYSCOM, INFO, "ia_css_syscom_open (secure %d) start\n", cfg->secure); + + /* check members of cfg: TBD */ + + /* + * Check if SP is in valid state, have to wait if not ready. + * In some platform (Such as VP), it will need more time to wait due to system performance; + * If return NULL without wait for SPC0 ready, Driver load FW will failed + */ + ia_css_cell_wait(cfg->ssid, SPC0); + + ia_css_syscom_size_intern(cfg, &size_intern); + ia_css_syscom_size_extern(&size_intern, &size); + + if (buf_extern) { + /* use externally allocated buffers */ + buf = buf_extern; + } else { + /* use internally allocated buffers */ + buf = &buf_intern; + if (ia_css_syscom_alloc(cfg->ssid, cfg->mmid, &size, buf) != 0) + return NULL; + } + + /* assign buffer pointers */ + ctx = ia_css_syscom_assign_buf(&size_intern, buf); + /* only need to free internally allocated buffers */ + ctx->free_buf = !buf_extern; + + ctx->cell_regs_addr = cfg->regs_addr; + /* regmem is at cell_dmem_addr + REGMEM_OFFSET */ + ctx->cell_dmem_addr = cfg->dmem_addr; + + ctx->num_input_queues = cfg->num_input_queues; + ctx->num_output_queues = cfg->num_output_queues; + + ctx->env.mmid = cfg->mmid; + ctx->env.ssid = cfg->ssid; + ctx->env.mem_addr = cfg->dmem_addr; + + ctx->regmem_idx = SYSCOM_QPR_BASE_REG; + + /* initialize input queues */ + res.reg = SYSCOM_QPR_BASE_REG; + res.host_address = ctx->ibuf_host_addr; + res.vied_address = ctx->ibuf_vied_addr; + for (i = 0; i < cfg->num_input_queues; i++) { + sys_queue_init(ctx->input_queue + i, + cfg->input[i].queue_size, + cfg->input[i].token_size, &res); + } + + /* initialize output queues */ + res.host_address = ctx->obuf_host_addr; + res.vied_address = ctx->obuf_vied_addr; + for (i = 0; i < cfg->num_output_queues; i++) { + sys_queue_init(ctx->output_queue + i, + cfg->output[i].queue_size, + cfg->output[i].token_size, &res); + } + + /* fill shared queue structs */ + shared_memory_store(cfg->mmid, ctx->input_queue_host_addr, + ctx->input_queue, + cfg->num_input_queues * sizeof(struct sys_queue)); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->input_queue_host_addr), + cfg->num_input_queues * sizeof(struct sys_queue)); + shared_memory_store(cfg->mmid, ctx->output_queue_host_addr, + ctx->output_queue, + cfg->num_output_queues * sizeof(struct sys_queue)); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->output_queue_host_addr), + cfg->num_output_queues * sizeof(struct sys_queue)); + + /* Zero the queue buffers. Is this really needed? */ + shared_memory_zero(cfg->mmid, buf->ibuf_host, size.ibuf); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(buf->ibuf_host), + size.ibuf); + shared_memory_zero(cfg->mmid, buf->obuf_host, size.obuf); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(buf->obuf_host), + size.obuf); + + /* copy firmware specific data */ + if (cfg->specific_addr && cfg->specific_size) { + shared_memory_store(cfg->mmid, ctx->specific_host_addr, + cfg->specific_addr, cfg->specific_size); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->specific_host_addr), + cfg->specific_size); + } + + fw_cfg.num_input_queues = cfg->num_input_queues; + fw_cfg.num_output_queues = cfg->num_output_queues; + fw_cfg.input_queue = ctx->input_queue_vied_addr; + fw_cfg.output_queue = ctx->output_queue_vied_addr; + fw_cfg.specific_addr = ctx->specific_vied_addr; + fw_cfg.specific_size = cfg->specific_size; + + shared_memory_store(cfg->mmid, ctx->config_host_addr, + &fw_cfg, sizeof(struct ia_css_syscom_config_fw)); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(ctx->config_host_addr), + sizeof(struct ia_css_syscom_config_fw)); + +#if !HAS_DUAL_CMD_CTX_SUPPORT + /* store syscom uninitialized state */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store STATE_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_STATE_UNINIT, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + SYSCOM_STATE_UNINIT, cfg->ssid); + /* store syscom uninitialized command */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store COMMAND_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_COMMAND_UNINIT, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_UNINIT, cfg->ssid); + /* store firmware configuration address */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store CONFIG_REG (%#x) @ dmem_addr %#x ssid %d\n", + ctx->config_vied_addr, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_CONFIG_REG, + ctx->config_vied_addr, cfg->ssid); +#endif + + /* Indicate if ctx is created for secure stream purpose */ + ctx->secure = cfg->secure; + + IA_CSS_TRACE_1(SYSCOM, INFO, "ia_css_syscom_open (secure %d) completed\n", cfg->secure); + return ctx; +} + + +int +ia_css_syscom_close( + struct ia_css_syscom_context *ctx +) +{ + int state; + + state = regmem_load_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle close request yet */ + return FW_ERROR_BUSY; + } + + /* set close request flag */ + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_INACTIVE, ctx->env.ssid); + + return 0; +} + +static void +ia_css_syscom_free(struct ia_css_syscom_context *ctx) +{ + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, ctx->ibuf_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->ibuf_host_addr); + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, ctx->obuf_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->obuf_host_addr); + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, + ctx->config_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->config_host_addr); + ia_css_cpu_mem_free(ctx); +} + +int +ia_css_syscom_release( + struct ia_css_syscom_context *ctx, + unsigned int force +) +{ + /* check if release is forced, an verify cell state if it is not */ + if (!force) { + if (!ia_css_cell_is_ready(ctx->env.ssid, SPC0)) + return FW_ERROR_BUSY; + } + + /* Reset the regmem idx */ + ctx->regmem_idx = 0; + + if (ctx->free_buf) + ia_css_syscom_free(ctx); + + return 0; +} + +int ia_css_syscom_send_port_open( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + int state; + + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + /* check if SP syscom is ready to open the queue */ + state = regmem_load_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle messages yet */ + return FW_ERROR_BUSY; + } + + /* initialize the port */ + send_port_open(ctx->send_port + port, + ctx->input_queue + port, &(ctx->env)); + + return 0; +} + +int ia_css_syscom_send_port_close( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return 0; +} + +int ia_css_syscom_send_port_available( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return send_port_available(ctx->send_port + port); +} + +int ia_css_syscom_send_port_transfer( + struct ia_css_syscom_context *ctx, + unsigned int port, + const void *token +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return send_port_transfer(ctx->send_port + port, token); +} + +int ia_css_syscom_recv_port_open( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + int state; + + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + /* check if SP syscom is ready to open the queue */ + state = regmem_load_32(ctx->cell_dmem_addr, + SYSCOM_STATE_REG, ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle messages yet */ + return FW_ERROR_BUSY; + } + + /* initialize the port */ + recv_port_open(ctx->recv_port + port, + ctx->output_queue + port, &(ctx->env)); + + return 0; +} + +int ia_css_syscom_recv_port_close( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return 0; +} + +/* + * Get the number of responses in the response queue + */ +int +ia_css_syscom_recv_port_available( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return recv_port_available(ctx->recv_port + port); +} + + +/* + * Dequeue the head of the response queue + * returns an error when the response queue is empty + */ +int +ia_css_syscom_recv_port_transfer( + struct ia_css_syscom_context *ctx, + unsigned int port, + void *token +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return recv_port_transfer(ctx->recv_port + port, token); +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +/* + * store subsystem context information in DMEM + */ +int +ia_css_syscom_store_dmem( + struct ia_css_syscom_context *ctx, + unsigned int ssid, + unsigned int vtl0_addr_mask +) +{ + unsigned int read_back; + + NOT_USED(vtl0_addr_mask); + NOT_USED(read_back); + + if (ctx->secure) { + /* store VTL0 address mask in 'secure' context */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem VTL0_ADDR_MASK (%#x) @ dmem_addr %#x ssid %d\n", + vtl0_addr_mask, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_VTL0_ADDR_MASK, vtl0_addr_mask, ssid); + } + /* store firmware configuration address */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem CONFIG_REG (%#x) @ dmem_addr %#x ssid %d\n", + ctx->config_vied_addr, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_CONFIG_REG, + ctx->config_vied_addr, ssid); + /* store syscom uninitialized state */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem STATE_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_STATE_UNINIT, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + SYSCOM_STATE_UNINIT, ssid); + /* store syscom uninitialized command */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem COMMAND_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_COMMAND_UNINIT, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_UNINIT, ssid); + + return 0; +} + +/* + * store truslet configuration status setting + */ +void +ia_css_syscom_set_trustlet_status( + unsigned int dmem_addr, + unsigned int ssid, + bool trustlet_exist +) +{ + unsigned int value; + + value = trustlet_exist ? TRUSTLET_EXIST : TRUSTLET_NOT_EXIST; + IA_CSS_TRACE_3(SYSCOM, INFO, + "ia_css_syscom_set_trustlet_status TRUSTLET_STATUS (%#x) @ dmem_addr %#x ssid %d\n", + value, dmem_addr, ssid); + regmem_store_32(dmem_addr, TRUSTLET_STATUS, value, ssid); +} + +/* + * check if SPC access blocker programming is completed + */ +bool +ia_css_syscom_is_ab_spc_ready( + struct ia_css_syscom_context *ctx +) +{ + unsigned int value; + + /* We only expect the call from non-secure context only */ + if (ctx->secure) { + IA_CSS_TRACE_0(SYSCOM, ERROR, "ia_css_syscom_is_spc_ab_ready - Please call from non-secure context\n"); + return false; + } + + value = regmem_load_32(ctx->cell_dmem_addr, AB_SPC_STATUS, ctx->env.ssid); + IA_CSS_TRACE_3(SYSCOM, INFO, + "ia_css_syscom_is_spc_ab_ready AB_SPC_STATUS @ dmem_addr %#x ssid %d - value %#x\n", + ctx->cell_dmem_addr, ctx->env.ssid, value); + + return (value == AB_SPC_READY); +} +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/src/ia_css_syscom_config_fw.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/src/ia_css_syscom_config_fw.h new file mode 100644 index 0000000000000..0cacd5a34934d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/src/ia_css_syscom_config_fw.h @@ -0,0 +1,69 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONFIG_FW_H +#define __IA_CSS_SYSCOM_CONFIG_FW_H + +#include "type_support.h" + +enum { + /* Program load or explicit host setting should init to this */ + SYSCOM_STATE_UNINIT = 0x57A7E000, + /* SP Syscom sets this when it is ready for use */ + SYSCOM_STATE_READY = 0x57A7E001, + /* SP Syscom sets this when no more syscom accesses will happen */ + SYSCOM_STATE_INACTIVE = 0x57A7E002 +}; + +enum { + /* Program load or explicit host setting should init to this */ + SYSCOM_COMMAND_UNINIT = 0x57A7F000, + /* Host Syscom requests syscom to become inactive */ + SYSCOM_COMMAND_INACTIVE = 0x57A7F001 +}; + +#if HAS_DUAL_CMD_CTX_SUPPORT +enum { + /* Program load or explicit host setting should init to this */ + TRUSTLET_UNINIT = 0x57A8E000, + /* Host Syscom informs SP that Trustlet exists */ + TRUSTLET_EXIST = 0x57A8E001, + /* Host Syscom informs SP that Trustlet does not exist */ + TRUSTLET_NOT_EXIST = 0x57A8E002 +}; + +enum { + /* Program load or explicit setting initialized by SP */ + AB_SPC_NOT_READY = 0x57A8F000, + /* SP informs host that SPC access programming is completed */ + AB_SPC_READY = 0x57A8F001 +}; +#endif + +/* firmware config: data that sent from the host to SP via DDR */ +/* Cell copies data into a context */ + +struct ia_css_syscom_config_fw { + unsigned int firmware_address; + + unsigned int num_input_queues; + unsigned int num_output_queues; + unsigned int input_queue; /* hmm_ptr / struct queue* */ + unsigned int output_queue; /* hmm_ptr / struct queue* */ + + unsigned int specific_addr; /* vied virtual address */ + unsigned int specific_size; +}; + +#endif /* __IA_CSS_SYSCOM_CONFIG_FW_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/src/ia_css_syscom_context.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/src/ia_css_syscom_context.h new file mode 100644 index 0000000000000..ecf22f6b7ac53 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/src/ia_css_syscom_context.h @@ -0,0 +1,65 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONTEXT_H +#define __IA_CSS_SYSCOM_CONTEXT_H + +#include + +#include "port_env_struct.h" +#include + +/* host context */ +struct ia_css_syscom_context { + vied_virtual_address_t cell_firmware_addr; + unsigned int cell_regs_addr; + unsigned int cell_dmem_addr; + + struct port_env env; + + unsigned int num_input_queues; + unsigned int num_output_queues; + + /* array of input queues (from host to SP) */ + struct sys_queue *input_queue; + /* array of output queues (from SP to host) */ + struct sys_queue *output_queue; + + struct send_port *send_port; + struct recv_port *recv_port; + + unsigned int regmem_idx; + unsigned int free_buf; + + host_virtual_address_t config_host_addr; + host_virtual_address_t input_queue_host_addr; + host_virtual_address_t output_queue_host_addr; + host_virtual_address_t specific_host_addr; + host_virtual_address_t ibuf_host_addr; + host_virtual_address_t obuf_host_addr; + + vied_virtual_address_t config_vied_addr; + vied_virtual_address_t input_queue_vied_addr; + vied_virtual_address_t output_queue_vied_addr; + vied_virtual_address_t specific_vied_addr; + vied_virtual_address_t ibuf_vied_addr; + vied_virtual_address_t obuf_vied_addr; + + /* if true; secure syscom object as in VTIO Case + * if false, non-secure syscom + */ + bool secure; +}; + +#endif /* __IA_CSS_SYSCOM_CONTEXT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/syscom.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/syscom.mk new file mode 100644 index 0000000000000..8d36b8928af55 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/syscom/syscom.mk @@ -0,0 +1,42 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is SYSCOM + +SYSCOM_DIR=$${MODULES_DIR}/syscom + +SYSCOM_INTERFACE=$(SYSCOM_DIR)/interface +SYSCOM_SOURCES1=$(SYSCOM_DIR)/src + +SYSCOM_HOST_FILES += $(SYSCOM_SOURCES1)/ia_css_syscom.c + +SYSCOM_HOST_CPPFLAGS += -I$(SYSCOM_INTERFACE) +SYSCOM_HOST_CPPFLAGS += -I$(SYSCOM_SOURCES1) +SYSCOM_HOST_CPPFLAGS += -I$${MODULES_DIR}/devices +ifdef REGMEM_SECURE_OFFSET +SYSCOM_HOST_CPPFLAGS += -DREGMEM_SECURE_OFFSET=$(REGMEM_SECURE_OFFSET) +else +SYSCOM_HOST_CPPFLAGS += -DREGMEM_SECURE_OFFSET=0 +endif + +SYSCOM_FW_FILES += $(SYSCOM_SOURCES1)/ia_css_syscom_fw.c + +SYSCOM_FW_CPPFLAGS += -I$(SYSCOM_INTERFACE) +SYSCOM_FW_CPPFLAGS += -I$(SYSCOM_SOURCES1) +SYSCOM_FW_CPPFLAGS += -DREGMEM_OFFSET=$(REGMEM_OFFSET) +ifdef REGMEM_SECURE_OFFSET +SYSCOM_FW_CPPFLAGS += -DREGMEM_SECURE_OFFSET=$(REGMEM_SECURE_OFFSET) +else +SYSCOM_FW_CPPFLAGS += -DREGMEM_SECURE_OFFSET=0 +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/trace/interface/ia_css_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/trace/interface/ia_css_trace.h new file mode 100644 index 0000000000000..b85b1810f1070 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/trace/interface/ia_css_trace.h @@ -0,0 +1,883 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/*! \file */ + +#ifndef __IA_CSS_TRACE_H +#define __IA_CSS_TRACE_H + +/* +** Configurations +*/ + +/** + * STEP 1: Define {Module Name}_TRACE_METHOD to one of the following. + * Where: + * {Module Name} is the name of the targeted module. + * + * Example: + * #define NCI_DMA_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + */ + +/**< Use whatever method of tracing that best suits the platform + * this code is compiled for. + */ +#define IA_CSS_TRACE_METHOD_NATIVE 1 +/**< Use the Tracing NCI. */ +#define IA_CSS_TRACE_METHOD_TRACE 2 + +/** + * STEP 2: Define {Module Name}_TRACE_LEVEL_{Level} to one of the following. + * Where: + * {Module Name} is the name of the targeted module. + * {Level}, in decreasing order of severity, is one of the + * following values: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * + * Example: + * #define NCI_DMA_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED + * #define NCI_DMA_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + */ +/**< Disables the corresponding trace level. */ +#define IA_CSS_TRACE_LEVEL_DISABLED 0 +/**< Enables the corresponding trace level. */ +#define IA_CSS_TRACE_LEVEL_ENABLED 1 + +/* + * Used in macro definition with do-while loop + * for removing checkpatch warnings + */ +#define IA_CSS_TRACE_FILE_DUMMY_DEFINE + +/** + * STEP 3: Define IA_CSS_TRACE_PRINT_FILE_LINE to have file name and + * line printed with every log message. + * + * Example: + * #define IA_CSS_TRACE_PRINT_FILE_LINE + */ + +/* +** Interface +*/ + +/* +** Static +*/ + +/** + * Logs a message with zero arguments if the targeted severity level is enabled + * at compile-time. + * @param module The targeted module. + * @param severity The severity level of the trace message. In decreasing order: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * @param format The message to be traced. + */ +#define IA_CSS_TRACE_0(module, severity, format) \ + IA_CSS_TRACE_IMPL(module, 0, severity, format) + +/** + * Logs a message with one argument if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_1(module, severity, format, a1) \ + IA_CSS_TRACE_IMPL(module, 1, severity, format, a1) + +/** + * Logs a message with two arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_2(module, severity, format, a1, a2) \ + IA_CSS_TRACE_IMPL(module, 2, severity, format, a1, a2) + +/** + * Logs a message with three arguments if the targeted severity level + * is enabled at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_3(module, severity, format, a1, a2, a3) \ + IA_CSS_TRACE_IMPL(module, 3, severity, format, a1, a2, a3) + +/** + * Logs a message with four arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_4(module, severity, format, a1, a2, a3, a4) \ + IA_CSS_TRACE_IMPL(module, 4, severity, format, a1, a2, a3, a4) + +/** + * Logs a message with five arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_5(module, severity, format, a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_IMPL(module, 5, severity, format, a1, a2, a3, a4, a5) + +/** + * Logs a message with six arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_6(module, severity, format, a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_IMPL(module, 6, severity, format, a1, a2, a3, a4, a5, a6) + +/** + * Logs a message with seven arguments if the targeted severity level + * is enabled at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_7(module, severity, format, a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_IMPL(module, 7, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) + +/* +** Dynamic +*/ + +/** +* Declares, but does not define, dynamic tracing functions and variables +* for module \p module. For each module, place an instance of this macro +* in the compilation unit in which you want to use dynamic tracing facility +* so as to inform the compiler of the declaration of the available functions. +* An invocation of this function does not enable any of the available tracing +* levels. Do not place a semicolon after a call to this macro. +* @see IA_CSS_TRACE_DYNAMIC_DEFINE +*/ +#define IA_CSS_TRACE_DYNAMIC_DECLARE(module) \ + IA_CSS_TRACE_DYNAMIC_DECLARE_IMPL(module) +/** +* Declares the configuration function for the dynamic api seperatly, if one +* wants to use it. +*/ +#define IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC(module) \ + IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC_IMPL(module) + +/** +* Defines dynamic tracing functions and variables for module \p module. +* For each module, place an instance of this macro in one, and only one, +* of your SOURCE files so as to allow the linker resolve the related symbols. +* An invocation of this macro does not enable any of the available tracing +* levels. Do not place a semicolon after a call to this macro. +* @see IA_CSS_TRACE_DYNAMIC_DECLARE +*/ +#define IA_CSS_TRACE_DYNAMIC_DEFINE(module) \ + IA_CSS_TRACE_DYNAMIC_DEFINE_IMPL(module) +/** +* Defines the configuration function for the dynamic api seperatly, if one +* wants to use it. +*/ +#define IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC(module) \ + IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC_IMPL(module) + +/** + * Logs a message with zero arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @param module The targeted module. + * @param severity The severity level of the trace message. In decreasing order: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * @param format The message to be traced. + */ +#define IA_CSS_TRACE_DYNAMIC_0(module, severity, format) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 0, severity, format) + +/** + * Logs a message with one argument if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_1(module, severity, format, a1) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 1, severity, format, a1) + +/** + * Logs a message with two arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_2(module, severity, format, a1, a2) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 2, severity, format, a1, a2) + +/** + * Logs a message with three arguments if the targeted severity level + * is enabled both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_3(module, severity, format, a1, a2, a3) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 3, severity, format, a1, a2, a3) + +/** + * Logs a message with four arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_4(module, severity, format, a1, a2, a3, a4) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 4, severity, format, a1, a2, a3, a4) + +/** + * Logs a message with five arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_5(module, severity, format, a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 5, severity, format, \ + a1, a2, a3, a4, a5) + +/** + * Logs a message with six arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_6(module, severity, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 6, severity, format, \ + a1, a2, a3, a4, a5, a6) + +/** + * Logs a message with seven arguments if the targeted severity level + * is enabled both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_7(module, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 7, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) + +/* +** Implementation +*/ + +/* CAT */ +#define IA_CSS_TRACE_CAT_IMPL(a, b) a ## b +#define IA_CSS_TRACE_CAT(a, b) IA_CSS_TRACE_CAT_IMPL(a, b) + +/* Bridge */ +#if defined(__HIVECC) || defined(__GNUC__) +#define IA_CSS_TRACE_IMPL(module, argument_count, severity, arguments ...) \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_, \ + argument_count \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_LEVEL_ \ + ), \ + severity \ + ) \ + ( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_SEVERITY_, \ + severity \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + #module, \ + ## arguments \ + ) \ + ) + +/* Bridge */ +#define IA_CSS_TRACE_DYNAMIC_IMPL(module, argument_count, severity, \ + arguments ...) \ + do { \ + if (IA_CSS_TRACE_CAT(IA_CSS_TRACE_CAT(module, _trace_level_), \ + severity)) { \ + IA_CSS_TRACE_IMPL(module, argument_count, severity, \ + ## arguments); \ + } \ + } while (0) +#elif defined(_MSC_VER) +#define IA_CSS_TRACE_IMPL(module, argument_count, severity, ...) \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_, \ + argument_count \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_LEVEL_ \ + ), \ + severity \ + ) \ + ( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_SEVERITY_, \ + severity \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + #module, \ + __VA_ARGS__ \ + ) \ + ) + +/* Bridge */ +#define IA_CSS_TRACE_DYNAMIC_IMPL(module, argument_count, severity, ...) \ + do { \ + if (IA_CSS_TRACE_CAT(IA_CSS_TRACE_CAT(module, _trace_level_), \ + severity)) { \ + IA_CSS_TRACE_IMPL(module, argument_count, severity, \ + __VA_ARGS__); \ + } \ + } while (0) +#endif + +/* +** Native Backend +*/ + +#if defined(__HIVECC) + #define IA_CSS_TRACE_PLATFORM_CELL +#elif defined(__GNUC__) + #define IA_CSS_TRACE_PLATFORM_HOST + + #define IA_CSS_TRACE_NATIVE(severity, module, format, arguments ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, module, \ + format), ## arguments); \ + } while (0) + /* TODO: In case Host Side tracing is needed to be mapped to the + * Tunit, the following "IA_CSS_TRACE_TRACE" needs to be modified from + * PRINT to vied_nci_tunit_print function calls + */ + #define IA_CSS_TRACE_TRACE(severity, module, format, arguments ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, module, \ + format), ## arguments); \ + } while (0) + +#elif defined(_MSC_VER) + #define IA_CSS_TRACE_PLATFORM_HOST + + #define IA_CSS_TRACE_NATIVE(severity, module, format, ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, \ + module, format), __VA_ARGS__); \ + } while (0) + /* TODO: In case Host Side tracing is needed to be mapped to the + * Tunit, the following "IA_CSS_TRACE_TRACE" needs to be modified from + * PRINT to vied_nci_tunit_print function calls + */ + #define IA_CSS_TRACE_TRACE(severity, module, format, ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, \ + module, format), __VA_ARGS__); \ + } while (0) +#else + #error Unsupported platform! +#endif /* Platform */ + +#if defined(IA_CSS_TRACE_PLATFORM_CELL) + #include /* VOLATILE */ + + #ifdef IA_CSS_TRACE_PRINT_FILE_LINE + #define IA_CSS_TRACE_FILE_PRINT_COMMAND \ + do { \ + OP___printstring(__FILE__":") VOLATILE; \ + OP___printdec(__LINE__) VOLATILE; \ + OP___printstring("\n") VOLATILE; \ + } while (0) + #else + #define IA_CSS_TRACE_FILE_PRINT_COMMAND + #endif + + #define IA_CSS_TRACE_MODULE_SEVERITY_PRINT(module, severity) \ + do { \ + IA_CSS_TRACE_FILE_DUMMY_DEFINE; \ + OP___printstring("["module"]:["severity"]:") \ + VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_MSG_NATIVE(severity, module, format) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + OP___printstring("["module"]:["severity"]: "format) \ + VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_ARG_NATIVE(module, severity, i, value) \ + do { \ + IA_CSS_TRACE_MODULE_SEVERITY_PRINT(module, severity); \ + OP___dump(i, value) VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_0(severity, module, format) \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format) + + #define IA_CSS_TRACE_NATIVE_1(severity, module, format, a1) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_2(severity, module, format, a1, a2) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_3(severity, module, format, a1, a2, a3) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_4(severity, module, format, \ + a1, a2, a3, a4) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 6, a6); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 6, a6); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 7, a7); \ + } while (0) + /* + ** Tracing Backend + */ +#if !defined(HRT_CSIM) && !defined(NO_TUNIT) + #include "vied_nci_tunit.h" +#endif + #define IA_CSS_TRACE_AUG_FORMAT_TRACE(format, module) \ + "[" module "]" format " : PID = %x : Timestamp = %d : PC = %x" + + #define IA_CSS_TRACE_TRACE_0(severity, module, format) \ + vied_nci_tunit_print(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity) + + #define IA_CSS_TRACE_TRACE_1(severity, module, format, a1) \ + vied_nci_tunit_print1i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1) + + #define IA_CSS_TRACE_TRACE_2(severity, module, format, a1, a2) \ + vied_nci_tunit_print2i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2) + + #define IA_CSS_TRACE_TRACE_3(severity, module, format, a1, a2, a3) \ + vied_nci_tunit_print3i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3) + + #define IA_CSS_TRACE_TRACE_4(severity, module, format, a1, a2, a3, a4) \ + vied_nci_tunit_print4i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4) + + #define IA_CSS_TRACE_TRACE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + vied_nci_tunit_print5i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_TRACE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + vied_nci_tunit_print6i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_TRACE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + vied_nci_tunit_print7i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5, a6, a7) + +#elif defined(IA_CSS_TRACE_PLATFORM_HOST) + #include "print_support.h" + + #ifdef IA_CSS_TRACE_PRINT_FILE_LINE + #define IA_CSS_TRACE_FILE_PRINT_COMMAND \ + PRINT("%s:%d:\n", __FILE__, __LINE__) + #else + #define IA_CSS_TRACE_FILE_PRINT_COMMAND + #endif + + #define IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, module, format) \ + "[" module "]:[" severity "]: " format + + #define IA_CSS_TRACE_NATIVE_0(severity, module, format) \ + IA_CSS_TRACE_NATIVE(severity, module, format) + + #define IA_CSS_TRACE_NATIVE_1(severity, module, format, a1) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1) + + #define IA_CSS_TRACE_NATIVE_2(severity, module, format, a1, a2) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2) + + #define IA_CSS_TRACE_NATIVE_3(severity, module, format, a1, a2, a3) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2, a3) + + #define IA_CSS_TRACE_NATIVE_4(severity, module, format, \ + a1, a2, a3, a4) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2, a3, a4) + + #define IA_CSS_TRACE_NATIVE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_NATIVE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_NATIVE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) + + #define IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, module, format) \ + "["module"]:["severity"]: "format + + #define IA_CSS_TRACE_TRACE_0(severity, module, format) \ + IA_CSS_TRACE_TRACE(severity, module, format) + + #define IA_CSS_TRACE_TRACE_1(severity, module, format, a1) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1) + + #define IA_CSS_TRACE_TRACE_2(severity, module, format, a1, a2) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2) + + #define IA_CSS_TRACE_TRACE_3(severity, module, format, a1, a2, a3) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2, a3) + + #define IA_CSS_TRACE_TRACE_4(severity, module, format, \ + a1, a2, a3, a4) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2, a3, a4) + + #define IA_CSS_TRACE_TRACE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_TRACE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_TRACE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) +#endif + +/* Disabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_1_0(severity, module, format) +#define IA_CSS_TRACE_1_1_0(severity, module, format, arg1) +#define IA_CSS_TRACE_2_1_0(severity, module, format, arg1, arg2) +#define IA_CSS_TRACE_3_1_0(severity, module, format, arg1, arg2, arg3) +#define IA_CSS_TRACE_4_1_0(severity, module, format, arg1, arg2, arg3, arg4) +#define IA_CSS_TRACE_5_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5) +#define IA_CSS_TRACE_6_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6) +#define IA_CSS_TRACE_7_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7) + +/* Enabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_1_1 IA_CSS_TRACE_NATIVE_0 +#define IA_CSS_TRACE_1_1_1 IA_CSS_TRACE_NATIVE_1 +#define IA_CSS_TRACE_2_1_1 IA_CSS_TRACE_NATIVE_2 +#define IA_CSS_TRACE_3_1_1 IA_CSS_TRACE_NATIVE_3 +#define IA_CSS_TRACE_4_1_1 IA_CSS_TRACE_NATIVE_4 +#define IA_CSS_TRACE_5_1_1 IA_CSS_TRACE_NATIVE_5 +#define IA_CSS_TRACE_6_1_1 IA_CSS_TRACE_NATIVE_6 +#define IA_CSS_TRACE_7_1_1 IA_CSS_TRACE_NATIVE_7 + +/* Enabled */ +/* Legend: IA_CSS_TRACE_SEVERITY_{Severity Level}_{Backend ID} */ +#define IA_CSS_TRACE_SEVERITY_ASSERT_1 "Assert" +#define IA_CSS_TRACE_SEVERITY_ERROR_1 "Error" +#define IA_CSS_TRACE_SEVERITY_WARNING_1 "Warning" +#define IA_CSS_TRACE_SEVERITY_INFO_1 "Info" +#define IA_CSS_TRACE_SEVERITY_DEBUG_1 "Debug" +#define IA_CSS_TRACE_SEVERITY_VERBOSE_1 "Verbose" + +/* Disabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_2_0(severity, module, format) +#define IA_CSS_TRACE_1_2_0(severity, module, format, arg1) +#define IA_CSS_TRACE_2_2_0(severity, module, format, arg1, arg2) +#define IA_CSS_TRACE_3_2_0(severity, module, format, arg1, arg2, arg3) +#define IA_CSS_TRACE_4_2_0(severity, module, format, arg1, arg2, arg3, arg4) +#define IA_CSS_TRACE_5_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5) +#define IA_CSS_TRACE_6_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6) +#define IA_CSS_TRACE_7_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7) + +/* Enabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_2_1 IA_CSS_TRACE_TRACE_0 +#define IA_CSS_TRACE_1_2_1 IA_CSS_TRACE_TRACE_1 +#define IA_CSS_TRACE_2_2_1 IA_CSS_TRACE_TRACE_2 +#define IA_CSS_TRACE_3_2_1 IA_CSS_TRACE_TRACE_3 +#define IA_CSS_TRACE_4_2_1 IA_CSS_TRACE_TRACE_4 +#define IA_CSS_TRACE_5_2_1 IA_CSS_TRACE_TRACE_5 +#define IA_CSS_TRACE_6_2_1 IA_CSS_TRACE_TRACE_6 +#define IA_CSS_TRACE_7_2_1 IA_CSS_TRACE_TRACE_7 + +/* Enabled */ +/* Legend: IA_CSS_TRACE_SEVERITY_{Severity Level}_{Backend ID} */ +#define IA_CSS_TRACE_SEVERITY_ASSERT_2 VIED_NCI_TUNIT_MSG_SEVERITY_FATAL +#define IA_CSS_TRACE_SEVERITY_ERROR_2 VIED_NCI_TUNIT_MSG_SEVERITY_ERROR +#define IA_CSS_TRACE_SEVERITY_WARNING_2 VIED_NCI_TUNIT_MSG_SEVERITY_WARNING +#define IA_CSS_TRACE_SEVERITY_INFO_2 VIED_NCI_TUNIT_MSG_SEVERITY_NORMAL +#define IA_CSS_TRACE_SEVERITY_DEBUG_2 VIED_NCI_TUNIT_MSG_SEVERITY_USER1 +#define IA_CSS_TRACE_SEVERITY_VERBOSE_2 VIED_NCI_TUNIT_MSG_SEVERITY_USER2 + +/* +** Dynamicism +*/ + +#define IA_CSS_TRACE_DYNAMIC_DECLARE_IMPL(module) \ + do { \ + void IA_CSS_TRACE_CAT(module, _trace_assert_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_assert_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_error_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_error_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_warning_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_warning_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_info_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_info_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_debug_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_debug_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_disable)(void); \ + } while (0) + +#define IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC_IMPL(module) \ + do { \ + IA_CSS_TRACE_FILE_DUMMY_DEFINE; \ + void IA_CSS_TRACE_CAT(module, _trace_configure)\ + (int argc, const char *const *argv); \ + } while (0) + +#include "platform_support.h" +#include "type_support.h" + +#define IA_CSS_TRACE_DYNAMIC_DEFINE_IMPL(module) \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_assert); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_error); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_warning); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_info); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_debug); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_verbose); \ + \ + void IA_CSS_TRACE_CAT(module, _trace_assert_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_assert) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_assert_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_assert) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_error_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_error) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_error_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_error) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_warning_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_warning) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_warning_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_warning) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_info_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_info) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_info_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_info) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_debug_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_debug) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_debug_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_debug) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_verbose) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_verbose) = 0; \ + } + +#define IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC_IMPL(module) \ +void IA_CSS_TRACE_CAT(module, _trace_configure)(const int argc, \ + const char *const *const argv) \ +{ \ + int i = 1; \ + const char *levels = 0; \ + \ + while (i < argc) { \ + if (!strcmp(argv[i], "-" #module "_trace")) { \ + ++i; \ + \ + if (i < argc) { \ + levels = argv[i]; \ + \ + while (*levels) { \ + switch (*levels++) { \ + case 'a': \ + IA_CSS_TRACE_CAT \ + (module, _trace_assert_enable)(); \ + break; \ + \ + case 'e': \ + IA_CSS_TRACE_CAT \ + (module, _trace_error_enable)(); \ + break; \ + \ + case 'w': \ + IA_CSS_TRACE_CAT \ + (module, _trace_warning_enable)(); \ + break; \ + \ + case 'i': \ + IA_CSS_TRACE_CAT \ + (module, _trace_info_enable)(); \ + break; \ + \ + case 'd': \ + IA_CSS_TRACE_CAT \ + (module, _trace_debug_enable)(); \ + break; \ + \ + case 'v': \ + IA_CSS_TRACE_CAT \ + (module, _trace_verbose_enable)(); \ + break; \ + \ + default: \ + } \ + } \ + } \ + } \ + \ + ++i; \ + } \ +} + +#endif /* __IA_CSS_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/trace/trace.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/trace/trace.mk new file mode 100644 index 0000000000000..b232880b882bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/trace/trace.mk @@ -0,0 +1,40 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE Trace + +# Dependencies +IA_CSS_TRACE_SUPPORT = $${MODULES_DIR}/support + +# API +IA_CSS_TRACE = $${MODULES_DIR}/trace +IA_CSS_TRACE_INTERFACE = $(IA_CSS_TRACE)/interface + +# +# Host +# + +# Host CPP Flags +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE_SUPPORT) +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE_INTERFACE) +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE)/trace_modules + +# +# Firmware +# + +# Firmware CPP Flags +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE_SUPPORT) +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE_INTERFACE) +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE)/trace_modules diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/utils/system_defs/system_const.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/utils/system_defs/system_const.h new file mode 100644 index 0000000000000..161f28fced973 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/utils/system_defs/system_const.h @@ -0,0 +1,26 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __SYSTEM_CONST_H +#define __SYSTEM_CONST_H + +/* The values included in this file should have been + * taken from system/device properties which + * are not currently available in SDK + */ + +#define XMEM_WIDTH (512) +#define MG_PPC (4) + +#endif /* __SYSTEM_CONST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/shared_memory_access.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/shared_memory_access.h new file mode 100644 index 0000000000000..fd11c12367fec --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/shared_memory_access.h @@ -0,0 +1,138 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _SHARED_MEMORY_ACCESS_H +#define _SHARED_MEMORY_ACCESS_H + +#include +#include +#include + +typedef enum { + sm_esuccess, + sm_enomem, + sm_ezeroalloc, + sm_ebadvaddr, + sm_einternalerror, + sm_ecorruption, + sm_enocontiguousmem, + sm_enolocmem, + sm_emultiplefree, +} shared_memory_error; + +/** + * \brief Virtual address of (DDR) shared memory space as seen from the VIED subsystem + */ +typedef uint32_t vied_virtual_address_t; + +/** + * \brief Virtual address of (DDR) shared memory space as seen from the host + */ +typedef unsigned long long host_virtual_address_t; + +/** + * \brief List of physical addresses of (DDR) shared memory space. This is used to represent a list of physical pages. + */ +typedef struct shared_memory_physical_page_list_s *shared_memory_physical_page_list; +typedef struct shared_memory_physical_page_list_s { + shared_memory_physical_page_list next; + vied_physical_address_t address; +} shared_memory_physical_page_list_s; + + +/** + * \brief Initialize the shared memory interface administration on the host. + * \param idm: id of ddr memory + * \param host_ddr_addr: physical address of memory as seen from host + * \param memory_size: size of ddr memory in bytes + * \param ps: size of page in bytes (for instance 4096) + */ +int shared_memory_allocation_initialize(vied_memory_t idm, vied_physical_address_t host_ddr_addr, size_t memory_size, size_t ps); + +/** + * \brief De-initialize the shared memory interface administration on the host. + * + */ +void shared_memory_allocation_uninitialize(vied_memory_t idm); + +/** + * \brief Allocate (DDR) shared memory space and return a host virtual address. Returns NULL when insufficient memory available + */ +host_virtual_address_t shared_memory_alloc(vied_memory_t idm, size_t bytes); + +/** + * \brief Free (DDR) shared memory space. +*/ +void shared_memory_free(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Translate a virtual host.address to a physical address. +*/ +vied_physical_address_t shared_memory_virtual_host_to_physical_address(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Return the allocated physical pages for a virtual host.address. +*/ +shared_memory_physical_page_list shared_memory_virtual_host_to_physical_pages(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Destroy a shared_memory_physical_page_list. +*/ +void shared_memory_physical_pages_list_destroy(shared_memory_physical_page_list ppl); + +/** + * \brief Store a byte into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_8(vied_memory_t idm, host_virtual_address_t addr, uint8_t data); + +/** + * \brief Store a 16-bit word into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_16(vied_memory_t idm, host_virtual_address_t addr, uint16_t data); + +/** + * \brief Store a 32-bit word into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_32(vied_memory_t idm, host_virtual_address_t addr, uint32_t data); + +/** + * \brief Store a number of bytes into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store(vied_memory_t idm, host_virtual_address_t addr, const void *data, size_t bytes); + +/** + * \brief Set a number of bytes of (DDR) shared memory space to 0 using a host virtual address + */ +void shared_memory_zero(vied_memory_t idm, host_virtual_address_t addr, size_t bytes); + +/** + * \brief Load a byte from (DDR) shared memory space using a host virtual address + */ +uint8_t shared_memory_load_8(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a 16-bit word from (DDR) shared memory space using a host virtual address + */ +uint16_t shared_memory_load_16(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a 32-bit word from (DDR) shared memory space using a host virtual address + */ +uint32_t shared_memory_load_32(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a number of bytes from (DDR) shared memory space using a host virtual address + */ +void shared_memory_load(vied_memory_t idm, host_virtual_address_t addr, void *data, size_t bytes); + +#endif /* _SHARED_MEMORY_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/shared_memory_map.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/shared_memory_map.h new file mode 100644 index 0000000000000..1bbedcf9e7fd8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/shared_memory_map.h @@ -0,0 +1,53 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _SHARED_MEMORY_MAP_H +#define _SHARED_MEMORY_MAP_H + +#include +#include +#include + +typedef void (*shared_memory_invalidate_mmu_tlb)(void); +typedef void (*shared_memory_set_page_table_base_address)(vied_physical_address_t); + +typedef void (*shared_memory_invalidate_mmu_tlb_ssid)(vied_subsystem_t id); +typedef void (*shared_memory_set_page_table_base_address_ssid)(vied_subsystem_t id, vied_physical_address_t); + +/** + * \brief Initialize the CSS virtual address system and MMU. The subsystem id will NOT be taken into account. +*/ +int shared_memory_map_initialize(vied_subsystem_t id, vied_memory_t idm, size_t mmu_ps, size_t mmu_pnrs, vied_physical_address_t ddr_addr, shared_memory_invalidate_mmu_tlb inv_tlb, shared_memory_set_page_table_base_address sbt); + +/** + * \brief Initialize the CSS virtual address system and MMU. The subsystem id will be taken into account. +*/ +int shared_memory_map_initialize_ssid(vied_subsystem_t id, vied_memory_t idm, size_t mmu_ps, size_t mmu_pnrs, vied_physical_address_t ddr_addr, shared_memory_invalidate_mmu_tlb_ssid inv_tlb, shared_memory_set_page_table_base_address_ssid sbt); + +/** + * \brief De-initialize the CSS virtual address system and MMU. +*/ +void shared_memory_map_uninitialize(vied_subsystem_t id, vied_memory_t idm); + +/** + * \brief Convert a host virtual address to a CSS virtual address and update the MMU. +*/ +vied_virtual_address_t shared_memory_map(vied_subsystem_t id, vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Free a CSS virtual address and update the MMU. +*/ +void shared_memory_unmap(vied_subsystem_t id, vied_memory_t idm, vied_virtual_address_t addr); + + +#endif /* _SHARED_MEMORY_MAP_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_config.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_config.h new file mode 100644 index 0000000000000..33ae98e27605d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_config.h @@ -0,0 +1,33 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_CONFIG_H +#define _HRT_VIED_CONFIG_H + +/* Defines from the compiler: + * HRT_HOST - this is code running on the host + * HRT_CELL - this is code running on a cell + */ +#ifdef HRT_HOST +# define CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL 1 +# undef CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL + +#elif defined(HRT_CELL) +# undef CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL +# define CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL 1 + +#else /* !HRT_CELL */ +/* Allow neither HRT_HOST nor HRT_CELL for testing purposes */ +#endif /* !HRT_CELL */ + +#endif /* _HRT_VIED_CONFIG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_memory_access_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_memory_access_types.h new file mode 100644 index 0000000000000..0b44492789e37 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_memory_access_types.h @@ -0,0 +1,36 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_MEMORY_ACCESS_TYPES_H +#define _HRT_VIED_MEMORY_ACCESS_TYPES_H + +/** Types for the VIED memory access interface */ + +#include "vied_types.h" + +/** + * \brief An identifier for a system memory. + * + * This identifier must be a compile-time constant. It is used in + * access to system memory. + */ +typedef unsigned int vied_memory_t; + +#ifndef __HIVECC +/** + * \brief The type for a physical address + */ +typedef unsigned long long vied_physical_address_t; +#endif + +#endif /* _HRT_VIED_MEMORY_ACCESS_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_subsystem_access.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_subsystem_access.h new file mode 100644 index 0000000000000..879bcb41253a9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_subsystem_access.h @@ -0,0 +1,70 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_H + +#include +#include "vied_config.h" +#include "vied_subsystem_access_types.h" + +#if !defined(CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL) && \ + !defined(CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL) +#error Implementation selection macro for vied subsystem access not defined +#endif + +#if defined(CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL) +#ifndef __HIVECC +#error "Inline implementation of subsystem access not supported for host" +#endif +#define _VIED_SUBSYSTEM_ACCESS_INLINE static inline +#include "vied_subsystem_access_impl.h" +#else +#define _VIED_SUBSYSTEM_ACCESS_INLINE +#endif + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_8(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint8_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_16(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint16_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_32(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint32_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store(vied_subsystem_t dev, + vied_subsystem_address_t addr, + const void *data, unsigned int size); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint8_t vied_subsystem_load_8(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint16_t vied_subsystem_load_16(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint32_t vied_subsystem_load_32(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_load(vied_subsystem_t dev, + vied_subsystem_address_t addr, + void *data, unsigned int size); + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_subsystem_access_initialization.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_subsystem_access_initialization.h new file mode 100644 index 0000000000000..344f31c4df104 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_subsystem_access_initialization.h @@ -0,0 +1,44 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H + +#include "vied_subsystem_access_types.h" + +/** @brief Initialises the access of a subsystem. + * @param[in] system The subsystem for which the access has to be initialised. + * + * vied_subsystem_access_initialize initilalises the access a subsystem. + * It sets the base address of the subsystem. This base address is extracted from the hsd file. + * + */ +void +vied_subsystem_access_initialize(vied_subsystem_t system); + + +/** @brief Initialises the access of multiple subsystems. + * @param[in] nr _subsystems The number of subsystems for which the access has to be initialised. + * @param[in] dev_base_addresses A pointer to an array of base addresses of subsystems. + * The size of this array must be "nr_subsystems". + * This array must be available during the accesses of the subsystem. + * + * vied_subsystems_access_initialize initilalises the access to multiple subsystems. + * It sets the base addresses of the subsystems that are provided by the array dev_base_addresses. + * + */ +void +vied_subsystems_access_initialize(unsigned int nr_subsystems + , const vied_subsystem_base_address_t *base_addresses); + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_subsystem_access_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_subsystem_access_types.h new file mode 100644 index 0000000000000..75fef6c4ddba2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_subsystem_access_types.h @@ -0,0 +1,34 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H + +/** Types for the VIED subsystem access interface */ +#include + +/** \brief An identifier for a VIED subsystem. + * + * This identifier must be a compile-time constant. It is used in + * access to a VIED subsystem. + */ +typedef unsigned int vied_subsystem_t; + + +/** \brief An address within a VIED subsystem */ +typedef uint32_t vied_subsystem_address_t; + +/** \brief A base address of a VIED subsystem seen from the host */ +typedef unsigned long long vied_subsystem_base_address_t; + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_types.h new file mode 100644 index 0000000000000..0acfdbb00cfa3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600/vied/vied/vied_types.h @@ -0,0 +1,45 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_TYPES_H +#define _HRT_VIED_TYPES_H + +/** Types shared by VIED interfaces */ + +#include + +/** \brief An address within a VIED subsystem + * + * This will eventually replace teh vied_memory_address_t and vied_subsystem_address_t + */ +typedef uint32_t vied_address_t; + +/** \brief Memory address type + * + * A memory address is an offset within a memory. + */ +typedef uint32_t vied_memory_address_t; + +/** \brief Master port id */ +typedef int vied_master_port_id_t; + +/** + * \brief Require the existence of a certain type + * + * This macro can be used in interface header files to ensure that + * an implementation define type with a specified name exists. + */ +#define _VIED_REQUIRE_TYPE(T) enum { _VIED_SIZEOF_##T = sizeof(T) } + + +#endif /* _HRT_VIED_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/Makefile b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/Makefile new file mode 100644 index 0000000000000..c68b63f58cc89 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/Makefile @@ -0,0 +1,52 @@ +# +# Copyright (c) 2010 - 2018 Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# + +ifneq ($(EXTERNAL_BUILD), 1) +srcpath := $(srctree) +endif + +include $(srcpath)/$(src)/../Makefile.ipu4ppsys_src +include $(srcpath)/$(src)/../Makefile.ipu4ppsys_inc + +SSID = 0 +MMID = 0 +IPU_SYSVER = cnl + +IPU_PSYSLIB_ROOT_REL = lib +IPU_PSYSLIB_ROOT = $(srcpath)/$(src)/$(IPU_PSYSLIB_ROOT_REL) + +ccflags-y += -I$(srcpath)/$(src)/../../../ +ccflags-y += -I$(srcpath)/$(src)/../../ +ccflags-y += -DHAS_DUAL_CMD_CTX_SUPPORT=0 -DHAS_LATE_BINDING_SUPPORT=0 -DIPU_PSYS_LEGACY + +IPU_PSYSLIB_SRC += libcsspsys2600.o + +#CFLAGS = -W -Wall -Wstrict-prototypes -Wmissing-prototypes -O2 -fomit-frame-pointer -Wno-unused-variable +HOST_DEFINES += -DSSID=$(SSID) +HOST_DEFINES += -DMMID=$(MMID) +HOST_DEFINES += -DHRT_ON_VIED_SUBSYSTEM_ACCESS=$(SSID) +HOST_DEFINES += -DCFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL +HOST_DEFINES += -DHRT_USE_VIR_ADDRS +HOST_DEFINES += -DHRT_HW +HOST_DEFINES += -DVIED_NCI_TUNIT_PSYS +HOST_DEFINES += -DFIRMWARE_RELEASE_VERSION +HOST_DEFINES += -DPSYS_SERVER_ON_SPC +HOST_DEFINES += -DAPI_SPLIT_START_STATE_UPDATE +HOST_DEFINES += -DHAS_DUAL_CMD_CTX_SUPPORT=0 +HOST_DEFINES += -DHAS_LATE_BINDING_SUPPORT=0 + +intel-ipu4p-psys-csslib-objs := ../../../ipu-wrapper.o \ + $(IPU_PSYSLIB_SRC) +obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu4p-psys-csslib.o + +ccflags-y += $(IPU_PSYSLIB_INC) $(HOST_DEFINES) -fno-common diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/CNL_program_group/ia_css_fw_pkg_release.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/CNL_program_group/ia_css_fw_pkg_release.h new file mode 100644 index 0000000000000..408726c817146 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/CNL_program_group/ia_css_fw_pkg_release.h @@ -0,0 +1,14 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#define IA_CSS_FW_PKG_RELEASE 0x20181222 diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/ICL_program_group/ia_css_fw_pkg_release.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/ICL_program_group/ia_css_fw_pkg_release.h new file mode 100644 index 0000000000000..408726c817146 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/ICL_program_group/ia_css_fw_pkg_release.h @@ -0,0 +1,14 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#define IA_CSS_FW_PKG_RELEASE 0x20181222 diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/buffer.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/buffer.mk new file mode 100644 index 0000000000000..c00a1133b440f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/buffer.mk @@ -0,0 +1,43 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is BUFFER + +ifdef _H_BUFFER_MK +$(error ERROR: buffer.mk included multiple times, please check makefile) +else +_H_BUFFER_MK=1 +endif + +BUFFER_DIR=$${MODULES_DIR}/buffer + +BUFFER_INTERFACE=$(BUFFER_DIR)/interface +BUFFER_SOURCES_CPU=$(BUFFER_DIR)/src/cpu +BUFFER_SOURCES_CSS=$(BUFFER_DIR)/src/css + +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_output_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_input_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/ia_css_shared_buffer.c +BUFFER_HOST_FILES += $(BUFFER_SOURCES_CPU)/buffer_access.c +BUFFER_HOST_CPPFLAGS += -I$(BUFFER_INTERFACE) +BUFFER_HOST_CPPFLAGS += -I$${MODULES_DIR}/support + +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_input_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_output_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/ia_css_shared_buffer.c +BUFFER_FW_FILES += $(BUFFER_SOURCES_CSS)/buffer_access.c + +BUFFER_FW_CPPFLAGS += -I$(BUFFER_INTERFACE) +BUFFER_FW_CPPFLAGS += -I$${MODULES_DIR}/support diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/buffer_access.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/buffer_access.h new file mode 100644 index 0000000000000..e5fe647742c9f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/buffer_access.h @@ -0,0 +1,36 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __BUFFER_ACCESS_H +#define __BUFFER_ACCESS_H + +#include "buffer_type.h" +/* #def to keep consistent the buffer load interfaces for host and css */ +#define IDM 0 + +void +buffer_load( + buffer_address address, + void *data, + unsigned int size, + unsigned int mm_id); + +void +buffer_store( + buffer_address address, + const void *data, + unsigned int size, + unsigned int mm_id); + +#endif /* __BUFFER_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/buffer_type.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/buffer_type.h new file mode 100644 index 0000000000000..de51f23941582 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/buffer_type.h @@ -0,0 +1,29 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __BUFFER_TYPE_H +#define __BUFFER_TYPE_H + +/* portable access to buffers in DDR */ + +#ifdef __VIED_CELL +typedef unsigned int buffer_address; +#else +/* workaround needed because shared_memory_access.h uses size_t */ +#include "type_support.h" +#include "vied/shared_memory_access.h" +typedef host_virtual_address_t buffer_address; +#endif + +#endif /* __BUFFER_TYPE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_buffer_address.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_buffer_address.h new file mode 100644 index 0000000000000..137bfb1fda166 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_buffer_address.h @@ -0,0 +1,24 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BUFFER_ADDRESS_H +#define __IA_CSS_BUFFER_ADDRESS_H + +#include "type_support.h" + +typedef uint32_t ia_css_buffer_address; /* CSS virtual address */ + +#define ia_css_buffer_address_null ((ia_css_buffer_address)0) + +#endif /* __IA_CSS_BUFFER_ADDRESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer.h new file mode 100644 index 0000000000000..4e92e35b61843 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_INPUT_BUFFER_H +#define __IA_CSS_INPUT_BUFFER_H + + +/* Input Buffers */ + +/* A CSS input buffer is a buffer in DDR that can be written by the CPU, + * and that can be read by CSS hardware, after the buffer has been handed over. + * Examples: command buffer, input frame buffer, parameter buffer + * An input buffer must be mapped into the CPU address space before it can be + * written by the CPU. + * After mapping, writing, and unmapping, the buffer can be handed over to the + * firmware. An input buffer is handed over to the CSS by mapping it to the + * CSS address space (by the CPU), and by passing the resulting CSS (virtial) + * address of the input buffer to the DA CSS hardware. + * The firmware can read from an input buffer as soon as it has been received + * CSS virtual address. + * The firmware should not write into an input buffer. + * The firmware hands over the input buffer (back to the CPU) by sending the + * buffer handle via a response. The host should unmap the buffer, + * before reusing it. + * The firmware should not read from the input buffer after returning the + * buffer handle to the CPU. + * + * A buffer may be pre-mapped to the CPU and/or to the CSS upon allocation, + * depending on the allocator's preference. In case of pre-mapped buffers, + * the map and unmap functions will only manage read and write access. + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_input_buffer; /* input buffer handle */ +typedef void *ia_css_input_buffer_cpu_address; /* CPU virtual address */ +/* CSS virtual address */ +typedef ia_css_buffer_address ia_css_input_buffer_css_address; + +#endif /* __IA_CSS_INPUT_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer_cpu.h new file mode 100644 index 0000000000000..d3d01353ce431 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_input_buffer_cpu.h @@ -0,0 +1,49 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_INPUT_BUFFER_CPU_H +#define __IA_CSS_INPUT_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_input_buffer.h" + +ia_css_input_buffer +ia_css_input_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_input_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_input_buffer b); + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_map(ia_css_input_buffer b); + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_unmap(ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map(vied_memory_t mid, ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map_no_invalidate(vied_memory_t mid, ia_css_input_buffer b); + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_unmap(ia_css_input_buffer b); + + +#endif /* __IA_CSS_INPUT_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer.h new file mode 100644 index 0000000000000..2c310ea92c6af --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer.h @@ -0,0 +1,30 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_OUTPUT_BUFFER_H +#define __IA_CSS_OUTPUT_BUFFER_H + +/* Output Buffers */ +/* A CSS output buffer a buffer in DDR that can be written by CSS hardware + * and that can be read by the host, after the buffer has been handed over + * Examples: output frame buffer + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_output_buffer; +typedef void *ia_css_output_buffer_cpu_address; +typedef ia_css_buffer_address ia_css_output_buffer_css_address; + +#endif /* __IA_CSS_OUTPUT_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer_cpu.h new file mode 100644 index 0000000000000..0299fc3b7eb66 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_output_buffer_cpu.h @@ -0,0 +1,48 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_OUTPUT_BUFFER_CPU_H +#define __IA_CSS_OUTPUT_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_output_buffer.h" + +ia_css_output_buffer +ia_css_output_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_output_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_output_buffer b); + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_map(ia_css_output_buffer b); + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_unmap(ia_css_output_buffer b); + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map(vied_memory_t mid, ia_css_output_buffer b); +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map_no_invalidate(vied_memory_t mid, ia_css_output_buffer b); + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_unmap(ia_css_output_buffer b); + + +#endif /* __IA_CSS_OUTPUT_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer.h new file mode 100644 index 0000000000000..558ec679f98a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SHARED_BUFFER_H +#define __IA_CSS_SHARED_BUFFER_H + +/* Shared Buffers */ +/* A CSS shared buffer is a buffer in DDR that can be read and written by the + * CPU and CSS. + * Both the CPU and CSS can have the buffer mapped simultaneously. + * Access rights are not managed by this interface, this could be done by means + * the read and write pointer of a queue, for example. + */ + +#include "ia_css_buffer_address.h" + +typedef struct ia_css_buffer_s *ia_css_shared_buffer; +typedef void *ia_css_shared_buffer_cpu_address; +typedef ia_css_buffer_address ia_css_shared_buffer_css_address; + +#endif /* __IA_CSS_SHARED_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer_cpu.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer_cpu.h new file mode 100644 index 0000000000000..ff62914f99dc3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/interface/ia_css_shared_buffer_cpu.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SHARED_BUFFER_CPU_H +#define __IA_CSS_SHARED_BUFFER_CPU_H + +#include "vied/shared_memory_map.h" +#include "ia_css_shared_buffer.h" + +ia_css_shared_buffer +ia_css_shared_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_shared_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_shared_buffer b); + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_map(ia_css_shared_buffer b); + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_unmap(ia_css_shared_buffer b); + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_map(ia_css_shared_buffer b); + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_unmap(ia_css_shared_buffer b); + +ia_css_shared_buffer +ia_css_shared_buffer_css_update(vied_memory_t mid, ia_css_shared_buffer b); + +ia_css_shared_buffer +ia_css_shared_buffer_cpu_update(vied_memory_t mid, ia_css_shared_buffer b); + +#endif /* __IA_CSS_SHARED_BUFFER_CPU_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/buffer_access.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/buffer_access.c new file mode 100644 index 0000000000000..f0c617fe501a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/buffer_access.c @@ -0,0 +1,39 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/* implementation of buffer access from the CPU */ +/* using shared_memory interface */ + +#include "buffer_access.h" +#include "vied/shared_memory_access.h" + +void +buffer_load( + buffer_address address, + void *data, + unsigned int bytes, + unsigned int mm_id) +{ + shared_memory_load(mm_id, address, data, bytes); +} + +void +buffer_store( + buffer_address address, + const void *data, + unsigned int bytes, + unsigned int mm_id) +{ + shared_memory_store(mm_id, address, data, bytes); +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.c new file mode 100644 index 0000000000000..146d4109de440 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.c @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/* provided interface */ +#include "ia_css_buffer.h" + +/* used interfaces */ +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + +ia_css_buffer_t +ia_css_buffer_alloc(vied_subsystem_t sid, vied_memory_t mid, unsigned int size) +{ + ia_css_buffer_t b; + + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + + b->css_address = shared_memory_map(sid, mid, b->mem); + b->size = size; + return b; +} + + +void +ia_css_buffer_free(vied_subsystem_t sid, vied_memory_t mid, ia_css_buffer_t b) +{ + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.h new file mode 100644 index 0000000000000..a8959fdcd04ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_buffer.h @@ -0,0 +1,58 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BUFFER_H +#define __IA_CSS_BUFFER_H + +/* workaround: needed because uses size_t */ +#include "type_support.h" +#include "vied/shared_memory_map.h" + +typedef enum { + buffer_unmapped, /* buffer is not accessible by cpu, nor css */ + buffer_write, /* output buffer: css has write access */ + /* input buffer: cpu has write access */ + buffer_read, /* input buffer: css has read access */ + /* output buffer: cpu has read access */ + buffer_cpu, /* shared buffer: cpu has read/write access */ + buffer_css /* shared buffer: css has read/write access */ +} buffer_state; + +struct ia_css_buffer_s { + /* number of bytes allocated */ + unsigned int size; + /* allocated virtual memory object */ + host_virtual_address_t mem; + /* virtual address to be used on css/firmware */ + vied_virtual_address_t css_address; + /* virtual address to be used on cpu/host */ + void *cpu_address; + buffer_state state; +}; + +typedef struct ia_css_buffer_s *ia_css_buffer_t; + +ia_css_buffer_t +ia_css_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size); + +void +ia_css_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_buffer_t b); + +#endif /* __IA_CSS_BUFFER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_input_buffer.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_input_buffer.c new file mode 100644 index 0000000000000..2a128795d03e2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_input_buffer.c @@ -0,0 +1,184 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_input_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_input_buffer +ia_css_input_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_input_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_input_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_input_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_map(ia_css_input_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map input buffer to CPU address space, acquire write access */ + b->state = buffer_write; + + /* return pre-mapped buffer */ + return b->cpu_address; +} + + +ia_css_input_buffer_cpu_address +ia_css_input_buffer_cpu_unmap(ia_css_input_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_write) + return NULL; + + /* unmap input buffer from CPU address space, release write access */ + b->state = buffer_unmapped; + + /* return pre-mapped buffer */ + return b->cpu_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map(vied_memory_t mid, ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map input buffer to CSS address space, acquire read access */ + b->state = buffer_read; + + /* now flush the cache */ + ia_css_cpu_mem_cache_flush(b->cpu_address, b->size); +#ifndef HRT_HW + /* only copy in case of simulation, otherwise it should just work */ + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return (ia_css_input_buffer_css_address)b->css_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_map_no_invalidate(vied_memory_t mid, ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map input buffer to CSS address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only copy in case of simulation, otherwise it should just work */ + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return (ia_css_input_buffer_css_address)b->css_address; +} + + +ia_css_input_buffer_css_address +ia_css_input_buffer_css_unmap(ia_css_input_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_read) + return 0; + + /* unmap input buffer from CSS address space, release read access */ + b->state = buffer_unmapped; + + /* input buffer only, no need to invalidate cache */ + + return (ia_css_input_buffer_css_address)b->css_address; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_output_buffer.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_output_buffer.c new file mode 100644 index 0000000000000..30bc8d52a5a9e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_output_buffer.c @@ -0,0 +1,181 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_output_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_output_buffer +ia_css_output_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_output_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_output_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_output_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_map(ia_css_output_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map output buffer to CSS address space, acquire write access */ + b->state = buffer_write; + + return (ia_css_output_buffer_css_address)b->css_address; +} + + +ia_css_output_buffer_css_address +ia_css_output_buffer_css_unmap(ia_css_output_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_write) + return 0; + + /* unmap output buffer from CSS address space, release write access */ + b->state = buffer_unmapped; + + return (ia_css_output_buffer_css_address)b->css_address; +} + + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map(vied_memory_t mid, ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map output buffer to CPU address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only in simulation */ + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + /* now invalidate the cache */ + ia_css_cpu_mem_cache_invalidate(b->cpu_address, b->size); + + return b->cpu_address; +} + + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_map_no_invalidate(vied_memory_t mid, ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map output buffer to CPU address space, acquire read access */ + b->state = buffer_read; + +#ifndef HRT_HW + /* only in simulation */ + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return b->cpu_address; +} + +ia_css_output_buffer_cpu_address +ia_css_output_buffer_cpu_unmap(ia_css_output_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_read) + return NULL; + + /* unmap output buffer from CPU address space, release read access */ + b->state = buffer_unmapped; + + /* output only, no need to flush cache */ + + return b->cpu_address; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_shared_buffer.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_shared_buffer.c new file mode 100644 index 0000000000000..92b7110644fe3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/buffer/src/cpu/ia_css_shared_buffer.c @@ -0,0 +1,187 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_shared_buffer_cpu.h" +#include "ia_css_buffer.h" +#include "vied/shared_memory_access.h" +#include "vied/shared_memory_map.h" +#include "cpu_mem_support.h" + + +ia_css_shared_buffer +ia_css_shared_buffer_alloc( + vied_subsystem_t sid, + vied_memory_t mid, + unsigned int size) +{ + ia_css_shared_buffer b; + + /* allocate buffer container */ + b = ia_css_cpu_mem_alloc(sizeof(*b)); + if (b == NULL) + return NULL; + + b->mem = shared_memory_alloc(mid, size); + if (b->mem == 0) { + ia_css_cpu_mem_free(b); + return NULL; + } + +#ifndef HRT_HW + /* initialize the buffer to avoid warnings when copying */ + shared_memory_zero(mid, b->mem, size); + + /* in simulation, we need to allocate a shadow host buffer */ + b->cpu_address = ia_css_cpu_mem_alloc_page_aligned(size); + if (b->cpu_address == NULL) { + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); + return NULL; + } +#else + /* on hw / real platform we can use the pointer from + * shared memory alloc + */ + b->cpu_address = (void *)HOST_ADDRESS(b->mem); +#endif + + b->css_address = shared_memory_map(sid, mid, b->mem); + + b->size = size; + b->state = buffer_unmapped; + + return b; +} + + +void +ia_css_shared_buffer_free( + vied_subsystem_t sid, + vied_memory_t mid, + ia_css_shared_buffer b) +{ + if (b == NULL) + return; + if (b->state != buffer_unmapped) + return; + +#ifndef HRT_HW + /* only free if we actually allocated it separately */ + ia_css_cpu_mem_free(b->cpu_address); +#endif + shared_memory_unmap(sid, mid, b->css_address); + shared_memory_free(mid, b->mem); + ia_css_cpu_mem_free(b); +} + + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_map(ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_unmapped) + return NULL; + + /* map shared buffer to CPU address space */ + b->state = buffer_cpu; + + return b->cpu_address; +} + + +ia_css_shared_buffer_cpu_address +ia_css_shared_buffer_cpu_unmap(ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + if (b->state != buffer_cpu) + return NULL; + + /* unmap shared buffer from CPU address space */ + b->state = buffer_unmapped; + + return b->cpu_address; +} + + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_map(ia_css_shared_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_unmapped) + return 0; + + /* map shared buffer to CSS address space */ + b->state = buffer_css; + + return (ia_css_shared_buffer_css_address)b->css_address; +} + + +ia_css_shared_buffer_css_address +ia_css_shared_buffer_css_unmap(ia_css_shared_buffer b) +{ + if (b == NULL) + return 0; + if (b->state != buffer_css) + return 0; + + /* unmap shared buffer from CSS address space */ + b->state = buffer_unmapped; + + return (ia_css_shared_buffer_css_address)b->css_address; +} + + +ia_css_shared_buffer +ia_css_shared_buffer_css_update(vied_memory_t mid, ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + + /* flush the buffer to CSS after it was modified by the CPU */ + /* flush cache to ddr */ + ia_css_cpu_mem_cache_flush(b->cpu_address, b->size); +#ifndef HRT_HW + /* copy data from CPU address space to CSS address space */ + shared_memory_store(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + + return b; +} + + +ia_css_shared_buffer +ia_css_shared_buffer_cpu_update(vied_memory_t mid, ia_css_shared_buffer b) +{ + if (b == NULL) + return NULL; + + /* flush the buffer to the CPU after it has been modified by CSS */ +#ifndef HRT_HW + /* copy data from CSS address space to CPU address space */ + shared_memory_load(mid, b->mem, b->cpu_address, b->size); +#else + (void)mid; +#endif + /* flush cache to ddr */ + ia_css_cpu_mem_cache_invalidate(b->cpu_address, b->size); + + return b; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell/cell.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell/cell.mk new file mode 100644 index 0000000000000..fa5e650226017 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell/cell.mk @@ -0,0 +1,43 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +ifndef _CELL_MK_ +_CELL_MK_ = 1 + + +CELL_DIR=$${MODULES_DIR}/cell +CELL_INTERFACE=$(CELL_DIR)/interface +CELL_SOURCES=$(CELL_DIR)/src + +CELL_HOST_FILES = +CELL_FW_FILES = + +CELL_HOST_CPPFLAGS = \ + -I$(CELL_INTERFACE) \ + -I$(CELL_SOURCES) + +CELL_FW_CPPFLAGS = \ + -I$(CELL_INTERFACE) \ + -I$(CELL_SOURCES) + +ifdef 0 +# Disabled until it is decided to go this way or not +include $(MODULES_DIR)/device_access/device_access.mk +CELL_HOST_FILES += $(DEVICE_ACCESS_HOST_FILES) +CELL_FW_FILES += $(DEVICE_ACCESS_FW_FILES) +CELL_HOST_CPPFLAGS += $(DEVICE_ACCESS_HOST_CPPFLAGS) +CELL_FW_CPPFLAGS += $(DEVICE_ACCESS_FW_CPPFLAGS) +endif + +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell/interface/ia_css_cell.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell/interface/ia_css_cell.h new file mode 100644 index 0000000000000..3fac3c791b6e6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell/interface/ia_css_cell.h @@ -0,0 +1,112 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_H +#define __IA_CSS_CELL_H + +#include "storage_class.h" +#include "type_support.h" + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stat_ctrl(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_stat_ctrl(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_pc(unsigned int ssid, unsigned int cell_id, + unsigned int pc); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +#if 0 /* To be implemented after completing cell device properties */ +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_info_bits(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_debug_pc(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stall_bits(unsigned int ssid, unsigned int cell_id); +#endif + +/* configure master ports */ + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_base_address(unsigned int ssid, + unsigned int cell_id, + unsigned int master, unsigned int segment, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_bits(unsigned int ssid, unsigned int cell_id, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_bits(unsigned int ssid, + unsigned int cell_id, + unsigned int master, unsigned int segment, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_override_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_override_bits(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value); + +/* Access memories */ + +STORAGE_CLASS_INLINE void +ia_css_cell_mem_store_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr, unsigned int value); + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_mem_load_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr); + +/***********************************************************************/ + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_is_ready(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_bit(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_set_run_bit(unsigned int ssid, unsigned int cell_id, + unsigned int value); + +STORAGE_CLASS_INLINE void +ia_css_cell_start(unsigned int ssid, unsigned int cell_id); + +STORAGE_CLASS_INLINE void +ia_css_cell_start_prefetch(unsigned int ssid, unsigned int cell_id, + bool prefetch); + +STORAGE_CLASS_INLINE void +ia_css_cell_wait(unsigned int ssid, unsigned int cell_id); + +/* include inline implementation */ +#include "ia_css_cell_impl.h" + +#endif /* __IA_CSS_CELL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell/src/ia_css_cell_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell/src/ia_css_cell_impl.h new file mode 100644 index 0000000000000..60b2e234da1a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell/src/ia_css_cell_impl.h @@ -0,0 +1,272 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_IMPL_H +#define __IA_CSS_CELL_IMPL_H + +#include "ia_css_cell.h" + +#include "ia_css_cmem.h" +#include "ipu_device_cell_properties.h" +#include "storage_class.h" +#include "assert_support.h" +#include "platform_support.h" +#include "misc_support.h" + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_regs_addr(unsigned int cell_id) +{ + /* mem_id 0 is for registers */ + return ipu_device_cell_memory_address(cell_id, 0); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_dmem_addr(unsigned int cell_id) +{ + /* mem_id 1 is for DMEM */ + return ipu_device_cell_memory_address(cell_id, 1); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_mem_store_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr, unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ipu_device_cell_memory_address( + cell_id, mem_id) + addr, value); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_mem_load_32(unsigned int ssid, unsigned int cell_id, + unsigned int mem_id, unsigned int addr) +{ + return ia_css_cmem_load_32( + ssid, ipu_device_cell_memory_address(cell_id, mem_id) + addr); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_get_stat_ctrl(unsigned int ssid, unsigned int cell_id) +{ + return ia_css_cmem_load_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_stat_ctrl(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS, value); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_is_ready(unsigned int ssid, unsigned int cell_id) +{ + unsigned int reg; + + reg = ia_css_cell_get_stat_ctrl(ssid, cell_id); + /* READY must be 1, START must be 0 */ + return (reg & (1 << IPU_DEVICE_CELL_STAT_CTRL_READY_BIT)) && + ((~reg) & (1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT)); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_pc(unsigned int ssid, unsigned int cell_id, + unsigned int pc) +{ + /* set start PC */ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_START_PC_REG_ADDRESS, pc); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_start_bit(unsigned int ssid, unsigned int cell_id) +{ + unsigned int reg; + + reg = 1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT; + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_run_bit(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + unsigned int reg; + + reg = value << IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT; + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_start(unsigned int ssid, unsigned int cell_id) +{ + ia_css_cell_start_prefetch(ssid, cell_id, 0); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_start_prefetch(unsigned int ssid, unsigned int cell_id, + bool prefetch) +{ + unsigned int reg = 0; + + /* Set run bit and start bit */ + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_START_BIT); + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT); + /* Invalidate the icache */ + reg |= (1 << IPU_DEVICE_CELL_STAT_CTRL_INVALIDATE_ICACHE_BIT); + /* Optionally enable prefetching */ + reg |= ((prefetch == 1) ? + (1 << IPU_DEVICE_CELL_STAT_CTRL_ICACHE_ENABLE_PREFETCH_BIT) : + 0); + + /* store into register */ + ia_css_cell_set_stat_ctrl(ssid, cell_id, reg); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_wait(unsigned int ssid, unsigned int cell_id) +{ + do { + ia_css_sleep(); + } while (!ia_css_cell_is_ready(ssid, cell_id)); +}; + +STORAGE_CLASS_INLINE void +ia_css_cell_set_icache_base_address(unsigned int ssid, unsigned int cell_id, + unsigned int value) +{ + ia_css_cmem_store_32( + ssid, ia_css_cell_regs_addr(cell_id) + + IPU_DEVICE_CELL_ICACHE_BASE_REG_ADDRESS, value); +} + +/* master port configuration */ + + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_info_override_bits(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_override_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_segment_base_address(unsigned int ssid, + unsigned int cell, + unsigned int master, unsigned int segment, unsigned int value) + +{ + unsigned int addr; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + assert(segment < ipu_device_cell_master_num_segments(cell, master)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_base_reg(cell, master); + addr += segment * ipu_device_cell_master_stride(cell, master); + ia_css_cmem_store_32(ssid, addr, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_info_override_bits(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_info_override_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cell_set_master_base_address(unsigned int ssid, unsigned int cell, + unsigned int master, unsigned int value) +{ + unsigned int addr, s, stride, num_segments, segment_size; + + assert(cell < ipu_device_cell_num_devices()); + assert(master < ipu_device_cell_num_masters(cell)); + + addr = ipu_device_cell_memory_address(cell, 0); + addr += ipu_device_cell_master_base_reg(cell, master); + stride = ipu_device_cell_master_stride(cell, master); + num_segments = ipu_device_cell_master_num_segments(cell, master); + segment_size = ipu_device_cell_master_segment_size(cell, master); + + for (s = 0; s < num_segments; s++) { + ia_css_cmem_store_32(ssid, addr, value); + addr += stride; + value += segment_size; + } +} + +#endif /* __IA_CSS_CELL_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/cell_program_load.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/cell_program_load.mk new file mode 100644 index 0000000000000..ec5389aff4a0a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/cell_program_load.mk @@ -0,0 +1,39 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +ifndef _CELL_PROGRAM_LOAD_MK_ +_CELL_PROGRAM_LOAD_MK_ = 1 + +CELL_PROGRAM_LOAD_DIR=$${MODULES_DIR}/cell_program_load +CELL_PROGRAM_LOAD_INTERFACE=$(CELL_PROGRAM_LOAD_DIR)/interface +CELL_PROGRAM_LOAD_SOURCES=$(CELL_PROGRAM_LOAD_DIR)/src + +CELL_PROGRAM_LOAD_HOST_FILES = $(CELL_PROGRAM_LOAD_SOURCES)/ia_css_cell_program_load.c + +CELL_PROGRAM_LOAD_FW_FILES = $(CELL_PROGRAM_LOAD_SOURCES)/ia_css_cell_program_load.c + +CELL_PROGRAM_LOAD_HOST_CPPFLAGS = \ + -I$(CELL_PROGRAM_LOAD_INTERFACE) \ + -I$(CELL_PROGRAM_LOAD_SOURCES) + +CELL_PROGRAM_LOAD_FW_CPPFLAGS = \ + -I$(CELL_PROGRAM_LOAD_INTERFACE) \ + -I$(CELL_PROGRAM_LOAD_SOURCES) + +ifeq ($(CRUN_DYNAMIC_LINK_PROGRAMS), 1) +CELL_PROGRAM_LOAD_HOST_CPPFLAGS += -DCRUN_DYNAMIC_LINK_PROGRAMS=1 +CELL_PROGRAM_LOAD_FW_CPPFLAGS += -DCRUN_DYNAMIC_LINK_PROGRAMS=1 +endif + +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_group_load.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_group_load.h new file mode 100644 index 0000000000000..812dd4ea09a84 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_group_load.h @@ -0,0 +1,76 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_PROGRAM_GROUP_LOAD_H +#define __IA_CSS_CELL_PROGRAM_GROUP_LOAD_H + +#include "ia_css_cell_program_load_storage_class.h" +#include "ia_css_xmem.h" +#include "ia_css_cell_program_struct.h" + +/* Load all programs in program group + * Return 0 on success, -1 on incorrect magic number, + * -2 on incorrect release tag + */ + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_group_load( + unsigned int ssid, + unsigned int mmid, + /* program address as seen from caller */ + ia_css_xmem_address_t program_addr, + /* program address as seen from cell's icache */ + unsigned int program_addr_icache +); + +/* Load all programs in program group + * each group may have multiple entry function. This function will return + * the info of each entry function to allow user start any of them + * Return 0 on success, -1 on incorrect magic number, + * -2 on incorrect release tag + */ + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_group_load_multi_entry( + unsigned int ssid, + unsigned int mmid, + /* program address as seen from caller */ + ia_css_xmem_address_t program_addr, + /* program address as seen from cell's icache */ + unsigned int program_addr_icache, + struct ia_css_cell_program_entry_func_info_s *entry_info, + unsigned int num_entry_info +); + +/* Load all programs in program group, except icache of first program + */ + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_group_load_mem( + unsigned int ssid, + unsigned int mmid, + /* program address as seen from caller */ + ia_css_xmem_address_t program_addr, + /* program address as seen from cell's icache */ + unsigned int program_addr_icache +); + +#ifdef __INLINE_IA_CSS_CELL_PROGRAM_LOAD__ +#include "ia_css_cell_program_group_load_impl.h" +#endif + +#endif /* __IA_CSS_CELL_PROGRAM_GROUP_LOAD_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_load.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_load.h new file mode 100644 index 0000000000000..0f1674c769d0a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_load.h @@ -0,0 +1,114 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_PROGRAM_LOAD_H +#define __IA_CSS_CELL_PROGRAM_LOAD_H + +#include "ia_css_cell_program_load_storage_class.h" +#include "ia_css_cell_program_struct.h" +#include "ia_css_xmem.h" + +/* Perform full program load: + * - load program header + * - initialize icache and start PC of exec entry function + * - initialize PMEM and DMEM + * Return 0 on success, -1 on incorrect magic number, + * -2 on incorrect release tag + */ + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_load( + unsigned int ssid, + unsigned int mmid, + /* program address as seen from caller */ + ia_css_xmem_address_t program_addr, + /* program address as seen from cell's icache */ + unsigned int program_addr_icache +); + +/* Perform full program load: + * - load program header + * - initialize icache and start PC of exec entry function + * - initialize info of all entry function + * - initialize PMEM and DMEM + * Return 0 on success, -1 on incorrect magic number, + * -2 on incorrect release tag + */ + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_load_multi_entry( + unsigned int ssid, + unsigned int mmid, + /* program address as seen from caller */ + ia_css_xmem_address_t program_addr, + /* program address as seen from cell's icache */ + unsigned int program_addr_icache, + struct ia_css_cell_program_entry_func_info_s *entry_info +); + +/* Load program header, and initialize icache and start PC. + * After this, the cell may be started, but the entry function may not yet use + * global data, nor may code from PMEM be executed. + * Before accessing global data or executing code from PMEM + * the function ia_css_cell_load_program_mem must be executed. + */ + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_load_icache( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t program_addr, + unsigned int program_addr_icache); + +/* Load program header and finish the program load by + * initializing PMEM and DMEM. + * After this any code from the program may be executed on the cell. + */ +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_load_mem( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t program_addr, + unsigned int program_addr_icache); + +/* set cell start PC to program init entry function */ +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +void +ia_css_cell_program_load_set_init_start_pc( + unsigned int ssid, + const struct ia_css_cell_program_entry_func_info_s *entry_info); + +/* set cell start PC to program exec entry function */ +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +void +ia_css_cell_program_load_set_exec_start_pc( + unsigned int ssid, + const struct ia_css_cell_program_entry_func_info_s *entry_info); + +/* set cell start PC to program done entry function */ +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +void +ia_css_cell_program_load_set_done_start_pc( + unsigned int ssid, + const struct ia_css_cell_program_entry_func_info_s *entry_info); + +#ifdef __INLINE_IA_CSS_CELL_PROGRAM_LOAD__ +#include "ia_css_cell_program_load_impl.h" +#endif + +#endif /* __IA_CSS_CELL_PROGRAM_LOAD_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_load_prog.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_load_prog.h new file mode 100644 index 0000000000000..0f8f1852449c1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_load_prog.h @@ -0,0 +1,84 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_PROGRAM_LOAD_PROG_H +#define __IA_CSS_CELL_PROGRAM_LOAD_PROG_H + +/* basic functions needed to implement all program(group) loads */ + +#include "ia_css_cell_program_load_storage_class.h" +#include "ia_css_cell_program_struct.h" +#include "ia_css_xmem.h" + + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +void +ia_css_cell_program_load_encode_entry_info( + struct ia_css_cell_program_entry_func_info_s *entry_info, + const struct ia_css_cell_program_s *prog); + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +void +ia_css_cell_program_load_set_start_pc( + unsigned int ssid, + const struct ia_css_cell_program_entry_func_info_s *entry_info, + enum ia_css_cell_program_entry_func_id func_id); + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_load_header( + unsigned int mmid, + ia_css_xmem_address_t host_addr, + struct ia_css_cell_program_s *prog); + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_load_icache_prog( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr, + const struct ia_css_cell_program_s *prog); + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_load_entry_prog( + unsigned int ssid, + unsigned int mmid, + enum ia_css_cell_program_entry_func_id entry_func_id, + const struct ia_css_cell_program_s *prog); + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_load_mem_prog( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr, + const struct ia_css_cell_program_s *prog); + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +int +ia_css_cell_program_load_prog( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr, + struct ia_css_cell_program_s *prog); + +#ifdef __INLINE_IA_CSS_CELL_PROGRAM_LOAD__ +#include "ia_css_cell_program_load_prog_impl.h" +#endif + +#endif /* __IA_CSS_CELL_PROGRAM_LOAD_PROG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_load_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_load_storage_class.h new file mode 100644 index 0000000000000..8691e1402eaf8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_load_storage_class.h @@ -0,0 +1,28 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H +#define __IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifdef __INLINE_IA_CSS_CELL_PROGRAM_LOAD__ +#define IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#else +#define IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C +#endif + +#endif /* __IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_struct.h new file mode 100644 index 0000000000000..de3c3682ff8df --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/interface/ia_css_cell_program_struct.h @@ -0,0 +1,114 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_PROGRAM_STRUCT_H +#define __IA_CSS_CELL_PROGRAM_STRUCT_H + +#define IA_CSS_CELL_ID_UNDEFINED 0xFFFFFFFF +#define IA_CSS_CELL_PROGRAM_MAGIC_NUMBER 0xF1A30002 + +#define CSIM_PROGRAM_NAME_SIZE 64 + +enum ia_css_cell_program_entry_func_id { + IA_CSS_CELL_PROGRAM_INIT_FUNC_ID, + IA_CSS_CELL_PROGRAM_EXEC_FUNC_ID, + IA_CSS_CELL_PROGRAM_DONE_FUNC_ID, + IA_CSS_CELL_PROGRAM_NUM_FUNC_ID, +}; + +struct ia_css_cell_program_entry_func_info_s { + /* start PC value of program entry functions */ + unsigned int start[IA_CSS_CELL_PROGRAM_NUM_FUNC_ID]; + +#if defined(C_RUN) + /* entry function names */ + char func_name[IA_CSS_CELL_PROGRAM_NUM_FUNC_ID][CSIM_PROGRAM_NAME_SIZE]; + /* for crun use only */ + unsigned int cell_id; +#endif + /* base address for cell's registers */ + unsigned int regs_addr; + +}; + +struct ia_css_cell_program_s { + /* must be equal to IA_CSS_CELL_PROGRAM_MAGIC_NUMBER */ + unsigned int magic_number; + + /* offset of blob relative to start of this struct */ + unsigned int blob_offset; + /* size of the blob, not used */ + unsigned int blob_size; + + /* start PC value of program entry functions */ + unsigned int start[IA_CSS_CELL_PROGRAM_NUM_FUNC_ID]; + +#if defined(C_RUN) || defined(HRT_UNSCHED) || defined(HRT_SCHED) + /* program name */ + char prog_name[CSIM_PROGRAM_NAME_SIZE]; +#if defined(C_RUN) + /* entry function names */ + char func_name[IA_CSS_CELL_PROGRAM_NUM_FUNC_ID][CSIM_PROGRAM_NAME_SIZE]; +#endif +#endif + + /* offset of icache section in blob */ + unsigned int icache_source; + /* offset in the instruction space, not used */ + unsigned int icache_target; + /* icache section size, not used */ + unsigned int icache_size; + + /* offset of pmem section in blob */ + unsigned int pmem_source; + /* offset in the pmem, typically 0 */ + unsigned int pmem_target; + /* pmem section size, 0 if not used */ + unsigned int pmem_size; + + /* offset of data section in blob */ + unsigned int data_source; + /* offset of data section in dmem */ + unsigned int data_target; + /* size of dmem data section */ + unsigned int data_size; + + /* offset of bss section in dmem, to be zeroed */ + unsigned int bss_target; + /* size of bss section in dmem */ + unsigned int bss_size; + + /* for checking */ + unsigned int cell_id; + /* base address for cell's registers */ + unsigned int regs_addr; + + /* pmem data bus address */ + unsigned int cell_pmem_data_bus_addres; + /* dmem data bus address */ + unsigned int cell_dmem_data_bus_addres; + /* pmem config bus address */ + unsigned int cell_pmem_control_bus_addres; + /* dmem config bus address */ + unsigned int cell_dmem_control_bus_addres; + + /* offset to header of next program */ + unsigned int next; + /* Temporary workaround for a dma bug where it fails to trasfer + * data with size which is not multiple of 64 bytes + */ + unsigned int dummy[2]; +}; + +#endif /* __IA_CSS_CELL_PROGRAM_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_group_load_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_group_load_impl.h new file mode 100644 index 0000000000000..20d71bb25d495 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_group_load_impl.h @@ -0,0 +1,128 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_PROGRAM_GROUP_LOAD_IMPL_H +#define __IA_CSS_CELL_PROGRAM_GROUP_LOAD_IMPL_H + +#include "ia_css_cell_program_group_load.h" + +#include "ia_css_cell_program_load_storage_class.h" +#include "ia_css_cell_program_load_prog.h" +#include "ia_css_cell_program_struct.h" + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C +int +ia_css_cell_program_group_load( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr) +{ + struct ia_css_cell_program_s prog; + unsigned int next; + int status = 0; + + do { + status = ia_css_cell_program_load_prog( + ssid, mmid, host_addr, vied_addr, &prog); + if (status) + return status; + + next = prog.next; + host_addr = + (ia_css_xmem_address_t)((unsigned long long)host_addr + next); + vied_addr += next; + } while (next); + + return status; +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C +int +ia_css_cell_program_group_load_multi_entry( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr, + struct ia_css_cell_program_entry_func_info_s *entry_info, + unsigned int num_entry_info) +{ + struct ia_css_cell_program_s prog; + unsigned int next; + int status = 0; + unsigned int i = 0; + + do { + status = ia_css_cell_program_load_prog( + ssid, mmid, host_addr, vied_addr, &prog); + if (status) + return status; + if (i >= num_entry_info) { + /* more program than entry info, + * cause access out of bound. + */ + return 1; + } + ia_css_cell_program_load_encode_entry_info( + &entry_info[i], &prog); + + next = prog.next; + host_addr = + (ia_css_xmem_address_t)((unsigned long long)host_addr + next); + vied_addr += next; + i++; + } while (next); + + return status; +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C +int +ia_css_cell_program_group_load_mem( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr) +{ + struct ia_css_cell_program_s prog; + unsigned int next; + int status = 0; + + status = ia_css_cell_program_load_header(mmid, host_addr, &prog); + if (status) + return status; + + /* load memories of first program */ + status = ia_css_cell_program_load_mem_prog( + ssid, mmid, host_addr, vied_addr, &prog); + if (status) + return status; + + /* return next from ia_css_cell_program_load_mem_prog? */ + next = prog.next; + + /* load next programs, if any */ + if (next) { + host_addr = + (ia_css_xmem_address_t)((unsigned long long)host_addr + next); + status = ia_css_cell_program_group_load( + ssid, mmid, host_addr, vied_addr + next); + if (status) + return status; + } + + return status; +} + +#endif /* __IA_CSS_CELL_PROGRAM_GROUP_LOAD_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load.c new file mode 100644 index 0000000000000..0a1ea1ac2ed1e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load.c @@ -0,0 +1,31 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifdef __INLINE_IA_CSS_CELL_PROGRAM_LOAD__ + +#include "storage_class.h" +STORAGE_CLASS_INLINE void __dummy(void) { } + +#else + +/* low-level functions */ +#include "ia_css_cell_program_load_prog_impl.h" + +/* functions for single, unmapped program load */ +#include "ia_css_cell_program_load_impl.h" + +/* functions for program group load */ +#include "ia_css_cell_program_group_load_impl.h" + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load_bin.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load_bin.h new file mode 100644 index 0000000000000..523ce536cb099 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load_bin.h @@ -0,0 +1,193 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_PROGRAM_LOAD_BIN_H +#define __IA_CSS_CELL_PROGRAM_LOAD_BIN_H + +#include "ia_css_cell_program_load_prog.h" + +#include "ia_css_cell_program_load_storage_class.h" +#include "ia_css_cell_program_struct.h" +#include "ia_css_cell_regs.h" +#include "misc_support.h" +#include "ia_css_fw_load.h" +#include "platform_support.h" +#include "ipu_device_buttress_properties_struct.h" + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C +void +ia_css_cell_program_load_encode_entry_info( + struct ia_css_cell_program_entry_func_info_s *entry_info, + const struct ia_css_cell_program_s *prog) +{ + unsigned int i; + + for (i = 0; i < IA_CSS_CELL_PROGRAM_NUM_FUNC_ID; i++) + entry_info->start[i] = prog->start[i]; + + entry_info->regs_addr = prog->regs_addr; +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C +void +ia_css_cell_program_load_set_start_pc( + unsigned int ssid, + const struct ia_css_cell_program_entry_func_info_s *entry_info, + enum ia_css_cell_program_entry_func_id func_id) +{ + unsigned int start_pc; + + start_pc = entry_info->start[func_id]; + /* set start address */ + ia_css_cell_regs_set_start_pc(ssid, entry_info->regs_addr, start_pc); +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C +int +ia_css_cell_program_load_icache_prog( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr, + const struct ia_css_cell_program_s *prog) +{ + unsigned int regs_addr; + struct ia_css_cell_program_entry_func_info_s entry_info; + + NOT_USED(mmid); + NOT_USED(host_addr); + + if (prog->cell_id == IA_CSS_CELL_ID_UNDEFINED) + return -1; + + regs_addr = prog->regs_addr; + + /* set icache base address */ + ia_css_cell_regs_set_icache_base_address(ssid, regs_addr, + vied_addr + prog->blob_offset + prog->icache_source); + + /* set icache info bits */ + ia_css_cell_regs_set_icache_info_bits( + ssid, regs_addr, IA_CSS_INFO_BITS_M0_DDR); + + /* by default we set to start PC of exec entry function */ + ia_css_cell_program_load_encode_entry_info(&entry_info, prog); + ia_css_cell_program_load_set_start_pc( + ssid, &entry_info, IA_CSS_CELL_PROGRAM_EXEC_FUNC_ID); + + return 0; +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C +int +ia_css_cell_program_load_entry_prog( + unsigned int ssid, + unsigned int mmid, + enum ia_css_cell_program_entry_func_id entry_func_id, + const struct ia_css_cell_program_s *prog) +{ + struct ia_css_cell_program_entry_func_info_s entry_info; + + NOT_USED(mmid); + + if (prog->cell_id == IA_CSS_CELL_ID_UNDEFINED) + return -1; + + ia_css_cell_program_load_encode_entry_info(&entry_info, prog); + ia_css_cell_program_load_set_start_pc(ssid, &entry_info, entry_func_id); + + return 0; +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C int +ia_css_cell_program_load_mem_prog( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr, + const struct ia_css_cell_program_s *prog) +{ + unsigned int transferred = 0; + unsigned int pending = 0; + unsigned int dmem_addr; + unsigned int pmem_addr; + + NOT_USED(vied_addr); + +#ifdef ENABLE_FW_LOAD_DMA + pmem_addr = prog->cell_pmem_data_bus_addres; + dmem_addr = prog->cell_dmem_data_bus_addres; +#else + pmem_addr = prog->cell_pmem_control_bus_addres; + dmem_addr = prog->cell_dmem_control_bus_addres; +#endif + + /* Copy text section from ddr to pmem. */ + if (prog->pmem_size) { + transferred = ia_css_fw_copy_begin(mmid, + ssid, + host_addr + prog->blob_offset + + prog->pmem_source, + pmem_addr + prog->pmem_target, + prog->pmem_size); + + assert(prog->pmem_size == transferred); + /* If less bytes are transferred that requested, signal error, + * This architecture enforces DMA xfer size > pmem_size. + * So, a DMA transfer request should be xferable*/ + if (transferred != prog->pmem_size) + return 1; + pending++; + } + + /* Copy data section from ddr to dmem. */ + if (prog->data_size) { + transferred = ia_css_fw_copy_begin(mmid, + ssid, + host_addr + prog->blob_offset + + prog->data_source, + dmem_addr + prog->data_target, + prog->data_size); + assert(prog->data_size == transferred); + /* If less bytes are transferred that requested, signal error, + * This architecture enforces DMA xfer size > data_size. + * So, a DMA transfer request should be xferable*/ + if (transferred != prog->data_size) + return 1; /*FALSE*/ + pending++; + } + + /* Zero bss section in dmem.*/ + if (prog->bss_size) { + transferred = ia_css_fw_zero_begin(ssid, + dmem_addr + prog->bss_target, + prog->bss_size); + assert(prog->bss_size == transferred); + /* If less bytes are transferred that requested, signal error, + * This architecture enforces DMA xfer size > bss_size. + * So, a DMA transfer request should be xferable*/ + if (transferred != prog->bss_size) + return 1; + pending++; + } + + /* Wait for all fw load to complete */ + while (pending) { + pending -= ia_css_fw_end(pending); + ia_css_sleep(); + } + return 0; /*Success*/ +} + +#endif /* __IA_CSS_CELL_PROGRAM_LOAD_BIN_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load_impl.h new file mode 100644 index 0000000000000..6201fd583482d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load_impl.h @@ -0,0 +1,134 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_PROGRAM_LOAD_IMPL_H +#define __IA_CSS_CELL_PROGRAM_LOAD_IMPL_H + +#include "ia_css_cell_program_load.h" + +#include "ia_css_cell_program_load_storage_class.h" +#include "ia_css_cell_program_load_prog.h" +#include "ia_css_cell_program_struct.h" + + + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C int +ia_css_cell_program_load( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr) +{ + struct ia_css_cell_program_s prog; + int status; + + status = ia_css_cell_program_load_prog( + ssid, mmid, host_addr, vied_addr, &prog); + + return status; +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C int +ia_css_cell_program_load_multi_entry( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr, + struct ia_css_cell_program_entry_func_info_s *entry_info) +{ + struct ia_css_cell_program_s prog; + int status; + + status = ia_css_cell_program_load_prog( + ssid, mmid, host_addr, vied_addr, &prog); + if (status) + return status; + + ia_css_cell_program_load_encode_entry_info(entry_info, &prog); + + return status; +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C int +ia_css_cell_program_load_icache( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr) +{ + struct ia_css_cell_program_s prog; + int status; + + status = ia_css_cell_program_load_header(mmid, host_addr, &prog); + if (status) + return status; + + status = ia_css_cell_program_load_icache_prog( + ssid, mmid, host_addr, vied_addr, &prog); + return status; +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C int +ia_css_cell_program_load_mem( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr) +{ + struct ia_css_cell_program_s prog; + int status; + + status = ia_css_cell_program_load_header(mmid, host_addr, &prog); + if (status) + return status; + + status = ia_css_cell_program_load_mem_prog( + ssid, mmid, host_addr, vied_addr, &prog); + return status; +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C void +ia_css_cell_program_load_set_init_start_pc( + unsigned int ssid, + const struct ia_css_cell_program_entry_func_info_s *entry_info) +{ + assert(entry_info != NULL); + + ia_css_cell_program_load_set_start_pc(ssid, entry_info, + IA_CSS_CELL_PROGRAM_INIT_FUNC_ID); +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C void +ia_css_cell_program_load_set_exec_start_pc( + unsigned int ssid, + const struct ia_css_cell_program_entry_func_info_s *entry_info) +{ + assert(entry_info != NULL); + + ia_css_cell_program_load_set_start_pc(ssid, entry_info, + IA_CSS_CELL_PROGRAM_EXEC_FUNC_ID); +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C void +ia_css_cell_program_load_set_done_start_pc( + unsigned int ssid, + const struct ia_css_cell_program_entry_func_info_s *entry_info) +{ + assert(entry_info != NULL); + + ia_css_cell_program_load_set_start_pc(ssid, entry_info, + IA_CSS_CELL_PROGRAM_DONE_FUNC_ID); +} + +#endif /* __IA_CSS_CELL_PROGRAM_LOAD_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load_prog_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load_prog_impl.h new file mode 100644 index 0000000000000..f20bc2f6da52a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_program_load_prog_impl.h @@ -0,0 +1,76 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_PROGRAM_LOAD_PROG_IMPL_H +#define __IA_CSS_CELL_PROGRAM_LOAD_PROG_IMPL_H + +#include "ia_css_cell_program_load_prog.h" +#include "ia_css_fw_load.h" + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C +int +ia_css_cell_program_load_prog( + unsigned int ssid, + unsigned int mmid, + ia_css_xmem_address_t host_addr, + unsigned int vied_addr, + struct ia_css_cell_program_s *prog) +{ + int status; + + status = ia_css_cell_program_load_header(mmid, host_addr, prog); + if (status) + return status; + + status = ia_css_cell_program_load_icache_prog( + ssid, mmid, host_addr, vied_addr, prog); + if (status) + return status; + + status = ia_css_cell_program_load_mem_prog( + ssid, mmid, host_addr, vied_addr, prog); + if (status) + return status; + + return status; +} + +IA_CSS_CELL_PROGRAM_LOAD_STORAGE_CLASS_C +int +ia_css_cell_program_load_header( + unsigned int mmid, + ia_css_xmem_address_t host_addr, + struct ia_css_cell_program_s *prog) +{ + + /* read the program header from DDR */ + ia_css_fw_load(mmid, + host_addr, + prog, + sizeof(struct ia_css_cell_program_s)); + + /* check magic number */ + if (prog->magic_number != IA_CSS_CELL_PROGRAM_MAGIC_NUMBER) + return -1; + + return 0; +} + +#if defined(C_RUN) || defined(HRT_UNSCHED) || defined(HRT_SCHED) +#include "ia_css_cell_program_load_csim.h" +#else +#include "ia_css_cell_program_load_bin.h" +#endif + +#endif /* __IA_CSS_CELL_PROGRAM_LOAD_PROG_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_regs.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_regs.h new file mode 100644 index 0000000000000..4eb283b58de69 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cell_program_load/src/ia_css_cell_regs.h @@ -0,0 +1,78 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CELL_REGS_H +#define __IA_CSS_CELL_REGS_H + +#include "storage_class.h" +#include "ipu_device_cell_type_properties.h" +#include "ia_css_cmem.h" + +STORAGE_CLASS_INLINE void +ia_css_cell_regs_set_stat_ctrl(unsigned int ssid, unsigned int regs_addr, + unsigned int value) +{ + ia_css_cmem_store_32(ssid, + regs_addr + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS, value); +} + +STORAGE_CLASS_INLINE unsigned int +ia_css_cell_regs_get_stat_ctrl(unsigned int ssid, unsigned int regs_addr) +{ + return ia_css_cmem_load_32(ssid, + regs_addr + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_icache_invalidate(unsigned int ssid, unsigned int regs_addr) +{ + ia_css_cell_regs_set_stat_ctrl(ssid, regs_addr, + 1u << IPU_DEVICE_CELL_STAT_CTRL_INVALIDATE_ICACHE_BIT); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_regs_set_start_pc(unsigned int ssid, unsigned int regs_addr, + unsigned int pc) +{ + ia_css_cmem_store_32(ssid, + regs_addr + IPU_DEVICE_CELL_START_PC_REG_ADDRESS, pc); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_regs_set_icache_base_address(unsigned int ssid, + unsigned int regs_addr, + unsigned int value) +{ + ia_css_cmem_store_32(ssid, + regs_addr + IPU_DEVICE_CELL_ICACHE_BASE_REG_ADDRESS, value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_regs_set_icache_info_bits(unsigned int ssid, + unsigned int regs_addr, + unsigned int value) +{ + ia_css_cmem_store_32(ssid, + regs_addr + IPU_DEVICE_CELL_ICACHE_INFO_BITS_REG_ADDRESS, + value); +} + +STORAGE_CLASS_INLINE void +ia_css_cell_regs_icache_invalidate(unsigned int ssid, unsigned int regs_addr) +{ + ia_css_cell_regs_set_stat_ctrl(ssid, regs_addr, + 1u << IPU_DEVICE_CELL_STAT_CTRL_INVALIDATE_ICACHE_BIT); +} + +#endif /* __IA_CSS_CELL_REGS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg.h new file mode 100644 index 0000000000000..e8b0a48b27e33 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg.h @@ -0,0 +1,60 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CLIENT_PKG_H +#define __IA_CSS_CLIENT_PKG_H + +#include "type_support.h" +#include "ia_css_client_pkg_storage_class.h" +/* for ia_css_client_pkg_header_s (ptr only), ia_css_client_pkg_t */ +#include "ia_css_client_pkg_types.h" + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +int ia_css_client_pkg_get_pg_manifest_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size); + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +int ia_css_client_pkg_get_prog_list_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size); + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +int ia_css_client_pkg_get_prog_desc_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size); + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +int ia_css_client_pkg_get_prog_bin_entry_offset_size( + const ia_css_client_pkg_t *client_pkg, + uint32_t program_id, + uint32_t *offset, + uint32_t *size); + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +int ia_css_client_pkg_get_indexed_prog_desc_entry_offset_size( + const ia_css_client_pkg_t *client_pkg, + uint32_t program_id, + uint32_t program_index, + uint32_t *offset, + uint32_t *size); + +#ifdef __INLINE_CLIENT_PKG__ +#include "ia_css_client_pkg_impl.h" +#endif + +#endif /* __IA_CSS_CLIENT_PKG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_storage_class.h new file mode 100644 index 0000000000000..98af98d5d824d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_storage_class.h @@ -0,0 +1,28 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CLIENT_PKG_STORAGE_CLASS_H +#define __IA_CSS_CLIENT_PKG_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __INLINE_CLIENT_PKG__ +#define IA_CSS_CLIENT_PKG_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +#else +#define IA_CSS_CLIENT_PKG_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_CLIENT_PKG_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_CLIENT_PKG_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_types.h new file mode 100644 index 0000000000000..ff5bf01358f1a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/interface/ia_css_client_pkg_types.h @@ -0,0 +1,44 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CLIENT_PKG_TYPES_H +#define __IA_CSS_CLIENT_PKG_TYPES_H + +#include "type_support.h" + +typedef void ia_css_client_pkg_t; + +struct ia_css_client_pkg_header_s { + uint32_t prog_list_offset; + uint32_t prog_list_size; + uint32_t prog_desc_offset; + uint32_t prog_desc_size; + uint32_t pg_manifest_offset; + uint32_t pg_manifest_size; + uint32_t prog_bin_offset; + uint32_t prog_bin_size; +}; + +struct ia_css_client_pkg_prog_s { + uint32_t prog_id; + uint32_t prog_offset; + uint32_t prog_size; +}; + +struct ia_css_client_pkg_prog_list_s { + uint32_t prog_desc_count; + uint32_t prog_bin_count; +}; + +#endif /* __IA_CSS_CLIENT_PKG_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg.c new file mode 100644 index 0000000000000..0b2fd86d09f36 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg.c @@ -0,0 +1,20 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifdef __INLINE_CLIENT_PKG__ +#include "storage_class.h" +STORAGE_CLASS_INLINE int __ia_css_client_pkg_avoid_warning_on_empty_file(void) { return 0; } +#else /* __INLINE_CLIENT_PKG__ */ +#include "ia_css_client_pkg_impl.h" +#endif /* __INLINE_CLIENT_PKG__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg_impl.h new file mode 100644 index 0000000000000..11ce55d8c669e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/client_pkg/src/ia_css_client_pkg_impl.h @@ -0,0 +1,161 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CLIENT_PKG_IMPL_H +#define __IA_CSS_CLIENT_PKG_IMPL_H + +#include "ia_css_client_pkg.h" +#include "ia_css_client_pkg_types.h" +#include "error_support.h" + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +int ia_css_client_pkg_get_pg_manifest_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size) +{ + int ret_val = -1; + + verifjmpexit(client_pkg_header != NULL); + verifjmpexit(offset != NULL); + verifjmpexit(size != NULL); + + *(offset) = client_pkg_header->pg_manifest_offset; + *(size) = client_pkg_header->pg_manifest_size; + ret_val = 0; +EXIT: + return ret_val; +} + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +int ia_css_client_pkg_get_prog_list_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size) +{ + int ret_val = -1; + + verifjmpexit(client_pkg_header != NULL); + verifjmpexit(offset != NULL); + verifjmpexit(size != NULL); + + *(offset) = client_pkg_header->prog_list_offset; + *(size) = client_pkg_header->prog_list_size; + ret_val = 0; +EXIT: + return ret_val; +} + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +int ia_css_client_pkg_get_prog_desc_offset_size( + const struct ia_css_client_pkg_header_s *client_pkg_header, + uint32_t *offset, + uint32_t *size) +{ + int ret_val = -1; + + verifjmpexit(client_pkg_header != NULL); + verifjmpexit(offset != NULL); + verifjmpexit(size != NULL); + + *(offset) = client_pkg_header->prog_desc_offset; + *(size) = client_pkg_header->prog_desc_size; + ret_val = 0; +EXIT: + return ret_val; +} + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +int ia_css_client_pkg_get_prog_bin_entry_offset_size( + const ia_css_client_pkg_t *client_pkg, + uint32_t program_id, + uint32_t *offset, + uint32_t *size) +{ + uint8_t i; + int ret_val = -1; + struct ia_css_client_pkg_header_s *client_pkg_header = NULL; + const struct ia_css_client_pkg_prog_list_s *pkg_prog_list = NULL; + const struct ia_css_client_pkg_prog_s *pkg_prog_bin_entry = NULL; + + verifjmpexit(client_pkg != NULL); + verifjmpexit(offset != NULL); + verifjmpexit(size != NULL); + + client_pkg_header = + (struct ia_css_client_pkg_header_s *)((uint8_t *)client_pkg); + pkg_prog_list = + (struct ia_css_client_pkg_prog_list_s *)((uint8_t *)client_pkg + + client_pkg_header->prog_list_offset); + pkg_prog_bin_entry = + (struct ia_css_client_pkg_prog_s *)((uint8_t *)pkg_prog_list + + sizeof(struct ia_css_client_pkg_prog_list_s)); + pkg_prog_bin_entry += pkg_prog_list->prog_desc_count; + + for (i = 0; i < pkg_prog_list->prog_bin_count; i++) { + if (program_id == pkg_prog_bin_entry->prog_id) { + *(offset) = pkg_prog_bin_entry->prog_offset; + *(size) = pkg_prog_bin_entry->prog_size; + ret_val = 0; + break; + } else if (pkg_prog_bin_entry->prog_size == 0) { + /* We can have a variable number of program descriptors. + * The first non-valid one will have size set to 0 + */ + break; + } + pkg_prog_bin_entry++; + } +EXIT: + return ret_val; +} + +IA_CSS_CLIENT_PKG_STORAGE_CLASS_C +int ia_css_client_pkg_get_indexed_prog_desc_entry_offset_size( + const ia_css_client_pkg_t *client_pkg, + uint32_t program_id, + uint32_t program_index, + uint32_t *offset, + uint32_t *size) +{ + int ret_val = -1; + struct ia_css_client_pkg_header_s *client_pkg_header = NULL; + const struct ia_css_client_pkg_prog_list_s *pkg_prog_list = NULL; + const struct ia_css_client_pkg_prog_s *pkg_prog_desc_entry = NULL; + + verifjmpexit(client_pkg != NULL); + verifjmpexit(offset != NULL); + verifjmpexit(size != NULL); + + client_pkg_header = + (struct ia_css_client_pkg_header_s *)((uint8_t *)client_pkg); + pkg_prog_list = + (struct ia_css_client_pkg_prog_list_s *)((uint8_t *)client_pkg + + client_pkg_header->prog_list_offset); + pkg_prog_desc_entry = + (struct ia_css_client_pkg_prog_s *)((uint8_t *)pkg_prog_list + + sizeof(struct ia_css_client_pkg_prog_list_s)); + + verifjmpexit(program_index < pkg_prog_list->prog_desc_count); + verifjmpexit(program_id == pkg_prog_desc_entry[program_index].prog_id); + verifjmpexit(pkg_prog_desc_entry[program_index].prog_size > 0); + *(offset) = pkg_prog_desc_entry[program_index].prog_offset; + *(size) = pkg_prog_desc_entry[program_index].prog_size; + ret_val = 0; + +EXIT: + return ret_val; +} + +#endif /* __IA_CSS_CLIENT_PKG_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/config/psys/subsystem_cnlB0.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/config/psys/subsystem_cnlB0.mk new file mode 100644 index 0000000000000..be397a0646bd3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/config/psys/subsystem_cnlB0.mk @@ -0,0 +1,138 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +############################################################################ +# This file is used to specify versions and properties of PSYS firmware +# components. Please note that these are subsystem specific. System specific +# properties should go to system_$IPU_SYSVER.mk. Also the device versions +# should be defined under "devices" or should be taken from the SDK. +############################################################################ + +# define for DPCM Compression/ Decompression module +HAS_DPCM = 1 + +# See HSD 1805169230 +HAS_FWDMA_ALIGNMENT_ISSUE_SIGHTING = 1 + +# Activate loading params and storing stats DDR<->REGs with DMA. +PSYS_USE_ISA_DMA = 1 + +# Used in ISA module +PSYS_ISL_DPC_DPC_V2 = 0 + +# Use the DMA for terminal loading in Psys server +PSYS_SERVER_ENABLE_TERMINAL_LOAD_DMA = 1 + +# Assume OFS will be running concurrently with IPF, and prioritize according to rates of services on devproxy +CONCURRENT_OFS_IPF_PRIORITY_OPTIMIZATION_ENABLED = 1 + +# Enable clock gating of input feeder ibufctrl +ENABLE_IPFD_IBUFCTRL_CLK_GATE = 1 + +# Enable clock gating of input slice light ibufctrl +ENABLE_ISL_IBUFCTRL_CLK_GATE = 1 + +# Enable clock gating of GDC0 +ENABLE_GDC0_CLK_GATE = 1 + + +# define for VCA_VCR2_FF +HAS_VCA_VCR2_FF = 1 + +HAS_GMEM = 1 +HAS_64KB_GDC_MEM = 1 + +# define for enabling mmu_stream_id_lut support +ENABLE_MMU_STREAM_ID_LUT = 1 + +# define for enabling rgbir related chnages in devproxy +HAS_RGBIR = 1 + +# Specification for Psys server's fixed globals' locations +REGMEM_OFFSET = 0 +REGMEM_SECURE_OFFSET = 4096 +REGMEM_SIZE = 20 +REGMEM_WORD_BYTES = 4 +REGMEM_SIZE_BYTES = 80 +GPC_ISP_PERF_DATA_OFFSET = 80 # Taken from REGMEM_OFFSET + REGMEM_SIZE_BYTES +GPC_ISP_PERF_DATA_SIZE_BYTES = 80 +FW_LOAD_NO_OF_REQUEST_OFFSET = 160 # Taken from GPC_ISP_PERF_DATA_OFFSET + GPC_ISP_PERF_DATA_SIZE_BYTES +FW_LOAD_NO_OF_REQUEST_SIZE_BYTES = 4 +DISPATCHER_SCRATCH_SPACE_OFFSET = 4176 # Taken from REGMEM_SECURE_OFFSET + REGMEM_SIZE_BYTES +# Total Used (@ REGMEM_OFFSET) = 164 # FW_LOAD_NO_OF_REQUEST_OFFSET + FW_LOAD_NO_OF_REQUEST_SIZE_BYTES +# Total Used (@ REGMEM_SECURE_OFFSET) = 80 # REGMEM_SIZE_BYTES + +# use DMA NCI for OFS Service to reduce load in tproxy +DMA_NCI_IN_OFS_SERVICE = 1 +# TODO use version naming scheme "v#" to decouple +# IPU_SYSVER from version. +PSYS_SERVER_MANIFEST_VERSION = cnlB0 +PSYS_RESOURCE_MODEL_VERSION = cnlB0 +PSYS_ACCESS_BLOCKER_VERSION = v1 + +# Disable support for PPG protocol to save codesize +PSYS_HAS_PPG_SUPPORT = 0 +# Disable support for late binding +PSYS_HAS_LATE_BINDING_SUPPORT = 0 + +# Specify PSYS server context spaces for caching context from DDR +PSYS_SERVER_NOF_CACHES = 4 +PSYS_SERVER_MAX_NUM_PROC_GRP = $(PSYS_SERVER_NOF_CACHES) +PSYS_SERVER_MAX_NUM_EXEC_PROC_GRP = 8 # Max PG's running, 4 running on Cores, 4 being updated on the host upon executing. +PSYS_SERVER_MAX_PROC_GRP_SIZE = 3352 +PSYS_SERVER_MAX_MANIFEST_SIZE = 3420 +PSYS_SERVER_MAX_CLIENT_PKG_SIZE = 2360 +PSYS_SERVER_MAX_BUFFER_SET_SIZE = 0 +PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_SECTIONS = 90 +PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_STORE_SECTIONS = 1 +# The caching scheme for this subsystem suits the method of queueing ahead separate PGs for frames in an interleaved +# fashion. As such there should be as many caches to support to heaviest two concurrent PGs, times two. This results +# in the following distribution of caches: two large ones for the maximum sized PG, two smaller ones for the +# second-largest sized PG. +PSYS_SERVER_CACHE_0_PROC_GRP_SIZE = $(PSYS_SERVER_MAX_PROC_GRP_SIZE) +PSYS_SERVER_CACHE_0_MANIFEST_SIZE = $(PSYS_SERVER_MAX_MANIFEST_SIZE) +PSYS_SERVER_CACHE_0_CLIENT_PKG_SIZE = $(PSYS_SERVER_MAX_CLIENT_PKG_SIZE) +PSYS_SERVER_CACHE_0_BUFFER_SET_SIZE = $(PSYS_SERVER_MAX_BUFFER_SET_SIZE) +PSYS_SERVER_CACHE_0_NUMBER_OF_TERMINAL_SECTIONS = $(PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_SECTIONS) +PSYS_SERVER_CACHE_0_NUMBER_OF_TERMINAL_STORE_SECTIONS = $(PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_STORE_SECTIONS) +PSYS_SERVER_CACHE_1_PROC_GRP_SIZE = $(PSYS_SERVER_CACHE_0_PROC_GRP_SIZE) +PSYS_SERVER_CACHE_1_MANIFEST_SIZE = $(PSYS_SERVER_CACHE_0_MANIFEST_SIZE) +PSYS_SERVER_CACHE_1_CLIENT_PKG_SIZE = $(PSYS_SERVER_CACHE_0_CLIENT_PKG_SIZE) +PSYS_SERVER_CACHE_1_BUFFER_SET_SIZE = $(PSYS_SERVER_CACHE_0_BUFFER_SET_SIZE) +PSYS_SERVER_CACHE_1_NUMBER_OF_TERMINAL_SECTIONS = $(PSYS_SERVER_CACHE_0_NUMBER_OF_TERMINAL_SECTIONS) +PSYS_SERVER_CACHE_1_NUMBER_OF_TERMINAL_STORE_SECTIONS = $(PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_STORE_SECTIONS) +PSYS_SERVER_CACHE_2_PROC_GRP_SIZE = 1624 +PSYS_SERVER_CACHE_2_MANIFEST_SIZE = 1248 +PSYS_SERVER_CACHE_2_CLIENT_PKG_SIZE = 1040 +PSYS_SERVER_CACHE_2_BUFFER_SET_SIZE = 0 +PSYS_SERVER_CACHE_2_NUMBER_OF_TERMINAL_SECTIONS = 43 +PSYS_SERVER_CACHE_2_NUMBER_OF_TERMINAL_STORE_SECTIONS = $(PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_STORE_SECTIONS) +PSYS_SERVER_CACHE_3_PROC_GRP_SIZE = $(PSYS_SERVER_CACHE_2_PROC_GRP_SIZE) +PSYS_SERVER_CACHE_3_MANIFEST_SIZE = $(PSYS_SERVER_CACHE_2_MANIFEST_SIZE) +PSYS_SERVER_CACHE_3_CLIENT_PKG_SIZE = $(PSYS_SERVER_CACHE_2_CLIENT_PKG_SIZE) +PSYS_SERVER_CACHE_3_BUFFER_SET_SIZE = $(PSYS_SERVER_CACHE_2_BUFFER_SET_SIZE) +PSYS_SERVER_CACHE_3_NUMBER_OF_TERMINAL_SECTIONS = $(PSYS_SERVER_CACHE_2_NUMBER_OF_TERMINAL_SECTIONS) +PSYS_SERVER_CACHE_3_NUMBER_OF_TERMINAL_STORE_SECTIONS = $(PSYS_SERVER_MAX_NUMBER_OF_TERMINAL_STORE_SECTIONS) +# Support dual command context for VTIO - concurrent secure and non-secure streams +PSYS_HAS_DUAL_CMD_CTX_SUPPORT = 1 + +HAS_SPC = 1 +HAS_SPP0 = 1 +HAS_SPP1 = 1 +HAS_ISP0 = 1 +HAS_ISP1 = 1 +HAS_ISP2 = 1 +HAS_ISP3 = 1 + +AB_CONFIG_ARRAY_SIZE = 50 diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/config/system_cnlB0.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/config/system_cnlB0.mk new file mode 100644 index 0000000000000..667282b519c4c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/config/system_cnlB0.mk @@ -0,0 +1,96 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +#--- DEFINES REQUIRED TO COMPILE USING LLVM --- +# Enable LLVM/Volcano for IPU4P, SPs only. +VOLCANO_IPU4P = 1 +VOLCANO_SP2601 = 1 +#---------------------------------------------- + +# enable NO_ALIAS for LLVM +ENABLE_NO_ALIAS_FOR_LLVM = 1 + +LOGICAL_FW_INPUT_SYSTEM = input_system_system +LOGICAL_FW_PROCESSING_SYSTEM = processing_system_system +LOGICAL_FW_IPU_SYSTEM = ipu_system +LOGICAL_FW_ISP_SYSTEM = isp2601_default_system +SP_CONTROL_CELL = sp2601_control +SP_PROXY_CELL = sp2601_proxy +ISP_CELL = isp2601 +# The non-capital define isp2601 is used in the sdk, in order to distinguish +# between different isp versions the ISP_CELL_IDENTIFIER define is added. +ISP_CELL_IDENTIFIER = ISP2601 +HAS_IPFD = 1 +HAS_S2M_IN_ISYS_ISL_NONSOC_PATH = 0 +HAS_S2V_IN_ISYS_ISL_NONSOC_PATH = 1 +# ISL-IS non-SoC path has ISA with PAF and DPC-Pext support for IPU4P-B0 +HAS_ISA_IN_ISYS_ISL = 1 +HAS_PAF_IN_ISYS_ISL = 1 +HAS_DPC_PEXT_IN_ISYS_ISL = 1 +HAS_PMA_IF = 1 + +HAS_MIPIBE_IN_PSYS_ISL = 1 + +HAS_VPLESS_SUPPORT = 0 + +DLI_SYSTEM = hive_isp_css_2600_system +RESOURCE_MANAGER_VERSION = v2 +MEM_RESOURCE_VALIDATION_ERROR = 0 +OFS_SCALER_1_4K_TILEY_422_SUPPORT= 1 +PROGDESC_ACC_SYMBOLS_VERSION = v1 +DEVPROXY_INTERFACE_VERSION = v1 +FW_ABI_IPU_TYPES_VERSION = v1 + +HAS_ONLINE_MODE_SUPPORT_IN_ISYS_PSYS = 0 + +MMU_INTERFACE_VERSION = v2 +DEVICE_ACCESS_VERSION = v2 +PSYS_SERVER_VERSION = v3 +PSYS_SERVER_LOADER_VERSION = v1 +PSYS_HW_VERSION = CNL_B0_HW + +# Enable FW_DMA for loading firmware +PSYS_SERVER_ENABLE_FW_LOAD_DMA = 1 + +NCI_SPA_VERSION = v1 +MANIFEST_TOOL_VERSION = v2 +PSYS_CON_MGR_TOOL_VERSION = v1 +# TODO: Should be removed after performance issues OTF are solved +PSYS_PROC_MGR_VERSION = v1 +IPU_RESOURCES_VERSION = v2 + +HAS_ACC_CLUSTER_PAF_PAL = 1 +HAS_ACC_CLUSTER_PEXT_PAL = 1 +HAS_ACC_CLUSTER_GBL_PAL = 1 + +# TODO use version naming scheme "v#" to decouple +# IPU_SYSVER from version. +PARAMBINTOOL_ISA_INIT_VERSION = cnlB0 + +# Select EQC2EQ version +# Version 1: uniform address space, equal EQ addresses regardless of EQC device +# Version 2: multiple addresses per EQ, depending on location of EQC device +EQC2EQ_VERSION = v1 + +# Select DMA instance for fw_load +FW_LOAD_DMA_INSTANCE = NCI_DMA_FW + +HAS_DMA_FW = 1 + +HAS_SIS = 0 +HAS_IDS = 1 + +PSYS_SERVER_ENABLE_TPROXY = 1 +PSYS_SERVER_ENABLE_DEVPROXY = 1 +NCI_OFS_VERSION = v1 diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_component/cpd_component.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_component/cpd_component.mk new file mode 100644 index 0000000000000..8ecc3e42e55d3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_component/cpd_component.mk @@ -0,0 +1,28 @@ +## +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +## + +# MODULE is cpd/cpd_component + +CPD_DIR = $${MODULES_DIR}/cpd +CPD_COMPONENT_DIR = $${MODULES_DIR}/cpd/cpd_component +CPD_COMPONENT_INTERFACE = $(CPD_COMPONENT_DIR)/interface +CPD_COMPONENT_SOURCES = $(CPD_COMPONENT_DIR)/src + +CPD_COMPONENT_FILES = $(CPD_COMPONENT_SOURCES)/ia_css_cpd_component_create.c +CPD_COMPONENT_FILES += $(CPD_COMPONENT_SOURCES)/ia_css_cpd_component.c +CPD_COMPONENT_CPPFLAGS = -I$(CPD_COMPONENT_INTERFACE) +CPD_COMPONENT_CPPFLAGS += -I$(CPD_COMPONENT_SOURCES) +CPD_COMPONENT_CPPFLAGS += -I$(CPD_DIR) diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_component/interface/ia_css_cpd_component_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_component/interface/ia_css_cpd_component_types.h new file mode 100644 index 0000000000000..7ad3070b2fd72 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_component/interface/ia_css_cpd_component_types.h @@ -0,0 +1,90 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_CPD_COMPONENT_TYPES_H +#define __IA_CSS_CPD_COMPONENT_TYPES_H + +/** @file + * This file contains datastructure related to generation of CPD file + */ + +#include "type_support.h" + +#define SIZE_OF_FW_ARCH_VERSION 7 +#define SIZE_OF_SYSTEM_VERSION 11 +#define SIZE_OF_COMPONENT_NAME 12 + +enum ia_css_cpd_component_endianness { + IA_CSSCPD_COMP_ENDIAN_RSVD, + IA_CSS_CPD_COMP_LITTLE_ENDIAN, + IA_CSS_CPD_COMP_BIG_ENDIAN +}; + +/** Module Data (components) Header + * Following data structure has been created using FAS section 5.25 + * Open : Should we add padding at the end of module directory + * (the component must be 512 aligned) + */ +typedef struct { + uint32_t header_size; + /**< Specifies endianness of the binary data */ + unsigned int endianness; + /**< fw_pkg_date is current date stored in 'binary decimal' + * representation e.g. 538248729 (0x20150619) + */ + uint32_t fw_pkg_date; + /**< hive_sdk_date is date of HIVE_SDK stored in + * 'binary decimal' representation + */ + uint32_t hive_sdk_date; + /**< compiler_date is date of ptools stored in + * 'binary decimal' representation + */ + uint32_t compiler_date; + /**< UNSCHED / SCHED / TARGET / CRUN */ + unsigned int target_platform_type; + /**< specifies the system version stored as string + * e.g. BXTB0_IPU4'\0' + */ + uint8_t system_version[SIZE_OF_SYSTEM_VERSION]; + /**< specifies fw architecture version e.g. for BXT CSS3.0'\0' */ + uint8_t fw_arch_version[SIZE_OF_FW_ARCH_VERSION]; + uint8_t rsvd[2]; +} ia_css_header_component_t; + +/** Module Data Directory = Directory Header + Directory Entry (0..n) + * Following two Data Structure has been taken from CSE Storage FAS (CPD desgin) + * Module Data Directory Header + */ +typedef struct { + uint32_t header_marker; + uint32_t number_of_entries; + uint8_t header_version; + uint8_t entry_version; + uint8_t header_length; /**< 0x10 (16) Fixed for this version*/ + uint8_t checksum; + uint32_t partition_name; +} ia_css_directory_header_component_t; + +/** Module Date Directory Entry + */ +typedef struct { + /**< character string describing the component name */ + uint8_t entry_name[SIZE_OF_COMPONENT_NAME]; + uint32_t offset; + uint32_t length; + uint32_t rsvd; /**< Must be 0 */ +} ia_css_directory_entry_component_t; + +#endif /* __IA_CSS_CPD_COMPONENT_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_metadata/cpd_metadata.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_metadata/cpd_metadata.mk new file mode 100644 index 0000000000000..ac78815dfbd8c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_metadata/cpd_metadata.mk @@ -0,0 +1,29 @@ +## +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +## + + +# MODULE is CPD UTL (Metadata File Extension) + +CPD_DIR = $${MODULES_DIR}/cpd/ +CPD_METADATA_DIR = $${MODULES_DIR}/cpd/cpd_metadata +CPD_METADATA_INTERFACE = $(CPD_METADATA_DIR)/interface +CPD_METADATA_SOURCES = $(CPD_METADATA_DIR)/src + +CPD_METADATA_FILES = $(CPD_METADATA_SOURCES)/ia_css_cpd_metadata_create.c +CPD_METADATA_FILES += $(CPD_METADATA_SOURCES)/ia_css_cpd_metadata.c +CPD_METADATA_CPPFLAGS = -I$(CPD_METADATA_INTERFACE) \ + -I$(CPD_METADATA_SOURCES) \ + -I$(CPD_DIR) diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_metadata/interface/ia_css_cpd_metadata_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_metadata/interface/ia_css_cpd_metadata_types.h new file mode 100644 index 0000000000000..a88c6aede08c5 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/cpd/cpd_metadata/interface/ia_css_cpd_metadata_types.h @@ -0,0 +1,111 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_CPD_METADATA_TYPES_H +#define __IA_CSS_CPD_METADATA_TYPES_H + +/** @file + * This file contains data structures related to generation of + * metadata file extension + */ +#include + +/* As per v0.2 manifest document + * Header = Extension Type (4) + Extension Length (4) + + * iUnit Image Type (4) + Reserved (16) + */ +#define IPU_METADATA_HEADER_RSVD_SIZE 16 +#define IPU_METADATA_HEADER_FIELDS_SIZE 12 +#define IPU_METADATA_HEADER_SIZE \ + (IPU_METADATA_HEADER_FIELDS_SIZE + IPU_METADATA_HEADER_RSVD_SIZE) + +/* iUnit metadata extension tpye value */ +#define IPU_METADATA_EXTENSION_TYPE 16 + +/* Unique id for level 0 bootloader component */ +#define IA_CSS_IUNIT_BTLDR_ID 0 +/* Unique id for psys server program group component */ +#define IA_CSS_IUNIT_PSYS_SERVER_ID 1 +/* Unique id for isys server program group component */ +#define IA_CSS_IUNIT_ISYS_SERVER_ID 2 +/* Initial Identifier for client program group component */ +#define IA_CSS_IUNIT_CLIENT_ID 3 + +/* Use this to parse date from release version from the iUnit component + * e.g. 20150701 + */ +#define IA_CSS_IUNIT_COMP_DATE_SIZE 8 +/* offset of release version in program group binary + * e.g. release_version = "scci_gerrit_20150716_2117" + * In cpd file we only use date/version for the component + */ +#define IA_CSS_IUNIT_DATE_OFFSET 12 + +#define IPU_METADATA_HASH_KEY_SIZE 32 +#define IPU_METADATA_ATTRIBUTE_SIZE 16 +#define IA_CSE_METADATA_COMPONENT_ID_MAX 127 + +typedef enum { + IA_CSS_CPD_METADATA_IMAGE_TYPE_RESERVED, + IA_CSS_CPD_METADATA_IMAGE_TYPE_BOOTLOADER, + IA_CSS_CPD_METADATA_IMAGE_TYPE_MAIN_FIRMWARE +} ia_css_cpd_metadata_image_type_t; + +typedef enum { + IA_CSS_CPD_MAIN_FW_TYPE_RESERVED, + IA_CSS_CPD_MAIN_FW_TYPE_PSYS_SERVER, + IA_CSS_CPD_MAIN_FW_TYPE_ISYS_SERVER, + IA_CSS_CPD_MAIN_FW_TYPE_CLIENT +} ia_css_cpd_iunit_main_fw_type_t; + +/** Data structure for component specific information + * Following data structure has been taken from CSE Manifest v0.2 + */ +typedef struct { + /**< Component ID - unique for each component */ + uint32_t id; + /**< Size of the components */ + uint32_t size; + /**< Version/date of when the components is being generated/created */ + uint32_t version; + /**< SHA 256 Hash Key for component */ + uint8_t sha2_hash[IPU_METADATA_HASH_KEY_SIZE]; + /**< component sp entry point + * - Only valid for btldr/psys/isys server component + */ + uint32_t entry_point; + /**< component icache base address + * - Only valid for btldr/psys/isys server component + */ + uint32_t icache_base_offset; + /**< Resevred - must be 0 */ + uint8_t attributes[IPU_METADATA_ATTRIBUTE_SIZE]; +} ia_css_cpd_metadata_component_t; + +/** Data structure for Metadata File Extension Header + */ +typedef struct { + /**< Specifies the binary image type + * - could be bootloader or main firmware + */ + ia_css_cpd_metadata_image_type_t image_type; + /**< Number of components available in metadata file extension + * (For btldr always 1) + */ + uint32_t component_count; + /**< Component specific information */ + ia_css_cpd_metadata_component_t *components; +} ia_css_cpd_metadata_desc_t; + +#endif /* __IA_CSS_CPD_METADATA_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/device_access.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/device_access.mk new file mode 100644 index 0000000000000..1629d9af803b6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/device_access.mk @@ -0,0 +1,40 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# + +ifndef _DEVICE_ACCESS_MK_ +_DEVICE_ACCESS_MK_ = 1 + +# DEVICE_ACCESS_VERSION= +include $(MODULES_DIR)/config/system_$(IPU_SYSVER).mk + +DEVICE_ACCESS_DIR=$${MODULES_DIR}/device_access +DEVICE_ACCESS_INTERFACE=$(DEVICE_ACCESS_DIR)/interface +DEVICE_ACCESS_SOURCES=$(DEVICE_ACCESS_DIR)/src + +DEVICE_ACCESS_HOST_FILES = + +DEVICE_ACCESS_FW_FILES = + +DEVICE_ACCESS_HOST_CPPFLAGS = \ + -I$(DEVICE_ACCESS_INTERFACE) \ + -I$(DEVICE_ACCESS_SOURCES) + +DEVICE_ACCESS_FW_CPPFLAGS = \ + -I$(DEVICE_ACCESS_INTERFACE) \ + -I$(DEVICE_ACCESS_SOURCES) + +DEVICE_ACCESS_FW_CPPFLAGS += \ + -I$(DEVICE_ACCESS_SOURCES)/$(DEVICE_ACCESS_VERSION) +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/interface/ia_css_cmem.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/interface/ia_css_cmem.h new file mode 100644 index 0000000000000..3dc47c29fcab7 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/interface/ia_css_cmem.h @@ -0,0 +1,58 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CMEM_H +#define __IA_CSS_CMEM_H + +#include "type_support.h" +#include "storage_class.h" + +#ifdef __VIED_CELL +typedef unsigned int ia_css_cmem_address_t; +#else +#include +typedef vied_subsystem_address_t ia_css_cmem_address_t; +#endif + +STORAGE_CLASS_INLINE uint32_t +ia_css_cmem_load_32(unsigned int ssid, ia_css_cmem_address_t address); + +STORAGE_CLASS_INLINE void +ia_css_cmem_store_32(unsigned int ssid, ia_css_cmem_address_t address, + uint32_t value); + +STORAGE_CLASS_INLINE void +ia_css_cmem_load(unsigned int ssid, ia_css_cmem_address_t address, void *data, + unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_cmem_store(unsigned int ssid, ia_css_cmem_address_t address, + const void *data, unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_cmem_zero(unsigned int ssid, ia_css_cmem_address_t address, + unsigned int size); + +STORAGE_CLASS_INLINE ia_css_cmem_address_t +ia_css_cmem_get_cmem_addr_from_dmem(unsigned int base_addr, void *p); + +/* Include inline implementation */ + +#ifdef __VIED_CELL +#include "ia_css_cmem_cell.h" +#else +#include "ia_css_cmem_host.h" +#endif + +#endif /* __IA_CSS_CMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/interface/ia_css_xmem.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/interface/ia_css_xmem.h new file mode 100644 index 0000000000000..de2b94d8af541 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/interface/ia_css_xmem.h @@ -0,0 +1,65 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_H +#define __IA_CSS_XMEM_H + +#include "type_support.h" +#include "storage_class.h" + +#ifdef __VIED_CELL +typedef unsigned int ia_css_xmem_address_t; +#else +#include +typedef host_virtual_address_t ia_css_xmem_address_t; +#endif + +STORAGE_CLASS_INLINE uint8_t +ia_css_xmem_load_8(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE uint16_t +ia_css_xmem_load_16(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE uint32_t +ia_css_xmem_load_32(unsigned int mmid, ia_css_xmem_address_t address); + +STORAGE_CLASS_INLINE void +ia_css_xmem_load(unsigned int mmid, ia_css_xmem_address_t address, void *data, + unsigned int size); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_8(unsigned int mmid, ia_css_xmem_address_t address, + uint8_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_16(unsigned int mmid, ia_css_xmem_address_t address, + uint16_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_32(unsigned int mmid, ia_css_xmem_address_t address, + uint32_t value); + +STORAGE_CLASS_INLINE void +ia_css_xmem_store(unsigned int mmid, ia_css_xmem_address_t address, + const void *data, unsigned int bytes); + +/* Include inline implementation */ + +#ifdef __VIED_CELL +#include "ia_css_xmem_cell.h" +#else +#include "ia_css_xmem_host.h" +#endif + +#endif /* __IA_CSS_XMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/interface/ia_css_xmem_cmem.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/interface/ia_css_xmem_cmem.h new file mode 100644 index 0000000000000..57aab3323c739 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/interface/ia_css_xmem_cmem.h @@ -0,0 +1,35 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_CMEM_H +#define __IA_CSS_XMEM_CMEM_H + +#include "ia_css_cmem.h" +#include "ia_css_xmem.h" + +/* Copy data from xmem to cmem, e.g., from a program in DDR to a cell's DMEM */ +/* This may also be implemented using DMA */ + +STORAGE_CLASS_INLINE void +ia_css_xmem_to_cmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size); + +/* include inline implementation */ +#include "ia_css_xmem_cmem_impl.h" + +#endif /* __IA_CSS_XMEM_CMEM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/src/ia_css_cmem_host.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/src/ia_css_cmem_host.h new file mode 100644 index 0000000000000..22799e67214c1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/src/ia_css_cmem_host.h @@ -0,0 +1,121 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_CMEM_HOST_H +#define __IA_CSS_CMEM_HOST_H + +/* This file is an inline implementation for the interface ia_css_cmem.h + * and should only be included there. */ + +#include "assert_support.h" +#include "misc_support.h" + +STORAGE_CLASS_INLINE uint32_t +ia_css_cmem_load_32(unsigned int ssid, ia_css_cmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + return vied_subsystem_load_32(ssid, address); +} + +STORAGE_CLASS_INLINE uint32_t +ia_css_cond_cmem_load_32(bool cond, unsigned int ssid, + ia_css_cmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + if (cond) + return vied_subsystem_load_32(ssid, address); + else + return 0; +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_store_32(unsigned int ssid, ia_css_cmem_address_t address, + uint32_t data) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + vied_subsystem_store_32(ssid, address, data); +} + +STORAGE_CLASS_INLINE void +ia_css_cond_cmem_store_32(bool cond, unsigned int ssid, + ia_css_cmem_address_t address, uint32_t data) +{ + /* Address has to be word aligned */ + assert(0 == address % 4); + if (cond) + vied_subsystem_store_32(ssid, address, data); +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_load(unsigned int ssid, ia_css_cmem_address_t address, void *data, + unsigned int size) +{ + uint32_t *data32 = (uint32_t *)data; + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + assert((long)data % 4 == 0); + + while (address != end) { + *data32 = ia_css_cmem_load_32(ssid, address); + address += 4; + data32 += 1; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_store(unsigned int ssid, ia_css_cmem_address_t address, + const void *data, unsigned int size) +{ + uint32_t *data32 = (uint32_t *)data; + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + assert((long)data % 4 == 0); + + while (address != end) { + ia_css_cmem_store_32(ssid, address, *data32); + address += 4; + data32 += 1; + } +} + +STORAGE_CLASS_INLINE void +ia_css_cmem_zero(unsigned int ssid, ia_css_cmem_address_t address, + unsigned int size) +{ + uint32_t end = address + size; + + assert(size % 4 == 0); + assert(address % 4 == 0); + + while (address != end) { + ia_css_cmem_store_32(ssid, address, 0); + address += 4; + } +} + +STORAGE_CLASS_INLINE ia_css_cmem_address_t +ia_css_cmem_get_cmem_addr_from_dmem(unsigned int base_addr, void *p) +{ + NOT_USED(base_addr); + return (ia_css_cmem_address_t)(uintptr_t)p; +} + +#endif /* __IA_CSS_CMEM_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/src/ia_css_xmem_cmem_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/src/ia_css_xmem_cmem_impl.h new file mode 100644 index 0000000000000..adc178b75059a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/src/ia_css_xmem_cmem_impl.h @@ -0,0 +1,79 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_CMEM_IMPL_H +#define __IA_CSS_XMEM_CMEM_IMPL_H + +#include "ia_css_xmem_cmem.h" + +#include "ia_css_cmem.h" +#include "ia_css_xmem.h" + +/* Copy data from xmem to cmem, e.g., from a program in DDR to a cell's DMEM */ +/* This may also be implemented using DMA */ + +STORAGE_CLASS_INLINE void +ia_css_xmem_to_cmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size) +{ + /* copy from ddr to subsystem, e.g., cell dmem */ + ia_css_cmem_address_t end = dst + size; + + assert(size % 4 == 0); + assert((uintptr_t) dst % 4 == 0); + assert((uintptr_t) src % 4 == 0); + + while (dst != end) { + uint32_t data; + + data = ia_css_xmem_load_32(mmid, src); + ia_css_cmem_store_32(ssid, dst, data); + dst += 4; + src += 4; + } +} + +/* Copy data from cmem to xmem */ + +STORAGE_CLASS_INLINE void +ia_css_cmem_to_xmem_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_cmem_address_t src, + ia_css_xmem_address_t dst, + unsigned int size) +{ + /* copy from ddr to subsystem, e.g., cell dmem */ + ia_css_xmem_address_t end = dst + size; + + assert(size % 4 == 0); + assert((uintptr_t) dst % 4 == 0); + assert((uintptr_t) src % 4 == 0); + + while (dst != end) { + uint32_t data; + + data = ia_css_cmem_load_32(mmid, src); + ia_css_xmem_store_32(ssid, dst, data); + dst += 4; + src += 4; + } +} + + +#endif /* __IA_CSS_XMEM_CMEM_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/src/ia_css_xmem_host.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/src/ia_css_xmem_host.h new file mode 100644 index 0000000000000..d94991fc11143 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/device_access/src/ia_css_xmem_host.h @@ -0,0 +1,84 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_XMEM_HOST_H +#define __IA_CSS_XMEM_HOST_H + +#include "ia_css_xmem.h" +#include +#include "assert_support.h" +#include + +STORAGE_CLASS_INLINE uint8_t +ia_css_xmem_load_8(unsigned int mmid, ia_css_xmem_address_t address) +{ + return shared_memory_load_8(mmid, address); +} + +STORAGE_CLASS_INLINE uint16_t +ia_css_xmem_load_16(unsigned int mmid, ia_css_xmem_address_t address) +{ + /* Address has to be half-word aligned */ + assert(0 == (uintptr_t) address % 2); + return shared_memory_load_16(mmid, address); +} + +STORAGE_CLASS_INLINE uint32_t +ia_css_xmem_load_32(unsigned int mmid, ia_css_xmem_address_t address) +{ + /* Address has to be word aligned */ + assert(0 == (uintptr_t) address % 4); + return shared_memory_load_32(mmid, address); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_load(unsigned int mmid, ia_css_xmem_address_t address, void *data, + unsigned int size) +{ + shared_memory_load(mmid, address, data, size); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_8(unsigned int mmid, ia_css_xmem_address_t address, + uint8_t value) +{ + shared_memory_store_8(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_16(unsigned int mmid, ia_css_xmem_address_t address, + uint16_t value) +{ + /* Address has to be half-word aligned */ + assert(0 == (uintptr_t) address % 2); + shared_memory_store_16(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store_32(unsigned int mmid, ia_css_xmem_address_t address, + uint32_t value) +{ + /* Address has to be word aligned */ + assert(0 == (uintptr_t) address % 4); + shared_memory_store_32(mmid, address, value); +} + +STORAGE_CLASS_INLINE void +ia_css_xmem_store(unsigned int mmid, ia_css_xmem_address_t address, + const void *data, unsigned int bytes) +{ + shared_memory_store(mmid, address, data, bytes); +} + +#endif /* __IA_CSS_XMEM_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/cnlB0/ipu_device_buttress_properties_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/cnlB0/ipu_device_buttress_properties_struct.h new file mode 100644 index 0000000000000..5102f6e44d2f6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/cnlB0/ipu_device_buttress_properties_struct.h @@ -0,0 +1,68 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H +#define __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H + +/* Destination values for master port 0 and bitfield "request_dest" */ +enum cio_M0_btrs_dest { + DEST_IS_BUT_REGS = 0, + DEST_IS_DDR, + RESERVED, + DEST_IS_SUBSYSTEM, + N_BTRS_DEST +}; + +/* Bit-field positions for M0 info bits */ +enum ia_css_info_bits_m0_pos { + IA_CSS_INFO_BITS_M0_SNOOPABLE_POS = 0, + IA_CSS_INFO_BITS_M0_IMR_DESTINED_POS = 1, + IA_CSS_INFO_BITS_M0_REQUEST_DEST_POS = 4 +}; + +#define IA_CSS_INFO_BITS_M0_DDR \ + (DEST_IS_DDR << IA_CSS_INFO_BITS_M0_REQUEST_DEST_POS) +#define IA_CSS_INFO_BITS_M0_SNOOPABLE (1 << IA_CSS_INFO_BITS_M0_SNOOPABLE_POS) + +/* Info bits as expected by the buttress */ +/* Deprecated because bit fields are not portable */ + +/* For master port 0*/ +union cio_M0_t { + struct { + unsigned int snoopable : 1; + unsigned int imr_destined : 1; + unsigned int spare0 : 2; + unsigned int request_dest : 2; + unsigned int spare1 : 26; + } as_bitfield; + unsigned int as_word; +}; + +/* For master port 1*/ +union cio_M1_t { + struct { + unsigned int spare0 : 1; + unsigned int deadline_pointer : 1; + unsigned int reserved : 1; + unsigned int zlw : 1; + unsigned int stream_id : 4; + unsigned int address_swizzling : 1; + unsigned int spare1 : 23; + } as_bitfield; + unsigned int as_word; +}; + + +#endif /* __IPU_DEVICE_BUTTRESS_PROPERTIES_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties.h new file mode 100644 index 0000000000000..e6e1e9dcbe80c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties.h @@ -0,0 +1,76 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_H +#define __IPU_DEVICE_CELL_PROPERTIES_H + +#include "storage_class.h" +#include "ipu_device_cell_type_properties.h" + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_devices(void); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_memories(const unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_size(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_address(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_databus_memory_address(const unsigned int cell_id, + const unsigned int mem_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_masters(const unsigned int cell_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_bits(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_num_segments(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_size(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_stride(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_base_reg(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_reg(const unsigned int cell_id, + const unsigned int master_id); + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_icache_align(unsigned int cell_id); + +#ifdef C_RUN +STORAGE_CLASS_INLINE int +ipu_device_cell_id_crun(int cell_id); +#endif + +#include "ipu_device_cell_properties_func.h" + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_func.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_func.h new file mode 100644 index 0000000000000..481b0504a2378 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_func.h @@ -0,0 +1,164 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_FUNC_H +#define __IPU_DEVICE_CELL_PROPERTIES_FUNC_H + +/* define properties for all cells uses in ISYS */ + +#include "ipu_device_cell_properties_impl.h" +#include "ipu_device_cell_devices.h" +#include "assert_support.h" +#include "storage_class.h" + +enum {IA_CSS_CELL_MASTER_ADDRESS_WIDTH = 32}; + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_devices(void) +{ + return NUM_CELLS; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_memories(const unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + num_memories; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_size(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + return ipu_device_cell_properties[cell_id].type_properties-> + mem_size[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_memory_address(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + return ipu_device_cell_properties[cell_id].mem_address[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_databus_memory_address(const unsigned int cell_id, + const unsigned int mem_id) +{ + assert(cell_id < NUM_CELLS); + assert(mem_id < ipu_device_cell_num_memories(cell_id)); + assert(mem_id != 0); + return ipu_device_cell_properties[cell_id].mem_databus_address[mem_id]; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_num_masters(const unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + num_master_ports; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_bits(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].segment_bits; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_num_segments(const unsigned int cell_id, + const unsigned int master_id) +{ + return 1u << ipu_device_cell_master_segment_bits(cell_id, master_id); +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_segment_size(const unsigned int cell_id, + const unsigned int master_id) +{ + return 1u << (IA_CSS_CELL_MASTER_ADDRESS_WIDTH - + ipu_device_cell_master_segment_bits(cell_id, master_id)); +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_stride(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].stride; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_base_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].base_address_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].info_bits_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_master_info_override_reg(const unsigned int cell_id, + const unsigned int master_id) +{ + assert(cell_id < NUM_CELLS); + assert(master_id < ipu_device_cell_num_masters(cell_id)); + return + ipu_device_cell_properties[cell_id].type_properties-> + master[master_id].info_override_bits_register; +} + +STORAGE_CLASS_INLINE unsigned int +ipu_device_cell_icache_align(unsigned int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_cell_properties[cell_id].type_properties->count-> + icache_align; +} + +#ifdef C_RUN +STORAGE_CLASS_INLINE int +ipu_device_cell_id_crun(int cell_id) +{ + assert(cell_id < NUM_CELLS); + return ipu_device_map_cell_id_to_crun_proc_id[cell_id]; +} +#endif + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_FUNC_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_struct.h new file mode 100644 index 0000000000000..63397dc0b7fe6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_properties_struct.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H +#define __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H + +/* definitions for all cell types */ + +struct ipu_device_cell_count_s { + unsigned int num_memories; + unsigned int num_master_ports; + unsigned int num_stall_bits; + unsigned int icache_align; +}; + +struct ipu_device_cell_master_properties_s { + unsigned int segment_bits; + unsigned int stride; /* offset to register of next segment */ + unsigned int base_address_register; /* address of first base address + register */ + unsigned int info_bits_register; + unsigned int info_override_bits_register; +}; + +struct ipu_device_cell_type_properties_s { + const struct ipu_device_cell_count_s *count; + const struct ipu_device_cell_master_properties_s *master; + const unsigned int *reg_offset; /* offsets of registers, some depend + on cell type */ + const unsigned int *mem_size; +}; + +struct ipu_device_cell_properties_s { + const struct ipu_device_cell_type_properties_s *type_properties; + const unsigned int *mem_address; + const unsigned int *mem_databus_address; + /* const cell_master_port_properties_s* master_port_properties; */ +}; + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_type_properties.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_type_properties.h new file mode 100644 index 0000000000000..72caed3eef0c9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_cell_type_properties.h @@ -0,0 +1,69 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_TYPE_PROPERTIES_H +#define __IPU_DEVICE_CELL_TYPE_PROPERTIES_H + +#define IPU_DEVICE_INVALID_MEM_ADDRESS 0xFFFFFFFF + +enum ipu_device_cell_stat_ctrl_bit { + IPU_DEVICE_CELL_STAT_CTRL_RESET_BIT = 0, + IPU_DEVICE_CELL_STAT_CTRL_START_BIT = 1, + IPU_DEVICE_CELL_STAT_CTRL_RUN_BIT = 3, + IPU_DEVICE_CELL_STAT_CTRL_READY_BIT = 5, + IPU_DEVICE_CELL_STAT_CTRL_SLEEP_BIT = 6, + IPU_DEVICE_CELL_STAT_CTRL_STALL_BIT = 7, + IPU_DEVICE_CELL_STAT_CTRL_CLEAR_IRQ_MASK_FLAG_BIT = 8, + IPU_DEVICE_CELL_STAT_CTRL_BROKEN_IRQ_MASK_FLAG_BIT = 9, + IPU_DEVICE_CELL_STAT_CTRL_READY_IRQ_MASK_FLAG_BIT = 10, + IPU_DEVICE_CELL_STAT_CTRL_SLEEP_IRQ_MASK_FLAG_BIT = 11, + IPU_DEVICE_CELL_STAT_CTRL_INVALIDATE_ICACHE_BIT = 12, + IPU_DEVICE_CELL_STAT_CTRL_ICACHE_ENABLE_PREFETCH_BIT = 13 +}; + +enum ipu_device_cell_reg_addr { + IPU_DEVICE_CELL_STAT_CTRL_REG_ADDRESS = 0x0, + IPU_DEVICE_CELL_START_PC_REG_ADDRESS = 0x4, + IPU_DEVICE_CELL_ICACHE_BASE_REG_ADDRESS = 0x10, + IPU_DEVICE_CELL_ICACHE_INFO_BITS_REG_ADDRESS = 0x14 +}; + +enum ipu_device_cell_reg { + IPU_DEVICE_CELL_STAT_CTRL_REG, + IPU_DEVICE_CELL_START_PC_REG, + IPU_DEVICE_CELL_ICACHE_BASE_REG, + IPU_DEVICE_CELL_DEBUG_PC_REG, + IPU_DEVICE_CELL_STALL_REG, + IPU_DEVICE_CELL_NUM_REGS +}; + +enum ipu_device_cell_mem { + IPU_DEVICE_CELL_REGS, /* memory id of registers */ + IPU_DEVICE_CELL_PMEM, /* memory id of pmem */ + IPU_DEVICE_CELL_DMEM, /* memory id of dmem */ + IPU_DEVICE_CELL_BAMEM, /* memory id of bamem */ + IPU_DEVICE_CELL_VMEM /* memory id of vmem */ +}; +#define IPU_DEVICE_CELL_NUM_MEMORIES (IPU_DEVICE_CELL_VMEM + 1) + +enum ipu_device_cell_master { + IPU_DEVICE_CELL_MASTER_ICACHE, /* master port id of icache */ + IPU_DEVICE_CELL_MASTER_QMEM, + IPU_DEVICE_CELL_MASTER_CMEM, + IPU_DEVICE_CELL_MASTER_XMEM, + IPU_DEVICE_CELL_MASTER_XVMEM +}; +#define IPU_DEVICE_CELL_MASTER_NUM_MASTERS (IPU_DEVICE_CELL_MASTER_XVMEM + 1) + +#endif /* __IPU_DEVICE_CELL_TYPE_PROPERTIES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties.h new file mode 100644 index 0000000000000..fd0c5a586c949 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties.h @@ -0,0 +1,26 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_GP_PROPERTIES_H +#define __IPU_DEVICE_GP_PROPERTIES_H + +#include "storage_class.h" +#include "ipu_device_gp_properties_types.h" + +STORAGE_CLASS_INLINE unsigned int +ipu_device_gp_mux_addr(const unsigned int device_id, const unsigned int mux_id); + +#include "ipu_device_gp_properties_func.h" + +#endif /* __IPU_DEVICE_GP_PROPERTIES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties_types.h new file mode 100644 index 0000000000000..3032273696eab --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/interface/ipu_device_gp_properties_types.h @@ -0,0 +1,103 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_GP_PROPERTIES_TYPES_H +#define __IPU_DEVICE_GP_PROPERTIES_TYPES_H + +enum ipu_device_gp_isa_value { + /* ISA_MUX_SEL options */ + IPU_DEVICE_GP_ISA_MUX_SEL_ICA = 0, /* Enable output after FF ICA */ + IPU_DEVICE_GP_ISA_MUX_SEL_LSC = 1, /* Enable output after FF LSC */ + IPU_DEVICE_GP_ISA_MUX_SEL_DPC = 2, /* Enable output after FF DPC */ + /* ICA stream block options */ + /* UNBLOCK signal received from ICA */ + IPU_DEVICE_GP_ISA_ICA_UNBLOCK = 0, + /* BLOCK signal received from ICA */ + IPU_DEVICE_GP_ISA_ICA_BLOCK = 1, + /* LSC stream block options */ + /* UNBLOCK signal received from LSC */ + IPU_DEVICE_GP_ISA_LSC_UNBLOCK = 0, + /* BLOCK signal received from LSC */ + IPU_DEVICE_GP_ISA_LSC_BLOCK = 1, + /* DPC stream block options */ + /* UNBLOCK signal received from DPC */ + IPU_DEVICE_GP_ISA_DPC_UNBLOCK = 0, + /* BLOCK signal received from DPC */ + IPU_DEVICE_GP_ISA_DPC_BLOCK = 1, + /* Defines needed only for bxtB0 */ + /* ISA_AWB_MUX_SEL options */ + /* Input Correction input */ + IPU_DEVICE_GP_ISA_AWB_MUX_SEL_ICA = 0, + /* DPC input */ + IPU_DEVICE_GP_ISA_AWB_MUX_SEL_DPC = 1, + /* ISA_AWB_MUX_SEL options */ + /* UNBLOCK DPC input */ + IPU_DEVICE_GP_ISA_AWB_MUX_ICA_UNBLOCK = 0, + /* BLOCK DPC input */ + IPU_DEVICE_GP_ISA_AWB_MUX_ICA_BLOCK = 1, + /* ISA_AWB_MUX_SEL options */ + /* UNBLOCK Input Correction input */ + IPU_DEVICE_GP_ISA_AWB_MUX_DPC_UNBLOCK = 0, + /* BLOCK Input Correction input */ + IPU_DEVICE_GP_ISA_AWB_MUX_DPC_BLOCK = 1, + + /* PAF STRM options */ + /* Disable streaming to PAF FF*/ + IPU_DEVICE_GP_ISA_PAF_DISABLE_STREAM = 0, + /* Enable stream0 to PAF FF*/ + IPU_DEVICE_GP_ISA_PAF_ENABLE_STREAM0 = 1, + /* Enable stream1 to PAF FF*/ + IPU_DEVICE_GP_ISA_PAF_ENABLE_STREAM1 = 2, + /* PAF SRC SEL options */ + /* External channel input */ + IPU_DEVICE_GP_ISA_PAF_SRC_SEL0 = 0, + /* DPC extracted input */ + IPU_DEVICE_GP_ISA_PAF_SRC_SEL1 = 1, + /* PAF_GDDPC_BLK options */ + IPU_DEVICE_GP_ISA_PAF_GDDPC_PORT_BLK0 = 0, + IPU_DEVICE_GP_ISA_PAF_GDDPC_PORT_BLK1 = 1, + /* PAF ISA STR_PORT options */ + IPU_DEVICE_GP_ISA_PAF_STR_PORT0 = 0, + IPU_DEVICE_GP_ISA_PAF_STR_PORT1 = 1, + + /* sis port block options */ + IPU_DEVICE_GP_ISA_SIS_PORT_UNBLOCK = 0, + IPU_DEVICE_GP_ISA_SIS_PORT_BLOCK = 1, + IPU_DEVICE_GP_ISA_CONF_INVALID = 0xFF +}; + +enum ipu_device_gp_psa_value { + /* Defines needed for bxtB0 */ + /* PSA_STILLS_MODE_MUX */ + IPU_DEVICE_GP_PSA_MUX_POST_RYNR_ROUTE_WO_DM = 0, + IPU_DEVICE_GP_PSA_MUX_POST_RYNR_ROUTE_W_DM = 1, + /* PSA_ACM_DEMUX */ + IPU_DEVICE_GP_PSA_DEMUX_PRE_ACM_ROUTE_TO_ACM = 0, + IPU_DEVICE_GP_PSA_DEMUX_PRE_ACM_ROUTE_TO_S2V = 1, + /* PSA_S2V_RGB_F_MUX */ + IPU_DEVICE_GP_PSA_MUX_PRE_S2V_RGB_F_FROM_ACM = 0, + IPU_DEVICE_GP_PSA_MUX_PRE_S2V_RGB_F_FROM_DM_OR_SPLITTER = 1, + /* PSA_V2S_RGB_4_DEMUX */ + IPU_DEVICE_GP_PSA_DEMUX_POST_V2S_RGB_4_TO_GTM = 0, + IPU_DEVICE_GP_PSA_DEMUX_POST_V2S_RGB_4_TO_ACM = 1, +}; + +enum ipu_device_gp_isl_value { + /* choose and route pixel stream to CSI BE */ + IPU_DEVICE_GP_ISL_CSI_BE_IN_USE = 0, + /* choose and route pixel stream bypass CSI BE */ + IPU_DEVICE_GP_ISL_CSI_BE_BYPASS +}; + +#endif /* __IPU_DEVICE_GP_PROPERTIES_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_acb_devices.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_acb_devices.h new file mode 100644 index 0000000000000..4898fbb2e875c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_acb_devices.h @@ -0,0 +1,43 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IPU_DEVICE_ACB_DEVICES_H +#define __IPU_DEVICE_ACB_DEVICES_H + +enum ipu_device_acb_id { + /* PSA accelerators */ + IPU_DEVICE_ACB_WBA_ID = 0, + IPU_DEVICE_ACB_RYNR_ID, + IPU_DEVICE_ACB_DEMOSAIC_ID, + IPU_DEVICE_ACB_ACM_ID, /* In CNLB0 ACM is called VCA in HW */ + IPU_DEVICE_ACB_GTC_ID, + IPU_DEVICE_ACB_YUV1_ID, + IPU_DEVICE_ACB_DVS_ID, + IPU_DEVICE_ACB_LACE_ID, + /* ISA accelerators */ + IPU_DEVICE_ACB_ICA_ID, + IPU_DEVICE_ACB_LSC_ID, + IPU_DEVICE_ACB_DPC_ID, + IPU_DEVICE_ACB_IDS_ID, + IPU_DEVICE_ACB_AWB_ID, + IPU_DEVICE_ACB_AF_ID, + IPU_DEVICE_ACB_AE_ID, + IPU_DEVICE_ACB_NUM_ACB +}; + +#define IPU_DEVICE_ACB_NUM_PSA_ACB (IPU_DEVICE_ACB_LACE_ID + 1) +#define IPU_DEVICE_ACB_NUM_ISA_ACB \ + (IPU_DEVICE_ACB_NUM_ACB - IPU_DEVICE_ACB_NUM_PSA_ACB) + +#endif /* __IPU_DEVICE_ACB_DEVICES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_cell_devices.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_cell_devices.h new file mode 100644 index 0000000000000..0c923d1396387 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_cell_devices.h @@ -0,0 +1,38 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IPU_DEVICE_CELL_DEVICES_H +#define __IPU_DEVICE_CELL_DEVICES_H + +#define SPC0_CELL processing_system_sp_cluster_sp_cluster_logic_spc_tile_sp +#define SPP0_CELL processing_system_sp_cluster_sp_cluster_logic_spp_tile0_sp +#define SPP1_CELL processing_system_sp_cluster_sp_cluster_logic_spp_tile1_sp +#define ISP0_CELL processing_system_isp_tile0_logic_isp +#define ISP1_CELL processing_system_isp_tile1_logic_isp +#define ISP2_CELL processing_system_isp_tile2_logic_isp +#define ISP3_CELL processing_system_isp_tile3_logic_isp + +enum ipu_device_psys_cell_id { + SPC0, + SPP0, + SPP1, + ISP0, + ISP1, + ISP2, + ISP3 +}; +#define NUM_CELLS (ISP3 + 1) +#define NUM_ISP_CELLS 4 + +#endif /* __IPU_DEVICE_CELL_DEVICES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_cell_properties_defs.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_cell_properties_defs.h new file mode 100644 index 0000000000000..2b80e2822a906 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_cell_properties_defs.h @@ -0,0 +1,65 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +/* Generated file - please do not edit. */ + +#ifndef _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ +#define _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ +#define SPC0_REGS_CBUS_ADDRESS 0x00000000 +#define SPC0_DMEM_CBUS_ADDRESS 0x00008000 +#define SPC0_DMEM_DBUS_ADDRESS 0x02000000 +#define SPC0_DMEM_DMA_M0_ADDRESS SPC0_DMEM_DBUS_ADDRESS +#define SPC0_DMEM_INT_DMA_M0_ADDRESS SPC0_DMEM_DBUS_ADDRESS +#define SPP0_REGS_CBUS_ADDRESS 0x00020000 +#define SPP0_DMEM_CBUS_ADDRESS 0x00028000 +#define SPP0_DMEM_DBUS_ADDRESS 0x02020000 +#define SPP1_REGS_CBUS_ADDRESS 0x00030000 +#define SPP1_DMEM_CBUS_ADDRESS 0x00038000 +#define SPP1_DMEM_DBUS_ADDRESS 0x02030000 +#define ISP0_REGS_CBUS_ADDRESS 0x001C0000 +#define ISP0_PMEM_CBUS_ADDRESS 0x001D0000 +#define ISP0_DMEM_CBUS_ADDRESS 0x001F0000 +#define ISP0_BAMEM_CBUS_ADDRESS 0x00200000 +#define ISP0_VMEM_CBUS_ADDRESS 0x00220000 +#define ISP1_REGS_CBUS_ADDRESS 0x00240000 +#define ISP1_PMEM_CBUS_ADDRESS 0x00250000 +#define ISP1_DMEM_CBUS_ADDRESS 0x00270000 +#define ISP1_BAMEM_CBUS_ADDRESS 0x00280000 +#define ISP1_VMEM_CBUS_ADDRESS 0x002A0000 +#define ISP2_REGS_CBUS_ADDRESS 0x002C0000 +#define ISP2_PMEM_CBUS_ADDRESS 0x002D0000 +#define ISP2_DMEM_CBUS_ADDRESS 0x002F0000 +#define ISP2_BAMEM_CBUS_ADDRESS 0x00300000 +#define ISP2_VMEM_CBUS_ADDRESS 0x00320000 +#define ISP3_REGS_CBUS_ADDRESS 0x00340000 +#define ISP3_PMEM_CBUS_ADDRESS 0x00350000 +#define ISP3_DMEM_CBUS_ADDRESS 0x00370000 +#define ISP3_BAMEM_CBUS_ADDRESS 0x00380000 +#define ISP3_VMEM_CBUS_ADDRESS 0x003A0000 +#define ISP0_PMEM_DBUS_ADDRESS 0x08000000 +#define ISP0_DMEM_DBUS_ADDRESS 0x08400000 +#define ISP0_BAMEM_DBUS_ADDRESS 0x09000000 +#define ISP0_VMEM_DBUS_ADDRESS 0x08800000 +#define ISP1_PMEM_DBUS_ADDRESS 0x0A000000 +#define ISP1_DMEM_DBUS_ADDRESS 0x0A400000 +#define ISP1_BAMEM_DBUS_ADDRESS 0x0B000000 +#define ISP1_VMEM_DBUS_ADDRESS 0x0A800000 +#define ISP2_PMEM_DBUS_ADDRESS 0x0C000000 +#define ISP2_DMEM_DBUS_ADDRESS 0x0C400000 +#define ISP2_BAMEM_DBUS_ADDRESS 0x0D000000 +#define ISP2_VMEM_DBUS_ADDRESS 0x0C800000 +#define ISP3_PMEM_DBUS_ADDRESS 0x0E000000 +#define ISP3_DMEM_DBUS_ADDRESS 0x0E400000 +#define ISP3_BAMEM_DBUS_ADDRESS 0x0F000000 +#define ISP3_VMEM_DBUS_ADDRESS 0x0E800000 +#endif /* _IPU_DEVICE_CELL_PROPERTIES_DEFS_H_ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_cell_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_cell_properties_impl.h new file mode 100644 index 0000000000000..428a394e81368 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_cell_properties_impl.h @@ -0,0 +1,193 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_CELL_PROPERTIES_IMPL_H +#define __IPU_DEVICE_CELL_PROPERTIES_IMPL_H + +#include "ipu_device_sp2600_control_properties_impl.h" +#include "ipu_device_sp2600_proxy_properties_impl.h" +#include "ipu_device_isp2600_properties_impl.h" +#include "ipu_device_cell_properties_defs.h" +#include "ipu_device_cell_devices.h" +#include "ipu_device_cell_type_properties.h"/* IPU_DEVICE_INVALID_MEM_ADDRESS */ + +static const unsigned int +ipu_device_spc0_mem_address[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + SPC0_REGS_CBUS_ADDRESS, + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPC0_DMEM_CBUS_ADDRESS +}; + +static const unsigned int +ipu_device_spp0_mem_address[IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES] = { + SPP0_REGS_CBUS_ADDRESS, + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPP0_DMEM_CBUS_ADDRESS +}; + +static const unsigned int +ipu_device_spp1_mem_address[IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES] = { + SPP1_REGS_CBUS_ADDRESS, + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPP1_DMEM_CBUS_ADDRESS +}; + +static const unsigned int +ipu_device_isp0_mem_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + ISP0_REGS_CBUS_ADDRESS, /* reg addr */ + ISP0_PMEM_CBUS_ADDRESS, /* pmem addr */ + ISP0_DMEM_CBUS_ADDRESS, /* dmem addr */ + ISP0_BAMEM_CBUS_ADDRESS,/* bamem addr */ + ISP0_VMEM_CBUS_ADDRESS /* vmem addr */ +}; + +static const unsigned int +ipu_device_isp1_mem_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + ISP1_REGS_CBUS_ADDRESS, /* reg addr */ + ISP1_PMEM_CBUS_ADDRESS, /* pmem addr */ + ISP1_DMEM_CBUS_ADDRESS, /* dmem addr */ + ISP1_BAMEM_CBUS_ADDRESS,/* bamem addr */ + ISP1_VMEM_CBUS_ADDRESS /* vmem addr */ +}; + +static const unsigned int +ipu_device_isp2_mem_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + ISP2_REGS_CBUS_ADDRESS, /* reg addr */ + ISP2_PMEM_CBUS_ADDRESS, /* pmem addr */ + ISP2_DMEM_CBUS_ADDRESS, /* dmem addr */ + ISP2_BAMEM_CBUS_ADDRESS,/* bamem addr */ + ISP2_VMEM_CBUS_ADDRESS /* vmem addr */ +}; + +static const unsigned int +ipu_device_isp3_mem_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + ISP3_REGS_CBUS_ADDRESS, /* reg addr */ + ISP3_PMEM_CBUS_ADDRESS, /* pmem addr */ + ISP3_DMEM_CBUS_ADDRESS, /* dmem addr */ + ISP3_BAMEM_CBUS_ADDRESS,/* bamem addr */ + ISP3_VMEM_CBUS_ADDRESS /* vmem addr */ +}; + +static const unsigned int +ipu_device_spc0_mem_databus_address[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPC0_DMEM_DBUS_ADDRESS +}; + +static const unsigned int +ipu_device_spp0_mem_databus_address[IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPP0_DMEM_DBUS_ADDRESS +}; + +static const unsigned int +ipu_device_spp1_mem_databus_address[IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no pmem */ + SPP1_DMEM_DBUS_ADDRESS +}; + +static const unsigned int +ipu_device_isp0_mem_databus_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + ISP0_PMEM_DBUS_ADDRESS, /* pmem databus addr */ + ISP0_DMEM_DBUS_ADDRESS, /* dmem databus addr */ + ISP0_BAMEM_DBUS_ADDRESS, /* bamem databus addr */ + ISP0_VMEM_DBUS_ADDRESS /* vmem databus addr */ +}; + +static const unsigned int +ipu_device_isp1_mem_databus_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + ISP1_PMEM_DBUS_ADDRESS, /* pmem databus addr */ + ISP1_DMEM_DBUS_ADDRESS, /* dmem databus addr */ + ISP1_BAMEM_DBUS_ADDRESS, /* bamem databus addr */ + ISP1_VMEM_DBUS_ADDRESS /* vmem databus addr */ +}; + +static const unsigned int +ipu_device_isp2_mem_databus_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + ISP2_PMEM_DBUS_ADDRESS, /* pmem databus addr */ + ISP2_DMEM_DBUS_ADDRESS, /* dmem databus addr */ + ISP2_BAMEM_DBUS_ADDRESS, /* bamem databus addr */ + ISP2_VMEM_DBUS_ADDRESS /* vmem databus addr */ +}; + +static const unsigned int +ipu_device_isp3_mem_databus_address[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + IPU_DEVICE_INVALID_MEM_ADDRESS, /* no reg addr */ + ISP3_PMEM_DBUS_ADDRESS, /* pmem databus addr */ + ISP3_DMEM_DBUS_ADDRESS, /* dmem databus addr */ + ISP3_BAMEM_DBUS_ADDRESS, /* bamem databus addr */ + ISP3_VMEM_DBUS_ADDRESS /* vmem databus addr */ +}; + +static const struct ipu_device_cell_properties_s +ipu_device_cell_properties[NUM_CELLS] = { + { + &ipu_device_sp2600_control_properties, + ipu_device_spc0_mem_address, + ipu_device_spc0_mem_databus_address + }, + { + &ipu_device_sp2600_proxy_properties, + ipu_device_spp0_mem_address, + ipu_device_spp0_mem_databus_address + }, + { + &ipu_device_sp2600_proxy_properties, + ipu_device_spp1_mem_address, + ipu_device_spp1_mem_databus_address + }, + { + &ipu_device_isp2600_properties, + ipu_device_isp0_mem_address, + ipu_device_isp0_mem_databus_address + }, + { + &ipu_device_isp2600_properties, + ipu_device_isp1_mem_address, + ipu_device_isp1_mem_databus_address + }, + { + &ipu_device_isp2600_properties, + ipu_device_isp2_mem_address, + ipu_device_isp2_mem_databus_address + }, + { + &ipu_device_isp2600_properties, + ipu_device_isp3_mem_address, + ipu_device_isp3_mem_databus_address + } +}; + +#ifdef C_RUN + +/* Mapping between hrt_hive_processors enum and cell_id's used in FW */ +static const int ipu_device_map_cell_id_to_crun_proc_id[NUM_CELLS] = { + 4, /* SPC0 */ + 5, /* SPP0 */ + 6, /* SPP1 */ + 0, /* ISP0 */ + 1, /* ISP1 */ + 2, /* ISP2 */ + 3 /* ISP3 */ +}; + +#endif + +#endif /* __IPU_DEVICE_CELL_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_ff_devices.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_ff_devices.h new file mode 100644 index 0000000000000..d784fb47ffaa1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_ff_devices.h @@ -0,0 +1,57 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IPU_DEVICE_FF_DEVICES_H +#define __IPU_DEVICE_FF_DEVICES_H + +enum ipu_device_ff_id { + /* Names (shortened) as used in */ + /* PSA fixed functions */ /* ipu_device_ff_hrt.txt */ + IPU_DEVICE_FF_WBA_WBA = 0, /* WBA_WBA */ + IPU_DEVICE_FF_RYNR_SPLITTER, /* RYNR_RYNR_SPLITTER */ + IPU_DEVICE_FF_RYNR_COLLECTOR, /* RYNR_RYNR_COLLECTOR */ + IPU_DEVICE_FF_RYNR_BNLM, /* RYNR_BNLM */ + IPU_DEVICE_FF_RYNR_VCUD, /* RYNR_VCUD */ + IPU_DEVICE_FF_DEMOSAIC_DEMOSAIC,/* DEMOSAIC_DEMOSAIC */ + IPU_DEVICE_FF_ACM_CCM, /* VCA_VCR, name as used in CNLB0 HW */ + IPU_DEVICE_FF_ACM_ACM, /* VCA_ACM, name as used in CNLB0 HW */ + IPU_DEVICE_FF_VCA_VCR2, /* VCA_VCR, part of ACM */ + IPU_DEVICE_FF_GTC_CSC_CDS, /* GTC_CSC_CDS */ + IPU_DEVICE_FF_GTC_GTM, /* GTC_GTM */ + IPU_DEVICE_FF_YUV1_SPLITTER, /* YUV1_Processing_YUV_SPLITTER */ + IPU_DEVICE_FF_YUV1_IEFD, /* YUV1_Processing_IEFD*/ + IPU_DEVICE_FF_YUV1_YDS, /* YUV1_Processing_YDS */ + IPU_DEVICE_FF_YUV1_TCC, /* YUV1_Processing_TCC */ + IPU_DEVICE_FF_DVS_YBIN, /* DVS_YBIN */ + IPU_DEVICE_FF_DVS_DVS, /* DVS_DVS */ + IPU_DEVICE_FF_LACE_LACE, /* Lace_Stat_LACE_STAT */ + /* ISA fixed functions */ + IPU_DEVICE_FF_ICA_INL, /* Input_Corr_INL */ + IPU_DEVICE_FF_ICA_GBL, /* Input_Corr_GBL */ + IPU_DEVICE_FF_ICA_PCLN, /* Input_Corr_PCLN */ + IPU_DEVICE_FF_LSC_LSC, /* Bayer_Lsc_LSC */ + IPU_DEVICE_FF_DPC_DPC, /* Bayer_Dpc_GDDPC */ + IPU_DEVICE_FF_IDS_SCALER, /* Bayer_Scaler_SCALER */ + IPU_DEVICE_FF_AWB_AWRG, /* Stat_AWB_AWRG */ + IPU_DEVICE_FF_AF_AF, /* Stat_AF_AWB_FR_AF_AWB_FR_GRD */ + IPU_DEVICE_FF_AE_WGHT_HIST, /* Stat_AE_WGHT_HIST */ + IPU_DEVICE_FF_AE_CCM, /* Stat_AE_AE_CCM */ + IPU_DEVICE_FF_NUM_FF +}; + +#define IPU_DEVICE_FF_NUM_PSA_FF (IPU_DEVICE_FF_LACE_LACE + 1) +#define IPU_DEVICE_FF_NUM_ISA_FF \ + (IPU_DEVICE_FF_NUM_FF - IPU_DEVICE_FF_NUM_PSA_FF) + +#endif /* __IPU_DEVICE_FF_DEVICES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_gp_devices.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_gp_devices.h new file mode 100644 index 0000000000000..ab8cd6a783ce6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/psys/cnlB0/ipu_device_gp_devices.h @@ -0,0 +1,67 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_GP_DEVICES_H +#define __IPU_DEVICE_GP_DEVICES_H +#include "math_support.h" +#include "type_support.h" + +enum ipu_device_gp_id { + IPU_DEVICE_GP_PSA = 0, /* PSA */ + IPU_DEVICE_GP_ISA_STATIC, /* ISA Static */ + IPU_DEVICE_GP_ISA_RUNTIME, /* ISA Runtime */ + IPU_DEVICE_GP_ISL, /* ISL */ + IPU_DEVICE_GP_NUM_GP +}; + +enum ipu_device_gp_psa_mux_id { + /* Post RYNR/CCN: 0-To ACM (Video), 1-To Demosaic (Stills)*/ + IPU_DEVICE_GP_PSA_STILLS_MODE_MUX = 0, + /* Post Vec2Str 4: 0-To GTC, 1-To ACM */ + IPU_DEVICE_GP_PSA_V2S_RGB_4_DEMUX, + /* Post DM and pre ACM 0-CCM/ACM: 1-DM Componenet Splitter */ + IPU_DEVICE_GP_PSA_S2V_RGB_F_MUX, + /* Pre ACM/CCM: 0-To CCM/ACM, 1-To str2vec id_f */ + IPU_DEVICE_GP_PSA_ACM_DEMUX, + IPU_DEVICE_GP_PSA_MUX_NUM_MUX +}; + +enum ipu_device_gp_isa_static_mux_id { + IPU_DEVICE_GP_ISA_STATIC_MUX_SEL = 0, + IPU_DEVICE_GP_ISA_STATIC_PORTA_BLK, + IPU_DEVICE_GP_ISA_STATIC_PORTB_BLK, + IPU_DEVICE_GP_ISA_STATIC_PORTC_BLK, + IPU_DEVICE_GP_ISA_STATIC_AWB_MUX_SEL, + IPU_DEVICE_GP_ISA_STATIC_AWB_MUX_INPUT_CORR_PORT_BLK, + IPU_DEVICE_GP_ISA_STATIC_AWB_MUX_DPC_PORT_BLK, + IPU_DEVICE_GP_ISA_STATIC_MUX_NUM_MUX +}; + +enum ipu_device_gp_isa_runtime_mux_id { + IPU_DEVICE_GP_ISA_RUNTIME_FRAME_SIZE = 0, + IPU_DEVICE_GP_ISA_RUNTIME_SCALED_FRAME_SIZE, + IPU_DEVICE_GP_ISA_RUNTIME_MUX_NUM_MUX +}; + +enum ipu_device_gp_isl_mux_id { + IPU_DEVICE_GP_ISL_MIPI_BE_MUX = 0, + IPU_DEVICE_GP_ISL_MUX_NUM_MUX +}; + +#define IPU_DEVICE_GP_MAX_NUM MAX4((uint32_t)IPU_DEVICE_GP_PSA_MUX_NUM_MUX, \ + (uint32_t)IPU_DEVICE_GP_ISA_STATIC_MUX_NUM_MUX, \ + (uint32_t)IPU_DEVICE_GP_ISA_RUNTIME_MUX_NUM_MUX, \ + (uint32_t)IPU_DEVICE_GP_ISL_MUX_NUM_MUX) + +#endif /* __IPU_DEVICE_GP_DEVICES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_isp2600_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_isp2600_properties_impl.h new file mode 100644 index 0000000000000..de733be679986 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_isp2600_properties_impl.h @@ -0,0 +1,151 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_ISP2600_PROPERTIES_IMPL_H +#define __IPU_DEVICE_ISP2600_PROPERTIES_IMPL_H + +/* isp2600 definition */ + +#include "ipu_device_cell_properties_struct.h" + +enum ipu_device_isp2600_registers { + /* control registers */ + IPU_DEVICE_ISP2600_STAT_CTRL = 0x0, + IPU_DEVICE_ISP2600_START_PC = 0x4, + + /* master port registers */ + IPU_DEVICE_ISP2600_ICACHE_BASE = 0x10, + IPU_DEVICE_ISP2600_ICACHE_INFO = 0x14, + IPU_DEVICE_ISP2600_ICACHE_INFO_OVERRIDE = 0x18, + + IPU_DEVICE_ISP2600_QMEM_BASE = 0x1C, + + IPU_DEVICE_ISP2600_CMEM_BASE = 0x28, + + IPU_DEVICE_ISP2600_XMEM_BASE = 0x88, + IPU_DEVICE_ISP2600_XMEM_INFO = 0x8C, + IPU_DEVICE_ISP2600_XMEM_INFO_OVERRIDE = 0x90, + + IPU_DEVICE_ISP2600_XVMEM_BASE = 0xB8, + + /* debug registers */ + IPU_DEVICE_ISP2600_DEBUG_PC = 0x130, + IPU_DEVICE_ISP2600_STALL = 0x134 +}; + + +enum ipu_device_isp2600_memories { + IPU_DEVICE_ISP2600_REGS, + IPU_DEVICE_ISP2600_PMEM, + IPU_DEVICE_ISP2600_DMEM, + IPU_DEVICE_ISP2600_BAMEM, + IPU_DEVICE_ISP2600_VMEM, + IPU_DEVICE_ISP2600_NUM_MEMORIES +}; + +static const unsigned int +ipu_device_isp2600_mem_size[IPU_DEVICE_ISP2600_NUM_MEMORIES] = { + 0x00140, + 0x14000, + 0x04000, + 0x20000, + 0x20000 +}; + + +enum ipu_device_isp2600_masters { + IPU_DEVICE_ISP2600_ICACHE, + IPU_DEVICE_ISP2600_QMEM, + IPU_DEVICE_ISP2600_CMEM, + IPU_DEVICE_ISP2600_XMEM, + IPU_DEVICE_ISP2600_XVMEM, + IPU_DEVICE_ISP2600_NUM_MASTERS +}; + +static const struct ipu_device_cell_master_properties_s +ipu_device_isp2600_masters[IPU_DEVICE_ISP2600_NUM_MASTERS] = { + { + 0, + 0xC, + IPU_DEVICE_ISP2600_ICACHE_BASE, + IPU_DEVICE_ISP2600_ICACHE_INFO, + IPU_DEVICE_ISP2600_ICACHE_INFO_OVERRIDE + }, + { + 0, + 0xC, + IPU_DEVICE_ISP2600_QMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 3, + 0xC, + IPU_DEVICE_ISP2600_CMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 2, + 0xC, + IPU_DEVICE_ISP2600_XMEM_BASE, + IPU_DEVICE_ISP2600_XMEM_INFO, + IPU_DEVICE_ISP2600_XMEM_INFO_OVERRIDE + }, + { + 3, + 0xC, + IPU_DEVICE_ISP2600_XVMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + } +}; + +enum ipu_device_isp2600_stall_bits { + IPU_DEVICE_ISP2600_STALL_ICACHE0, + IPU_DEVICE_ISP2600_STALL_ICACHE1, + IPU_DEVICE_ISP2600_STALL_DMEM, + IPU_DEVICE_ISP2600_STALL_QMEM, + IPU_DEVICE_ISP2600_STALL_CMEM, + IPU_DEVICE_ISP2600_STALL_XMEM, + IPU_DEVICE_ISP2600_STALL_BAMEM, + IPU_DEVICE_ISP2600_STALL_VMEM, + IPU_DEVICE_ISP2600_STALL_XVMEM, + IPU_DEVICE_ISP2600_NUM_STALL_BITS +}; + +#define IPU_DEVICE_ISP2600_ICACHE_WORD_SIZE 64 /* 512 bits per instruction */ +#define IPU_DEVICE_ISP2600_ICACHE_BURST_SIZE 8 /* 8 instructions per burst */ + +static const struct ipu_device_cell_count_s ipu_device_isp2600_count = { + IPU_DEVICE_ISP2600_NUM_MEMORIES, + IPU_DEVICE_ISP2600_NUM_MASTERS, + IPU_DEVICE_ISP2600_NUM_STALL_BITS, + IPU_DEVICE_ISP2600_ICACHE_WORD_SIZE * + IPU_DEVICE_ISP2600_ICACHE_BURST_SIZE +}; + +static const unsigned int ipu_device_isp2600_reg_offset[/* CELL_NUM_REGS */] = { + 0x0, 0x4, 0x10, 0x130, 0x134 +}; + +static const struct ipu_device_cell_type_properties_s +ipu_device_isp2600_properties = { + &ipu_device_isp2600_count, + ipu_device_isp2600_masters, + ipu_device_isp2600_reg_offset, + ipu_device_isp2600_mem_size +}; + +#endif /* __IPU_DEVICE_ISP2600_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_sp2600_control_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_sp2600_control_properties_impl.h new file mode 100644 index 0000000000000..430295cd9d949 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_sp2600_control_properties_impl.h @@ -0,0 +1,136 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H +#define __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H + +/* sp2600_control definition */ + +#include "ipu_device_cell_properties_struct.h" + +enum ipu_device_sp2600_control_registers { + /* control registers */ + IPU_DEVICE_SP2600_CONTROL_STAT_CTRL = 0x0, + IPU_DEVICE_SP2600_CONTROL_START_PC = 0x4, + + /* master port registers */ + IPU_DEVICE_SP2600_CONTROL_ICACHE_BASE = 0x10, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO = 0x14, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO_OVERRIDE = 0x18, + + IPU_DEVICE_SP2600_CONTROL_QMEM_BASE = 0x1C, + + IPU_DEVICE_SP2600_CONTROL_CMEM_BASE = 0x28, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO = 0x2C, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO_OVERRIDE = 0x30, + + IPU_DEVICE_SP2600_CONTROL_XMEM_BASE = 0x58, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO = 0x5C, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO_OVERRIDE = 0x60, + + /* debug registers */ + IPU_DEVICE_SP2600_CONTROL_DEBUG_PC = 0x9C, + IPU_DEVICE_SP2600_CONTROL_STALL = 0xA0 +}; + +enum ipu_device_sp2600_control_mems { + IPU_DEVICE_SP2600_CONTROL_REGS, + IPU_DEVICE_SP2600_CONTROL_PMEM, + IPU_DEVICE_SP2600_CONTROL_DMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES +}; + +static const unsigned int +ipu_device_sp2600_control_mem_size[IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES] = { + 0x000AC, + 0x00000, + 0x10000 +}; + +enum ipu_device_sp2600_control_masters { + IPU_DEVICE_SP2600_CONTROL_ICACHE, + IPU_DEVICE_SP2600_CONTROL_QMEM, + IPU_DEVICE_SP2600_CONTROL_CMEM, + IPU_DEVICE_SP2600_CONTROL_XMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS +}; + +static const struct ipu_device_cell_master_properties_s +ipu_device_sp2600_control_masters[IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS] = { + { + 0, + 0xC, + IPU_DEVICE_SP2600_CONTROL_ICACHE_BASE, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO, + IPU_DEVICE_SP2600_CONTROL_ICACHE_INFO_OVERRIDE + }, + { + 0, + 0xC, + IPU_DEVICE_SP2600_CONTROL_QMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_CONTROL_CMEM_BASE, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO, + IPU_DEVICE_SP2600_CONTROL_CMEM_INFO_OVERRIDE + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_CONTROL_XMEM_BASE, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO, + IPU_DEVICE_SP2600_CONTROL_XMEM_INFO_OVERRIDE + } +}; + +enum ipu_device_sp2600_control_stall_bits { + IPU_DEVICE_SP2600_CONTROL_STALL_ICACHE, + IPU_DEVICE_SP2600_CONTROL_STALL_DMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_QMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_CMEM, + IPU_DEVICE_SP2600_CONTROL_STALL_XMEM, + IPU_DEVICE_SP2600_CONTROL_NUM_STALL_BITS +}; + +/* 32 bits per instruction */ +#define IPU_DEVICE_SP2600_CONTROL_ICACHE_WORD_SIZE 4 +/* 32 instructions per burst */ +#define IPU_DEVICE_SP2600_CONTROL_ICACHE_BURST_SIZE 32 + +static const struct ipu_device_cell_count_s ipu_device_sp2600_control_count = { + IPU_DEVICE_SP2600_CONTROL_NUM_MEMORIES, + IPU_DEVICE_SP2600_CONTROL_NUM_MASTERS, + IPU_DEVICE_SP2600_CONTROL_NUM_STALL_BITS, + IPU_DEVICE_SP2600_CONTROL_ICACHE_WORD_SIZE * + IPU_DEVICE_SP2600_CONTROL_ICACHE_BURST_SIZE +}; + +static const unsigned int +ipu_device_sp2600_control_reg_offset[/* CELL_NUM_REGS */] = { + 0x0, 0x4, 0x10, 0x9C, 0xA0 +}; + +static const struct ipu_device_cell_type_properties_s +ipu_device_sp2600_control_properties = { + &ipu_device_sp2600_control_count, + ipu_device_sp2600_control_masters, + ipu_device_sp2600_control_reg_offset, + ipu_device_sp2600_control_mem_size +}; + +#endif /* __IPU_DEVICE_SP2600_CONTROL_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_sp2600_fp_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_sp2600_fp_properties_impl.h new file mode 100644 index 0000000000000..b3f120f9fea86 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_sp2600_fp_properties_impl.h @@ -0,0 +1,140 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_SP2600_FP_PROPERTIES_IMPL_H +#define __IPU_DEVICE_SP2600_FP_PROPERTIES_IMPL_H + +/* sp2600_fp definition */ + +#include "ipu_device_cell_properties_struct.h" + +enum ipu_device_sp2600_fp_registers { + /* control registers */ + IPU_DEVICE_SP2600_FP_STAT_CTRL = 0x0, + IPU_DEVICE_SP2600_FP_START_PC = 0x4, + + /* master port registers */ + IPU_DEVICE_SP2600_FP_ICACHE_BASE = 0x10, + IPU_DEVICE_SP2600_FP_ICACHE_INFO = 0x14, + IPU_DEVICE_SP2600_FP_ICACHE_INFO_OVERRIDE = 0x18, + + IPU_DEVICE_SP2600_FP_QMEM_BASE = 0x1C, + + IPU_DEVICE_SP2600_FP_CMEM_BASE = 0x28, + IPU_DEVICE_SP2600_FP_CMEM_INFO = 0x2C, + IPU_DEVICE_SP2600_FP_CMEM_INFO_OVERRIDE = 0x30, + + IPU_DEVICE_SP2600_FP_XMEM_BASE = 0x88, + IPU_DEVICE_SP2600_FP_XMEM_INFO = 0x8C, + IPU_DEVICE_SP2600_FP_XMEM_INFO_OVERRIDE = 0x90, + + /* debug registers */ + IPU_DEVICE_SP2600_FP_DEBUG_PC = 0xCC, + IPU_DEVICE_SP2600_FP_STALL = 0xD0 +}; + + +enum ipu_device_sp2600_fp_memories { + IPU_DEVICE_SP2600_FP_REGS, + IPU_DEVICE_SP2600_FP_PMEM, + IPU_DEVICE_SP2600_FP_DMEM, + IPU_DEVICE_SP2600_FP_DMEM1, + IPU_DEVICE_SP2600_FP_NUM_MEMORIES +}; + +static const unsigned int +ipu_device_sp2600_fp_mem_size[IPU_DEVICE_SP2600_FP_NUM_MEMORIES] = { + 0x000DC, + 0x00000, + 0x10000, + 0x08000 +}; + +enum ipu_device_sp2600_fp_masters { + IPU_DEVICE_SP2600_FP_ICACHE, + IPU_DEVICE_SP2600_FP_QMEM, + IPU_DEVICE_SP2600_FP_CMEM, + IPU_DEVICE_SP2600_FP_XMEM, + IPU_DEVICE_SP2600_FP_NUM_MASTERS +}; + +static const struct ipu_device_cell_master_properties_s +ipu_device_sp2600_fp_masters[IPU_DEVICE_SP2600_FP_NUM_MASTERS] = { + { + 0, + 0xC, + IPU_DEVICE_SP2600_FP_ICACHE_BASE, + IPU_DEVICE_SP2600_FP_ICACHE_INFO, + IPU_DEVICE_SP2600_FP_ICACHE_INFO_OVERRIDE + }, + { + 0, + 0xC, + IPU_DEVICE_SP2600_FP_QMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 3, + 0xC, + IPU_DEVICE_SP2600_FP_CMEM_BASE, + IPU_DEVICE_SP2600_FP_CMEM_INFO, + IPU_DEVICE_SP2600_FP_CMEM_INFO_OVERRIDE + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_FP_XMEM_BASE, + IPU_DEVICE_SP2600_FP_XMEM_INFO, + IPU_DEVICE_SP2600_FP_XMEM_INFO_OVERRIDE + } +}; + +enum ipu_device_sp2600_fp_stall_bits { + IPU_DEVICE_SP2600_FP_STALL_ICACHE, + IPU_DEVICE_SP2600_FP_STALL_DMEM, + IPU_DEVICE_SP2600_FP_STALL_QMEM, + IPU_DEVICE_SP2600_FP_STALL_CMEM, + IPU_DEVICE_SP2600_FP_STALL_XMEM, + IPU_DEVICE_SP2600_FP_STALL_DMEM1, + IPU_DEVICE_SP2600_FP_NUM_STALL_BITS +}; + +/* 32 bits per instruction */ +#define IPU_DEVICE_SP2600_FP_ICACHE_WORD_SIZE 4 +/* 32 instructions per burst */ +#define IPU_DEVICE_SP2600_FP_ICACHE_BURST_SIZE 32 + +static const struct ipu_device_cell_count_s ipu_device_sp2600_fp_count = { + IPU_DEVICE_SP2600_FP_NUM_MEMORIES, + IPU_DEVICE_SP2600_FP_NUM_MASTERS, + IPU_DEVICE_SP2600_FP_NUM_STALL_BITS, + IPU_DEVICE_SP2600_FP_ICACHE_WORD_SIZE * + IPU_DEVICE_SP2600_FP_ICACHE_BURST_SIZE +}; + +static const unsigned int +ipu_device_sp2600_fp_reg_offset[/* CELL_NUM_REGS */] = { + 0x0, 0x4, 0x10, 0x9C, 0xA0 +}; + +static const struct ipu_device_cell_type_properties_s +ipu_device_sp2600_fp_properties = { + &ipu_device_sp2600_fp_count, + ipu_device_sp2600_fp_masters, + ipu_device_sp2600_fp_reg_offset, + ipu_device_sp2600_fp_mem_size +}; + +#endif /* __IPU_DEVICE_SP2600_FP_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_sp2600_proxy_properties_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_sp2600_proxy_properties_impl.h new file mode 100644 index 0000000000000..6fdcd7faea9b8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/devices/src/ipu_device_sp2600_proxy_properties_impl.h @@ -0,0 +1,138 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IPU_DEVICE_SP2600_PROXY_PROPERTIES_IMPL_H +#define __IPU_DEVICE_SP2600_PROXY_PROPERTIES_IMPL_H + +/* sp2600_proxy definition */ + +#include "ipu_device_cell_properties_struct.h" + +enum ipu_device_sp2600_proxy_registers { + /* control registers */ + IPU_DEVICE_SP2600_PROXY_STAT_CTRL = 0x0, + IPU_DEVICE_SP2600_PROXY_START_PC = 0x4, + + /* THESE ADDRESSES NEED TO BE CHECKED !!!! */ + /* master port registers */ + IPU_DEVICE_SP2600_PROXY_ICACHE_BASE = 0x10, + IPU_DEVICE_SP2600_PROXY_ICACHE_INFO = 0x14, + IPU_DEVICE_SP2600_PROXY_ICACHE_INFO_OVERRIDE = 0x18, + + IPU_DEVICE_SP2600_PROXY_QMEM_BASE = 0x1C, + + IPU_DEVICE_SP2600_PROXY_CMEM_BASE = 0x28, + IPU_DEVICE_SP2600_PROXY_CMEM_INFO = 0x2C, + IPU_DEVICE_SP2600_PROXY_CMEM_INFO_OVERRIDE = 0x30, + + IPU_DEVICE_SP2600_PROXY_XMEM_BASE = 0x58, + IPU_DEVICE_SP2600_PROXY_XMEM_INFO = 0x5C, + IPU_DEVICE_SP2600_PROXY_XMEM_INFO_OVERRIDE = 0x60, + + /* debug registers */ + IPU_DEVICE_SP2600_PROXY_DEBUG_PC = 0x9C, + IPU_DEVICE_SP2600_PROXY_STALL = 0xA0 +}; + + +enum ipu_device_sp2600_proxy_memories { + IPU_DEVICE_SP2600_PROXY_REGS, + IPU_DEVICE_SP2600_PROXY_PMEM, + IPU_DEVICE_SP2600_PROXY_DMEM, + IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES +}; + +static const unsigned int +ipu_device_sp2600_proxy_mem_size[IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES] = { + 0x00AC, + 0x0000, + 0x4000 +}; + +enum ipu_device_sp2600_proxy_masters { + IPU_DEVICE_SP2600_PROXY_ICACHE, + IPU_DEVICE_SP2600_PROXY_QMEM, + IPU_DEVICE_SP2600_PROXY_CMEM, + IPU_DEVICE_SP2600_PROXY_XMEM, + IPU_DEVICE_SP2600_PROXY_NUM_MASTERS +}; + +static const struct ipu_device_cell_master_properties_s +ipu_device_sp2600_proxy_masters[IPU_DEVICE_SP2600_PROXY_NUM_MASTERS] = { + { + 0, + 0xC, + IPU_DEVICE_SP2600_PROXY_ICACHE_BASE, + IPU_DEVICE_SP2600_PROXY_ICACHE_INFO, + IPU_DEVICE_SP2600_PROXY_ICACHE_INFO_OVERRIDE + }, + { + 0, + 0xC, + IPU_DEVICE_SP2600_PROXY_QMEM_BASE, + 0xFFFFFFFF, + 0xFFFFFFFF + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_PROXY_CMEM_BASE, + IPU_DEVICE_SP2600_PROXY_CMEM_INFO, + IPU_DEVICE_SP2600_PROXY_CMEM_INFO_OVERRIDE + }, + { + 2, + 0xC, + IPU_DEVICE_SP2600_PROXY_XMEM_BASE, + IPU_DEVICE_SP2600_PROXY_XMEM_INFO, + IPU_DEVICE_SP2600_PROXY_XMEM_INFO_OVERRIDE + } +}; + +enum ipu_device_sp2600_proxy_stall_bits { + IPU_DEVICE_SP2600_PROXY_STALL_ICACHE, + IPU_DEVICE_SP2600_PROXY_STALL_DMEM, + IPU_DEVICE_SP2600_PROXY_STALL_QMEM, + IPU_DEVICE_SP2600_PROXY_STALL_CMEM, + IPU_DEVICE_SP2600_PROXY_STALL_XMEM, + IPU_DEVICE_SP2600_PROXY_NUM_STALL_BITS +}; + +/* 32 bits per instruction */ +#define IPU_DEVICE_SP2600_PROXY_ICACHE_WORD_SIZE 4 +/* 32 instructions per burst */ +#define IPU_DEVICE_SP2600_PROXY_ICACHE_BURST_SIZE 32 + +static const struct ipu_device_cell_count_s ipu_device_sp2600_proxy_count = { + IPU_DEVICE_SP2600_PROXY_NUM_MEMORIES, + IPU_DEVICE_SP2600_PROXY_NUM_MASTERS, + IPU_DEVICE_SP2600_PROXY_NUM_STALL_BITS, + IPU_DEVICE_SP2600_PROXY_ICACHE_WORD_SIZE * + IPU_DEVICE_SP2600_PROXY_ICACHE_BURST_SIZE +}; + +static const unsigned int +ipu_device_sp2600_proxy_reg_offset[/* CELL_NUM_REGS */] = { + 0x0, 0x4, 0x10, 0xCC, 0xD0 +}; + +static const struct ipu_device_cell_type_properties_s +ipu_device_sp2600_proxy_properties = { + &ipu_device_sp2600_proxy_count, + ipu_device_sp2600_proxy_masters, + ipu_device_sp2600_proxy_reg_offset, + ipu_device_sp2600_proxy_mem_size +}; + +#endif /* __IPU_DEVICE_SP2600_PROXY_PROPERTIES_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/cpu/fw_abi_cpu_types.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/cpu/fw_abi_cpu_types.mk new file mode 100644 index 0000000000000..b1ffbf7ea21ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/cpu/fw_abi_cpu_types.mk @@ -0,0 +1,24 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# + +# MODULE is FW ABI COMMON TYPES + +FW_ABI_COMMON_TYPES_DIRS = -I$${MODULES_DIR}/fw_abi_common_types +FW_ABI_COMMON_TYPES_DIRS += -I$${MODULES_DIR}/fw_abi_common_types/cpu + +FW_ABI_COMMON_TYPES_HOST_FILES = +FW_ABI_COMMON_TYPES_HOST_CPPFLAGS = $(FW_ABI_COMMON_TYPES_DIRS) + +FW_ABI_COMMON_TYPES_FW_FILES = +FW_ABI_COMMON_TYPES_FW_CPPFLAGS = $(FW_ABI_COMMON_TYPES_DIRS) diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_base_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_base_types.h new file mode 100644 index 0000000000000..21cc3f43f485e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_base_types.h @@ -0,0 +1,42 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_BASE_TYPES_H +#define __IA_CSS_TERMINAL_BASE_TYPES_H + + +#include "type_support.h" +#include "ia_css_terminal_defs.h" + +#define N_UINT16_IN_TERMINAL_STRUCT 3 +#define N_PADDING_UINT8_IN_TERMINAL_STRUCT 5 + +#define SIZE_OF_TERMINAL_STRUCT_BITS \ + (IA_CSS_TERMINAL_TYPE_BITS \ + + IA_CSS_TERMINAL_ID_BITS \ + + N_UINT16_IN_TERMINAL_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_IN_TERMINAL_STRUCT * IA_CSS_UINT8_T_BITS) + +/* ==================== Base Terminal - START ==================== */ +struct ia_css_terminal_s { /**< Base terminal */ + ia_css_terminal_type_t terminal_type; /**< Type ia_css_terminal_type_t */ + int16_t parent_offset; /**< Offset to the process group */ + uint16_t size; /**< Size of this whole terminal layout-structure */ + uint16_t tm_index; /**< Index of the terminal manifest object */ + ia_css_terminal_ID_t ID; /**< Absolute referal ID for this terminal, valid ID's != 0 */ + uint8_t padding[N_PADDING_UINT8_IN_TERMINAL_STRUCT]; +}; +/* ==================== Base Terminal - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h new file mode 100644 index 0000000000000..056e1b6d5d4bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/cpu/ia_css_terminal_manifest_base_types.h @@ -0,0 +1,42 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H +#define __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H + +#include "ia_css_terminal_defs.h" + +#define N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT 5 +#define SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + (IA_CSS_UINT16_T_BITS \ + + IA_CSS_TERMINAL_ID_BITS \ + + IA_CSS_TERMINAL_TYPE_BITS \ + + IA_CSS_UINT32_T_BITS \ + + (N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT*IA_CSS_UINT8_T_BITS)) + +/* ==================== Base Terminal Manifest - START ==================== */ +struct ia_css_terminal_manifest_s { + ia_css_terminal_type_t terminal_type; /**< Type ia_css_terminal_type_t */ + int16_t parent_offset; /**< Offset to the program group manifest */ + uint16_t size; /**< Size of this whole terminal-manifest layout-structure */ + ia_css_terminal_ID_t ID; + uint8_t padding[N_PADDING_UINT8_IN_TERMINAL_MAN_STRUCT]; +}; + +typedef struct ia_css_terminal_manifest_s + ia_css_terminal_manifest_t; + +/* ==================== Base Terminal Manifest - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_MANIFEST_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/ia_css_base_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/ia_css_base_types.h new file mode 100644 index 0000000000000..3b80a17a6ad38 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/ia_css_base_types.h @@ -0,0 +1,38 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BASE_TYPES_H +#define __IA_CSS_BASE_TYPES_H + +#include "type_support.h" + +#define VIED_VADDRESS_BITS 32 +typedef uint32_t vied_vaddress_t; + +#define DEVICE_DESCRIPTOR_ID_BITS 32 +typedef struct { + uint8_t device_id; + uint8_t instance_id; + uint8_t channel_id; + uint8_t section_id; +} device_descriptor_fields_t; + +typedef union { + device_descriptor_fields_t fields; + uint32_t data; +} device_descriptor_id_t; + +typedef uint16_t ia_css_process_id_t; + +#endif /* __IA_CSS_BASE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/ia_css_terminal_defs.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/ia_css_terminal_defs.h new file mode 100644 index 0000000000000..dbf1cf93756ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_abi_common_types/ia_css_terminal_defs.h @@ -0,0 +1,105 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_DEFS_H +#define __IA_CSS_TERMINAL_DEFS_H + + +#include "type_support.h" + +#define IA_CSS_TERMINAL_ID_BITS 8 +typedef uint8_t ia_css_terminal_ID_t; +#define IA_CSS_TERMINAL_INVALID_ID ((ia_css_terminal_ID_t)(-1)) + +/* + * Terminal Base Type + */ +typedef enum ia_css_terminal_type { + /**< Data input */ + IA_CSS_TERMINAL_TYPE_DATA_IN = 0, + /**< Data output */ + IA_CSS_TERMINAL_TYPE_DATA_OUT, + /**< Type 6 parameter input */ + IA_CSS_TERMINAL_TYPE_PARAM_STREAM, + /**< Type 1-5 parameter input */ + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN, + /**< Type 1-5 parameter output */ + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT, + /**< Represent the new type of terminal for the + * "spatial dependent parameters", when params go in + */ + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN, + /**< Represent the new type of terminal for the + * "spatial dependent parameters", when params go out + */ + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT, + /**< Represent the new type of terminal for the + * explicit slicing, when params go in + */ + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN, + /**< Represent the new type of terminal for the + * explicit slicing, when params go out + */ + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT, + /**< State (private data) input */ + IA_CSS_TERMINAL_TYPE_STATE_IN, + /**< State (private data) output */ + IA_CSS_TERMINAL_TYPE_STATE_OUT, + IA_CSS_TERMINAL_TYPE_PROGRAM, + IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT, + IA_CSS_N_TERMINAL_TYPES +} ia_css_terminal_type_t; + +#define IA_CSS_TERMINAL_TYPE_BITS 32 + +/* Temporary redirection needed to facilicate merging with the drivers + in a backwards compatible manner */ +#define IA_CSS_TERMINAL_TYPE_PARAM_CACHED IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN + +/* + * Dimensions of the data objects. Note that a C-style + * data order is assumed. Data stored by row. + */ +typedef enum ia_css_dimension { + /**< The number of columns, i.e. the size of the row */ + IA_CSS_COL_DIMENSION = 0, + /**< The number of rows, i.e. the size of the column */ + IA_CSS_ROW_DIMENSION = 1, + IA_CSS_N_DATA_DIMENSION = 2 +} ia_css_dimension_t; + +#define IA_CSS_N_COMMAND_COUNT (4) + +#ifndef PIPE_GENERATION +/* Don't include these complex enum structures in Genpipe, it can't handle and it does not need them */ +/* + * enum ia_css_isys_link_id. Lists the link IDs used by the FW for On The Fly feature + */ +typedef enum ia_css_isys_link_id { + IA_CSS_ISYS_LINK_OFFLINE = 0, + IA_CSS_ISYS_LINK_MAIN_OUTPUT = 1, + IA_CSS_ISYS_LINK_PDAF_OUTPUT = 2 +} ia_css_isys_link_id_t; +#define N_IA_CSS_ISYS_LINK_ID (IA_CSS_ISYS_LINK_PDAF_OUTPUT + 1) + +/* + * enum ia_css_data_barrier_link_id. Lists the link IDs used by the FW for data barrier feature + */ +typedef enum ia_css_data_barrier_link_id { + IA_CSS_DATA_BARRIER_LINK_MEMORY = N_IA_CSS_ISYS_LINK_ID, + N_IA_CSS_DATA_BARRIER_LINK_ID +} ia_css_data_barrier_link_id_t; + +#endif /* #ifndef PIPE_GENERATION */ +#endif /* __IA_CSS_TERMINAL_DEFS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/fw_load.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/fw_load.mk new file mode 100644 index 0000000000000..0af62100cba82 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/fw_load.mk @@ -0,0 +1,59 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is FW_LOAD + +# select implementation for fw_load +ifeq ($(FW_LOAD_DMA), 1) +FW_LOAD_IMPL = fwdma +else +FW_LOAD_IMPL = xmem +endif + +FW_LOAD_FW_CPPFLAGS = + +# select DMA instance for fw_load +ifeq ($(FW_LOAD_DMA_INSTANCE),) +$(error FW_LOAD_DMA_INSTANCE not specified) +else +ifeq ($(FW_LOAD_DMA_INSTANCE), NCI_DMA_EXT0) +FW_LOAD_FW_CPPFLAGS += -DFW_LOAD_INSTANCE_USE_DMA_EXT0 +else +ifeq ($(FW_LOAD_DMA_INSTANCE), NCI_DMA_FW) +FW_LOAD_FW_CPPFLAGS += -DFW_LOAD_INSTANCE_USE_DMA_FW +else +$(error FW_LOAD_DMA_INSTANCE $(FW_LOAD_DMA_INSTANCE) not supported) +endif +endif +endif + +FW_LOAD_DIR = $${MODULES_DIR}/fw_load +FW_LOAD_INTERFACE = $(FW_LOAD_DIR)/interface +FW_LOAD_SOURCES = $(FW_LOAD_DIR)/src/$(FW_LOAD_IMPL) + +# XMEM/FWDMA supports on SP side +FW_LOAD_FW_FILES = $(FW_LOAD_SOURCES)/ia_css_fw_load.c +FW_LOAD_FW_CPPFLAGS += -I$(FW_LOAD_INTERFACE) \ + -I$(FW_LOAD_SOURCES) \ + -I$(FW_LOAD_DIR)/src + +# Only XMEM supports on Host side +FW_LOAD_HOST_FILES = $(FW_LOAD_DIR)/src/xmem/ia_css_fw_load.c +FW_LOAD_HOST_CPPFLAGS = -I$(FW_LOAD_INTERFACE) \ + -I$(FW_LOAD_DIR)/src/xmem \ + -I$(FW_LOAD_DIR)/src + +ifdef FW_LOAD_NO_OF_REQUEST_OFFSET +FW_LOAD_FW_CPPFLAGS += -DFW_LOAD_NO_OF_REQUEST_ADDRESS=$(FW_LOAD_NO_OF_REQUEST_OFFSET) +endif # FW_LOAD_NO_OF_REQUEST_OFFSET diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/interface/ia_css_fw_load.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/interface/ia_css_fw_load.h new file mode 100644 index 0000000000000..d1f7926f39c60 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/interface/ia_css_fw_load.h @@ -0,0 +1,155 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_FW_LOAD_H +#define __IA_CSS_FW_LOAD_H + +#include "ia_css_fw_load_storage_class.h" +#include "ia_css_xmem.h" +#include "ia_css_cmem.h" + +enum ia_css_fw_load_mode { + IA_CSS_DBUS_ADDRESS = 0, + IA_CSS_CBUS_ADDRESS +}; + +/* Perform Initialization for fwload + Client must call init before it calls any other API + */ + +IA_CSS_FW_LOAD_STORAGE_CLASS_H void +ia_css_fw_load_init(void); + +/* This motifies the use what address has to be passed into the 'dst' parameter + * of the ia_css_fw_copy function and the ia_css_fw_zero function. + * When this function returns IA_CSS_DBUS_ADDRESS, the user must pass a data-bus + * address, when the function returns IA_CSS_CBUS_ADDRESS, the user must pass a + * control-bus address. + * XMEM implementation will require control-bus address while, + * DMA implementation will require data-bus addresses. +*/ +IA_CSS_FW_LOAD_STORAGE_CLASS_H unsigned int +ia_css_fw_load_get_mode(void); + +/***************** FW LOAD BLOCKING FUNCTIONS *******************************/ +/* NOTE : User cannot use blocking functions immidiate after calling any + * non-blocking request functions. User must finish all the load request before + * it calls any blocking function. + * e.g. Following is the invalid use case. + * - ia_css_fw_load_copy_begin (non-blocking) then without ending this request, + * it calls ia_css_fw_load_copy (blocking). Client should not do this. + * But before calling ia_css_fw_load_copy, it shouold finish all request by + * calling ia_css_fw_end(). + */ + +/* Perform a single data transfer from DDR/IMR (src) to local variable(dst). + All arguments are multiples of 4. + The function returns when the transfer has completed. + The function may block. + */ +IA_CSS_FW_LOAD_STORAGE_CLASS_H void +ia_css_fw_load( + unsigned int mmid, + ia_css_xmem_address_t src, + void *dst, + unsigned int size +); + +/* Perform a single data transfer from DDR/IMR (src) to the subsystem (dst). + All arguments are multiples of 4. + The function returns when the transfer has completed. + The function may block. + */ +IA_CSS_FW_LOAD_STORAGE_CLASS_H void +ia_css_fw_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size +); + +/* Perform zeroing the memory in subsystem (dst) + The function returns when all transfers have completed. + The function may block. + */ +IA_CSS_FW_LOAD_STORAGE_CLASS_H void +ia_css_fw_zero( + unsigned int ssid, + ia_css_cmem_address_t dst, + unsigned int size); + +/***************** FW LOAD NON_BLOCKING FUNCTIONS ****************************/ + +/* Perform a single data transfer from DDR/IMR (src) to local variable(dst). + All arguments are multiples of 4. + The function returns when the transfer has completed. + The function will not block. + */ +IA_CSS_FW_LOAD_STORAGE_CLASS_H unsigned int +ia_css_fw_load_begin( + unsigned int mmid, + ia_css_xmem_address_t src, + void *dst, + unsigned int size +); + +/* START OF TRANSFER / SUBMIT */ +/* Start a single data transfer from DDR/IMR (src) to the subsystem (dst). + The function returns 1 when the transfer has been issued successfully. + When the transfer cannot be issued, the function returns 0. + The function will not block. + */ +IA_CSS_FW_LOAD_STORAGE_CLASS_H unsigned int +ia_css_fw_copy_begin( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size +); + +/* Perform zeroing the subsystem (dst) memory + This function will not block + */ +IA_CSS_FW_LOAD_STORAGE_CLASS_H unsigned int +ia_css_fw_zero_begin( + unsigned int ssid, + ia_css_cmem_address_t dst, + unsigned int size); + +/* END OF TRANSFER / ACKNOWLEDGES */ +/* Complete at most n transfers, + returns the number of transfers that could be completed + */ +IA_CSS_FW_LOAD_STORAGE_CLASS_H unsigned int +ia_css_fw_end(unsigned int n); + +/* OPTIONALLY USED FUNCTIONS */ +/* Return the number of transactions that may be submitted without blocking */ +IA_CSS_FW_LOAD_STORAGE_CLASS_H unsigned int +ia_css_fw_copy_begin_available(void); + +/* Return the number of transactions may be ended */ +IA_CSS_FW_LOAD_STORAGE_CLASS_H unsigned int +ia_css_fw_copy_end_available(void); + +#ifdef __INLINE_IA_CSS_FW_LOAD__ +#include "ia_css_fw_load_blocking_impl.h" +#include "ia_css_fw_load_non_blocking_impl.h" +#include "ia_css_fw_load_impl.h" +#endif + + +#endif /* __IA_CSS_FW_LOAD_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/interface/ia_css_fw_load_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/interface/ia_css_fw_load_storage_class.h new file mode 100644 index 0000000000000..10ad61f89ea91 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/interface/ia_css_fw_load_storage_class.h @@ -0,0 +1,28 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_FW_LOAD_STORAGE_CLASS_H +#define __IA_CSS_FW_LOAD_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __INLINE_IA_CSS_FW_LOAD__ +#define IA_CSS_FW_LOAD_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_FW_LOAD_STORAGE_CLASS_C +#else +#define IA_CSS_FW_LOAD_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_FW_LOAD_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_FW_LOAD_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load.c new file mode 100644 index 0000000000000..5930a6b1e8d21 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load.c @@ -0,0 +1,29 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/* C file with (optionally) inlined files */ + +/* Global variable for tracking the number of fw_load transactions */ +/* Needed in host side implementaion */ +#ifndef __VIED_CELL +unsigned int started; +#endif + +#ifdef __INLINE_IA_CSS_FW_LOAD__ +static inline int __avoid_warning_on_empty_file(void) { return 0; } +#else +#include "ia_css_fw_load_blocking_impl.h" +#include "ia_css_fw_load_non_blocking_impl.h" +#include "ia_css_fw_load_impl.h" +#endif /* __INLINE_IA_CSS_FW_LOAD__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_blocking_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_blocking_impl.h new file mode 100644 index 0000000000000..02ad9c36156e0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_blocking_impl.h @@ -0,0 +1,54 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_FW_LOAD_BLOCKING_IMPL_H +#define __IA_CSS_FW_LOAD_BLOCKING_IMPL_H + +#include "ia_css_fw_load.h" +#include "ia_css_fw_load_storage_class.h" +#include "ia_css_xmem_cmem.h" +#include "ia_css_xmem.h" +#include "ia_css_cmem.h" + +IA_CSS_FW_LOAD_STORAGE_CLASS_C void +ia_css_fw_load( + unsigned int mmid, + ia_css_xmem_address_t src, + void *dst, + unsigned int size) +{ + ia_css_xmem_load(mmid, src, dst, size); +} + +IA_CSS_FW_LOAD_STORAGE_CLASS_C void +ia_css_fw_copy( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size) +{ + ia_css_xmem_to_cmem_copy(mmid, ssid, src, dst, size); +} + +IA_CSS_FW_LOAD_STORAGE_CLASS_C void +ia_css_fw_zero( + unsigned int ssid, + ia_css_cmem_address_t dst, + unsigned int size) +{ + ia_css_cmem_zero(ssid, dst, size); +} + +#endif /* __IA_CSS_FW_LOAD_BLOCKING_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_impl.h new file mode 100644 index 0000000000000..a9b6db8a5f55c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_impl.h @@ -0,0 +1,26 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_FW_LOAD_IMPL_H +#define __IA_CSS_FW_LOAD_IMPL_H + +#include "ia_css_fw_load.h" + +IA_CSS_FW_LOAD_STORAGE_CLASS_C unsigned int +ia_css_fw_load_get_mode(void) +{ + return IA_CSS_CBUS_ADDRESS; +} + +#endif /* __IA_CSS_FW_LOAD_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_non_blocking_host_state.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_non_blocking_host_state.h new file mode 100644 index 0000000000000..1691e4522f78b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_non_blocking_host_state.h @@ -0,0 +1,21 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_FW_LOAD_NON_BLOCKING_HOST_STATE_H +#define __IA_CSS_FW_LOAD_NON_BLOCKING_HOST_STATE_H +/* Global variable for tracking the number of fw_load transactions */ +/* Used in xmem non blocking host side implementaion */ +extern unsigned int started; + +#endif /* __IA_CSS_FW_LOAD_NON_BLOCKING_HOST_STATE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_non_blocking_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_non_blocking_impl.h new file mode 100644 index 0000000000000..ae02df6c46c01 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_non_blocking_impl.h @@ -0,0 +1,125 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_FW_LOAD_NON_BLOCKING_IMPL_H +#define __IA_CSS_FW_LOAD_NON_BLOCKING_IMPL_H + +#include "type_support.h" +#include "ia_css_fw_load.h" +#include "ia_css_fw_load_storage_class.h" +#include "math_support.h" +#include "error_support.h" + +#ifdef __VIED_CELL +#include "ia_css_fw_load_non_blocking_impl_sp.h" +#else +#include "ia_css_fw_load_non_blocking_impl_host.h" +#endif + +#define FW_LOAD_MAX_NB_TRANS UINT_MAX +#define FW_LOAD_XMEM_MAX_TRANSACTION_SUPPORT \ + ipu4_umin(FW_LOAD_MAX_NB_TRANS, FW_LOAD_MAX_TRANS_SUPPORTED) + + +IA_CSS_FW_LOAD_STORAGE_CLASS_C void +ia_css_fw_load_init(void) +{ + fw_load_transaction_init(); +} + +/* START OF TRANSFER */ +IA_CSS_FW_LOAD_STORAGE_CLASS_C unsigned int +ia_css_fw_load_begin( + unsigned int mmid, + ia_css_xmem_address_t src, + void *dst, + unsigned int size +) +{ + if (!ia_css_fw_copy_begin_available()) + return 0; + ia_css_fw_load(mmid, src, dst, size); + fw_load_transaction_add(); + return size; +} + +IA_CSS_FW_LOAD_STORAGE_CLASS_C unsigned int +ia_css_fw_copy_begin( + unsigned int mmid, + unsigned int ssid, + ia_css_xmem_address_t src, + ia_css_cmem_address_t dst, + unsigned int size) +{ + /* Check if there is space to hold the ack event in the queue */ + if (!ia_css_fw_copy_begin_available()) + return 0; + ia_css_fw_copy(mmid, ssid, src, dst, size); + fw_load_transaction_add(); + return size; +} + + +IA_CSS_FW_LOAD_STORAGE_CLASS_C unsigned int +ia_css_fw_zero_begin( + unsigned int ssid, + ia_css_cmem_address_t dst, + unsigned int size) +{ + if (!ia_css_fw_copy_begin_available()) + return 0; /*quote exceeded*/ + + ia_css_fw_zero(ssid, dst, size); + fw_load_transaction_add(); + return size; +} + +/* END OF TRANSFER */ +IA_CSS_FW_LOAD_STORAGE_CLASS_C unsigned int +ia_css_fw_end(unsigned int n) +{ + int no_of_ack_received; + int fw_end_count; + int transaction_done; + bool success; + + no_of_ack_received = ia_css_fw_copy_end_available(); + fw_end_count = min(n, no_of_ack_received); + + transaction_done = 0; + + while (transaction_done < fw_end_count) { + success = fw_load_transaction_remove(); + assert(success == true); + transaction_done++; + } + return fw_end_count; +} + +/* OPTIONALLY USED */ +IA_CSS_FW_LOAD_STORAGE_CLASS_C unsigned int +ia_css_fw_copy_begin_available(void) +{ + return (FW_LOAD_XMEM_MAX_TRANSACTION_SUPPORT - + ia_css_fw_copy_end_available()); +} + +IA_CSS_FW_LOAD_STORAGE_CLASS_C unsigned int +ia_css_fw_copy_end_available(void) +{ + /* check how many transactions are ready to be ended */ + return fw_load_transaction_get_finished(); +} + +#endif /* __IA_CSS_FW_LOAD_NON_BLOCKING_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_non_blocking_impl_host.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_non_blocking_impl_host.h new file mode 100644 index 0000000000000..25a05cce25768 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/fw_load/src/xmem/ia_css_fw_load_non_blocking_impl_host.h @@ -0,0 +1,45 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_FW_LOAD_NON_BLOCKING_IMPL_HOST_H +#define __IA_CSS_FW_LOAD_NON_BLOCKING_IMPL_HOST_H + +#include "storage_class.h" +#include "type_support.h" +#include "ia_css_fw_load_non_blocking_host_state.h" + +#define FW_LOAD_MAX_TRANS_SUPPORTED UINT_MAX + +STORAGE_CLASS_INLINE void fw_load_transaction_init(void) +{ + started = 0; +} + +STORAGE_CLASS_INLINE bool fw_load_transaction_add(void) +{ + started++; + return true; +} + +STORAGE_CLASS_INLINE bool fw_load_transaction_remove(void) +{ + started--; + return true; +} + +STORAGE_CLASS_INLINE unsigned int fw_load_transaction_get_finished(void) +{ + return started; +} +#endif /* __IA_CSS_FW_LOAD_NON_BLOCKING_IMPL_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir.h new file mode 100644 index 0000000000000..a284d74bb4a67 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir.h @@ -0,0 +1,99 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_H +#define __IA_CSS_PKG_DIR_H + +#include "ia_css_pkg_dir_storage_class.h" +#include "ia_css_pkg_dir_types.h" +#include "type_support.h" + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +const ia_css_pkg_dir_entry_t *ia_css_pkg_dir_get_entry( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index +); + +/* User is expected to call the verify function manually, + * other functions do not call it internally + */ +IA_CSS_PKG_DIR_STORAGE_CLASS_H +int ia_css_pkg_dir_verify_header( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_get_num_entries( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_get_size_in_bytes( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +enum ia_css_pkg_dir_version ia_css_pkg_dir_get_version( + const ia_css_pkg_dir_entry_t *pkg_dir_header +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint16_t ia_css_pkg_dir_set_version( + ia_css_pkg_dir_entry_t *pkg_dir_header, + enum ia_css_pkg_dir_version version +); + + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_address_lo( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_address_hi( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint32_t ia_css_pkg_dir_entry_get_size( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint16_t ia_css_pkg_dir_entry_get_version( + const ia_css_pkg_dir_entry_t *entry +); + +IA_CSS_PKG_DIR_STORAGE_CLASS_H +uint8_t ia_css_pkg_dir_entry_get_type( + const ia_css_pkg_dir_entry_t *entry +); + +/* Get the address of the specified entry in the PKG_DIR + * Note: This function expects the complete PKG_DIR in the same memory space + * and the entries contains offsets and not addresses. + */ +IA_CSS_PKG_DIR_STORAGE_CLASS_H +void *ia_css_pkg_dir_get_entry_address( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index +); + +#ifdef __IA_CSS_PKG_DIR_INLINE__ + +#include "ia_css_pkg_dir_impl.h" + +#endif + +#endif /* __IA_CSS_PKG_DIR_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_iunit.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_iunit.h new file mode 100644 index 0000000000000..ad194b0389eb7 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_iunit.h @@ -0,0 +1,46 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_IUNIT_H +#define __IA_CSS_PKG_DIR_IUNIT_H + +/* In bootflow, pkg_dir only supports upto 16 entries in pkg_dir + * pkg_dir_header + Psys_server pg + Isys_server pg + 13 Client pg + */ + +enum { + IA_CSS_PKG_DIR_SIZE = 16, + IA_CSS_PKG_DIR_ENTRIES = IA_CSS_PKG_DIR_SIZE - 1 +}; + +#define IUNIT_MAX_CLIENT_PKG_ENTRIES 13 + +/* Example assignment of unique identifiers for the FW components + * This should match the identifiers in the manifest + */ +enum ia_css_pkg_dir_entry_type { + IA_CSS_PKG_DIR_HEADER = 0, + IA_CSS_PKG_DIR_PSYS_SERVER_PG, + IA_CSS_PKG_DIR_ISYS_SERVER_PG, + IA_CSS_PKG_DIR_CLIENT_PG +}; + +/* Fixed entries in the package directory */ +enum ia_css_pkg_dir_index { + IA_CSS_PKG_DIR_PSYS_INDEX = 0, + IA_CSS_PKG_DIR_ISYS_INDEX = 1, + IA_CSS_PKG_DIR_CLIENT_0 = 2 +}; + +#endif /* __IA_CSS_PKG_DIR_IUNIT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_storage_class.h new file mode 100644 index 0000000000000..cb64172151f92 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_storage_class.h @@ -0,0 +1,29 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_STORAGE_CLASS_H +#define __IA_CSS_PKG_DIR_STORAGE_CLASS_H + + +#include "storage_class.h" + +#ifndef __IA_CSS_PKG_DIR_INLINE__ +#define IA_CSS_PKG_DIR_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PKG_DIR_STORAGE_CLASS_C +#else +#define IA_CSS_PKG_DIR_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PKG_DIR_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PKG_DIR_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_types.h new file mode 100644 index 0000000000000..b024b3da2f9e6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/interface/ia_css_pkg_dir_types.h @@ -0,0 +1,41 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_TYPES_H +#define __IA_CSS_PKG_DIR_TYPES_H + +#include "type_support.h" + +struct ia_css_pkg_dir_entry { + uint32_t address[2]; + uint32_t size; + uint16_t version; + uint8_t type; + uint8_t unused; +}; + +typedef void ia_css_pkg_dir_t; +typedef struct ia_css_pkg_dir_entry ia_css_pkg_dir_entry_t; + +/* The version field of the pkg_dir header defines + * if entries contain offsets or pointers + */ +/* This is temporary, until all pkg_dirs use pointers */ +enum ia_css_pkg_dir_version { + IA_CSS_PKG_DIR_POINTER, + IA_CSS_PKG_DIR_OFFSET +}; + + +#endif /* __IA_CSS_PKG_DIR_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/pkg_dir.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/pkg_dir.mk new file mode 100644 index 0000000000000..32c8a68f3653c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/pkg_dir.mk @@ -0,0 +1,29 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PKG DIR + +PKG_DIR_DIR = $${MODULES_DIR}/pkg_dir +PKG_DIR_INTERFACE = $(PKG_DIR_DIR)/interface +PKG_DIR_SOURCES = $(PKG_DIR_DIR)/src + +PKG_DIR_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir.c +PKG_DIR_CPPFLAGS = -I$(PKG_DIR_INTERFACE) +PKG_DIR_CPPFLAGS += -I$(PKG_DIR_SOURCES) +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/../isp/kernels/io_ls/common +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/fw_abi_common_types/ipu +PKG_DIR_CPPFLAGS += -I$${MODULES_DIR}/fw_abi_common_types/ipu/$(FW_ABI_IPU_TYPES_VERSION) + +PKG_DIR_CREATE_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir_create.c +PKG_DIR_UPDATE_FILES = $(PKG_DIR_DIR)/src/ia_css_pkg_dir_update.c diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir.c new file mode 100644 index 0000000000000..348b56833e060 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir.c @@ -0,0 +1,27 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifdef __IA_CSS_PKG_DIR_INLINE__ + +#include "storage_class.h" + +STORAGE_CLASS_INLINE int __ia_css_pkg_dir_avoid_warning_on_empty_file(void) +{ + return 0; +} + +#else +#include "ia_css_pkg_dir_impl.h" + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_impl.h new file mode 100644 index 0000000000000..d5067d21398f9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_impl.h @@ -0,0 +1,201 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_IMPL_H +#define __IA_CSS_PKG_DIR_IMPL_H + +#include "ia_css_pkg_dir.h" +#include "ia_css_pkg_dir_int.h" +#include "error_support.h" +#include "type_support.h" +#include "assert_support.h" + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +const ia_css_pkg_dir_entry_t *ia_css_pkg_dir_get_entry( + const ia_css_pkg_dir_t *pkg_dir, + uint32_t index) +{ + DECLARE_ERRVAL + struct ia_css_pkg_dir_entry *pkg_dir_header = NULL; + + verifexitval(pkg_dir != NULL, EFAULT); + + pkg_dir_header = (struct ia_css_pkg_dir_entry *)pkg_dir; + + /* First entry of the structure is the header, skip that */ + index++; + verifexitval(index < pkg_dir_header->size, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + return NULL; + } + return &(pkg_dir_header[index]); +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +int ia_css_pkg_dir_verify_header(const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + verifexitval(pkg_dir_header != NULL, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + return -1; + } + return ((pkg_dir_header->address[0] == PKG_DIR_MAGIC_VAL_0) + && (pkg_dir_header->address[1] == PKG_DIR_MAGIC_VAL_1)) ? + 0 : -1; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_get_num_entries( + const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + uint32_t size = 0; + + verifexitval(pkg_dir_header != NULL, EFAULT); + size = pkg_dir_header->size; + verifexitval(size > 0, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return size - 1; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +enum ia_css_pkg_dir_version +ia_css_pkg_dir_get_version(const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + assert(pkg_dir_header != NULL); + return pkg_dir_header->version; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint16_t ia_css_pkg_dir_set_version(ia_css_pkg_dir_entry_t *pkg_dir_header, + enum ia_css_pkg_dir_version version) +{ + DECLARE_ERRVAL + + verifexitval(pkg_dir_header != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 1; + } + pkg_dir_header->version = version; + return 0; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_get_size_in_bytes( + const ia_css_pkg_dir_entry_t *pkg_dir_header) +{ + DECLARE_ERRVAL + + verifexitval(pkg_dir_header != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return sizeof(struct ia_css_pkg_dir_entry) * pkg_dir_header->size; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_address_lo( + const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->address[0]; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_address_hi( + const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->address[1]; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint32_t ia_css_pkg_dir_entry_get_size(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->size; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint16_t ia_css_pkg_dir_entry_get_version(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->version; +} + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +uint8_t ia_css_pkg_dir_entry_get_type(const ia_css_pkg_dir_entry_t *entry) +{ + DECLARE_ERRVAL + + verifexitval(entry != NULL, EFAULT); +EXIT: + if (haserror(EFAULT)) { + return 0; + } + return entry->type; +} + + +IA_CSS_PKG_DIR_STORAGE_CLASS_C +void *ia_css_pkg_dir_get_entry_address(const ia_css_pkg_dir_t *pkg_dir, + uint32_t index) +{ + void *entry_blob = NULL; + const ia_css_pkg_dir_entry_t *pkg_dir_entry = + ia_css_pkg_dir_get_entry(pkg_dir, index-1); + + if ((pkg_dir_entry != NULL) && + (ia_css_pkg_dir_entry_get_size(pkg_dir_entry) > 0)) { + assert(ia_css_pkg_dir_entry_get_address_hi(pkg_dir_entry) == 0); + entry_blob = (void *)((char *)pkg_dir + + ia_css_pkg_dir_entry_get_address_lo(pkg_dir_entry)); + } + return entry_blob; +} + +#endif /* __IA_CSS_PKG_DIR_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_int.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_int.h new file mode 100644 index 0000000000000..203505fbee54e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/pkg_dir/src/ia_css_pkg_dir_int.h @@ -0,0 +1,49 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PKG_DIR_INT_H +#define __IA_CSS_PKG_DIR_INT_H + +/* + * Package Dir structure as specified in CSE FAS + * + * PKG DIR Header + * Qword 63:56 55 54:48 47:32 31:24 23:0 + * 0 "_IUPKDR_" + * 1 Rsvd Rsvd Type Version Rsvd Size + * + * Version: Version of the Structure + * Size: Size of the entire table (including header) in 16 byte chunks + * Type: Must be 0 for header + * + * Figure 13: PKG DIR Header + * + * + * PKG DIR Entry + * Qword 63:56 55 54:48 47:32 31:24 23:0 + * N Address/Offset + * N+1 Rsvd Rsvd Type Version Rsvd Size + * + * Version: Version # of the Component + * Size: Size of the component in bytes + * Type: Component Identifier + */ + +#define PKG_DIR_SIZE_BITS 24 +#define PKG_DIR_TYPE_BITS 7 + +#define PKG_DIR_MAGIC_VAL_1 (('_' << 24) | ('I' << 16) | ('U' << 8) | 'P') +#define PKG_DIR_MAGIC_VAL_0 (('K' << 24) | ('D' << 16) | ('R' << 8) | '_') + +#endif /* __IA_CSS_PKG_DIR_INT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/port_env_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/port_env_struct.h new file mode 100644 index 0000000000000..4d39a4739a8b0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/port_env_struct.h @@ -0,0 +1,24 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PORT_ENV_STRUCT_H +#define __PORT_ENV_STRUCT_H + +struct port_env { + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; +}; + +#endif /* __PORT_ENV_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/queue.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/queue.h new file mode 100644 index 0000000000000..b233ab3baf014 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/queue.h @@ -0,0 +1,40 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __QUEUE_H +#define __QUEUE_H + +#include "queue_struct.h" +#include "port_env_struct.h" + +/* + * SYS queues are created by the host + * SYS queues cannot be accessed through the queue interface + * To send data into a queue a send_port must be opened. + * To receive data from a queue, a recv_port must be opened. + */ + +/* return required buffer size for queue */ +unsigned int +sys_queue_buf_size(unsigned int size, unsigned int token_size); + +/* + * initialize a queue that can hold at least 'size' tokens of + * 'token_size' bytes. + */ +void +sys_queue_init(struct sys_queue *q, unsigned int size, + unsigned int token_size, struct sys_queue_res *res); + +#endif /* __QUEUE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/queue_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/queue_struct.h new file mode 100644 index 0000000000000..ef48fcfded2b6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/queue_struct.h @@ -0,0 +1,47 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __QUEUE_STRUCT_H +#define __QUEUE_STRUCT_H + +/* queue description, shared between sender and receiver */ + +#include "type_support.h" + +#ifdef __VIED_CELL +typedef struct {uint32_t v[2]; } host_buffer_address_t; +#else +typedef uint64_t host_buffer_address_t; +#endif + +typedef uint32_t vied_buffer_address_t; + + +struct sys_queue { + host_buffer_address_t host_address; + vied_buffer_address_t vied_address; + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* reg no in subsystem's regmem */ + unsigned int rd_reg; + unsigned int _align; +}; + +struct sys_queue_res { + host_buffer_address_t host_address; + vied_buffer_address_t vied_address; + unsigned int reg; +}; + +#endif /* __QUEUE_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/recv_port.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/recv_port.h new file mode 100644 index 0000000000000..cce253b266687 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/recv_port.h @@ -0,0 +1,34 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __RECV_PORT_H +#define __RECV_PORT_H + + +struct recv_port; +struct sys_queue; +struct port_env; + +void +recv_port_open(struct recv_port *p, const struct sys_queue *q, + const struct port_env *env); + +unsigned int +recv_port_available(const struct recv_port *p); + +unsigned int +recv_port_transfer(const struct recv_port *p, void *data); + + +#endif /* __RECV_PORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/recv_port_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/recv_port_struct.h new file mode 100644 index 0000000000000..52ec563b13cf5 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/recv_port_struct.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __RECV_PORT_STRUCT_H +#define __RECV_PORT_STRUCT_H + +#include "buffer_type.h" + +struct recv_port { + buffer_address buffer; /* address of buffer in DDR */ + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* index of write pointer located in regmem */ + unsigned int rd_reg; /* index read pointer located in regmem */ + + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; /* address of memory containing regmem */ +}; + +#endif /* __RECV_PORT_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/send_port.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/send_port.h new file mode 100644 index 0000000000000..04a160f3f0199 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/send_port.h @@ -0,0 +1,52 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __SEND_PORT_H +#define __SEND_PORT_H + + +/* + * A send port can be used to send tokens into a queue. + * The interface can be used on any type of processor (host, SP, ...) + */ + +struct send_port; +struct sys_queue; +struct port_env; + +/* + * Open a send port on a queue. After the port is opened, tokens can be sent + */ +void +send_port_open(struct send_port *p, const struct sys_queue *q, + const struct port_env *env); + +/* + * Determine how many tokens can be sent + */ +unsigned int +send_port_available(const struct send_port *p); + +/* + * Send a token via a send port. The function returns the number of + * tokens that have been sent: + * 1: the token was accepted + * 0: the token was not accepted (full queue) + * The size of a token is determined at initialization. + */ +unsigned int +send_port_transfer(const struct send_port *p, const void *data); + + +#endif /* __SEND_PORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/send_port_struct.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/send_port_struct.h new file mode 100644 index 0000000000000..f834c62bc3db6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/interface/send_port_struct.h @@ -0,0 +1,32 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __SEND_PORT_STRUCT_H +#define __SEND_PORT_STRUCT_H + +#include "buffer_type.h" + +struct send_port { + buffer_address buffer; + unsigned int size; + unsigned int token_size; + unsigned int wr_reg; /* index of write pointer in regmem */ + unsigned int rd_reg; /* index of read pointer in regmem */ + + unsigned int mmid; + unsigned int ssid; + unsigned int mem_addr; +}; + +#endif /* __SEND_PORT_STRUCT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/port.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/port.mk new file mode 100644 index 0000000000000..b3801247802e9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/port.mk @@ -0,0 +1,31 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PORT + +PORT_DIR=$${MODULES_DIR}/port + +PORT_INTERFACE=$(PORT_DIR)/interface +PORT_SOURCES1=$(PORT_DIR)/src + +PORT_HOST_FILES += $(PORT_SOURCES1)/send_port.c +PORT_HOST_FILES += $(PORT_SOURCES1)/recv_port.c +PORT_HOST_FILES += $(PORT_SOURCES1)/queue.c + +PORT_HOST_CPPFLAGS += -I$(PORT_INTERFACE) + +PORT_FW_FILES += $(PORT_SOURCES1)/send_port.c +PORT_FW_FILES += $(PORT_SOURCES1)/recv_port.c + +PORT_FW_CPPFLAGS += -I$(PORT_INTERFACE) diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/src/queue.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/src/queue.c new file mode 100644 index 0000000000000..eeec99dfe2d0d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/src/queue.c @@ -0,0 +1,47 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "queue.h" + +#include "regmem_access.h" +#include "port_env_struct.h" + +unsigned int sys_queue_buf_size(unsigned int size, unsigned int token_size) +{ + return (size + 1) * token_size; +} + +void +sys_queue_init(struct sys_queue *q, unsigned int size, unsigned int token_size, + struct sys_queue_res *res) +{ + unsigned int buf_size; + + q->size = size + 1; + q->token_size = token_size; + buf_size = sys_queue_buf_size(size, token_size); + + /* acquire the shared buffer space */ + q->host_address = res->host_address; + res->host_address += buf_size; + q->vied_address = res->vied_address; + res->vied_address += buf_size; + + /* acquire the shared read and writer pointers */ + q->wr_reg = res->reg; + res->reg++; + q->rd_reg = res->reg; + res->reg++; + +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/src/recv_port.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/src/recv_port.c new file mode 100644 index 0000000000000..31b36e9ceafbb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/src/recv_port.c @@ -0,0 +1,95 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "recv_port.h" +#include "port_env_struct.h" /* for port_env */ +#include "queue_struct.h" /* for sys_queue */ +#include "recv_port_struct.h" /* for recv_port */ +#include "buffer_access.h" /* for buffer_load, buffer_address */ +#include "regmem_access.h" /* for regmem_load_32, regmem_store_32 */ +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "math_support.h" /* for OP_std_modadd */ +#include "type_support.h" /* for HOST_ADDRESS */ + +#ifndef __VIED_CELL +#include "cpu_mem_support.h" /* for ia_css_cpu_mem_cache_invalidate */ +#endif + +void +recv_port_open(struct recv_port *p, const struct sys_queue *q, + const struct port_env *env) +{ + p->mmid = env->mmid; + p->ssid = env->ssid; + p->mem_addr = env->mem_addr; + + p->size = q->size; + p->token_size = q->token_size; + p->wr_reg = q->wr_reg; + p->rd_reg = q->rd_reg; + +#ifdef __VIED_CELL + p->buffer = q->vied_address; +#else + p->buffer = q->host_address; +#endif +} + +STORAGE_CLASS_INLINE unsigned int +recv_port_index(const struct recv_port *p, unsigned int i) +{ + unsigned int rd = regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + + return OP_std_modadd(rd, i, p->size); +} + +unsigned int +recv_port_available(const struct recv_port *p) +{ + int wr = (int)regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + int rd = (int)regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + + return OP_std_modadd(wr, -rd, p->size); +} + +STORAGE_CLASS_INLINE void +recv_port_copy(const struct recv_port *p, unsigned int i, void *data) +{ + unsigned int rd = recv_port_index(p, i); + unsigned int token_size = p->token_size; + buffer_address addr = p->buffer + (rd * token_size); +#ifndef __VIED_CELL + ia_css_cpu_mem_cache_invalidate((void *)HOST_ADDRESS(p->buffer), + token_size*p->size); +#endif + buffer_load(addr, data, token_size, p->mmid); +} + +STORAGE_CLASS_INLINE void +recv_port_release(const struct recv_port *p, unsigned int i) +{ + unsigned int rd = recv_port_index(p, i); + + regmem_store_32(p->mem_addr, p->rd_reg, rd, p->ssid); +} + +unsigned int +recv_port_transfer(const struct recv_port *p, void *data) +{ + if (!recv_port_available(p)) + return 0; + recv_port_copy(p, 0, data); + recv_port_release(p, 1); + return 1; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/src/send_port.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/src/send_port.c new file mode 100644 index 0000000000000..8d1fba08c5d58 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/port/src/send_port.c @@ -0,0 +1,94 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "send_port.h" +#include "queue_struct.h" /* for sys_queue */ +#include "send_port_struct.h" /* for send_port */ +#include "port_env_struct.h" /* for port_env */ +#include "regmem_access.h" /* for regmem_load_32, regmem_store_32 */ +#include "buffer_access.h" /* for buffer_store, buffer_address */ +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "math_support.h" /* for OP_std_modadd */ +#include "type_support.h" /* for HOST_ADDRESS */ + +#ifndef __VIED_CELL +#include "cpu_mem_support.h" /* for ia_css_cpu_mem_cache_flush */ +#endif + +void +send_port_open(struct send_port *p, const struct sys_queue *q, + const struct port_env *env) +{ + p->mmid = env->mmid; + p->ssid = env->ssid; + p->mem_addr = env->mem_addr; + + p->size = q->size; + p->token_size = q->token_size; + p->wr_reg = q->wr_reg; + p->rd_reg = q->rd_reg; +#ifdef __VIED_CELL + p->buffer = q->vied_address; +#else + p->buffer = q->host_address; +#endif +} + +STORAGE_CLASS_INLINE unsigned int +send_port_index(const struct send_port *p, unsigned int i) +{ + unsigned int wr = regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + + return OP_std_modadd(wr, i, p->size); +} + +unsigned int +send_port_available(const struct send_port *p) +{ + int rd = (int)regmem_load_32(p->mem_addr, p->rd_reg, p->ssid); + int wr = (int)regmem_load_32(p->mem_addr, p->wr_reg, p->ssid); + + return OP_std_modadd(rd, -(wr+1), p->size); +} + +STORAGE_CLASS_INLINE void +send_port_copy(const struct send_port *p, unsigned int i, const void *data) +{ + unsigned int wr = send_port_index(p, i); + unsigned int token_size = p->token_size; + buffer_address addr = p->buffer + (wr * token_size); + + buffer_store(addr, data, token_size, p->mmid); +#ifndef __VIED_CELL + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(addr), token_size); +#endif +} + +STORAGE_CLASS_INLINE void +send_port_release(const struct send_port *p, unsigned int i) +{ + unsigned int wr = send_port_index(p, i); + + regmem_store_32(p->mem_addr, p->wr_reg, wr, p->ssid); +} + +unsigned int +send_port_transfer(const struct send_port *p, const void *data) +{ + if (!send_port_available(p)) + return 0; + send_port_copy(p, 0, data); + send_port_release(p, 1); + return 1; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_infobits/interface/psys_infobits.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_infobits/interface/psys_infobits.h new file mode 100644 index 0000000000000..11029a1805313 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_infobits/interface/psys_infobits.h @@ -0,0 +1,20 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PSYS_INFOBITS_H +#define __PSYS_INFOBITS_H + +void ia_css_psys_set_master_port_regs(unsigned int ssid); + +#endif /* __PSYS_INFOBITS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_infobits/psys_infobits.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_infobits/psys_infobits.mk new file mode 100644 index 0000000000000..c6641e293fe64 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_infobits/psys_infobits.mk @@ -0,0 +1,29 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# PSYS_INFOBITS +# + +PSYS_INFOBITS_DIR = $${MODULES_DIR}/psys_infobits + +PSYS_INFOBITS_INTERFACE = $(PSYS_INFOBITS_DIR)/interface +PSYS_INFOBITS_SOURCES = $(PSYS_INFOBITS_DIR)/src + +PSYS_INFOBITS_CPPFLAGS := \ + -I$(PSYS_INFOBITS_INTERFACE) + +PSYS_INFOBITS_HOST_FILES = \ + $(PSYS_INFOBITS_SOURCES)/psys_infobits.c + +PSYS_INFOBITS_FW_FILES = $(PSYS_INFOBITS_HOST_FILES) diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_infobits/src/psys_infobits.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_infobits/src/psys_infobits.c new file mode 100644 index 0000000000000..5c43583f6193e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_infobits/src/psys_infobits.c @@ -0,0 +1,107 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "psys_infobits.h" + +#include "assert_support.h" +#include "ia_css_cell.h" +#include "ipu_device_cell_properties.h" +#include "ipu_device_cell_properties_impl.h" +#include "ipu_device_buttress_properties_struct.h" + +/* +** According to BXT CSS HAS PS the info bits as expected by buttress are +** Field---------Description---------------------Encoding---------------| + | 0 | CIOM0: Snoopable | 0 - non snoopable | + | | | 1 - snoopable | + ----------------------------------------------------------------------| + | 1 | CIOM0: VC0_RS_for_IMR | Deadline | + | | CIOM1: VC1_deadline_pointer | 0 - regular deadline | + | | | 1 - urgent deadline | + ----------------------------------------------------------------------| + | 2 | Deadline pointer reserved | | + ----------------------------------------------------------------------| + | 3 | CIOM1: Zero-length write (ZLW)| 0 - NOP | + | | | 1 - Convert transaction as ZLW + ----------------------------------------------------------------------| + | 5:4 | CIOM0: Request destination | Destination | + | | CIOM1: Stream_ID[1:0] | 00 - Buttress registers| + | | | 01 - Primary | + | | | 10 - Reserved | + | | | 11 - Input system | + ----------------------------------------------------------------------| + | 7:6 | CIOM1: Stream_ID[3:2] | For data prefetch | + ----------------------------------------------------------------------| + | 8 | CIOM1: Address swizzeling | | + ----------------------------------------------------------------------| + + ** As PSYS devices use MO port and the request destination is DDR + ** then bit 4 (Request destination) should be 1 (Primary), thus 0x10 +*/ + + +void ia_css_psys_set_master_port_regs(unsigned int ssid) +{ + /* set primary destination(DDR) */ + unsigned int info_bits = IA_CSS_INFO_BITS_M0_DDR; + enum ipu_device_psys_cell_id cell_id; + + COMPILATION_ERROR_IF(0 != SPC0); + + /* Configure SPC */ + cell_id = SPC0; + ia_css_cell_set_master_info_bits(ssid, cell_id, + IPU_DEVICE_SP2600_CONTROL_ICACHE, info_bits); + ia_css_cell_set_master_info_bits(ssid, cell_id, + IPU_DEVICE_SP2600_CONTROL_XMEM, info_bits); + ia_css_cell_set_master_base_address(ssid, cell_id, + IPU_DEVICE_SP2600_CONTROL_XMEM, 0); + +#if defined(HAS_SPP0) + /* Configure SPP0 proxy */ + cell_id = SPP0; + ia_css_cell_set_master_info_bits(ssid, cell_id, + IPU_DEVICE_SP2600_PROXY_ICACHE, info_bits); + ia_css_cell_set_master_info_bits(ssid, cell_id, + IPU_DEVICE_SP2600_PROXY_XMEM, info_bits); + ia_css_cell_set_master_base_address(ssid, cell_id, + IPU_DEVICE_SP2600_PROXY_XMEM, 0); + COMPILATION_ERROR_IF(SPP0 < SPC0); +#endif + +#if defined(HAS_SPP1) + /* Configure SPP1 proxy */ + cell_id = SPP1; + ia_css_cell_set_master_info_bits(ssid, cell_id, + IPU_DEVICE_SP2600_PROXY_ICACHE, info_bits); + ia_css_cell_set_master_info_bits(ssid, cell_id, + IPU_DEVICE_SP2600_PROXY_XMEM, info_bits); + ia_css_cell_set_master_base_address(ssid, cell_id, + IPU_DEVICE_SP2600_PROXY_XMEM, 0); + COMPILATION_ERROR_IF(SPP1 < SPC0); +#endif + +#if defined(HAS_ISP0) + /* Configure ISP(s) */ + for (cell_id = ISP0; cell_id < NUM_CELLS; cell_id++) { + ia_css_cell_set_master_info_bits(ssid, cell_id, + IPU_DEVICE_CELL_MASTER_ICACHE, info_bits); + ia_css_cell_set_master_info_bits(ssid, cell_id, + IPU_DEVICE_CELL_MASTER_XMEM, info_bits); + ia_css_cell_set_master_base_address(ssid, cell_id, + IPU_DEVICE_CELL_MASTER_XMEM, 0); + } + COMPILATION_ERROR_IF(ISP0 < SPP0); +#endif +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_private_pg/interface/ia_css_psys_private_pg_data.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_private_pg/interface/ia_css_psys_private_pg_data.h new file mode 100644 index 0000000000000..6b2387352ae36 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_private_pg/interface/ia_css_psys_private_pg_data.h @@ -0,0 +1,43 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PRIVATE_PG_DATA_H +#define __IA_CSS_PSYS_PRIVATE_PG_DATA_H + +#include "ipu_device_acb_devices.h" +#include "ipu_device_gp_devices.h" +#include "type_support.h" +#include "vied_nci_acb_route_type.h" + +#define PRIV_CONF_INVALID 0xFF + +struct ia_css_psys_pg_buffer_information_s { + unsigned int buffer_base_addr; + unsigned int bpe; + unsigned int buffer_width; + unsigned int buffer_height; + unsigned int num_of_buffers; + unsigned int dfm_port_addr; +}; + +typedef struct ia_css_psys_pg_buffer_information_s ia_css_psys_pg_buffer_information_t; + +struct ia_css_psys_private_pg_data { + nci_acb_route_t acb_route[IPU_DEVICE_ACB_NUM_ACB]; + uint8_t psa_mux_conf[IPU_DEVICE_GP_PSA_MUX_NUM_MUX]; + uint8_t isa_mux_conf[IPU_DEVICE_GP_ISA_STATIC_MUX_NUM_MUX]; + ia_css_psys_pg_buffer_information_t input_buffer_info; +}; + +#endif /* __IA_CSS_PSYS_PRIVATE_PG_DATA_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_server/interface/ia_css_bxt_spctrl_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_server/interface/ia_css_bxt_spctrl_trace.h new file mode 100644 index 0000000000000..eee1d6ab0a496 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_server/interface/ia_css_bxt_spctrl_trace.h @@ -0,0 +1,107 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_BXT_SPCTRL_TRACE_H +#define __IA_CSS_BXT_SPCTRL_TRACE_H + +#include "ia_css_trace.h" + +/* Not using 0 to identify wrong configuration being passed from + * the .mk file outside. + * Log levels not in the range below will cause a + * "No BXT_SPCTRL_TRACE_CONFIG Tracing level defined" + */ +#define BXT_SPCTRL_TRACE_LOG_LEVEL_OFF 1 +#define BXT_SPCTRL_TRACE_LOG_LEVEL_NORMAL 2 +#define BXT_SPCTRL_TRACE_LOG_LEVEL_DEBUG 3 + +/* BXT_SPCTRL and all the submodules in BXT_SPCTRL will have the + * default tracing level set to the BXT_SPCTRL_TRACE_CONFIG level. + * If not defined in the psysapi.mk fill it will be set by + * default to no trace (BXT_SPCTRL_TRACE_LOG_LEVEL_NORMAL) + */ +#define BXT_SPCTRL_TRACE_CONFIG_DEFAULT BXT_SPCTRL_TRACE_LOG_LEVEL_NORMAL + +#if !defined(BXT_SPCTRL_TRACE_CONFIG) +# define BXT_SPCTRL_TRACE_CONFIG BXT_SPCTRL_TRACE_CONFIG_DEFAULT +#endif + +/* BXT_SPCTRL Module tracing backend is mapped to TUNIT tracing for + * target platforms + */ +#ifdef __HIVECC +# ifndef HRT_CSIM +# define BXT_SPCTRL_TRACE_METHOD IA_CSS_TRACE_METHOD_TRACE +# else +# define BXT_SPCTRL_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +# endif +#else +# define BXT_SPCTRL_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#endif + +#if (defined(BXT_SPCTRL_TRACE_CONFIG)) + /* Module specific trace setting */ +# if BXT_SPCTRL_TRACE_CONFIG == BXT_SPCTRL_TRACE_LOG_LEVEL_OFF + /* BXT_SPCTRL_TRACE_LOG_LEVEL_OFF */ +# define BXT_SPCTRL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED +# elif BXT_SPCTRL_TRACE_CONFIG == BXT_SPCTRL_TRACE_LOG_LEVEL_NORMAL + /* BXT_SPCTRL_TRACE_LOG_LEVEL_NORMAL */ +# define BXT_SPCTRL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED +# define BXT_SPCTRL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED +# elif BXT_SPCTRL_TRACE_CONFIG == BXT_SPCTRL_TRACE_LOG_LEVEL_DEBUG + /* BXT_SPCTRL_TRACE_LOG_LEVEL_DEBUG */ +# define BXT_SPCTRL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED +# define BXT_SPCTRL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED +# else +# error "No BXT_SPCTRL_TRACE_CONFIG Tracing level defined" +# endif +#else +# error "BXT_SPCTRL_TRACE_CONFIG not defined" +#endif + +/* Overriding submodules in BXT_SPCTRL with a specific tracing level */ +/* #define BXT_SPCTRL_DYNAMIC_TRACING_OVERRIDE TRACE_LOG_LEVEL_VERBOSE */ + +#endif /* __IA_CSS_BXT_SPCTRL_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_server/psys_server.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_server/psys_server.mk new file mode 100644 index 0000000000000..c4462c9847935 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_server/psys_server.mk @@ -0,0 +1,81 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PSYS_SERVER + +include $(MODULES_DIR)/config/system_$(IPU_SYSVER).mk +include $(MODULES_DIR)/config/$(SUBSYSTEM)/subsystem_$(IPU_SYSVER).mk + +PSYS_SERVER_DIR=${MODULES_DIR}/psys_server + +# The watchdog should never be merged enabled +PSYS_SERVER_WATCHDOG_ENABLE ?= 0 + +PSYS_SERVER_INTERFACE=$(PSYS_SERVER_DIR)/interface +PSYS_SERVER_SOURCES=$(PSYS_SERVER_DIR)/src + +# PSYS API implementation files. Consider a new module for those to avoid +# having them together with firmware. +PSYS_SERVER_HOST_FILES += $${MODULES_DIR}/psysapi/device/src/ia_css_psys_device.c +PSYS_SERVER_HOST_FILES += $(PSYS_SERVER_SOURCES)/bxt_spctrl_process_group_cmd_impl.c + +PSYS_SERVER_HOST_CPPFLAGS += -I$(PSYS_SERVER_INTERFACE) + +PSYS_SERVER_HOST_CPPFLAGS += -DSSID=$(SSID) +PSYS_SERVER_HOST_CPPFLAGS += -DMMID=$(MMID) + + +PSYS_SERVER_FW_FILES += $(PSYS_SERVER_SOURCES)/psys_cmd_queue_fw.c +PSYS_SERVER_FW_FILES += $(PSYS_SERVER_SOURCES)/psys_event_queue_fw.c +PSYS_SERVER_FW_FILES += $(PSYS_SERVER_SOURCES)/psys_init_fw.c +PSYS_SERVER_FW_FILES += $(PSYS_SERVER_SOURCES)/psys_process_group_fw.c + +# Files that server modules need to use +PSYS_SERVER_SUPPORT_FILES = $(PSYS_SERVER_SOURCES)/dev_access_conv/$(IPU_SYSVER)/ia_css_psys_server_dev_access_type_conv.c +PSYS_SERVER_SUPPORT_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_config.c + +# Include those to build the release firmware. Otherwise replace by test code. +PSYS_SERVER_RELEASE_FW_FILES = $(PSYS_SERVER_SOURCES)/psys_server.c +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_proxy.c +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_dev_access.c +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_terminal_load.c +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_remote_obj_access.c +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_dma_access.c +ifeq ($(HAS_DEC400), 1) +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_dec400_access.c +endif +PSYS_SERVER_RELEASE_FW_FILES += $(PSYS_SERVER_SUPPORT_FILES) + +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_INTERFACE) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES)/$(IPU_SYSVER) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES)/$(PSYS_SERVER_VERSION) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES)/loader/$(PSYS_SERVER_LOADER_VERSION) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES)/access_blocker/$(PSYS_ACCESS_BLOCKER_VERSION) +PSYS_SERVER_FW_CPPFLAGS += -I$(PSYS_SERVER_SOURCES)/access_blocker/src + +PSYS_SERVER_FW_CPPFLAGS += -DSSID=$(SSID) +PSYS_SERVER_FW_CPPFLAGS += -DMMID=$(MMID) +PSYS_SERVER_FW_CPPFLAGS += -DHAS_DPCM=$(if $(HAS_DPCM),1,0) + +# PSYS server watchdog for debugging +ifeq ($(PSYS_SERVER_WATCHDOG_ENABLE), 1) + PSYS_SERVER_FW_FILES += $(PSYS_SERVER_SOURCES)/ia_css_psys_server_watchdog.c + PSYS_SERVER_FW_CPPFLAGS += -DPSYS_SERVER_WATCHDOG_DEBUG +endif + +PSYS_SERVER_FW_CPPFLAGS += -D$(PSYS_HW_VERSION) + +PSYS_SERVER_FW_CPPFLAGS += -DENABLE_TPROXY=$(PSYS_SERVER_ENABLE_TPROXY) +PSYS_SERVER_FW_CPPFLAGS += -DENABLE_DEVPROXY=$(PSYS_SERVER_ENABLE_DEVPROXY) diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_server/src/bxt_spctrl_process_group_cmd_impl.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_server/src/bxt_spctrl_process_group_cmd_impl.c new file mode 100644 index 0000000000000..0a1ef5dfcae77 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psys_server/src/bxt_spctrl_process_group_cmd_impl.c @@ -0,0 +1,332 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_device.h" +#include "ia_css_psys_process_group_cmd_impl.h" +#include "ia_css_psysapi.h" +#include "ia_css_psys_terminal.h" +#include "ia_css_psys_process.h" +#include "ia_css_psys_process.psys.h" +#include "ia_css_psys_process_group.h" +#include "ia_css_psys_process_group.psys.h" +#include "ia_css_psys_program_group_manifest.h" +#include "type_support.h" +#include "error_support.h" +#include "misc_support.h" +#include "cpu_mem_support.h" +#include "ia_css_bxt_spctrl_trace.h" + +#if HAS_DUAL_CMD_CTX_SUPPORT +#define MAX_CLIENT_PGS 8 /* same as test_params.h */ +struct ia_css_process_group_context { + ia_css_process_group_t *pg; + bool secure; +}; +struct ia_css_process_group_context pg_contexts[MAX_CLIENT_PGS]; +static unsigned int num_of_pgs; + +STORAGE_CLASS_INLINE +struct ia_css_syscom_context *ia_css_process_group_get_context(ia_css_process_group_t *process_group) +{ + unsigned int i; + bool secure = false; + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_get_context(): enter:\n"); + + for (i = 0; i < num_of_pgs; i++) { + if (pg_contexts[i].pg == process_group) { + secure = pg_contexts[i].secure; + break; + } + } + + IA_CSS_TRACE_1(BXT_SPCTRL, INFO, + "ia_css_process_group_get_context(): secure %d\n", secure); + return secure ? psys_syscom_secure : psys_syscom; +} + +int ia_css_process_group_store(ia_css_process_group_t *process_group, bool secure) +{ + IA_CSS_TRACE_2(BXT_SPCTRL, INFO, + "ia_css_process_group_store(): pg instance %d secure %d\n", num_of_pgs, secure); + + pg_contexts[num_of_pgs].pg = process_group; + pg_contexts[num_of_pgs].secure = secure; + num_of_pgs++; + return 0; +} +#else /* HAS_DUAL_CMD_CTX_SUPPORT */ +STORAGE_CLASS_INLINE +struct ia_css_syscom_context *ia_css_process_group_get_context(ia_css_process_group_t *process_group) +{ + NOT_USED(process_group); + + return psys_syscom; +} + +int ia_css_process_group_store(ia_css_process_group_t *process_group, bool secure) +{ + NOT_USED(process_group); + NOT_USED(secure); + + return 0; +} +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +int ia_css_process_group_on_create( + ia_css_process_group_t *process_group, + const ia_css_program_group_manifest_t *program_group_manifest, + const ia_css_program_group_param_t *program_group_param) +{ + NOT_USED(process_group); + NOT_USED(program_group_manifest); + NOT_USED(program_group_param); + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_on_create(): enter:\n"); + + return 0; +} + +int ia_css_process_group_on_destroy( + ia_css_process_group_t *process_group) +{ + NOT_USED(process_group); + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_on_destroy(): enter:\n"); + + return 0; +} + +int ia_css_process_group_exec_cmd( + ia_css_process_group_t *process_group, + const ia_css_process_group_cmd_t cmd) +{ + int retval = -1; + ia_css_process_group_state_t state; + struct ia_css_psys_cmd_s psys_cmd; + bool cmd_queue_full; + unsigned int queue_id; + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): enter:\n"); + + verifexit(process_group != NULL); + + state = ia_css_process_group_get_state(process_group); + + verifexit(state != IA_CSS_PROCESS_GROUP_ERROR); + verifexit(state < IA_CSS_N_PROCESS_GROUP_STATES); + + switch (cmd) { + case IA_CSS_PROCESS_GROUP_CMD_SUBMIT: + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): IA_CSS_PROCESS_GROUP_CMD_SUBMIT:\n"); + verifexit(state == IA_CSS_PROCESS_GROUP_READY); + + /* External resource availability checks */ + verifexit(ia_css_can_process_group_submit(process_group)); + + process_group->state = IA_CSS_PROCESS_GROUP_BLOCKED; + break; + case IA_CSS_PROCESS_GROUP_CMD_START: + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): IA_CSS_PROCESS_GROUP_CMD_START:\n"); + verifexit(state == IA_CSS_PROCESS_GROUP_BLOCKED); + + /* External resource state checks */ + verifexit(ia_css_can_process_group_start(process_group)); + + process_group->state = IA_CSS_PROCESS_GROUP_STARTED; + break; + case IA_CSS_PROCESS_GROUP_CMD_DISOWN: + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): IA_CSS_PROCESS_GROUP_CMD_DISOWN:\n"); + verifexit(state == IA_CSS_PROCESS_GROUP_STARTED); + + cmd_queue_full = ia_css_is_psys_cmd_queue_full(ia_css_process_group_get_context(process_group), + IA_CSS_PSYS_CMD_QUEUE_COMMAND_ID); + retval = EBUSY; + verifexit(cmd_queue_full == false); + + psys_cmd.command = IA_CSS_PROCESS_GROUP_CMD_START; + psys_cmd.msg = 0; + psys_cmd.context_handle = process_group->ipu_virtual_address; + + verifexit(ia_css_process_group_print(process_group, NULL) == 0); + + retval = ia_css_psys_cmd_queue_send(ia_css_process_group_get_context(process_group), + IA_CSS_PSYS_CMD_QUEUE_COMMAND_ID, &psys_cmd); + verifexit(retval > 0); + break; + case IA_CSS_PROCESS_GROUP_CMD_STOP: + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): IA_CSS_PROCESS_GROUP_CMD_STOP:\n"); + + cmd_queue_full = ia_css_is_psys_cmd_queue_full(ia_css_process_group_get_context(process_group), + IA_CSS_PSYS_CMD_QUEUE_COMMAND_ID); + retval = EBUSY; + verifexit(cmd_queue_full == false); + + psys_cmd.command = IA_CSS_PROCESS_GROUP_CMD_STOP; + psys_cmd.msg = 0; + psys_cmd.context_handle = process_group->ipu_virtual_address; + + queue_id = ia_css_process_group_get_base_queue_id(process_group); + verifexit(queue_id < IA_CSS_N_PSYS_CMD_QUEUE_ID); + + retval = ia_css_psys_cmd_queue_send(ia_css_process_group_get_context(process_group), + queue_id, &psys_cmd); + verifexit(retval > 0); + break; + case IA_CSS_PROCESS_GROUP_CMD_ABORT: + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_process_group_exec_cmd(): IA_CSS_PROCESS_GROUP_CMD_ABORT:\n"); + + /* Once the flushing of shared buffers is fixed this verifexit + * should be changed to be state = IA_CSS_PROCESS_GROUP_STARTED + */ + verifexit(state == IA_CSS_PROCESS_GROUP_BLOCKED); + + cmd_queue_full = ia_css_is_psys_cmd_queue_full(ia_css_process_group_get_context(process_group), + IA_CSS_PSYS_CMD_QUEUE_COMMAND_ID); + retval = EBUSY; + verifexit(cmd_queue_full == false); + + psys_cmd.command = IA_CSS_PROCESS_GROUP_CMD_ABORT; + psys_cmd.msg = 0; + psys_cmd.context_handle = process_group->ipu_virtual_address; + + retval = ia_css_psys_cmd_queue_send(ia_css_process_group_get_context(process_group), + IA_CSS_PSYS_CMD_QUEUE_DEVICE_ID, &psys_cmd); + verifexit(retval > 0); + break; + default: + verifexit(false); + break; + } + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(BXT_SPCTRL, ERROR, + "ia_css_process_group_exec_cmd failed (%i)\n", retval); + } + return retval; +} + +STORAGE_CLASS_INLINE int enqueue_buffer_set_cmd( + ia_css_process_group_t *process_group, + ia_css_buffer_set_t *buffer_set, + unsigned int queue_offset, + uint16_t command + ) +{ + int retval = -1; + struct ia_css_psys_cmd_s psys_cmd; + bool cmd_queue_full; + unsigned int queue_id; + + verifexit(ia_css_process_group_get_state(process_group) + == IA_CSS_PROCESS_GROUP_STARTED); + + verifexit(queue_offset < + ia_css_process_group_get_num_queues(process_group)); + + queue_id = + ia_css_process_group_get_base_queue_id(process_group) + + queue_offset; + verifexit(queue_id < IA_CSS_N_PSYS_CMD_QUEUE_ID); + + cmd_queue_full = ia_css_is_psys_cmd_queue_full(ia_css_process_group_get_context(process_group), queue_id); + retval = EBUSY; + verifexit(cmd_queue_full == false); + + psys_cmd.command = command; + psys_cmd.msg = 0; + psys_cmd.context_handle = + ia_css_buffer_set_get_ipu_address(buffer_set); + + retval = ia_css_psys_cmd_queue_send(ia_css_process_group_get_context(process_group), queue_id, &psys_cmd); + verifexit(retval > 0); + + retval = 0; + +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(BXT_SPCTRL, ERROR, + "enqueue_buffer_set failed (%i)\n", retval); + } + return retval; +} + +int ia_css_enqueue_buffer_set( + ia_css_process_group_t *process_group, + ia_css_buffer_set_t *buffer_set, + unsigned int queue_offset) +{ + int retval = -1; + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_enqueue_buffer_set():\n"); + retval = enqueue_buffer_set_cmd( + process_group, + buffer_set, + queue_offset, + IA_CSS_PROCESS_GROUP_CMD_RUN); + + if (retval != 0) { + IA_CSS_TRACE_1(BXT_SPCTRL, ERROR, + "ia_css_enqueue_buffer_set failed (%i)\n", retval); + } + return retval; +} + +int ia_css_enqueue_param_buffer_set( + ia_css_process_group_t *process_group, + ia_css_buffer_set_t *param_buffer_set) +{ +#if (HAS_LATE_BINDING_SUPPORT == 1) + int retval = -1; + + IA_CSS_TRACE_0(BXT_SPCTRL, INFO, + "ia_css_enqueue_param_buffer_set():\n"); + + retval = enqueue_buffer_set_cmd( + process_group, + param_buffer_set, + IA_CSS_PSYS_LATE_BINDING_QUEUE_OFFSET, + IA_CSS_PROCESS_GROUP_CMD_SUBMIT); + + if (retval != 0) { + IA_CSS_TRACE_1(BXT_SPCTRL, ERROR, + "ia_css_enqueue_param_buffer_set failed (%i)\n", retval); + } +#else + int retval = -1; + + NOT_USED(process_group); + NOT_USED(param_buffer_set); + IA_CSS_TRACE_0(BXT_SPCTRL, ERROR, + "ia_css_enqueue_param_buffer_set failed, no late binding supported\n"); +#endif /* (HAS_LATE_BINDING_SUPPORT == 1) */ + return retval; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data.h new file mode 100644 index 0000000000000..0f6fb5542913e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data.h @@ -0,0 +1,418 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_DATA_H +#define __IA_CSS_PROGRAM_GROUP_DATA_H + +#include "ia_css_psys_data_storage_class.h" + +/*! \file */ + +/** @file ia_css_program_group_data.h + * + * Define the data objects that are passed to the process groups + * i.e. frames and matrices with their sub-structures + * + * The data objects are separate from the process group terminal, + * although they are stored by value rather than by reference and + * make the process group terminal dependendent on its definition + * + * This frame definition overloads the current CSS frame definition + * they are the same object, just a slightly different implementation + */ + +#include /* vied_vaddress_t */ + +#include +#include "ia_css_program_group_data_defs.h" /* ia_css_frame_format_type */ + +#include "ia_css_terminal_defs.h" + +/* + * Frame buffer state used for sequencing + * (see FAS 5.5.3) + * + * The buffer can be in DDR or a handle to a stream + */ +typedef enum ia_css_buffer_state { + IA_CSS_BUFFER_NULL = 0, + IA_CSS_BUFFER_UNDEFINED, + IA_CSS_BUFFER_EMPTY, + IA_CSS_BUFFER_NONEMPTY, + IA_CSS_BUFFER_FULL, + IA_CSS_N_BUFFER_STATES +} ia_css_buffer_state_t; + +#define IA_CSS_BUFFER_STATE_IN_BITS 32 + +/* + * Pointer state used to signal MMU invalidation + */ +typedef enum ia_css_pointer_state { + IA_CSS_POINTER_INVALID = 0, + IA_CSS_POINTER_VALID, + IA_CSS_N_POINTER_STATES +} ia_css_pointer_state_t; + +#define IA_CSS_POINTER_STATE_IN_BITS 32 + +/* + * Access direction needed to select the access port + */ +typedef enum ia_css_access_type { + IA_CSS_ACCESS_LOCKED = 0, + IA_CSS_ACCESS_READ, + IA_CSS_ACCESS_WRITE, + IA_CSS_ACCESS_MODIFY, + IA_CSS_N_ACCESS_TYPES +} ia_css_access_type_t; + +#define IA_CSS_ACCESS_TYPE_IN_BITS 32 + +/* + * Access attribute needed to select the access port + * - public : snooped + * - private: non-snooped + * Naming is a bit awkward, lack of inspiration + */ +typedef enum ia_css_access_scope { + IA_CSS_ACCESS_PRIVATE = 0, + IA_CSS_ACCESS_PUBLIC, + IA_CSS_N_ACCESS_SCOPES +} ia_css_access_scopes_t; + +#define IA_CSS_ACCESS_SCOPES_IN_BITS 32 + +#define IA_CSS_N_FRAME_PLANES 6 + +#define IA_CSS_FRAME_FORMAT_BITMAP_BITS 64 +typedef uint64_t ia_css_frame_format_bitmap_t; + +typedef struct ia_css_param_frame_descriptor_s ia_css_param_frame_descriptor_t; +typedef struct ia_css_param_frame_s ia_css_param_frame_t; + +typedef struct ia_css_frame_descriptor_s ia_css_frame_descriptor_t; +typedef struct ia_css_frame_s ia_css_frame_t; +typedef struct ia_css_fragment_descriptor_s ia_css_fragment_descriptor_t; + +typedef struct ia_css_stream_s ia_css_stream_t; + + +#define N_UINT64_IN_STREAM_STRUCT 1 + +#define IA_CSS_STREAM_STRUCT_BITS \ + (N_UINT64_IN_STREAM_STRUCT * 64) + +struct ia_css_stream_s { + uint64_t dummy; +}; + +struct ia_css_param_frame_descriptor_s { + uint16_t size; /**< Size of the descriptor */ + uint32_t buffer_count; /**< Number of parameter buffers */ +}; + +struct ia_css_param_frame_s { + /*< Base virtual addresses to parameters in subsystem virtual + * memory space + */ + vied_vaddress_t *data; +}; + +#define N_UINT32_IN_FRAME_DESC_STRUCT \ + (1 + IA_CSS_N_FRAME_PLANES + (IA_CSS_N_DATA_DIMENSION - 1)) +#define N_UINT16_IN_FRAME_DESC_STRUCT (1 + IA_CSS_N_DATA_DIMENSION) +#define N_UINT8_IN_FRAME_DESC_STRUCT 3 +#define N_PADDING_UINT8_IN_FRAME_DESC_STRUCT 3 + +#define IA_CSS_FRAME_DESCRIPTOR_STRUCT_BITS \ + (IA_CSS_FRAME_FORMAT_TYPE_BITS \ + + (N_UINT32_IN_FRAME_DESC_STRUCT * 32) \ + + (N_UINT16_IN_FRAME_DESC_STRUCT * 16) \ + + (N_UINT8_IN_FRAME_DESC_STRUCT * 8) \ + + (N_PADDING_UINT8_IN_FRAME_DESC_STRUCT * 8)) + +/* + * Structure defining the frame (size and access) properties for + * inbuild types only. + * + * The inbuild types like FourCC, MIPI and CSS private types are supported + * by FW all other types are custom types which interpretation must be encoded + * on the buffer itself or known by the source and sink + */ +struct ia_css_frame_descriptor_s { + /**< Indicates if this is a generic type or inbuild with + * variable size descriptor + */ + ia_css_frame_format_type_t frame_format_type; + /**< Number of data planes (pointers) */ + uint32_t plane_count; + /**< Plane offsets accounting for fragments */ + uint32_t plane_offsets[IA_CSS_N_FRAME_PLANES]; + /**< Physical size aspects */ + uint32_t stride[IA_CSS_N_DATA_DIMENSION - 1]; + /**< Logical dimensions */ + uint16_t dimension[IA_CSS_N_DATA_DIMENSION]; + /**< Size of this descriptor */ + uint16_t size; + /**< Bits per pixel */ + uint8_t bpp; + /**< Bits per element */ + uint8_t bpe; + /**< 1 if terminal uses compressed datatype, 0 otherwise */ + uint8_t is_compressed; + /**< Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_FRAME_DESC_STRUCT]; +}; + +#define N_UINT32_IN_FRAME_STRUCT 2 +#define N_PADDING_UINT8_IN_FRAME_STRUCT 4 + +#define IA_CSS_FRAME_STRUCT_BITS \ + (IA_CSS_BUFFER_STATE_IN_BITS \ + + IA_CSS_ACCESS_TYPE_IN_BITS \ + + IA_CSS_POINTER_STATE_IN_BITS \ + + IA_CSS_ACCESS_SCOPES_IN_BITS \ + + VIED_VADDRESS_BITS \ + + (N_UINT32_IN_FRAME_STRUCT * 32) \ + + (N_PADDING_UINT8_IN_FRAME_STRUCT * 8)) + + +/* + * Main frame structure holding the main store and auxilary access properties + * the "pointer_state" and "access_scope" should be encoded on the + * "vied_vaddress_t" type + */ +struct ia_css_frame_s { + /**< State of the frame for purpose of sequencing */ + ia_css_buffer_state_t buffer_state; + /**< Access direction, may change when buffer state changes */ + ia_css_access_type_t access_type; + /**< State of the pointer for purpose of embedded MMU coherency */ + ia_css_pointer_state_t pointer_state; + /**< Access to the pointer for purpose of host cache coherency */ + ia_css_access_scopes_t access_scope; + /**< Base virtual address to data in subsystem virtual memory space */ + vied_vaddress_t data; + /**< Offset to buffer address within external buffer set structure */ + uint32_t data_index; + /**< Total allocation size in bytes */ + uint32_t data_bytes; + /**< Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_FRAME_STRUCT]; +}; + +#define N_UINT16_IN_FRAGMENT_DESC_STRUCT (3 * IA_CSS_N_DATA_DIMENSION) +#define N_PADDING_UINT8_IN_FRAGMENT_DESC_STRUCT 4 + +#define IA_CSS_FRAGMENT_DESCRIPTOR_STRUCT_BITS \ + ((N_UINT16_IN_FRAME_DESC_STRUCT * 16) \ + + (N_PADDING_UINT8_IN_FRAGMENT_DESC_STRUCT * 8)) + +/* + * Structure defining the fragment (size and access) properties. + * + * All cropping and padding effects are described by the difference between + * the frame size and its location and the fragment size(s) and location(s) + */ +struct ia_css_fragment_descriptor_s { + /**< Logical dimensions of the fragment */ + uint16_t dimension[IA_CSS_N_DATA_DIMENSION]; + /**< Logical location of the fragment in the frame */ + uint16_t index[IA_CSS_N_DATA_DIMENSION]; + /**< Fractional start (phase) of the fragment in the access unit */ + uint16_t offset[IA_CSS_N_DATA_DIMENSION]; + /**< Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_FRAGMENT_DESC_STRUCT]; +}; + + +/*! Print the frame object to file/stream + + @param frame[in] frame object + @param fid[out] file/stream handle + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_print( + const ia_css_frame_t *frame, void *fid); + +/*! Get the data buffer handle from the frame object + +@param frame[in] frame object + +@return buffer pointer, VIED_NULL on error +*/ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +const vied_vaddress_t *ia_css_frame_get_buffer_host_virtual_address( + const ia_css_frame_t *frame); + +/*! Get the data buffer handle from the frame object + + @param frame[in] frame object + + @return buffer pointer, VIED_NULL on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +vied_vaddress_t ia_css_frame_get_buffer(const ia_css_frame_t *frame); + +/*! Set the data buffer handle on the frame object + + @param frame[in] frame object + @param buffer[in] buffer pointer + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_set_buffer( + ia_css_frame_t *frame, vied_vaddress_t buffer); + +/*! Get the data buffer index in the frame object + + @param frame[in] frame object + + @return data buffer index on success, -1 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_get_data_index( + const ia_css_frame_t *frame); + +/*! Set the data buffer index in the frame object + + @param frame[in] frame object + @param data_index[in] data buffer index + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_set_data_index( + ia_css_frame_t *frame, + unsigned int data_index); + +/*! Set the data buffer size on the frame object + + @param frame[in] frame object + @param size[in] number of data bytes + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_set_data_bytes( + ia_css_frame_t *frame, unsigned int size); + +/*! Get the data buffer state from the frame object + + @param frame[in] frame object + + @return buffer state, limit value on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +ia_css_buffer_state_t ia_css_frame_get_buffer_state( + const ia_css_frame_t *frame); + +/*! Set the data buffer state of the frame object + + @param frame[in] frame object + @param buffer_state[in] buffer state + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_set_buffer_state(ia_css_frame_t *frame, + const ia_css_buffer_state_t buffer_state); + +/*! Get the data pointer state from the frame object + + @param frame[in] frame object + + @return pointer state, limit value on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +ia_css_pointer_state_t ia_css_frame_get_pointer_state( + const ia_css_frame_t *frame); + +/*! Set the data pointer state of the frame object + + @param frame[in] frame object + @param pointer_state[in] pointer state + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_set_pointer_state(ia_css_frame_t *frame, + const ia_css_pointer_state_t pointer_state); + +/*! Print the frame descriptor object to file/stream + + @param frame_descriptor[in] frame descriptor object + @param fid[out] file/stream handle + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_frame_descriptor_print( + const ia_css_frame_descriptor_t *frame_descriptor, void *fid); + +/*! Print the fragment descriptor object to file/stream + + @param fragment_descriptor[in] fragment descriptor object + @param fid[out] file/stream handle + + @return < 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +int ia_css_fragment_descriptor_print( + const ia_css_fragment_descriptor_t *fragment_descriptor, void *fid); + +/*! Compute the bitmap for the frame format type + + @param frame_format_type[in] frame format type + + @return 0 on error + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +ia_css_frame_format_bitmap_t ia_css_frame_format_bit_mask( + const ia_css_frame_format_type_t frame_format_type); + +/*! clear frame format bitmap + + @return cleared bitmap + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +ia_css_frame_format_bitmap_t ia_css_frame_format_bitmap_clear(void); + + +/*! Compute the size of storage required for the data descriptor object + * on a terminal + *@param plane_count[in] The number of data planes in the buffer + */ +IA_CSS_PSYS_DATA_STORAGE_CLASS_H +size_t ia_css_sizeof_frame_descriptor( + const uint8_t plane_count); +/*! Compute the size of storage required for the kernel parameter descriptor + * object on a terminal + + @param section_count[in] The number of parameter sections in the buffer + + @return 0 on error + */ +extern size_t ia_css_sizeof_kernel_param_descriptor( + const uint16_t section_count); + +#ifdef __IA_CSS_PSYS_DATA_INLINE__ +#include "ia_css_program_group_data_impl.h" +#endif /* __IA_CSS_PSYS_DATA_INLINE__ */ + +#endif /* __IA_CSS_PROGRAM_GROUP_DATA_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data_defs.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data_defs.h new file mode 100644 index 0000000000000..d3caacdc192fb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_program_group_data_defs.h @@ -0,0 +1,196 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_DATA_DEFS_H +#define __IA_CSS_PROGRAM_GROUP_DATA_DEFS_H + + +/* + * Pre-defined frame format + * + * Those formats have inbuild support of traffic + * and access functions + * + * Note that the formats are for terminals, so there + * is no distinction between input and output formats + * - Custom formats with ot without descriptor + * - 4CC formats such as YUV variants + * - MIPI (line) formats as produced by CSI receivers + * - MIPI (sensor) formats such as Bayer or RGBC + * - CSS internal formats (private types) + * - CSS parameters (type 1 - 6) + */ +#define IA_CSS_FRAME_FORMAT_TYPE_BITS 32 +typedef enum ia_css_frame_format_type { + IA_CSS_DATA_CUSTOM_NO_DESCRIPTOR = 0, + IA_CSS_DATA_CUSTOM, + + /* 12 bit YUV 411, Y, UV 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV11, + /* bpp bit YUV 420, Y, U, V 3-plane (bpp/1.5 bpe) */ + IA_CSS_DATA_FORMAT_YUV420, + /* 12 bit YUV 420, Y, V, U 3-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_YV12, + /* 12 bit YUV 420, Y, UV 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV12, + /* 16 bit YUV 420, Y, UV 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV12_16, + /* 12 bit YUV 420, Intel proprietary tiled format, TileY */ + IA_CSS_DATA_FORMAT_NV12_TILEY, + /* 12 bit YUV 420, Y, VU 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV21, + /* bpp bit YUV 422, Y, U, V 3-plane (bpp/2 bpe) */ + IA_CSS_DATA_FORMAT_YUV422, + /* 16 bit YUV 422, Y, V, U 3-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_YV16, + /* 16 bit YUV 422, Y, UV 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV16, + /* 16 bit YUV 422, Y, VU 2-plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_NV61, + /* 16 bit YUV 422, UYVY 1-plane interleaved (8 bit per element) */ + IA_CSS_DATA_FORMAT_UYVY, + /* 16 bit YUV 422, YUYV 1-plane interleaved (8 bit per element) */ + IA_CSS_DATA_FORMAT_YUYV, + /* bpp bit YUV 444, Y, U, V 3-plane (bpp/3 bpe) */ + IA_CSS_DATA_FORMAT_YUV444, + /* 8 bit monochrome plane */ + IA_CSS_DATA_FORMAT_Y800, + + /* 5-6-5 bit packed (1-plane) RGB (16bpp, ~5 bpe) */ + IA_CSS_DATA_FORMAT_RGB565, + /* 24 bit RGB, 3 planes (8 bit per element) */ + IA_CSS_DATA_FORMAT_RGB888, + /* 32 bit RGB-Alpha, 1 plane (8 bit per element) */ + IA_CSS_DATA_FORMAT_RGBA888, + + /* bpp bit raw, [[Gr, R];[B, Gb]] 1-plane (bpp == bpe) */ + IA_CSS_DATA_FORMAT_BAYER_GRBG, + /* bpp bit raw, [[R, Gr];[Gb, B]] 1-plane (bpp == bpe) */ + IA_CSS_DATA_FORMAT_BAYER_RGGB, + /* bpp bit raw, [[B, Gb];[Gr, R]] 1-plane (bpp == bpe) */ + IA_CSS_DATA_FORMAT_BAYER_BGGR, + /* bpp bit raw, [[Gb, B];[R, Gr]] 1-plane (bpp == bpe) */ + IA_CSS_DATA_FORMAT_BAYER_GBRG, + + /* bpp bit (NV12) YUV 420, Y, UV 2-plane derived 3-line, + * 2-Y, 1-UV (bpp/1.5 bpe): M420 format + */ + IA_CSS_DATA_FORMAT_YUV420_LINE, + /* Deprecated RAW, 1 plane */ + IA_CSS_DATA_FORMAT_RAW, + /* Deprecated RAW, 1 plane, packed */ + IA_CSS_DATA_FORMAT_RAW_PACKED, + /* Internal, for advanced ISP */ + IA_CSS_DATA_FORMAT_QPLANE6, + /* 1D byte stream, used for jpeg 1-plane */ + IA_CSS_DATA_FORMAT_BINARY_8, + /* Deprecated MIPI frame, 1D byte stream 1 plane */ + IA_CSS_DATA_FORMAT_MIPI, + /* 12 bit [[YY];[UYVY]] 1-plane interleaved 2-line + * (8 bit per element) + */ + IA_CSS_DATA_FORMAT_MIPI_YUV420_8, + /* 15 bit [[YY];[UYVY]] 1-plane interleaved 2-line + * (10 bit per element) + */ + IA_CSS_DATA_FORMAT_MIPI_YUV420_10, + /* 12 bit [[UY];[VY]] 1-plane interleaved 2-line (8 bit per element) */ + IA_CSS_DATA_FORMAT_MIPI_LEGACY_YUV420_8, + + /* Type 1-5 parameter, not fragmentable */ + IA_CSS_DATA_GENERIC_PARAMETER, + /* Video stabilisation Type 6 parameter, fragmentable */ + IA_CSS_DATA_DVS_PARAMETER, + /* Video stabilisation Type 6 parameter, coordinates */ + IA_CSS_DATA_DVS_COORDINATES, + /* Dead Pixel correction Type 6 parameter, fragmentable */ + IA_CSS_DATA_DPC_PARAMETER, + /* Lens Shading Correction Type 6 parameter, fragmentable */ + IA_CSS_DATA_LSC_PARAMETER, + /* 3A statistics output HI. */ + IA_CSS_DATA_S3A_STATISTICS_HI, + /* 3A statistics output LO. */ + IA_CSS_DATA_S3A_STATISTICS_LO, + /* histogram output */ + IA_CSS_DATA_S3A_HISTOGRAM, + /* GammaStar grid */ + IA_CSS_DATA_GAMMASTAR_GRID, + + /* Gr R B Gb Gr R B Gb in PIXELS (also called isys interleaved) */ + IA_CSS_DATA_FORMAT_BAYER_LINE_INTERLEAVED, + /* Gr R B Gb Gr R B Gb in VECTORS (VCC IMAGE, ISP NWAY depentdent) */ + IA_CSS_DATA_FORMAT_BAYER_VECTORIZED, + /* Gr R Gr R ... | B Gb B Gb .. in VECTORS (ISP NWAY depentdent) */ + IA_CSS_DATA_FORMAT_BAYER_GRBG_VECTORIZED, + + /* 16 bit YUV 420, Y even plane, Y uneven plane, + * UV plane vector interleaved + */ + IA_CSS_DATA_FORMAT_YUV420_VECTORIZED, + /* 16 bit YUV 420, YYUVYY vector interleaved */ + IA_CSS_DATA_FORMAT_YYUVYY_VECTORIZED, + + /* 12 bit YUV 420, Intel proprietary tiled format, TileYf */ + IA_CSS_DATA_FORMAT_NV12_TILEYF, + + /*Y samples appear first in the memory. All Y samples are array of WORDs; + * even number of lines ; + * Surface stride can be larger than the width of Y plane. + * This array is followed immediately by chroma array. + * Chroma array is an array of WORDs, with interleaved U/V samples. + * If the interleaved U/V plane is addresses as an * array of DWORDs, + * the least significant word contains U sample. The stride of the + * interleaved U/V plane is equal to Y plane. 10 bit data. + */ + IA_CSS_DATA_FORMAT_P010, + + /* MSB aligned version of P010*/ + IA_CSS_DATA_FORMAT_P010_MSB, + + /* P016/P012 Y samples appear first in the memory. + * All Y samples are array of WORDs; + * even number of lines ; + * Surface stride can be larger than the width of Y plane. + * This array is followed immediately by chroma array. + * Chroma array is an array of WORDs, with interleaved U/V samples. + * If the interleaved U/V plane is addresses as an * array of DWORDs, + * the least significant word contains U sample. The stride of the + * interleaved U/V plane is equal to Y plane. 12 bit data. + */ + IA_CSS_DATA_FORMAT_P016, + + /* MSB aligned version of P016*/ + IA_CSS_DATA_FORMAT_P016_MSB, + + /* TILEYYf representation of P010*/ + IA_CSS_DATA_FORMAT_P010_TILEYF, + + /* TILEYYf representation of P010 MSB aligned*/ + IA_CSS_DATA_FORMAT_P010_MSB_TILEYF, + + /* TILEYYf representation of P016*/ + IA_CSS_DATA_FORMAT_P016_TILEYF, + + /* TILEYYf representation of P016 MSB aligned*/ + IA_CSS_DATA_FORMAT_P016_MSB_TILEYF, + + /* consists of L and R PDAF pixel pairs. + * L and R can be interleaved or not. 1-plane (bpp == bpe) */ + IA_CSS_DATA_FORMAT_PAF, + + IA_CSS_N_FRAME_FORMAT_TYPES +} ia_css_frame_format_type_t; + + +#endif /* __IA_CSS_PROGRAM_GROUP_DATA_DEFS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_storage_class.h new file mode 100644 index 0000000000000..6a4e3a28e5336 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_storage_class.h @@ -0,0 +1,28 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DATA_STORAGE_CLASS_H +#define __IA_CSS_PSYS_DATA_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __IA_CSS_PSYS_DATA_INLINE__ +#define IA_CSS_PSYS_DATA_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PSYS_DATA_STORAGE_CLASS_C +#else +#define IA_CSS_PSYS_DATA_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PSYS_DATA_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PSYS_DATA_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_trace.h new file mode 100644 index 0000000000000..49afed9ce9dfc --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/interface/ia_css_psys_data_trace.h @@ -0,0 +1,102 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DATA_TRACE_H +#define __IA_CSS_PSYS_DATA_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_DATA_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_DATA_TRACING_OVERRIDE)) + #define PSYS_DATA_TRACE_LEVEL_CONFIG PSYS_DATA_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_DATA_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_DATA_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_DATA_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_DATA_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DATA_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DATA_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_DATA_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DATA_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DATA_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DATA_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_DATA_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DATA_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DATA_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_DATA_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_DATA_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_DATA_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_DATA_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_DATA_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_DATA_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_DATA_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_DATA_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data.c new file mode 100644 index 0000000000000..779d98741cfa7 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data.c @@ -0,0 +1,29 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_data_storage_class.h" + +/* + * Functions to possibly inline + */ + +#ifdef __IA_CSS_PSYS_DATA_INLINE__ +STORAGE_CLASS_INLINE int +__ia_css_program_group_data_avoid_warning_on_empty_file(void) +{ + return 0; +} +#else /* __IA_CSS_PSYS_DATA_INLINE__ */ +#include "ia_css_program_group_data_impl.h" +#endif /* __IA_CSS_PSYS_DATA_INLINE__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data_impl.h new file mode 100644 index 0000000000000..3e6fca051ee9c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/data/src/ia_css_program_group_data_impl.h @@ -0,0 +1,456 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_DATA_IMPL_H +#define __IA_CSS_PROGRAM_GROUP_DATA_IMPL_H + +#include "ia_css_program_group_data.h" +#include "ia_css_psys_data_trace.h" +#include "ia_css_terminal_defs.h" +#include /* for verifexit */ +#include /* for COMPILATION_ERROR_IF */ +#include /* for NOT_USED */ + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_print( + const ia_css_frame_t *frame, void *fid) +{ + int retval = -1; + + NOT_USED(fid); + + IA_CSS_TRACE_0(PSYSAPI_DATA, INFO, "ia_css_frame_print(): enter:\n"); + + verifexit(frame != NULL); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tbuffer = %d\n", ia_css_frame_get_buffer(frame)); + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tbuffer_state = %d\n", ia_css_frame_get_buffer_state(frame)); + /* IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, "\tbuffer_state = %s\n", + * ia_css_buffer_state_string(ia_css_frame_get_buffer_state(frame))); + */ + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tpointer_state = %d\n", ia_css_frame_get_pointer_state(frame)); + /* IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, "\tpointer_state = %s\n", + * ia_css_pointer_state_string(ia_css_frame_get_pointer_state(frame))); + */ + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tdata_bytes = %d\n", frame->data_bytes); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_print failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +const vied_vaddress_t *ia_css_frame_get_buffer_host_virtual_address( + const ia_css_frame_t *frame) +{ + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_get_buffer_host_virtual_address(): enter:\n"); + + verifexit(frame != NULL); + return &(frame->data); + +EXIT: + if (frame == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_get_buffer_host_virtual_address invalid argument\n"); + } + return NULL; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +vied_vaddress_t ia_css_frame_get_buffer( + const ia_css_frame_t *frame) +{ + vied_vaddress_t buffer = VIED_NULL; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_get_buffer(): enter:\n"); + + verifexit(frame != NULL); + buffer = frame->data; + +EXIT: + if (frame == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_get_buffer invalid argument\n"); + } + return buffer; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_set_buffer( + ia_css_frame_t *frame, + vied_vaddress_t buffer) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_set_buffer(): enter:\n"); + + verifexit(frame != NULL); + frame->data = buffer; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_set_buffer failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_get_data_index( + const ia_css_frame_t *frame) +{ + int data_index = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_get_data_index(): enter:\n"); + + verifexit(frame != NULL); + + data_index = frame->data_index; + +EXIT: + if (frame == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_get_data_index invalid argument\n"); + } + return data_index; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_set_data_index( + ia_css_frame_t *frame, + unsigned int data_index) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_set_data_index(): enter:\n"); + + verifexit(frame != NULL); + + frame->data_index = data_index; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_set_data_index failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_set_data_bytes( + ia_css_frame_t *frame, + unsigned int size) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_set_data_bytes(): enter:\n"); + + verifexit(frame != NULL); + frame->data_bytes = size; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_set_data_bytes failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +ia_css_buffer_state_t ia_css_frame_get_buffer_state( + const ia_css_frame_t *frame) +{ + ia_css_buffer_state_t buffer_state = IA_CSS_N_BUFFER_STATES; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_get_buffer_state(): enter:\n"); + + verifexit(frame != NULL); + buffer_state = frame->buffer_state; + +EXIT: + if (frame == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_get_buffer_state invalid argument\n"); + } + return buffer_state; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_set_buffer_state( + ia_css_frame_t *frame, + const ia_css_buffer_state_t buffer_state) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_set_buffer_state(): enter:\n"); + + verifexit(frame != NULL); + frame->buffer_state = buffer_state; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_set_buffer_state failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +ia_css_pointer_state_t ia_css_frame_get_pointer_state( + const ia_css_frame_t *frame) +{ + ia_css_pointer_state_t pointer_state = IA_CSS_N_POINTER_STATES; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_get_pointer_state(): enter:\n"); + + verifexit(frame != NULL); + pointer_state = frame->pointer_state; + +EXIT: + if (frame == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_get_pointer_state invalid argument\n"); + } + return pointer_state; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_set_pointer_state( + ia_css_frame_t *frame, + const ia_css_pointer_state_t pointer_state) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_set_pointer_state(): enter:\n"); + + verifexit(frame != NULL); + frame->pointer_state = pointer_state; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_set_pointer_state failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_frame_descriptor_print( + const ia_css_frame_descriptor_t *frame_descriptor, + void *fid) +{ + int retval = -1; + int i; + uint8_t frame_plane_count; + + NOT_USED(fid); + + IA_CSS_TRACE_0(PSYSAPI_DATA, INFO, + "ia_css_frame_descriptor_print(): enter:\n"); + + COMPILATION_ERROR_IF(IA_CSS_N_DATA_DIMENSION <= 0); + + verifexit(frame_descriptor != NULL); + + IA_CSS_TRACE_0(PSYSAPI_DATA, INFO, + "ia_css_frame_descriptor_print(): enter:\n"); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tframe_format_type = %d\n", + frame_descriptor->frame_format_type); + /* IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, "\tframe_format_type = %s\n", + * ia_css_frame_format_string(frame_descriptor->frame_format_type)); + */ + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tbpp = %d\n", frame_descriptor->bpp); + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tbpe = %d\n", frame_descriptor->bpe); + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tis_compressed = %d\n", frame_descriptor->is_compressed); + + frame_plane_count = IA_CSS_N_FRAME_PLANES; + /* frame_plane_count = + * ia_css_frame_plane_count(frame_descriptor->frame_format_type); + */ + + verifexit(frame_plane_count > 0); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tplane_offsets[%d]: [\n", frame_plane_count); + for (i = 0; i < (int)frame_plane_count - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", frame_descriptor->plane_offsets[i]); + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d ]\n", frame_descriptor->plane_offsets[i]); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tdimension[%d] = {\n", IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", frame_descriptor->dimension[i]); + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d }\n", frame_descriptor->dimension[i]); + + COMPILATION_ERROR_IF(0 > (IA_CSS_N_DATA_DIMENSION - 2)); + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\tstride[%d] = {\n", IA_CSS_N_DATA_DIMENSION - 1); + i = 0; + if (IA_CSS_N_DATA_DIMENSION > 2) { + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 2; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", frame_descriptor->stride[i]); + } + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d }\n", frame_descriptor->stride[i]); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_frame_descriptor_print failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +int ia_css_fragment_descriptor_print( + const ia_css_fragment_descriptor_t *fragment_descriptor, + void *fid) +{ + int retval = -1; + int i; + + NOT_USED(fid); + + IA_CSS_TRACE_0(PSYSAPI_DATA, INFO, + "ia_css_fragment_descriptor_print(): enter:\n"); + + verifexit(fragment_descriptor != NULL); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "dimension[%d] = {\n", IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", fragment_descriptor->dimension[i]); + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d }\n", fragment_descriptor->dimension[i]); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "index[%d] = {\n", IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", fragment_descriptor->index[i]); + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d }\n", fragment_descriptor->index[i]); + + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "offset[%d] = {\n", IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, + "\t%4d,\n", fragment_descriptor->offset[i]); + } + IA_CSS_TRACE_1(PSYSAPI_DATA, INFO, "\t%4d }\n", + fragment_descriptor->offset[i]); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DATA, ERROR, + "ia_css_fragment_descriptor_print failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +ia_css_frame_format_bitmap_t ia_css_frame_format_bit_mask( + const ia_css_frame_format_type_t frame_format_type) +{ + ia_css_frame_format_bitmap_t bit_mask = 0; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_format_bit_mask(): enter:\n"); + + if ((frame_format_type < IA_CSS_N_FRAME_FORMAT_TYPES) && + (frame_format_type < IA_CSS_FRAME_FORMAT_BITMAP_BITS)) { + bit_mask = (ia_css_frame_format_bitmap_t)1 << frame_format_type; + } else { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_frame_format_bit_mask invalid argument\n"); + } + + return bit_mask; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +ia_css_frame_format_bitmap_t ia_css_frame_format_bitmap_clear(void) +{ + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_frame_format_bitmap_clear(): enter:\n"); + + return 0; +} + +IA_CSS_PSYS_DATA_STORAGE_CLASS_C +size_t ia_css_sizeof_frame_descriptor( + const uint8_t plane_count) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DATA, VERBOSE, + "ia_css_sizeof_frame_descriptor(): enter:\n"); + + verifexit(plane_count > 0); + size += sizeof(ia_css_frame_descriptor_t); + size += plane_count * sizeof(uint32_t); + +EXIT: + if (plane_count == 0) { + IA_CSS_TRACE_0(PSYSAPI_DATA, WARNING, + "ia_css_sizeof_frame_descriptor invalid argument\n"); + } + return size; +} + +#endif /* __IA_CSS_PROGRAM_GROUP_DATA_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/cnlB0/ia_css_psys_transport_dep.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/cnlB0/ia_css_psys_transport_dep.h new file mode 100644 index 0000000000000..7bb145c1b183b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/cnlB0/ia_css_psys_transport_dep.h @@ -0,0 +1,35 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TRANSPORT_DEP_H +#define __IA_CSS_PSYS_TRANSPORT_DEP_H + +/* + * The ID's of the Psys specific queues. + */ +typedef enum ia_css_psys_cmd_queues { + /**< The in-order queue for scheduled process groups */ + IA_CSS_PSYS_CMD_QUEUE_COMMAND_ID = 0, + /**< The in-order queue for commands changing psys or + * process group state + */ + IA_CSS_PSYS_CMD_QUEUE_DEVICE_ID, + /**< An in-order queue for dedicated PPG commands */ + IA_CSS_PSYS_CMD_QUEUE_PPG0_COMMAND_ID, + /**< An in-order queue for dedicated PPG commands */ + IA_CSS_PSYS_CMD_QUEUE_PPG1_COMMAND_ID, + IA_CSS_N_PSYS_CMD_QUEUE_ID +} ia_css_psys_cmd_queue_ID_t; + +#endif /* __IA_CSS_PSYS_TRANSPORT_DEP_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device.h new file mode 100644 index 0000000000000..dc8fa531b11e3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device.h @@ -0,0 +1,516 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DEVICE_H +#define __IA_CSS_PSYS_DEVICE_H + +#include "ia_css_psys_init.h" +#include "ia_css_psys_transport.h" + +/*! \file */ + +/** @file ia_css_psys_device.h + * + * Define the interface to open the psys specific communication layer + * instance + */ + +#include /* vied_vaddress_t */ + +#include +#include + +#include +#include + +#define IA_CSS_PSYS_STATE_READY_PATTERN (0xF7F7F7F7) +#define IA_CSS_PSYS_STATE_RUNNING_PATTERN (0xE6E6E6E6) +#define IA_CSS_PSYS_STATE_STARTING_PATTERN (0xD5D5D5D5) +#define IA_CSS_PSYS_STATE_STARTED_PATTERN (0xC4C4C4C4) +#define IA_CSS_PSYS_STATE_INITIALIZING_PATTERN (0xB3B3B3B3) +#define IA_CSS_PSYS_STATE_INITIALIZED_PATTERN (0xA0A0A0A0) + +/* + * Defines the state of psys: + * - IA_CSS_PSYS_STATE_UNKNOWN = psys status is unknown (or not recognized) + * - IA_CSS_PSYS_STATE_INITIALING = some of the psys components are + * not initialized yet + * - IA_CSS_PSYS_STATE_INITIALIZED = psys components are initialized + * - IA_CSS_PSYS_STATE_STARTING = some of the psys components are initialized + * but not started yet + * - IA_CSS_PSYS_STATE_STARTED = psys components are started + * - IA_CSS_PSYS_STATE_RUNNING = some of the psys components are started + * but not ready yet + * - IA_CSS_PSYS_STATE_READY = psys is ready + * The state of psys can be obtained calling ia_css_psys_check_state() +*/ +typedef enum ia_css_psys_state { + IA_CSS_PSYS_STATE_UNKNOWN = 0, /**< psys state is unknown */ + /*< some of the psys components are not initialized yet*/ + IA_CSS_PSYS_STATE_INITIALIZING = IA_CSS_PSYS_STATE_INITIALIZING_PATTERN, + /**< psys components are initialized */ + IA_CSS_PSYS_STATE_INITIALIZED = IA_CSS_PSYS_STATE_INITIALIZED_PATTERN, + /**< some of the psys components are not started yet */ + IA_CSS_PSYS_STATE_STARTING = IA_CSS_PSYS_STATE_STARTING_PATTERN, + /**< psys components are started */ + IA_CSS_PSYS_STATE_STARTED = IA_CSS_PSYS_STATE_STARTED_PATTERN, + /**< some of the psys components are not ready yet */ + IA_CSS_PSYS_STATE_RUNNING = IA_CSS_PSYS_STATE_RUNNING_PATTERN, + /**< psys is ready */ + IA_CSS_PSYS_STATE_READY = IA_CSS_PSYS_STATE_READY_PATTERN, +} ia_css_psys_state_t; + +extern struct ia_css_syscom_context *psys_syscom; +#if HAS_DUAL_CMD_CTX_SUPPORT +extern struct ia_css_syscom_context *psys_syscom_secure; +#endif + +/*! Print the syscom creation descriptor to file/stream + + @param config[in] Psys syscom descriptor + @param fid[out] file/stream handle + + @return < 0 on error +*/ +extern int ia_css_psys_config_print( + const struct ia_css_syscom_config *config, void *fid); + +/*! Print the Psys syscom object to file/stream + + @param context[in] Psys syscom object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_psys_print( + const struct ia_css_syscom_context *context, void *fid); + +/*! Create the syscom creation descriptor + + @return NULL on error + */ +extern struct ia_css_syscom_config *ia_css_psys_specify(void); + +#if HAS_DUAL_CMD_CTX_SUPPORT +/*! Create the syscom creation descriptor for secure stream + + @param vtl0_addr_mask[in] VTL0 address mask that will be stored in 'secure' ctx + @return NULL on error + */ +extern struct ia_css_syscom_config *ia_css_psys_specify_secure(unsigned int vtl0_addr_mask); +#endif + +/*! Compute the size of storage required for allocating the Psys syscom object + + @param config[in] Psys syscom descriptor + + @return 0 on error + */ +extern size_t ia_css_sizeof_psys( + struct ia_css_syscom_config *config); + +#if HAS_DUAL_CMD_CTX_SUPPORT +/*! Open (and map the storage for) the Psys syscom object + This is the same as ia_css_psys_open() excluding server start. + Target for VTIO usage where multiple syscom objects need to be + created first before this API is invoked. + + @param buffer[in] storage buffers for the syscom object + in the kernel virtual memory space and + its Psys mapped version + @param config[in] Psys syscom descriptor + @return NULL on error + */ + +extern struct ia_css_syscom_context *ia_css_psys_context_create( + const struct ia_css_psys_buffer_s *buffer, + struct ia_css_syscom_config *config); + +/*! Store the parameters of the Psys syscom object in DMEM, so + they can be communicated with FW. This step needs to be invoked + after SPC starts in ia_css_psys_open(), so SPC DMEM access blocker + programming already takes effective. + + @param context[in] Psys syscom object + @param config[in] Psys syscom descriptor + @return 0 if successful + */ +extern int ia_css_psys_context_store_dmem( + struct ia_css_syscom_context *context, + struct ia_css_syscom_config *config); + +/*! Start PSYS Server. Psys syscom object must have been created already. + Target for VTIO usage where multiple syscom objects need to be + created first before this API is invoked. + @param config[in] Psys syscom descriptor + + @return true if psys open started successfully + */ +extern int ia_css_psys_open( + struct ia_css_syscom_config *config); +#else +/*! Open (and map the storage for) the Psys syscom object + + @param buffer[in] storage buffers for the syscom object + in the kernel virtual memory space and + its Psys mapped version + @param config[in] Psys syscom descriptor + + Precondition(1): The buffer must be large enough to hold the syscom object. + Its size must be computed with the function "ia_css_sizeof_psys()". + The buffer must be created in the kernel memory space. + + Precondition(2): If buffer == NULL, the storage allocations and mapping + is performed in this function. Config must hold the handle to the Psys + virtual memory space + + Postcondition: The context is initialised in the provided/created buffer. + The syscom context pointer is the kernel space handle to the syscom object + + @return NULL on error + */ +extern struct ia_css_syscom_context *ia_css_psys_open( + const struct ia_css_psys_buffer_s *buffer, + struct ia_css_syscom_config *config); +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +/*! completes the psys open procedure. Must be called multiple times + until it succeeds or driver determines the boot sequence has failed. + + @param context[in] Psys syscom object + + @return false if psys open has not completed successfully + */ +extern bool ia_css_psys_open_is_ready( + struct ia_css_syscom_context *context); + +#if HAS_DUAL_CMD_CTX_SUPPORT +/*! Request close of a PSYS context + * The functionatlity is the same as ia_css_psys_close() which closes PSYS syscom object. + * Counterpart of ia_css_psys_context_create() + * @param context[in]: Psys context + * @return NULL if close is successful context otherwise + */ +extern struct ia_css_syscom_context *ia_css_psys_context_destroy( + struct ia_css_syscom_context *context); + +/*! Request close of a PSYS device for VTIO case + * @param None + * @return 0 if successful + */ +extern int ia_css_psys_close(void); +#else +/*! Request close of a PSYS context + * @param context[in]: Psys context + * @return NULL if close is successful context otherwise + */ +extern struct ia_css_syscom_context *ia_css_psys_close( + struct ia_css_syscom_context *context); +#endif /* HAS_DUAL_CMD_CTX_SUPPORT*/ + +/*! Unmap and free the storage of the PSYS context + * @param context[in] Psys context + * @param force[in] Force release even if device is busy + * @return 0 if release is successful + * EINVAL if context is invalid + * EBUSY if device is not yet idle, and force==0 + */ +extern int ia_css_psys_release( + struct ia_css_syscom_context *context, + bool force); + +/*! Checks the state of the Psys syscom object + + @param context[in] Psys syscom object + + @return State of the syscom object + */ +extern ia_css_psys_state_t ia_css_psys_check_state( + struct ia_css_syscom_context *context); + +/*!Indicate if the designated cmd queue in the Psys syscom object is full + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + + @return false if the cmd queue is not full or on error + */ + +extern bool ia_css_is_psys_cmd_queue_full( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id); + +/*!Indicate if the designated cmd queue in the Psys syscom object is notfull + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + + @return false if the cmd queue is full on error + */ +extern bool ia_css_is_psys_cmd_queue_not_full( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id); + +/*!Indicate if the designated cmd queue in the Psys syscom object holds N space + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + @param N[in] Number of messages + + @return false if the cmd queue space is unavailable or on error + */ +extern bool ia_css_has_psys_cmd_queue_N_space( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const unsigned int N); + +/*!Return the free space count in the designated cmd queue in the + * Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + + @return the space, < 0 on error + */ +extern int ia_css_psys_cmd_queue_get_available_space( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id); + +/*!Indicate if there are any messages pending in the Psys syscom + * object event queues + + @param context[in] Psys syscom object + + @return false if there are no messages or on error + */ +extern bool ia_css_any_psys_event_queue_not_empty( + struct ia_css_syscom_context *context); + +/*!Indicate if the designated event queue in the Psys syscom object is empty + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + + @return false if the event queue is not empty or on error + */ +extern bool ia_css_is_psys_event_queue_empty( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id); + +/*!Indicate if the designated event queue in the Psys syscom object is not empty + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + + @return false if the receive queue is empty or on error + */ +extern bool ia_css_is_psys_event_queue_not_empty( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id); + +/*!Indicate if the designated event queue + * in the Psys syscom object holds N items + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + @param N[in] Number of messages + + @return false if the event queue has insufficient messages + available or on error +*/ +extern bool ia_css_has_psys_event_queue_N_msgs( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + const unsigned int N); + +/*!Return the message count in the designated event queue in the + * Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + + @return the messages, < 0 on error + */ +extern int ia_css_psys_event_queue_get_available_msgs( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id); + +/*! Send (pass by value) a command on a queue in the Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID +@param cmd_msg_buffer[in] pointer to the command message buffer + +Precondition: The command message buffer must be large enough + to hold the command + +Postcondition: Either 0 or 1 commands have been sent + +Note: The message size is fixed and determined on creation + + @return the number of sent commands (1), <= 0 on error + */ +extern int ia_css_psys_cmd_queue_send( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const void *cmd_msg_buffer); + +/*! Send (pass by value) N commands on a queue in the Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + @param cmd_msg_buffer[in] Pointer to the command message buffer +@param N[in] Number of commands + +Precondition: The command message buffer must be large enough + to hold the commands + +Postcondition: Either 0 or up to and including N commands have been sent + + Note: The message size is fixed and determined on creation + + @return the number of sent commands, <= 0 on error + */ +extern int ia_css_psys_cmd_queue_send_N( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const void *cmd_msg_buffer, + const unsigned int N); + +/*! Receive (pass by value) an event from an event queue in the + * Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + @param event_msg_buffer[out] pointer to the event message buffer + + Precondition: The event message buffer must be large enough to hold the event + + Postcondition: Either 0 or 1 events have been received + + Note: The event size is fixed and determined on creation + + @return the number of received events (1), <= 0 on error + */ +extern int ia_css_psys_event_queue_receive( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + void *event_msg_buffer); + +/*! Receive (pass by value) N events from an event queue in the + * Psys syscom object + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + @param event_msg_buffer[out] pointer to the event message buffer + @param N[in] Number of events + + Precondition: The event buffer must be large enough to hold the events + + Postcondition: Either 0 or up to and including N events have been received + + Note: The message size is fixed and determined on creation + + @return the number of received event messages, <= 0 on error + */ +extern int ia_css_psys_event_queue_receive_N( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + void *event_msg_buffer, + const unsigned int N); + + +/* + * Access functions to query the object stats + */ + + +/*!Return the size of the Psys syscom object + + @param context[in] Psys syscom object + + @return 0 on error + */ +extern size_t ia_css_psys_get_size( + const struct ia_css_syscom_context *context); + +/*!Return the number of cmd queues in the Psys syscom object + + @param context[in] Psys syscom object + + @return 0 on error + */ +extern unsigned int ia_css_psys_get_cmd_queue_count( + const struct ia_css_syscom_context *context); + +/*!Return the number of event queues in the Psys syscom object + + @param context[in] Psys syscom object + + @return 0 on error + */ +extern unsigned int ia_css_psys_get_event_queue_count( + const struct ia_css_syscom_context *context); + +/*!Return the size of the indicated Psys command queue + + @param context[in] Psys syscom object + @param id[in] Psys syscom cmd queue ID + + Note: The queue size is expressed in the number of fields + + @return 0 on error + */ +extern size_t ia_css_psys_get_cmd_queue_size( + const struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id); + +/*!Return the size of the indicated Psys event queue + + @param context[in] Psys syscom object + @param id[in] Psys syscom event queue ID + + Note: The queue size is expressed in the number of fields + + @return 0 on error + */ +extern size_t ia_css_psys_get_event_queue_size( + const struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id); + +/*!Return the command message size of the indicated Psys command queue + + @param context[in] Psys syscom object + + Note: The message size is expressed in uint8_t + + @return 0 on error + */ +extern size_t ia_css_psys_get_cmd_msg_size( + const struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id); + +/*!Return the event message size of the indicated Psys event queue + + @param context[in] Psys syscom object + + Note: The message size is expressed in uint8_t + + @return 0 on error + */ +extern size_t ia_css_psys_get_event_msg_size( + const struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id); + +#endif /* __IA_CSS_PSYS_DEVICE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device_trace.h new file mode 100644 index 0000000000000..8e5899bc66dba --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_device_trace.h @@ -0,0 +1,103 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DEVICE_TRACE_H +#define __IA_CSS_PSYS_DEVICE_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_DEVICE_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_DEVICE_TRACING_OVERRIDE)) + #define PSYS_DEVICE_TRACE_LEVEL_CONFIG \ + PSYS_DEVICE_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_DEVICE_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_DEVICE_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_DEVICE_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_DEVICE_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DEVICE_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DEVICE_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_DEVICE_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DEVICE_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DEVICE_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_DEVICE_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DEVICE_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DEVICE_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_DEVICE_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_DEVICE_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_DEVICE_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_DEVICE_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_DEVICE_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_DEVICE_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_DEVICE_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_DEVICE_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_init.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_init.h new file mode 100644 index 0000000000000..1120b357632cf --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_init.h @@ -0,0 +1,37 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_INIT_H +#define __IA_CSS_PSYS_INIT_H + +#include /* vied_vaddress_t */ + +/* Init parameters passed to the fw on device open (non secure mode) */ +typedef struct ia_css_psys_server_init { + /* These members are used in PSS only and will be removed */ + /* Shared memory host address of pkg dir */ + unsigned long long host_ddr_pkg_dir; + /* Address of pkg_dir structure in DDR */ + vied_vaddress_t ddr_pkg_dir_address; + /* Size of Package dir in DDR */ + uint32_t pkg_dir_size; + + /* Prefetch configiration */ + /* enable prefetching on SPC, SPP0 and SPP1 */ + uint32_t icache_prefetch_sp; + /* enable prefetching on ISP0..N */ + uint32_t icache_prefetch_isp; +} ia_css_psys_server_init_t; + +#endif /* __IA_CSS_PSYS_INIT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_transport.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_transport.h new file mode 100644 index 0000000000000..e0d1e935c2211 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/interface/ia_css_psys_transport.h @@ -0,0 +1,92 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TRANSPORT_H +#define __IA_CSS_PSYS_TRANSPORT_H + +#include /* ia_css_psys_cmd_queues */ +#include /* vied_vaddress_t */ + +#include + +typedef enum ia_css_psys_event_queues { + /**< The in-order queue for event returns */ + IA_CSS_PSYS_EVENT_QUEUE_MAIN_ID, + IA_CSS_N_PSYS_EVENT_QUEUE_ID +} ia_css_psys_event_queue_ID_t; + +typedef enum ia_css_psys_event_types { + /**< No error to report. */ + IA_CSS_PSYS_EVENT_TYPE_SUCCESS = 0, + /**< Unknown unhandled error */ + IA_CSS_PSYS_EVENT_TYPE_UNKNOWN_ERROR = 1, + /* Retrieving remote object: */ + /**< Object ID not found */ + IA_CSS_PSYS_EVENT_TYPE_RET_REM_OBJ_NOT_FOUND = 2, + /**< Objects too big, or size is zero. */ + IA_CSS_PSYS_EVENT_TYPE_RET_REM_OBJ_TOO_BIG = 3, + /**< Failed to load whole process group from tproxy/dma */ + IA_CSS_PSYS_EVENT_TYPE_RET_REM_OBJ_DDR_TRANS_ERR = 4, + /**< The proper package could not be found */ + IA_CSS_PSYS_EVENT_TYPE_RET_REM_OBJ_NULL_PKG_DIR_ADDR = 5, + /* Process group: */ + /**< Failed to run, error while loading frame */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_LOAD_FRAME_ERR = 6, + /**< Failed to run, error while loading fragment */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_LOAD_FRAGMENT_ERR = 7, + /**< The process count of the process group is zero */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_PROCESS_COUNT_ZERO = 8, + /**< Process(es) initialization */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_PROCESS_INIT_ERR = 9, + /**< Aborted (after host request) */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_ABORT = 10, + /**< NULL pointer in the process group */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_NULL = 11, + /**< Process group validation failed */ + IA_CSS_PSYS_EVENT_TYPE_PROC_GRP_VALIDATION_ERR = 12 +} ia_css_psys_event_type_t; + +#define IA_CSS_PSYS_CMD_BITS 64 +struct ia_css_psys_cmd_s { + /**< The command issued to the process group */ + uint16_t command; + /**< Message field of the command */ + uint16_t msg; + /**< The context reference (process group/buffer set/...) */ + uint32_t context_handle; +}; + +#define IA_CSS_PSYS_EVENT_BITS 128 +struct ia_css_psys_event_s { + /**< The (return) status of the command issued to + * the process group this event refers to + */ + uint16_t status; + /**< The command issued to the process group this event refers to */ + uint16_t command; + /**< The context reference (process group/buffer set/...) */ + uint32_t context_handle; + /**< This token (size) must match the token registered + * in a process group + */ + uint64_t token; +}; + +struct ia_css_psys_buffer_s { + /**< The in-order queue for scheduled process groups */ + void *host_buffer; + vied_vaddress_t *isp_buffer; +}; + +#endif /* __IA_CSS_PSYS_TRANSPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/src/ia_css_psys_device.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/src/ia_css_psys_device.c new file mode 100644 index 0000000000000..658b377352a6d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/device/src/ia_css_psys_device.c @@ -0,0 +1,854 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include "ia_css_psys_device.h" +#include "ia_css_psys_device_trace.h" +#include "ia_css_psys_init.h" +#include "regmem_access.h" + +#include +#include +#include + +#include "ia_css_cell.h" + +#define IA_CSS_PSYS_CMD_QUEUE_SIZE 0x20 +#define IA_CSS_PSYS_EVENT_QUEUE_SIZE 0x40 + +static struct ia_css_syscom_queue_config ia_css_psys_cmd_queue_cfg[IA_CSS_N_PSYS_CMD_QUEUE_ID]; + +static struct ia_css_syscom_queue_config + ia_css_psys_event_queue_cfg[IA_CSS_N_PSYS_EVENT_QUEUE_ID] = { + {IA_CSS_PSYS_EVENT_QUEUE_SIZE, IA_CSS_PSYS_EVENT_BITS/8}, +}; + +static struct ia_css_syscom_config psys_syscom_config; +struct ia_css_syscom_context *psys_syscom; +#if HAS_DUAL_CMD_CTX_SUPPORT +static struct ia_css_syscom_config psys_syscom_config_secure; +struct ia_css_syscom_context *psys_syscom_secure; +#endif +static bool external_alloc = true; + +int ia_css_psys_config_print( + const struct ia_css_syscom_config *config, + void *fh) +{ + int retval = -1; + + NOT_USED(fh); + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "ia_css_frame_print(): enter:\n"); + + verifexit(config != NULL); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DEVICE, ERROR, + "ia_css_frame_print failed (%i)\n", retval); + } + return retval; +} + +int ia_css_psys_print( + const struct ia_css_syscom_context *context, + void *fh) +{ + int retval = -1; + + NOT_USED(fh); + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "ia_css_psys_print(): enter:\n"); + + verifexit(context != NULL); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_print failed (%i)\n", retval); + } + return retval; +} + +static void set_syscom_config(struct ia_css_syscom_config *config) +{ + int i; + + config->num_input_queues = IA_CSS_N_PSYS_CMD_QUEUE_ID; + config->num_output_queues = IA_CSS_N_PSYS_EVENT_QUEUE_ID; + /* The number of queues are different for different platforms + * so the array is initialized here + */ + for (i = 0; i < IA_CSS_N_PSYS_CMD_QUEUE_ID; i++) { + ia_css_psys_cmd_queue_cfg[i].queue_size = IA_CSS_PSYS_CMD_QUEUE_SIZE; + ia_css_psys_cmd_queue_cfg[i].token_size = IA_CSS_PSYS_CMD_BITS/8; + } + config->input = ia_css_psys_cmd_queue_cfg; + config->output = ia_css_psys_event_queue_cfg; + config->vtl0_addr_mask = 0; +} + +struct ia_css_syscom_config *ia_css_psys_specify(void) +{ + struct ia_css_syscom_config *config = &psys_syscom_config; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "ia_css_psys_specify(): enter:\n"); + set_syscom_config(config); + config->secure = false; + + return config; +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +struct ia_css_syscom_config *ia_css_psys_specify_secure(unsigned int vtl0_addr_mask) +{ + struct ia_css_syscom_config *config = &psys_syscom_config_secure; + + IA_CSS_TRACE_1(PSYSAPI_DEVICE, INFO, "ia_css_psys_specify_secure(mask %#x): enter:\n", vtl0_addr_mask); + set_syscom_config(config); + config->secure = true; + config->vtl0_addr_mask = vtl0_addr_mask; + return config; +} +#endif + +size_t ia_css_sizeof_psys( + struct ia_css_syscom_config *config) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_sizeof_psys(): enter:\n"); + + NOT_USED(config); + + return size; +} + +/* Internal function to create syscom_context */ +static struct ia_css_syscom_context *psys_context_create( + const struct ia_css_psys_buffer_s *buffer, + struct ia_css_syscom_config *config) +{ + struct ia_css_syscom_context *context; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "psys_context_create(): enter:\n"); + + if (config == NULL) + goto EXIT; + + if (buffer == NULL) { + /* Allocate locally */ + external_alloc = false; + } + + /* + * Here we would like to pass separately the sub-system ID + * and optionally the user pointer to be mapped, depending on + * where this open is called, and which virtual memory handles + * we see here. + */ + /* context = ia_css_syscom_open(get_virtual_memory_handle(vied_psys_ID), + * buffer, config); + */ + context = ia_css_syscom_open(config, NULL); + if (context == NULL) + goto EXIT; + + return context; + +EXIT: + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, "psys_context_create failed\n"); + return NULL; +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +struct ia_css_syscom_context *ia_css_psys_context_create( + const struct ia_css_psys_buffer_s *buffer, + struct ia_css_syscom_config *config) +{ + return psys_context_create(buffer, config); +} + +/* push context information to DMEM for FW to access */ +int ia_css_psys_context_store_dmem( + struct ia_css_syscom_context *context, + struct ia_css_syscom_config *config) +{ + return ia_css_syscom_store_dmem(context, config->ssid, config->vtl0_addr_mask); +} +#endif + +/* Internal function to start psys server */ +static int psys_start_server( + struct ia_css_syscom_config *config) +{ + ia_css_psys_server_init_t *server_config; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "psys_start_server(): enter:\n"); + + /* Configure SPC icache prefetching and start SPC */ + server_config = (ia_css_psys_server_init_t *)config->specific_addr; + IA_CSS_TRACE_1(PSYSAPI_DEVICE, INFO, "SPC prefetch: %d\n", + server_config->icache_prefetch_sp); + ia_css_cell_start_prefetch(config->ssid, SPC0, + server_config->icache_prefetch_sp); + return 0; +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +int ia_css_psys_open( + struct ia_css_syscom_config *config) +{ + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "ia_css_psys_open(): enter:\n"); + return psys_start_server(config); +} +#else +struct ia_css_syscom_context *ia_css_psys_open( + const struct ia_css_psys_buffer_s *buffer, + struct ia_css_syscom_config *config) +{ + struct ia_css_syscom_context *context; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "ia_css_psys_open(): enter:\n"); + + context = psys_context_create(buffer, config); + + /* Configure SPC icache prefetching and start SPC */ + psys_start_server(config); + + return context; +} +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +bool ia_css_psys_open_is_ready( + struct ia_css_syscom_context *context) +{ + int retval = -1; + bool ready = 0; + unsigned int i; + int syscom_retval; + + verifexit(context != NULL); + + for (i = 0; i < IA_CSS_N_PSYS_CMD_QUEUE_ID; i++) { + syscom_retval = ia_css_syscom_send_port_open(context, i); + if (syscom_retval != 0) { + if (syscom_retval == FW_ERROR_BUSY) { + /* Do not print error */ + retval = 0; + } + /* Not ready yet */ + goto EXIT; + } + } + + for (i = 0; i < IA_CSS_N_PSYS_EVENT_QUEUE_ID; i++) { + syscom_retval = ia_css_syscom_recv_port_open(context, i); + if (syscom_retval != 0) { + if (syscom_retval == FW_ERROR_BUSY) { + /* Do not print error */ + retval = 0; + } + /* Not ready yet */ + goto EXIT; + } + } + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, + "ia_css_psys_open_is_ready(): complete:\n"); + + /* If this point reached, do not print error */ + retval = 0; + /* If this point reached, ready */ + ready = 1; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_open_is_ready failed\n"); + } + return ready; +} + +/* Internal function to close syscom_context */ +static struct ia_css_syscom_context *psys_context_destroy( + struct ia_css_syscom_context *context) +{ + /* Success: return NULL, Error: return context pointer value + * Intention is to change return type to int (errno), + * see commented values. + */ + + unsigned int i; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, "psys_context_destroy(): enter:\n"); + + /* NULL pointer check disabled, since there is no proper return value */ + + for (i = 0; i < IA_CSS_N_PSYS_CMD_QUEUE_ID; i++) { + if (ia_css_syscom_send_port_close(context, i) != 0) + return context; /* EINVAL */ + } + + for (i = 0; i < IA_CSS_N_PSYS_EVENT_QUEUE_ID; i++) { + if (ia_css_syscom_recv_port_close(context, i) != 0) + return context; /* EINVAL */ + } + + /* request device close */ + if (ia_css_syscom_close(context) != 0) + return context; /* EBUSY */ + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, + "psys_context_destroy(): leave: OK\n"); + return NULL; +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +struct ia_css_syscom_context *ia_css_psys_context_destroy( + struct ia_css_syscom_context *context) +{ + return psys_context_destroy(context); +} + +int ia_css_psys_close(void) +{ + /* Intentionally left blank for now since syscom objects should have + * been destroyed already by prior ia_css_psys_context_destroy() calls. + */ + return 0; +} +#else +struct ia_css_syscom_context *ia_css_psys_close( + struct ia_css_syscom_context *context) +{ + return psys_context_destroy(context); +} +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +int ia_css_psys_release( + struct ia_css_syscom_context *context, + bool force) +{ + if (context == NULL) + return -EFAULT; + + /* try to free resources */ + if (ia_css_syscom_release(context, force) != 0) + return -EBUSY; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, INFO, + "ia_css_psys_release(): leave: OK\n"); + return 0; +} + +ia_css_psys_state_t ia_css_psys_check_state( + struct ia_css_syscom_context *context) +{ + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_check_state(): enter:\n"); + + NOT_USED(context); + + /* For the time being, return the READY state to be used by SPC test */ + return IA_CSS_PSYS_STATE_READY; +} + +bool ia_css_is_psys_cmd_queue_full( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id) +{ + bool is_full = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_is_psys_cmd_queue_full(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_send_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + is_full = (num_tokens == 0); + retval = 0; +EXIT: + if (retval != 0) { + is_full = true; + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_is_psys_cmd_queue_full failed\n"); + } + return is_full; +} + +bool ia_css_is_psys_cmd_queue_not_full( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id) +{ + bool is_not_full = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_is_psys_cmd_queue_not_full(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_send_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + is_not_full = (num_tokens != 0); + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_is_psys_cmd_queue_not_full failed\n"); + } + return is_not_full; +} + +bool ia_css_has_psys_cmd_queue_N_space( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const unsigned int N) +{ + bool has_N_space = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_has_psys_cmd_queue_N_space(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_send_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + has_N_space = ((unsigned int)num_tokens >= N); +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_has_psys_cmd_queue_N_space failed\n"); + } + return has_N_space; +} + +int ia_css_psys_cmd_queue_get_available_space( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id) +{ + int N_space = -1; + int num_tokens; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_cmd_queue_get_available_space(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_send_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + N_space = (int)(num_tokens); +EXIT: + if (N_space < 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_cmd_queue_get_available_space failed\n"); + } + return N_space; +} + +bool ia_css_any_psys_event_queue_not_empty( + struct ia_css_syscom_context *context) +{ + ia_css_psys_event_queue_ID_t i; + bool any_msg = false; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_any_psys_event_queue_not_empty(): enter:\n"); + verifexit(context != NULL); + + for (i = (ia_css_psys_event_queue_ID_t)0; + i < IA_CSS_N_PSYS_EVENT_QUEUE_ID; i++) { + any_msg = + any_msg || ia_css_is_psys_event_queue_not_empty(context, i); + } + +EXIT: + return any_msg; +} + +bool ia_css_is_psys_event_queue_empty( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id) +{ + bool is_empty = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_is_psys_event_queue_empty(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_recv_port_available(context, (unsigned int)id); + verifexit(num_tokens >= 0); + + is_empty = (num_tokens == 0); + retval = 0; +EXIT: + if (retval != 0) { + is_empty = true; + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_is_psys_event_queue_empty failed\n"); + } + return is_empty; +} + +bool ia_css_is_psys_event_queue_not_empty( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id) +{ + bool is_not_empty = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_is_psys_event_queue_not_empty(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_recv_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + is_not_empty = (num_tokens != 0); + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_is_psys_event_queue_not_empty failed\n"); + } + return is_not_empty; +} + +bool ia_css_has_psys_event_queue_N_msgs( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + const unsigned int N) +{ + bool has_N_msgs = false; + int num_tokens; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_has_psys_event_queue_N_msgs(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_recv_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + has_N_msgs = ((unsigned int)num_tokens >= N); + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_has_psys_event_queue_N_msgs failed\n"); + } + return has_N_msgs; +} + +int ia_css_psys_event_queue_get_available_msgs( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id) +{ + int N_msgs = -1; + int num_tokens; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_event_queue_get_available_msgs(): enter:\n"); + verifexit(context != NULL); + + num_tokens = ia_css_syscom_recv_port_available(context, + (unsigned int)id); + verifexit(num_tokens >= 0); + + N_msgs = (int)(num_tokens); +EXIT: + if (N_msgs < 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_event_queue_get_available_msgs failed\n"); + } + return N_msgs; +} + +int ia_css_psys_cmd_queue_send( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const void *cmd_msg_buffer) +{ + int count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_cmd_queue_send(): enter:\n"); + verifexit(context != NULL); + + verifexit(context != NULL); + /* The ~full check fails on receive queues */ + verifexit(ia_css_is_psys_cmd_queue_not_full(context, id)); + verifexit(cmd_msg_buffer != NULL); + + verifexit(ia_css_syscom_send_port_transfer(context, (unsigned int)id, + cmd_msg_buffer) >= 0); + + count = 1; +EXIT: + if (count == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_cmd_queue_send failed\n"); + } + return count; +} + +int ia_css_psys_cmd_queue_send_N( + struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id, + const void *cmd_msg_buffer, + const unsigned int N) +{ + struct ia_css_psys_cmd_s *cmd_msg_buffer_loc = + (struct ia_css_psys_cmd_s *)cmd_msg_buffer; + int count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_cmd_queue_send_N(): enter:\n"); + verifexit(context != NULL); + + for (count = 0; count < (int)N; count++) { + int count_loc = ia_css_psys_cmd_queue_send(context, id, + (void *)(&cmd_msg_buffer_loc[count])); + + verifexit(count_loc == 1); + } + +EXIT: + if ((unsigned int) count < N) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_cmd_queue_send_N failed\n"); + } + return count; +} + +int ia_css_psys_event_queue_receive( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + void *event_msg_buffer) +{ + int count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_event_queue_receive(): enter:\n"); + + verifexit(context != NULL); + /* The ~empty check fails on send queues */ + verifexit(ia_css_is_psys_event_queue_not_empty(context, id)); + verifexit(event_msg_buffer != NULL); + + verifexit(ia_css_syscom_recv_port_transfer(context, (unsigned int)id, + event_msg_buffer) >= 0); + + count = 1; +EXIT: + if (count == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_event_queue_receive failed\n"); + } + return count; +} + +int ia_css_psys_event_queue_receive_N( + struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id, + void *event_msg_buffer, + const unsigned int N) +{ + struct ia_css_psys_event_s *event_msg_buffer_loc; + int count; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_event_queue_receive_N(): enter:\n"); + + event_msg_buffer_loc = (struct ia_css_psys_event_s *)event_msg_buffer; + + for (count = 0; count < (int)N; count++) { + int count_loc = ia_css_psys_event_queue_receive(context, id, + (void *)(&event_msg_buffer_loc[count])); + + verifexit(count_loc == 1); + } + +EXIT: + if ((unsigned int) count < N) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_event_queue_receive_N failed\n"); + } + return count; +} + +size_t ia_css_psys_get_size( + const struct ia_css_syscom_context *context) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_size(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ +EXIT: + if (size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_size failed\n"); + } + return size; +} + +unsigned int ia_css_psys_get_cmd_queue_count( + const struct ia_css_syscom_context *context) +{ + unsigned int count = 0; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_cmd_queue_count(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + count = (unsigned int)IA_CSS_N_PSYS_CMD_QUEUE_ID; + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_cmd_queue_count failed\n"); + } + return count; +} + +unsigned int ia_css_psys_get_event_queue_count( + const struct ia_css_syscom_context *context) +{ + unsigned int count = 0; + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_event_queue_count(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + count = (unsigned int)IA_CSS_N_PSYS_EVENT_QUEUE_ID; + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_event_queue_count failed\n"); + } + return count; +} + +size_t ia_css_psys_get_cmd_queue_size( + const struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id) +{ + size_t queue_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_cmd_queue_size(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + queue_size = ia_css_psys_cmd_queue_cfg[id].queue_size; +EXIT: + if (queue_size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_cmd_queue_size failed\n"); + } + return queue_size; +} + +size_t ia_css_psys_get_event_queue_size( + const struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id) +{ + size_t queue_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_event_queue_size(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + queue_size = ia_css_psys_event_queue_cfg[id].queue_size; +EXIT: + if (queue_size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_event_queue_size failed\n"); + } + return queue_size; +} + +size_t ia_css_psys_get_cmd_msg_size( + const struct ia_css_syscom_context *context, + ia_css_psys_cmd_queue_ID_t id) +{ + size_t msg_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_cmd_msg_size(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + msg_size = ia_css_psys_cmd_queue_cfg[id].token_size; +EXIT: + if (msg_size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_cmd_msg_size failed\n"); + } + return msg_size; +} + +size_t ia_css_psys_get_event_msg_size( + const struct ia_css_syscom_context *context, + ia_css_psys_event_queue_ID_t id) +{ + size_t msg_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DEVICE, VERBOSE, + "ia_css_psys_get_event_msg_size(): enter:\n"); + + verifexit(context != NULL); + /* How can I query the context ? */ + NOT_USED(context); + msg_size = ia_css_psys_event_queue_cfg[id].token_size; +EXIT: + if (msg_size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DEVICE, ERROR, + "ia_css_psys_get_cmd_msg_size failed\n"); + } + return msg_size; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_buffer_set.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_buffer_set.h new file mode 100644 index 0000000000000..392b4359353f4 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_buffer_set.h @@ -0,0 +1,174 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_PSYS_BUFFER_SET_H +#define __IA_CSS_PSYS_BUFFER_SET_H + +#include "ia_css_base_types.h" +#include "ia_css_psys_dynamic_storage_class.h" +#include "ia_css_psys_process_types.h" +#include "ia_css_terminal_types.h" + +#define N_UINT64_IN_BUFFER_SET_STRUCT 1 +#define N_UINT16_IN_BUFFER_SET_STRUCT 1 +#define N_UINT8_IN_BUFFER_SET_STRUCT 1 +#define N_PADDING_UINT8_IN_BUFFER_SET_STRUCT 5 +#define SIZE_OF_BUFFER_SET \ + (N_UINT64_IN_BUFFER_SET_STRUCT * IA_CSS_UINT64_T_BITS \ + + VIED_VADDRESS_BITS \ + + VIED_VADDRESS_BITS \ + + N_UINT16_IN_BUFFER_SET_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_UINT8_IN_BUFFER_SET_STRUCT * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_BUFFER_SET_STRUCT * IA_CSS_UINT8_T_BITS) + +typedef struct ia_css_buffer_set_s ia_css_buffer_set_t; + +struct ia_css_buffer_set_s { + /* Token for user context reference */ + uint64_t token; + /* IPU virtual address of this buffer set */ + vied_vaddress_t ipu_virtual_address; + /* IPU virtual address of the process group corresponding to this buffer set */ + vied_vaddress_t process_group_handle; + /* Number of terminal buffer addresses in this structure */ + uint16_t terminal_count; + /* Frame id to associate with this buffer set */ + uint8_t frame_counter; + /* Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_BUFFER_SET_STRUCT]; +}; + + +/*! Construct a buffer set object at specified location + + @param buffer_set_mem[in] memory location to create buffer set object + @param process_group[in] process group corresponding to this buffer set + @param frame_counter[in] frame number for this buffer set object + + @return pointer to buffer set object on success, NULL on error + */ +ia_css_buffer_set_t *ia_css_buffer_set_create( + void *buffer_set_mem, + const ia_css_process_group_t *process_group, + const unsigned int frame_counter); + +/*! Compute size (in bytes) required for full buffer set object + + @param process_group[in] process group corresponding to this buffer set + + @return size in bytes of buffer set object on success, 0 on error + */ +size_t ia_css_sizeof_buffer_set( + const ia_css_process_group_t *process_group); + +/*! Set a buffer address in a buffer set object + + @param buffer_set[in] buffer set object to set buffer in + @param terminal_index[in] terminal index to use as a reference between + buffer and terminal + @param buffer[in] buffer address to store + + @return 0 on success, -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_buffer_set_set_buffer( + ia_css_buffer_set_t *buffer_set, + const unsigned int terminal_index, + const vied_vaddress_t buffer); + +/*! Get virtual buffer address from a buffer set object and terminal object by + resolving the index used + + @param buffer_set[in] buffer set object to get buffer from + @param terminal[in] terminal object to get buffer of + + @return virtual buffer address on success, VIED_NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_vaddress_t ia_css_buffer_set_get_buffer( + const ia_css_buffer_set_t *buffer_set, + const ia_css_terminal_t *terminal); + +/*! Set ipu virtual address of a buffer set object within the buffer set object + + @param buffer_set[in] buffer set object to set ipu address in + @param ipu_vaddress[in] ipu virtual address of the buffer set object + + @return 0 on success, -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_buffer_set_set_ipu_address( + ia_css_buffer_set_t *buffer_set, + const vied_vaddress_t ipu_vaddress); + +/*! Get ipu virtual address from a buffer set object + + @param buffer_set[in] buffer set object to get ipu address from + + @return virtual buffer set address on success, VIED_NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_vaddress_t ia_css_buffer_set_get_ipu_address( + const ia_css_buffer_set_t *buffer_set); + +/*! Set process group handle in a buffer set object + + @param buffer_set[in] buffer set object to set handle in + @param process_group_handle[in] process group handle of the buffer set + object + + @return 0 on success, -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_buffer_set_set_process_group_handle( + ia_css_buffer_set_t *buffer_set, + const vied_vaddress_t process_group_handle); + +/*! Get process group handle from a buffer set object + + @param buffer_set[in] buffer set object to get handle from + + @return virtual process group address on success, VIED_NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_vaddress_t ia_css_buffer_set_get_process_group_handle( + const ia_css_buffer_set_t *buffer_set); + +/*! Set token of a buffer set object within the buffer set object + + @param buffer_set[in] buffer set object to set ipu address in + @param token[in] token of the buffer set object + + @return 0 on success, -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_buffer_set_set_token( + ia_css_buffer_set_t *buffer_set, + const uint64_t token); + +/*! Get token from a buffer set object + + @param buffer_set[in] buffer set object to get token from + + @return token on success, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint64_t ia_css_buffer_set_get_token( + const ia_css_buffer_set_t *buffer_set); + +#ifdef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_buffer_set_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +#endif /* __IA_CSS_PSYS_BUFFER_SET_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_storage_class.h new file mode 100644 index 0000000000000..9a1e3a7a12949 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_storage_class.h @@ -0,0 +1,28 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +#define __IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#define IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +#else +#define IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_trace.h new file mode 100644 index 0000000000000..e8a979dfce0bf --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_dynamic_trace.h @@ -0,0 +1,103 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_DYNAMIC_TRACE_H +#define __IA_CSS_PSYS_DYNAMIC_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_DYNAMIC_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_DYNAMIC_TRACING_OVERRIDE)) + #define PSYS_DYNAMIC_TRACE_LEVEL_CONFIG \ + PSYS_DYNAMIC_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_DYNAMIC_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_DYNAMIC_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_DYNAMIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_DYNAMIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DYNAMIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_DYNAMIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_DYNAMIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_DYNAMIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_DYNAMIC_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_DYNAMIC_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_DYNAMIC_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.h new file mode 100644 index 0000000000000..fd4c6608c9310 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.h @@ -0,0 +1,396 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_H +#define __IA_CSS_PSYS_PROCESS_H + +/*! \file */ + +/** @file ia_css_psys_process.h + * + * Define the methods on the process object that are not part of + * a single interface + */ + +#include +#include + +#include + +#include /* uint8_t */ + +/* + * Creation + */ +#include + +/* + * Internal resources + */ +#include + +/* + * Process manager + */ +#include + +/* + * Command processor + */ + +/*! Execute a command locally or send it to be processed remotely + + @param process[in] process object + @param cmd[in] command + + @return < 0 on invalid argument(s) or process state + */ +extern int ia_css_process_cmd( + ia_css_process_t *process, + const ia_css_process_cmd_t cmd); + +/*! Get the internal memory offset of the process object + + @param process[in] process object + @param mem_id[in] memory id + + @return internal memory offset, + IA_CSS_PROCESS_INVALID_OFFSET on invalid argument(s) +*/ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_size_t ia_css_process_get_int_mem_offset( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_id); + + +/*! Get the external memory offset of the process object + + @param process[in] process object + @param mem_id[in] memory id + + @return external memory offset, + IA_CSS_PROCESS_INVALID_OFFSET on invalid argument(s) +*/ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_size_t ia_css_process_get_ext_mem_offset( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id); + + +/*! Get the stored size of the process object + + @param process[in] process object + + @return size, 0 on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +size_t ia_css_process_get_size(const ia_css_process_t *process); + +/*! Get the (pointer to) the process group parent of the process object + + @param process[in] process object + + @return the pointer to the parent, NULL on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_process_group_t *ia_css_process_get_parent( + const ia_css_process_t *process); + +/*! Set the (pointer to) the process group parent of the process object + + @param process[in] process object + @param parent[in] (pointer to the) process group parent object + + @return < 0 on invalid argument(s) + */ +extern int ia_css_process_set_parent( + ia_css_process_t *process, + ia_css_process_group_t *parent); + +/*! Get the unique ID of program used by the process object + + @param process[in] process object + + @return ID, 0 on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_program_ID_t ia_css_process_get_program_ID( + const ia_css_process_t *process); + +/*! Get the state of the process object + + @param process[in] process object + + @return state, limit value (IA_CSS_N_PROCESS_STATES) on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_process_state_t ia_css_process_get_state( + const ia_css_process_t *process); + +/*! Set the state of the process object + + @param process[in] process object + @param state[in] state of the process + + @return < 0 on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_set_state( + ia_css_process_t *process, + ia_css_process_state_t state); + +/*! Get the assigned cell of the process object + + @param process[in] process object + + @return cell ID, limit value (VIED_NCI_N_CELL_ID) on invalid argument + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_cell_ID_t ia_css_process_get_cell( + const ia_css_process_t *process); + +/*! Get the number of cells the process object depends on + + @param process[in] process object + + @return number of cells + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_get_cell_dependency_count( + const ia_css_process_t *process); + +/*! Get the number of terminals the process object depends on + + @param process[in] process object + + @return number of terminals + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_get_terminal_dependency_count( + const ia_css_process_t *process); + +/*! Set n-th cell dependency of a process object + + @param process[in] Process object + @param dep_index[in] dep index + @param id[in] dep id + + @return < 0 on invalid process argument + */ +extern int ia_css_process_set_cell_dependency( + const ia_css_process_t *process, + const unsigned int dep_index, + const vied_nci_resource_id_t id); + +/*! Get n-th cell dependency of a process object + + @param process[in] Process object + @param cell_num[in] n-th cell + + @return n-th cell dependency, + IA_CSS_PROCESS_INVALID_DEPENDENCY on invalid argument(s) +*/ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_id_t ia_css_process_get_cell_dependency( + const ia_css_process_t *process, + const unsigned int cell_num); + +/*! Set n-th terminal dependency of a process object + + @param process[in] Process object + @param dep_index[in] dep index + @param id[in] dep id + + @return < 0 on invalid argument(s) + */ +extern int ia_css_process_set_terminal_dependency( + const ia_css_process_t *process, + const unsigned int dep_index, + const vied_nci_resource_id_t id); + +/*! Get n-th terminal dependency of a process object + + @param process[in] Process object + @param terminal_num[in] n-th cell + + @return n-th terminal dependency, + IA_CSS_PROCESS_INVALID_DEPENDENCY on invalid argument(s) +*/ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_get_terminal_dependency( + const ia_css_process_t *process, + const unsigned int terminal_num); + +/*! Get the kernel bitmap of the process object + + @param process[in] process object + + @return process kernel bitmap + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_kernel_bitmap_t ia_css_process_get_kernel_bitmap( + const ia_css_process_t *process); + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t *ia_css_process_get_dfm_port_bitmap_ptr( + ia_css_process_t *process); + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t *ia_css_process_get_dfm_active_port_bitmap_ptr( + ia_css_process_t *process); + + +/*! Get the cells bitmap of the process object + + @param process[in] process object + + @return process cells bitmap + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t ia_css_process_get_cells_bitmap( + const ia_css_process_t *process); + +/*! Sets the dfm device resource allocation bitmap of + * the process object + + @param process[in] process object + @param dfm_dev_id[in] dfm device id + @param bitmap[in] resource bitmap + + @return < 0 on invalid argument(s) or process state + */ +int ia_css_process_set_dfm_port_bitmap( + ia_css_process_t *process, + const vied_nci_dev_dfm_id_t dfm_dev_id, + const vied_nci_resource_bitmap_t bitmap); + + +/*! Sets the active dfm ports bitmap of + * the process object + + @param process[in] process object + @param dfm_dev_id[in] dfm device id + @param bitmap[in] active ports bitmap + + @return < 0 on invalid argument(s) or process state + */ +int ia_css_process_set_dfm_active_port_bitmap( + ia_css_process_t *process, + const vied_nci_dev_dfm_id_t dfm_dev_id, + const vied_nci_resource_bitmap_t bitmap); + +/*! Get the dfm port bitmap of the process object + + @param process[in] process object + @param dfm_res_id dfm resource id + + @return bitmap of all DFM ports used by process, corresponding to the input dfm resource id + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t ia_css_process_get_dfm_port_bitmap( + const ia_css_process_t *process, + vied_nci_dev_dfm_id_t dfm_res_id); + +/*! Get the dfm active port bitmap of the process object + + @param process[in] process object + @param dfm_res_id[in] dfm resource id + + @return bitmap of all active DFM ports used by the process, corresponding to the input + dfm resource id + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t ia_css_process_get_dfm_active_port_bitmap( + const ia_css_process_t *process, + vied_nci_dev_dfm_id_t dfm_res_id); + + +/*! Sets the cells bitmap of + * the process object + + @param process[in] process object + @param bitmap[in] bitmap + + @return < 0 on invalid argument(s) or process state + */ +int ia_css_process_set_cells_bitmap( + ia_css_process_t *process, + const vied_nci_resource_bitmap_t bitmap); + +/*! Get the device channel id-n resource allocation offset of the process object + + @param process[in] process object + @param dev_chn_id[in] channel id + + @return resource offset, IA_CSS_PROCESS_INVALID_OFFSET on invalid argument(s) + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_size_t ia_css_process_get_dev_chn( + const ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id); + +/*! Get the ext mem type-n resource id of the process object + + @param process[in] process object + @param mem_type[in] mem type + + @return resource offset, IA_CSS_PROCESS_INVALID_OFFSET on invalid argument(s) + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_mem_ID_t ia_css_process_get_ext_mem_id( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type); + + +/*! Sets the device channel id-n resource allocation offset of + * the process object + + @param process[in] process object + @param dev_chn_id[in] channel id + @param offset[in] resource offset + + @return < 0 on invalid argument(s) or process state + */ +int ia_css_process_set_dev_chn( + ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t offset); + +/*! Boolean test if the process object type is valid + + @param process[in] process object + @param p_manifest[in] program manifest + + @return true if the process object is correct, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_process_valid( + const ia_css_process_t *process, + const ia_css_program_manifest_t *p_manifest); + +/*! Gets the program_idx from the process object + + @param process[in] process object + + @return program index + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_get_program_idx( + const ia_css_process_t *process); + +#ifdef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_process_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +#endif /* __IA_CSS_PSYS_PROCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.kernel.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.kernel.h new file mode 100644 index 0000000000000..cab7965604146 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.kernel.h @@ -0,0 +1,144 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_HSYS_KERNEL_H +#define __IA_CSS_PSYS_PROCESS_HSYS_KERNEL_H + +/*! \file */ + +/** @file ia_css_psys_process.hsys.kernel.h + * + * Define the methods on the process object: Hsys kernel interface + */ + +#include + +#include + +/* + * Internal resources + */ + +/*! Clear all resource (offset) specifications + + @param process[in] process object + + @return < 0 on error + */ +extern int ia_css_process_clear_all(ia_css_process_t *process); + +/*! Set the cell ID resource specification + + @param process[in] process object + @param cell_id[in] cell ID + + @return < 0 on error + */ +extern int ia_css_process_set_cell( + ia_css_process_t *process, + const vied_nci_cell_ID_t cell_id); + +/*! Clear cell ID resource specification + + @param process[in] process object + + @return < 0 on error + */ +extern int ia_css_process_clear_cell(ia_css_process_t *process); + +/*! Set the memory resource (offset) specification for a memory + that belongs to the cell that is assigned to the process + + @param process[in] process object + @param mem_type_id[in] mem type ID + @param offset[in] offset + + Precondition: The cell ID must be set + + @return < 0 on error + */ +extern int ia_css_process_set_int_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t offset); + +/*! Clear the memory resource (offset) specification for a memory + type that belongs to the cell that is assigned to the process + + @param process[in] process object + @param mem_id[in] mem ID + + Precondition: The cell ID must be set + + @return < 0 on error + */ +extern int ia_css_process_clear_int_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Set the memory resource (offset) specification for a memory + that does not belong to the cell that is assigned to the process + + @param process[in] process object + @param mem_type_id[in] mem type ID + @param offset[in] offset + + Precondition: The cell ID must be set + + @return < 0 on error + */ +extern int ia_css_process_set_ext_mem( + ia_css_process_t *process, + const vied_nci_mem_ID_t mem_id, + const vied_nci_resource_size_t offset); + +/*! Clear the memory resource (offset) specification for a memory + type that does not belong to the cell that is assigned to the process + + @param process[in] process object + @param mem_id[in] mem ID + + Precondition: The cell ID must be set + + @return < 0 on error + */ +extern int ia_css_process_clear_ext_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Set a device channel resource (offset) specification + + @param process[in] process object + @param dev_chn_id[in] device channel ID + @param offset[in] offset + + @return < 0 on error + */ +extern int ia_css_process_set_dev_chn( + ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t offset); + +/*! Clear a device channel resource (offset) specification + + @param process[in] process object + @param dev_chn_id[in] device channel ID + + @return < 0 on error + */ +extern int ia_css_process_clear_dev_chn( + ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id); + +#endif /* __IA_CSS_PSYS_PROCESS_HSYS_KERNEL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.user.h new file mode 100644 index 0000000000000..015a60b0e1afb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.hsys.user.h @@ -0,0 +1,85 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_HSYS_USER_H +#define __IA_CSS_PSYS_PROCESS_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_process.hsys.user.h + * + * Define the methods on the process object: Hsys user interface + */ + +#include /* ia_css_program_param_t */ + +#include +#include + +#include /* uint8_t */ + +/* + * Creation + */ + +/*! Compute the size of storage required for allocating the process object + + @param manifest[in] program manifest + @param param[in] program parameters + + @return 0 on error + */ +extern size_t ia_css_sizeof_process( + const ia_css_program_manifest_t *manifest, + const ia_css_program_param_t *param); + +/*! Create the process object + + @param raw_mem[in] pre allocated memory + @param manifest[in] program manifest + @param param[in] program parameters + + @return NULL on error + */ +extern ia_css_process_t *ia_css_process_create( + void *raw_mem, + const ia_css_program_manifest_t *manifest, + const ia_css_program_param_t *param, + const uint32_t program_idx); + +/*! Destroy (the storage of) the process object + + @param process[in] process object + + @return NULL + */ +extern ia_css_process_t *ia_css_process_destroy( + ia_css_process_t *process); + +/* + * Access functions + */ + +/*! Print the process object to file/stream + + @param process[in] process object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_process_print( + const ia_css_process_t *process, + void *fid); + +#endif /* __IA_CSS_PSYS_PROCESS_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.psys.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.psys.h new file mode 100644 index 0000000000000..ba1db574a4388 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process.psys.h @@ -0,0 +1,53 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_PSYS_H +#define __IA_CSS_PSYS_PROCESS_PSYS_H + +/*! \file */ + +/** @file ia_css_psys_process.psys.h + * + * Define the methods on the process object: Psys embedded interface + */ + +#include + +/* + * Process manager + */ + +/*! Acquire the resources specificed in process object + + @param process[in] process object + + Postcondition: This is a try process if any of the + resources is not available, all succesfully acquired + ones will be release and the function will return an + error + + @return < 0 on error + */ +extern int ia_css_process_acquire(ia_css_process_t *process); + +/*! Release the resources specificed in process object + + @param process[in] process object + + @return < 0 on error + */ +extern int ia_css_process_release(ia_css_process_t *process); + + +#endif /* __IA_CSS_PSYS_PROCESS_PSYS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.h new file mode 100644 index 0000000000000..845590efd9039 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.h @@ -0,0 +1,366 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_H +#define __IA_CSS_PSYS_PROCESS_GROUP_H + +/*! \file */ + +/** @file ia_css_psys_process_group.h + * + * Define the methods on the process object that are not part of + * a single interface + */ +#include "ia_css_rbm.h" + +#include +#include + +#include /* uint8_t */ + +/* + * Creation + */ +#include + +/* + * Registration of user contexts / callback info + * External resources + * Sequencing resources + */ +#include + +/* + * Dispatcher + */ +#include + +/* + * Access to sub-structure handles / fields + */ + +#include "ia_css_terminal.h" + +/*! Get the number of fragments on the process group + + @param process_group[in] process group object + + Note: Future change is to have a fragment count per + independent subgraph + + @return the fragment count, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint16_t ia_css_process_group_get_fragment_count( + const ia_css_process_group_t *process_group); + + +/*! Get the fragment state on the process group + + @param process_group[in] process group object + @param fragment_state[in] current fragment of processing + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_get_fragment_state( + const ia_css_process_group_t *process_group, + uint16_t *fragment_state); + +/*! Set the fragment state on the process group + + @param process_group[in] process group object + @param fragment_state[in] current fragment of processing + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_fragment_state( + ia_css_process_group_t *process_group, + uint16_t fragment_state); + +/*! Get the number of processes on the process group + + @param process_group[in] process group object + + @return the process count, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_group_get_process_count( + const ia_css_process_group_t *process_group); + +/*! Get the number of terminals on the process group + + @param process_group[in] process group object + + Note: Future change is to have a terminal count per + independent subgraph + + @return the terminal count, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_group_get_terminal_count( + const ia_css_process_group_t *process_group); + +/*! Get the PG load start timestamp + + @param process_group[in] process group object + + @return PG load start timestamp, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_get_pg_load_start_ts( + const ia_css_process_group_t *process_group); + +/*! Get the PG load time in cycles + + @param process_group[in] process group object + + @return PG load time in cycles, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_get_pg_load_cycles( + const ia_css_process_group_t *process_group); + +/*! Get the PG init time in cycles + + @param process_group[in] process group object + + @return PG init time in cycles, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_get_pg_init_cycles( + const ia_css_process_group_t *process_group); + +/*! Get the PG processing time in cycles + + @param process_group[in] process group object + + @return PG processing time in cycles, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_get_pg_processing_cycles( + const ia_css_process_group_t *process_group); + +/*! Get the (pointer to) the terminal of the process group object + + @param process_group[in] process group object + @param terminal_type[in] terminal type of terminal + + @return the pointer to the terminal, NULL on error + */ + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_terminal_t *ia_css_process_group_get_terminal_from_type( + const ia_css_process_group_t *process_group, + const ia_css_terminal_type_t terminal_type); + +/*! Get the (pointer to) the terminal of the process group object + * for terminals which have only a single instance + * (cached in, cached out, program, program_ctrl_init) + + @param process_group[in] process group object + @param terminal_type[in] terminal type of terminal + + @return the pointer to the terminal, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +const ia_css_terminal_t *ia_css_process_group_get_single_instance_terminal( + const ia_css_process_group_t *process_group, + ia_css_terminal_type_t term_type); + +/*! Get the (pointer to) the indexed terminal of the process group object + + @param process_group[in] process group object + @param terminal_index[in] index of the terminal + + @return the pointer to the terminal, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_terminal_t *ia_css_process_group_get_terminal( + const ia_css_process_group_t *process_group, + const unsigned int terminal_index); + +/*! Get the (pointer to) the indexed process of the process group object + + @param process_group[in] process group object + @param process_index[in] index of the process + + @return the pointer to the process, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_process_t *ia_css_process_group_get_process( + const ia_css_process_group_t *process_group, + const unsigned int process_index); + +/*! Get the stored size of the process group object + + @param process_group[in] process group object + + @return size, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +size_t ia_css_process_group_get_size( + const ia_css_process_group_t *process_group); + +/*! Get the state of the process group object + + @param process_group[in] process group object + + @return state, limit value on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_process_group_state_t ia_css_process_group_get_state( + const ia_css_process_group_t *process_group); + +/*! Get the unique ID of program group used by the process group object + + @param process_group[in] process group object + + @return ID, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_program_group_ID_t ia_css_process_group_get_program_group_ID( + const ia_css_process_group_t *process_group); + +/*! Get the resource bitmap of the process group + + @param process_group[in] process group object + + @return the reource bitmap + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_nci_resource_bitmap_t ia_css_process_group_get_resource_bitmap( + const ia_css_process_group_t *process_group); + +/*! Set the resource bitmap of the process group + + @param process_group[in] process group object + @param resource_bitmap[in] the resource bitmap + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_resource_bitmap( + ia_css_process_group_t *process_group, + const vied_nci_resource_bitmap_t resource_bitmap); + +/*! Get the routing bitmap of the process group + + @param process_group[in] process group object + + @return routing bitmap (pointer) + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +const ia_css_rbm_t *ia_css_process_group_get_routing_bitmap( + const ia_css_process_group_t *process_group); + +/*! Set the routing bitmap of the process group + + @param process_group[in] process group object + @param rbm[in] routing bitmap + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_routing_bitmap( + ia_css_process_group_t *process_group, + const ia_css_rbm_t rbm); + +/*! Get IPU virtual address of process group + + @param process_group[in] process group object + @param ipu_vaddress[in/out] process group ipu virtual address + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_get_ipu_vaddress( + const ia_css_process_group_t *process_group, + vied_vaddress_t *ipu_vaddress); + +/*! Set IPU virtual address of process group + + @param process_group[in] process group object + @param ipu_vaddress[in] process group ipu address + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_ipu_vaddress( + ia_css_process_group_t *process_group, + vied_vaddress_t ipu_vaddress); + +/*! Get protocol version used by a process group + + @param process_group[in] process group object + + @return invalid protocol version on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_group_get_protocol_version( + const ia_css_process_group_t *process_group); + +/*! Get base queue id used by a process group + + @param process_group[in] process group object + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_group_get_base_queue_id( + ia_css_process_group_t *process_group); + +/*! Set base queue id used by a process group + + @param process_group[in] process group object + @param queue_id[in] process group queue id + + @return invalid queue id on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_base_queue_id( + ia_css_process_group_t *process_group, + uint8_t queue_id); + +/*! Get number of queues used by a process group + + @param process_group[in] process group object + + @return invalid number of queues (0) on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_process_group_get_num_queues( + ia_css_process_group_t *process_group); + +/*! Set number of queues used by a process group + + @param process_group[in] process group object + @param num_queues[in] process group number of queues + + @return -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_num_queues( + ia_css_process_group_t *process_group, + uint8_t num_queues); + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_process_group_has_vp(const ia_css_process_group_t *process_group); + +#ifdef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_process_group_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.kernel.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.kernel.h new file mode 100644 index 0000000000000..93cce2555de9f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.kernel.h @@ -0,0 +1,324 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_HSYS_KERNEL_H +#define __IA_CSS_PSYS_PROCESS_GROUP_HSYS_KERNEL_H + +/*! \file */ + +/** @file ia_css_psys_process_group.hsys.kernel.h + * + * Define the methods on the process group object: Hsys kernel interface + */ + +#include + +#include +#include + +#include /* uint8_t */ + +/* + * Registration of user contexts / callback info + */ + +/*! Get the user (callback) token as registered in the process group + + @param process_group[in] process group object + + @return 0 on error + */ +extern uint64_t ia_css_process_group_get_token( + ia_css_process_group_t *process_group); + +/*! Set (register) a user (callback) token in the process group + + @param process_group[in] process group object + @param token[in] user token + + Note: The token value shall be non-zero. This token is + returned in each return message related to the process + group the token is registered with. + + @return < 0 on error + */ +extern int ia_css_process_group_set_token( + ia_css_process_group_t *process_group, + const uint64_t token); + +/* + * Passing of a (fragment) watermark + */ + +/*! Get the fragment progress limit of the process group + + @param process_group[in] process group object + + @return 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint16_t ia_css_process_group_get_fragment_limit( + const ia_css_process_group_t *process_group); + +/*! Set the new fragment progress limit of the process group + + @param process_group[in] process group object + @param fragment_limit[in] New limit value + + Note: The limit value must be less or equal to the fragment + count value. The process group will not make progress beyond + the limit value. The limit value can be modified asynchronously + If the limit value is reached before an update happens, the + process group will suspend and will not automatically resume. + + The limit is monotonically increasing. The default value is + equal to the fragment count + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_fragment_limit( + ia_css_process_group_t *process_group, + const uint16_t fragment_limit); + +/*! Clear the fragment progress limit of the process group + + @param process_group[in] process group object + + Note: This function sets the fragment limit to zero. + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_clear_fragment_limit( + ia_css_process_group_t *process_group); + +/* + * Commands + */ + +/*! Perform the start command on the process group + + @param process_group[in] process group object + + Note: Start is an action of the l-Scheduler it makes the + process group eligible for execution + + Precondition: The external resources that are attached to + the process group must be in the correct state, i.e. input + buffers are not-empty and output buffers not-full + + @return < 0 on error + */ +extern int ia_css_process_group_start( + ia_css_process_group_t *process_group); + +/*! Perform the suspend command on the process group + + @param process_group[in] process group object + + Note: Suspend indicates that the process group execution + is halted at the next fragment boundary. The process group + will not automatically resume + + Precondition: The process group must be running + + @return < 0 on error + */ +extern int ia_css_process_group_suspend( + ia_css_process_group_t *process_group); + +/*! Perform the resume command on the process group + + @param process_group[in] process group object + + Note: Resume indicates that the process group is again + eligible for execution + + Precondition: The process group must be started + + @return < 0 on error + */ +extern int ia_css_process_group_resume( + ia_css_process_group_t *process_group); + +/*! Perform the reset command on the process group + + @param process_group[in] process group object + + Note: Return the process group to the started state + + Precondition: The process group must be running or stopped + + @return < 0 on error + */ +extern int ia_css_process_group_reset( + ia_css_process_group_t *process_group); + +/*! Perform the abort command on the process group + + @param process_group[in] process group object + + Note: Force the process group to the stopped state + + Precondition: The process group must be running or started + + @return < 0 on error + */ +extern int ia_css_process_group_abort( + ia_css_process_group_t *process_group); + +/*! Release ownership of the process group + + @param process_group[in] process group object + + Note: Release notifies PSYS and hands over ownership of the + process group from SW to FW + + Precondition: The process group must be in the started state + + @return < 0 on error + */ +extern int ia_css_process_group_disown( + ia_css_process_group_t *process_group); + +/* + * External resources + */ + +/*! Set (register) a data buffer to the indexed terminal in the process group + + @param process_group[in] process group object + @param buffer[in] buffer handle + @param buffer_state[in] state of the buffer + @param terminal_index[in] index of the terminal + + Note: The buffer handle shall not be VIED_NULL, the buffer + state can be undefined; BUFFER_UNDEFINED + + Note: The buffer can be in memory or streaming over memory + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_attach_buffer( + ia_css_process_group_t *process_group, + vied_vaddress_t buffer, + const ia_css_buffer_state_t buffer_state, + const unsigned int terminal_index); + +/*! Get (unregister) the data buffer on the indexed terminal of + * the process group + + @param process_group[in] process group object + @param terminal_index[in] index of the terminal + + Precondition: The process group must be stopped + + Postcondition: The buffer handle shall be reset to VIED_NULL, the buffer + state to BUFFER_NULL + + @return VIED_NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_vaddress_t ia_css_process_group_detach_buffer( + ia_css_process_group_t *process_group, + const unsigned int terminal_index); + +/*! Set (register) a data buffer to the indexed terminal in the process group + + @param process_group[in] process group object + @param stream[in] stream handle + @param buffer_state[in] state of the buffer + @param terminal_index[in] index of the terminal + + Note: The stream handle shall not be zero, the buffer + state can be undefined; BUFFER_UNDEFINED + + Note: The stream is used exclusive to a buffer; the latter can be in memory + or streaming over memory + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_attach_stream( + ia_css_process_group_t *process_group, + uint32_t stream, + const ia_css_buffer_state_t buffer_state, + const unsigned int terminal_index); + +/*! Get (unregister) the stream handle on the indexed terminal of + * the process group + + @param process_group[in] process group object + @param terminal_index[in] index of the terminal + + Precondition: The process group must be stopped + + Postcondition: The stream handle shall be reset to zero, the buffer + state to BUFFER_NULL + + @return 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_detach_stream( + ia_css_process_group_t *process_group, + const unsigned int terminal_index); + +/* + * Sequencing resources + */ + +/*! Set a(n artificial) blocking resource (barrier) in + * the process group resource map + + @param process_group[in] process group object + @param barrier_index[in] index of the barrier + + Note: The barriers have to be set to force sequence between started + process groups + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_set_barrier( + ia_css_process_group_t *process_group, + const vied_nci_barrier_ID_t barrier_index); + +/*! Clear a previously set blocking resource (barrier) in + * the process group resource map + + @param process_group[in] process group object + @param barrier_index[in] index of the barrier + + Precondition: The barriers must have been set + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_clear_barrier( + ia_css_process_group_t *process_group, + const vied_nci_barrier_ID_t barrier_index); + +/*! Boolean test if the process group preconditions for start are satisfied + + @param process_group[in] process group object + + @return true if the process group can be started + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_can_process_group_start( + const ia_css_process_group_t *process_group); + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_HSYS_KERNEL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.user.h new file mode 100644 index 0000000000000..dfbcc8815c1ef --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.hsys.user.h @@ -0,0 +1,199 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_HSYS_USER_H +#define __IA_CSS_PSYS_PROCESS_GROUP_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_process_group.hsys.user.h + * + * Define the methods on the process group object: Hsys user interface + */ + +#include /* ia_css_program_group_param_t */ + +#include +#include +#include + +#include "ia_css_psys_dynamic_storage_class.h" + +#include /* uint8_t */ + +/* + * Creation + */ + +/*! Compute the size of storage required for allocating the process group object + + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return 0 on error + */ +extern size_t ia_css_sizeof_process_group( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Create (the storage for) the process group object + + @param process_grp_mem[in/out] raw memory for process group + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return NULL on error + */ +extern ia_css_process_group_t *ia_css_process_group_create( + void *process_grp_mem, + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Destroy (the storage of) the process group object + + @param process_group[in] process group object + + @return NULL + */ +extern ia_css_process_group_t *ia_css_process_group_destroy( + ia_css_process_group_t *process_group); + +/*! Print the process group object to file/stream + + @param process_group[in] process group object + @param fid[out] file/stream handle + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_process_group_print( + const ia_css_process_group_t *process_group, + void *fid); + +/* + * Commands + */ + +/*! Perform the submit command on the process group + + @param process_group[in] process group object + + Note: Submit is an action of the h-Scheduler it makes the + process group eligible for the l-Scheduler + + Precondition: The external resources must be attached to + the process group + + @return < 0 on error + */ +extern int ia_css_process_group_submit( + ia_css_process_group_t *process_group); + +/*! Boolean test if the process group object type is valid + + @param process_group[in] process group object + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return true if the process group is correct, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_process_group_valid( + const ia_css_process_group_t *process_group, + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Boolean test if the process group preconditions for submit are satisfied + + @param process_group[in] process group object + + @return true if the process group can be submitted + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_can_process_group_submit( + const ia_css_process_group_t *process_group); + +/*! Boolean test if the preconditions on process group and buffer set are + satisfied for enqueuing buffer set + + @param process_group[in] process group object + @param buffer_set[in] buffer set object + + @return true if the buffer set can be enqueued + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_can_enqueue_buffer_set( + const ia_css_process_group_t *process_group, + const ia_css_buffer_set_t *buffer_set); + +/*! Compute the cyclecount required for executing the process group object + + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint32_t ia_css_process_group_compute_cycle_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Compute the number of processes required for + * executing the process group object + + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return 0 on error + */ +extern uint8_t ia_css_process_group_compute_process_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Compute the number of terminals required for + * executing the process group object + + @param manifest[in] program group manifest + @param param[in] program group parameters + + @return 0 on error + */ +extern uint8_t ia_css_process_group_compute_terminal_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Get private token as registered in the process group by the implementation + + @param process_group[in] process group object + + @return 0 on error + */ +extern uint64_t ia_css_process_group_get_private_token( + ia_css_process_group_t *process_group); + +/*! Set private token in the process group as needed by the implementation + + @param process_group[in] process group object + @param token[in] user token + + Note: The token value shall be non-zero. This token is private + to the implementation. This is in addition to the user token + + @return < 0 on error, 0 on success + */ +extern int ia_css_process_group_set_private_token( + ia_css_process_group_t *process_group, + const uint64_t token); + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.psys.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.psys.h new file mode 100644 index 0000000000000..6ceccfc2f9bc3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group.psys.h @@ -0,0 +1,60 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_PSYS_H +#define __IA_CSS_PSYS_PROCESS_GROUP_PSYS_H + +/*! \file */ + +/** @file ia_css_psys_process_group.psys.h + * + * Define the methods on the process group object: Psys embedded interface + */ + +#include + +/* + * Dispatcher + */ + +/*! Perform the run command on the process group + + @param process_group[in] process group object + + Note: Run indicates that the process group will execute + + Precondition: The process group must be started or + suspended and the processes have acquired the necessary + internal resources + + @return < 0 on error + */ +extern int ia_css_process_group_run( + ia_css_process_group_t *process_group); + +/*! Perform the stop command on the process group + + @param process_group[in] process group object + + Note: Stop indicates that the process group has completed execution + + Postcondition: The external resoruces can now be detached + + @return < 0 on error + */ +extern int ia_css_process_group_stop( + ia_css_process_group_t *process_group); + + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_PSYS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group_cmd_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group_cmd_impl.h new file mode 100644 index 0000000000000..530f93ef6ce03 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_group_cmd_impl.h @@ -0,0 +1,178 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_CMD_IMPL_H +#define __IA_CSS_PSYS_PROCESS_GROUP_CMD_IMPL_H + +#include "type_support.h" +#include "ia_css_psys_process_group.h" +#include "ia_css_rbm_manifest_types.h" + +#define N_UINT64_IN_PROCESS_GROUP_STRUCT 2 +#define N_UINT32_IN_PROCESS_GROUP_STRUCT 5 +#define N_UINT16_IN_PROCESS_GROUP_STRUCT 5 +#define N_UINT8_IN_PROCESS_GROUP_STRUCT 7 +#define N_PADDING_UINT8_IN_PROCESS_GROUP_STRUCT 3 + +#define SIZE_OF_PROCESS_GROUP_STRUCT_BITS \ + (IA_CSS_RBM_BITS \ + + N_UINT64_IN_PROCESS_GROUP_STRUCT * IA_CSS_UINT64_T_BITS \ + + N_UINT32_IN_PROCESS_GROUP_STRUCT * IA_CSS_UINT32_T_BITS \ + + IA_CSS_PROGRAM_GROUP_ID_BITS \ + + IA_CSS_PROCESS_GROUP_STATE_BITS \ + + VIED_VADDRESS_BITS \ + + VIED_NCI_RESOURCE_BITMAP_BITS \ + + N_UINT16_IN_PROCESS_GROUP_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_UINT8_IN_PROCESS_GROUP_STRUCT * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_PROCESS_GROUP_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_process_group_s { + /**< User (callback) token / user context reference, + * zero is an error value + */ + uint64_t token; + /**< private token / context reference, zero is an error value */ + uint64_t private_token; + /**< PG routing bitmap used to set connection between programs >*/ + ia_css_rbm_t routing_bitmap; + /**< Size of this structure */ + uint32_t size; + /**< The timestamp when PG load starts */ + uint32_t pg_load_start_ts; + /**< PG load time in cycles */ + uint32_t pg_load_cycles; + /**< PG init time in cycles */ + uint32_t pg_init_cycles; + /**< PG processing time in cycles */ + uint32_t pg_processing_cycles; + /**< Referral ID to program group FW */ + ia_css_program_group_ID_t ID; + /**< State of the process group FSM */ + ia_css_process_group_state_t state; + /**< Virtual address of process group in IPU */ + vied_vaddress_t ipu_virtual_address; + /**< Bitmap of the compute resources used by the process group */ + vied_nci_resource_bitmap_t resource_bitmap; + /**< Number of fragments offered on each terminal */ + uint16_t fragment_count; + /**< Current fragment of processing */ + uint16_t fragment_state; + /**< Watermark to control fragment processing */ + uint16_t fragment_limit; + /**< Array[process_count] of process addresses in this process group */ + uint16_t processes_offset; + /**< Array[terminal_count] of terminal addresses on this process group */ + uint16_t terminals_offset; + /**< Parameter dependent number of processes in this process group */ + uint8_t process_count; + /**< Parameter dependent number of terminals on this process group */ + uint8_t terminal_count; + /**< Parameter dependent number of independent subgraphs in + * this process group + */ + uint8_t subgraph_count; + /**< Process group protocol version */ + uint8_t protocol_version; + /**< Dedicated base queue id used for enqueueing payload buffer sets */ + uint8_t base_queue_id; + /**< Number of dedicated queues used */ + uint8_t num_queues; + /**< Mask the send_pg_done IRQ */ + uint8_t mask_irq; + /**< Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_PROCESS_GROUP_STRUCT]; +}; + +/*! Callback after process group is created. Implementations can provide + * suitable actions needed when process group is created. + + @param process_group[in] process group object + @param program_group_manifest[in] program group manifest + @param program_group_param[in] program group parameters + + @return 0 on success and non-zero on failure + */ +extern int ia_css_process_group_on_create( + ia_css_process_group_t *process_group, + const ia_css_program_group_manifest_t *program_group_manifest, + const ia_css_program_group_param_t *program_group_param); + +/*! Callback before process group is about to be destoyed. Any implementation + * specific cleanups can be done here. + + @param process_group[in] process group object + + @return 0 on success and non-zero on failure + */ +extern int ia_css_process_group_on_destroy( + ia_css_process_group_t *process_group); + +/* + * Command processor + */ + +/*! Execute a command locally or send it to be processed remotely + + @param process_group[in] process group object + @param cmd[in] command + + @return < 0 on error + */ +extern int ia_css_process_group_exec_cmd( + ia_css_process_group_t *process_group, + const ia_css_process_group_cmd_t cmd); + + +/*! Enqueue a buffer set corresponding to a persistent program group by + * sending a command to subsystem. + + @param process_group[in] process group object + @param buffer_set[in] buffer set + @param queue_offset[in] offset to be used from the queue id + specified in the process group object + (0 for first buffer set for frame, 1 + for late binding) + + @return < 0 on error + */ +extern int ia_css_enqueue_buffer_set( + ia_css_process_group_t *process_group, + ia_css_buffer_set_t *buffer_set, + unsigned int queue_offset); + +/*! Enqueue a parameter buffer set corresponding to a persistent program + * group by sending a command to subsystem. + + @param process_group[in] process group object + @param buffer_set[in] parameter buffer set + + @return < 0 on error + */ +extern int ia_css_enqueue_param_buffer_set( + ia_css_process_group_t *process_group, + ia_css_buffer_set_t *buffer_set); + +/*! Need to store the 'secure' mode for each PG for FW test app only + * + * @param process_group[in] process group object + * @param secure[in] parameter buffer set + * + * @return < 0 on error + */ +extern int ia_css_process_group_store( + ia_css_process_group_t *process_group, + bool secure); + + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_CMD_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_types.h new file mode 100644 index 0000000000000..4fb064dc00df6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_process_types.h @@ -0,0 +1,95 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_TYPES_H +#define __IA_CSS_PSYS_PROCESS_TYPES_H + +/*! \file */ + +/** @file ia_css_psys_process_types.h + * + * The types belonging to the terminal/process/process group dynamic module + */ + +#include +#include + +#include + +#define IA_CSS_PROCESS_INVALID_PROGRAM_IDX ((uint32_t)-1) + +/* private */ +typedef enum ia_css_process_group_cmd { + IA_CSS_PROCESS_GROUP_CMD_NOP = 0, + IA_CSS_PROCESS_GROUP_CMD_SUBMIT, + IA_CSS_PROCESS_GROUP_CMD_ATTACH, + IA_CSS_PROCESS_GROUP_CMD_DETACH, + IA_CSS_PROCESS_GROUP_CMD_START, + IA_CSS_PROCESS_GROUP_CMD_DISOWN, + IA_CSS_PROCESS_GROUP_CMD_RUN, + IA_CSS_PROCESS_GROUP_CMD_STOP, + IA_CSS_PROCESS_GROUP_CMD_SUSPEND, + IA_CSS_PROCESS_GROUP_CMD_RESUME, + IA_CSS_PROCESS_GROUP_CMD_ABORT, + IA_CSS_PROCESS_GROUP_CMD_RESET, + IA_CSS_N_PROCESS_GROUP_CMDS +} ia_css_process_group_cmd_t; + +/* private */ +#define IA_CSS_PROCESS_GROUP_STATE_BITS 32 +typedef enum ia_css_process_group_state { + IA_CSS_PROCESS_GROUP_ERROR = 0, + IA_CSS_PROCESS_GROUP_CREATED, + IA_CSS_PROCESS_GROUP_READY, + IA_CSS_PROCESS_GROUP_BLOCKED, + IA_CSS_PROCESS_GROUP_STARTED, + IA_CSS_PROCESS_GROUP_RUNNING, + IA_CSS_PROCESS_GROUP_STALLED, + IA_CSS_PROCESS_GROUP_STOPPED, + IA_CSS_N_PROCESS_GROUP_STATES +} ia_css_process_group_state_t; + +/* private */ +typedef enum ia_css_process_cmd { + IA_CSS_PROCESS_CMD_NOP = 0, + IA_CSS_PROCESS_CMD_ACQUIRE, + IA_CSS_PROCESS_CMD_RELEASE, + IA_CSS_PROCESS_CMD_START, + IA_CSS_PROCESS_CMD_LOAD, + IA_CSS_PROCESS_CMD_STOP, + IA_CSS_PROCESS_CMD_SUSPEND, + IA_CSS_PROCESS_CMD_RESUME, + IA_CSS_N_PROCESS_CMDS +} ia_css_process_cmd_t; + +/* private */ +#define IA_CSS_PROCESS_STATE_BITS 32 +typedef enum ia_css_process_state { + IA_CSS_PROCESS_ERROR = 0, + IA_CSS_PROCESS_CREATED, + IA_CSS_PROCESS_READY, + IA_CSS_PROCESS_STARTED, + IA_CSS_PROCESS_RUNNING, + IA_CSS_PROCESS_STOPPED, + IA_CSS_PROCESS_SUSPENDED, + IA_CSS_N_PROCESS_STATES +} ia_css_process_state_t; + +/* public */ +typedef struct ia_css_process_group_s ia_css_process_group_t; +typedef struct ia_css_process_s ia_css_process_t; + +typedef struct ia_css_data_terminal_s ia_css_data_terminal_t; + +#endif /* __IA_CSS_PSYS_PROCESS_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.h new file mode 100644 index 0000000000000..7a164cd41b8fe --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.h @@ -0,0 +1,316 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_H +#define __IA_CSS_PSYS_TERMINAL_H + +/*! \file */ + +/** @file ia_css_psys_terminal.h + * + * Define the methods on the terminal object that are not part of + * a single interface + */ + +#include /* ia_css_frame_t */ +#include /* ia_css_program_group_param_t */ + +#include +#include + +#include /* bool */ +#include /* FILE */ +#include "ia_css_psys_dynamic_storage_class.h" +#include "ia_css_terminal.h" +#include "ia_css_terminal_manifest_base_types.h" + +/* + * Creation + */ +#include + +/*! Boolean test if the terminal object type is input + + @param terminal[in] terminal object + + @return true if the terminal is input, false otherwise or on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_input( + const ia_css_terminal_t *terminal); + +/*! Get the stored size of the terminal object + + @param terminal[in] terminal object + + @return size, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +size_t ia_css_terminal_get_size( + const ia_css_terminal_t *terminal); + +/*! Get the type of the terminal object + + @param terminal[in] terminal object + + @return the type of the terminal, limit value on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_terminal_type_t ia_css_terminal_get_type( + const ia_css_terminal_t *terminal); + +/*! Set the type of the terminal object + + @param terminal[in] terminal object + @param terminal_type[in] type of the terminal + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_terminal_set_type( + ia_css_terminal_t *terminal, + const ia_css_terminal_type_t terminal_type); + +/*! Get the index of the terminal manifest object + + @param terminal[in] terminal object + + @return the index of the terminal manifest object, limit value on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint16_t ia_css_terminal_get_terminal_manifest_index( + const ia_css_terminal_t *terminal); + +/*! Set the index of the terminal manifest object + + @param terminal[in] terminal object + @param tm_index[in] terminal manifest index + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_terminal_set_terminal_manifest_index( + ia_css_terminal_t *terminal, + const uint16_t tm_index); + +/*! Get id of the terminal object + + @param terminal[in] terminal object + + @return id of terminal + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_terminal_ID_t ia_css_terminal_get_ID( + const ia_css_terminal_t *terminal); + +/*! Get kernel id of the data terminal object + + @param dterminal[in] data terminal object + + @return kernel id of terminal + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_data_terminal_get_kernel_id( + const ia_css_data_terminal_t *dterminal); + +/*! Get the connection type from the terminal object + + @param terminal[in] terminal object + + @return buffer type, limit value on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_connection_type_t ia_css_data_terminal_get_connection_type( + const ia_css_data_terminal_t *dterminal); + +/*! Set the connection type of the terminal object + + @param terminal[in] terminal object + @param connection_type[in] connection type + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_data_terminal_set_connection_type( + ia_css_data_terminal_t *dterminal, + const ia_css_connection_type_t connection_type); + +/*! Get link id of the data terminal object + + @param dterminal[in] data terminal object + + @return link id of terminal + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_data_terminal_get_link_id( + const ia_css_data_terminal_t *dterminal); + + +/*! Set link id of the terminal object + + @param terminal[in] data terminal object + @param link_id[in] synchronization link id + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_data_terminal_set_link_id( + ia_css_data_terminal_t *dterminal, + const uint8_t link_id); + +/*! Get the (pointer to) the process group parent of the terminal object + + @param terminal[in] terminal object + + @return the pointer to the parent, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_process_group_t *ia_css_terminal_get_parent( + const ia_css_terminal_t *terminal); + +/*! Set the (pointer to) the process group parent of the terminal object + + @param terminal[in] terminal object + @param parent[in] (pointer to the) process group parent object + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_terminal_set_parent( + ia_css_terminal_t *terminal, + ia_css_process_group_t *parent); + +/*! Boolean test if the terminal object type is valid + + @param terminal[in] process terminal object + @param terminal_manifest[in] program terminal manifest + + @return true if the process terminal object is correct, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_valid( + const ia_css_terminal_t *terminal, + const ia_css_terminal_manifest_t *terminal_manifest); + +/* ================= Program Control Init Terminal - START ================= */ + +/*! + * Gets the program init terminal descripor size + * @param manifest[in] program control init terminal manifest + * @return size, error if < 0. + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +unsigned int +ia_css_program_control_init_terminal_get_descriptor_size( + const ia_css_program_control_init_terminal_manifest_t *manifest); + +/*! + * Initialize program control init terminal + * @param nof_fragments[in] Number of fragments + * @param terminal[in] program control init terminal + * @param manifest[in] program control init terminal manifest + * @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int +ia_css_program_control_init_terminal_init( + ia_css_program_control_init_terminal_t *terminal, + const ia_css_program_control_init_terminal_manifest_t *manifest); + +/*! + * Get a program desc for a program control init terminal + * @param terminal[in] program control init terminal + * @param manifest[in] program control init terminal manifest + * @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_program_control_init_program_desc_t * +ia_css_program_control_init_terminal_get_program_desc( + const ia_css_program_control_init_terminal_t *prog_ctrl_init_terminal, + const unsigned int program_index +); + +/*! + * Pretty prints the program control init termnial + * @param terminal[in] program control init terminal + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +void ia_css_program_control_init_terminal_print( + const ia_css_program_control_init_terminal_t *terminal); + +/*! + * Gets a load section desc for a program desc + * of a program control init terminal + * @param program_desc[in] program control init terminal program desc + * @param load_section_index[in] section index + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_program_control_init_load_section_desc_t * +ia_css_program_control_init_terminal_get_load_section_desc( + const ia_css_program_control_init_program_desc_t *program_desc, + const unsigned int load_section_index +); + +/*! + * Gets process_id from program desc + * of a program control init terminal + * @param program_desc[in] program control init terminal program desc + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_id_t ia_css_program_control_init_terminal_get_process_id( + const ia_css_program_control_init_program_desc_t *program_desc); + +/*! + * Set control info of program desc + * of a program control init terminal + * @param program_desc[in] program control init terminal program desc + * @param process_id unique process id used to identify the process + * among all active process + * @param num_done_events number of events required to close the process + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +void ia_css_program_control_init_terminal_set_control_info( + ia_css_program_control_init_program_desc_t *program_desc, + ia_css_process_id_t process_id, + uint8_t num_done_events); + +/*! + * Gets num_done_events value from program desc + * of a program control init terminal + * @param program_desc[in] program control init terminal program desc + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_program_control_init_terminal_get_num_done_events( + const ia_css_program_control_init_program_desc_t *program_desc); + +/*! + * Gets a connect section desc for a program desc + * of a program control init terminal + * @param program_desc[in] program control init terminal program desc + * @param connect_section_index[in] section index + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_program_control_init_connect_section_desc_t * +ia_css_program_control_init_terminal_get_connect_section_desc( + const ia_css_program_control_init_program_desc_t *program_desc, + const unsigned int connect_section_index +); + +/* ================= Program Control Init Terminal - END ================= */ + +#ifdef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_terminal_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +#endif /* __IA_CSS_PSYS_TERMINAL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.hsys.user.h new file mode 100644 index 0000000000000..b8aa08c19754a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/interface/ia_css_psys_terminal.hsys.user.h @@ -0,0 +1,255 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_HSYS_USER_H +#define __IA_CSS_PSYS_TERMINAL_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_terminal.hsys.user.h + * + * Define the methods on the terminal object: Hsys user interface + */ + +#include /* ia_css_frame_t */ +#include /* ia_css_program_group_param_t */ + +#include +#include + +#include /* bool */ +#include "ia_css_psys_dynamic_storage_class.h" +#include "ia_css_terminal.h" +#include "ia_css_terminal_manifest.h" +#include "ia_css_kernel_bitmap.h" + +/* + * Creation + */ + +/* + * This source file is created with the intention of sharing and + * compiled for host and firmware. Since there is no native 64bit + * data type support for firmware this wouldn't compile for SP + * tile. The part of the file that is not compilable are marked + * with the following __VIED_CELL marker and this comment. Once we + * come up with a solution to address this issue this will be + * removed. + */ +#if !defined(__VIED_CELL) +/*! Compute the size of storage required for allocating the terminal object + + @param manifest[in] terminal manifest + @param param[in] program group parameters + + @return 0 on error + */ +extern size_t ia_css_sizeof_terminal( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Create the terminal object + + @param raw_mem[in] pre allocated memory + @param manifest[in] terminal manifest + @param terminal_param[in] terminal parameter + @param enable_bitmap program group enable bitmap + + @return NULL on error + */ +extern ia_css_terminal_t *ia_css_terminal_create( + void *raw_mem, + const ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_param_t *terminal_param, + ia_css_kernel_bitmap_t enable_bitmap); + +/*! Destroy (the storage of) the process object + + @param terminal[in] terminal object + + @return NULL + */ +extern ia_css_terminal_t *ia_css_terminal_destroy( + ia_css_terminal_t *terminal); +#endif /* !defined(__VIED_CELL) */ + +/*! Print the terminal object to file/stream + + @param terminal[in] terminal object + @param fid[out] file/stream handle + + @return < 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_terminal_print( + const ia_css_terminal_t *terminal, + void *fid); + +/*! Get the (pointer to) the frame object in the terminal object + + @param terminal[in] terminal object + + @return the pointer to the frame, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_frame_t *ia_css_data_terminal_get_frame( + const ia_css_data_terminal_t *terminal); + +/*! Get the (pointer to) the frame descriptor object in the terminal object + + @param terminal[in] terminal object + + @return the pointer to the frame descriptor, NULL on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_frame_descriptor_t *ia_css_data_terminal_get_frame_descriptor( + const ia_css_data_terminal_t *dterminal); + +/*! Get the (pointer to) the fragment descriptor object in the terminal object + + @param terminal[in] terminal object + +@return the pointer to the fragment descriptor, NULL on error +*/ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +ia_css_fragment_descriptor_t + *ia_css_data_terminal_get_fragment_descriptor( + const ia_css_data_terminal_t *dterminal, + const unsigned int fragment_index); + +/*! Get the number of fragments on the terminal + + @param terminal[in] terminal object + + @return the fragment count, 0 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint16_t ia_css_data_terminal_get_fragment_count( + const ia_css_data_terminal_t *dterminal); + +/*! Get the number of section on the (param)terminal + @param manifest[in] terminal manifest + @param terminal_param[in] terminal parameter + + @return the section count, 0 on error + */ +extern uint16_t ia_css_param_terminal_compute_section_count( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! Get the number of planes on the (data)terminal + @param manifest[in] terminal manifest + @param terminal_param[in] terminal parameter + + @return the plane count, 1(default) on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +uint8_t ia_css_data_terminal_compute_plane_count( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param); + +/*! check if given terminal is parameter terminal. + + @param terminal[in] (base)terminal object + + @return true on success, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_parameter_terminal( + const ia_css_terminal_t *terminal); + +/*! check if given terminal is program terminal. + + @program terminal[in] (base)terminal object + + @return true on success, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_program_terminal( + const ia_css_terminal_t *terminal); + +/*! check if given terminal is program control init terminal. + + @program control init terminal[in] (base)terminal object + + @return true on success, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_program_control_init_terminal( + const ia_css_terminal_t *terminal); + +/*! check if given terminal is spatial parameter terminal. + + @spatial terminal[in] (base)terminal object + + @return true on success, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_spatial_parameter_terminal( + const ia_css_terminal_t *terminal); + +/*! check if given terminal is data terminal. + + @param terminal[in] (base)terminal object + + @return true on success, false on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +bool ia_css_is_terminal_data_terminal( + const ia_css_terminal_t *terminal); + +/*! obtain buffer out of terminal(both data & param terminals can call this) + + @param terminal[in] (base)terminal object of either data or param terminal. + + @return vied address of buffer stored in terminal + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +vied_vaddress_t ia_css_terminal_get_buffer( + const ia_css_terminal_t *terminal); + +/*!store a buffer in the terminal. + + @param terminal[in] (base)terminal object of either data or param terminal. + @param buffer[in] buffer in vied (hrt address) space. + + @return 0 on success + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_H +int ia_css_terminal_set_buffer(ia_css_terminal_t *terminal, + vied_vaddress_t buffer); + +/*! Obtain terminal buffer index out of terminal object + + @param terminal[in] (base)terminal object of either data or param terminal. + + @return terminal buffer index stored in terminal object on success, -1 on error + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_get_terminal_index( + const ia_css_terminal_t *terminal); + +/*! Store a terminal buffer index in the terminal object + + @param terminal[in] (base)terminal object of either data or param terminal. + @param terminal_index[in] terminal buffer index + + @return 0 on success + */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_terminal_index( + ia_css_terminal_t *terminal, + unsigned int terminal_index); + +#endif /* __IA_CSS_PSYS_TERMINAL_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set.c new file mode 100644 index 0000000000000..82d53831f9a98 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set.c @@ -0,0 +1,111 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "assert_support.h" +#include "ia_css_psys_dynamic_trace.h" +#include "ia_css_psys_buffer_set.h" +#include "ia_css_psys_process_group.h" + +/* + * Functions to possibly inline + */ +#ifndef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_buffer_set_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +STORAGE_CLASS_INLINE void __buffer_set_dummy_check_alignment(void) +{ + COMPILATION_ERROR_IF(SIZE_OF_BUFFER_SET != + CHAR_BIT * sizeof(ia_css_buffer_set_t)); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_buffer_set_t) % sizeof(uint64_t)); +} + +/* + * Functions not to inline + */ + +/* The below functions are not to be compiled for firmware */ +#if !defined(__HIVECC) + +ia_css_buffer_set_t *ia_css_buffer_set_create( + void *buffer_set_mem, + const ia_css_process_group_t *process_group, + const unsigned int frame_counter) +{ + ia_css_buffer_set_t *buffer_set = NULL; + unsigned int i; + int ret = -1; + + verifexit(buffer_set_mem != NULL); + verifexit(process_group != NULL); + + buffer_set = (ia_css_buffer_set_t *)buffer_set_mem; + + /* + * Set base struct members + */ + buffer_set->ipu_virtual_address = VIED_NULL; + ia_css_process_group_get_ipu_vaddress(process_group, + &buffer_set->process_group_handle); + buffer_set->frame_counter = frame_counter; + buffer_set->terminal_count = + ia_css_process_group_get_terminal_count(process_group); + + /* + * Initialize adjacent buffer addresses + */ + for (i = 0; i < buffer_set->terminal_count; i++) { + vied_vaddress_t *buffer = + (vied_vaddress_t *)( + (char *)buffer_set + + sizeof(ia_css_buffer_set_t) + + sizeof(vied_vaddress_t) * i); + + *buffer = VIED_NULL; + } + ret = 0; + +EXIT: + if (ret != 0) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_create failed\n"); + } + return buffer_set; +} + +size_t ia_css_sizeof_buffer_set( + const ia_css_process_group_t *process_group) +{ + size_t size = 0; + + verifexit(process_group != NULL); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_sizeof_buffer_set(): enter:\n"); + + size = sizeof(ia_css_buffer_set_t) + + ia_css_process_group_get_terminal_count(process_group) * + sizeof(vied_vaddress_t); + +EXIT: + if (size == 0) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_sizeof_buffer_set failed\n"); + } + return size; +} + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set_impl.h new file mode 100644 index 0000000000000..0399d76f33315 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_buffer_set_impl.h @@ -0,0 +1,241 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_PSYS_BUFFER_SET_IMPL_H +#define __IA_CSS_PSYS_BUFFER_SET_IMPL_H + +#include "error_support.h" +#include "ia_css_psys_dynamic_trace.h" +#include "vied_nci_psys_system_global.h" +#include "ia_css_psys_terminal.hsys.user.h" + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_buffer_set_set_buffer( + ia_css_buffer_set_t *buffer_set, + const unsigned int terminal_index, + const vied_vaddress_t buffer) +{ + DECLARE_ERRVAL + vied_vaddress_t *buffer_ptr; + int ret = -1; + + verifexitval(buffer_set != NULL, EFAULT); + verifexitval(terminal_index < buffer_set->terminal_count, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_set_buffer(): enter:\n"); + + /* + * Set address in buffer set object + */ + buffer_ptr = + (vied_vaddress_t *)( + (char *)buffer_set + + sizeof(ia_css_buffer_set_t) + + terminal_index * sizeof(vied_vaddress_t)); + *buffer_ptr = buffer; + + ret = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_set_buffer: invalid argument\n"); + } + return ret; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_vaddress_t ia_css_buffer_set_get_buffer( + const ia_css_buffer_set_t *buffer_set, + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + vied_vaddress_t buffer = VIED_NULL; + vied_vaddress_t *buffer_ptr; + int terminal_index; + + verifexitval(buffer_set != NULL, EFAULT); + verifexitval(terminal != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_get_buffer(): enter:\n"); + + /* + * Retrieve terminal index from terminal object + */ + terminal_index = ia_css_terminal_get_terminal_index(terminal); + verifexitval(terminal_index >= 0, EFAULT); + verifexitval(terminal_index < buffer_set->terminal_count, EFAULT); + + /* + * Retrieve address from buffer set object + */ + buffer_ptr = + (vied_vaddress_t *)( + (char *)buffer_set + + sizeof(ia_css_buffer_set_t) + + terminal_index * sizeof(vied_vaddress_t)); + buffer = *buffer_ptr; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_get_buffer: invalid argument\n"); + } + return buffer; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_buffer_set_set_ipu_address( + ia_css_buffer_set_t *buffer_set, + const vied_vaddress_t ipu_vaddress) +{ + DECLARE_ERRVAL + int ret = -1; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_set_ipu_address(): enter:\n"); + + buffer_set->ipu_virtual_address = ipu_vaddress; + + ret = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_set_ipu_address invalid argument\n"); + } + return ret; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_vaddress_t ia_css_buffer_set_get_ipu_address( + const ia_css_buffer_set_t *buffer_set) +{ + DECLARE_ERRVAL + vied_vaddress_t ipu_virtual_address = VIED_NULL; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_get_ipu_address(): enter:\n"); + + ipu_virtual_address = buffer_set->ipu_virtual_address; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_get_ipu_address: invalid argument\n"); + } + return ipu_virtual_address; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_buffer_set_set_process_group_handle( + ia_css_buffer_set_t *buffer_set, + const vied_vaddress_t process_group_handle) +{ + DECLARE_ERRVAL + int ret = -1; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_set_process_group_context(): enter:\n"); + + buffer_set->process_group_handle = process_group_handle; + + ret = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_set_process_group_context invalid argument\n"); + } + return ret; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_vaddress_t ia_css_buffer_set_get_process_group_handle( + const ia_css_buffer_set_t *buffer_set) +{ + DECLARE_ERRVAL + vied_vaddress_t process_group_handle = VIED_NULL; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_get_process_group_handle(): enter:\n"); + + process_group_handle = buffer_set->process_group_handle; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_get_process_group_handle: invalid argument\n"); + } + return process_group_handle; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_buffer_set_set_token( + ia_css_buffer_set_t *buffer_set, + const uint64_t token) +{ + DECLARE_ERRVAL + int ret = -1; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_set_token(): enter:\n"); + + buffer_set->token = token; + + ret = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_set_token invalid argument\n"); + } + return ret; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint64_t ia_css_buffer_set_get_token( + const ia_css_buffer_set_t *buffer_set) +{ + DECLARE_ERRVAL + uint64_t token = 0; + + verifexitval(buffer_set != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_buffer_set_get_token(): enter:\n"); + + token = buffer_set->token; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_buffer_set_get_token: invalid argument\n"); + } + return token; +} + +#endif /* __IA_CSS_PSYS_BUFFER_SET_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process.c new file mode 100644 index 0000000000000..04a837cb60f22 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process.c @@ -0,0 +1,1148 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_process.h" +#include "ia_css_psys_dynamic_storage_class.h" +#include "ia_css_psys_process_private_types.h" +#include /* for NOT_USED */ + +/* + * Functions to possibly inline + */ + +#ifndef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_process_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +/* + * Functions not to inline + */ + +/* This source file is created with the intention of sharing and + * compiled for host and firmware. Since there is no native 64bit + * data type support for firmware this wouldn't compile for SP + * tile. The part of the file that is not compilable are marked + * with the following __HIVECC marker and this comment. Once we + * come up with a solution to address this issue this will be + * removed. + */ +#if !defined(__HIVECC) +size_t ia_css_sizeof_process( + const ia_css_program_manifest_t *manifest, + const ia_css_program_param_t *param) +{ + size_t size = 0, tmp_size; + + uint8_t program_dependency_count; + uint8_t terminal_dependency_count; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_sizeof_process(): enter:\n"); + + COMPILATION_ERROR_IF( + SIZE_OF_PROCESS_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_process_t))); + + COMPILATION_ERROR_IF(0 != sizeof(ia_css_process_t)%sizeof(uint64_t)); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + size += sizeof(ia_css_process_t); + + program_dependency_count = + ia_css_program_manifest_get_program_dependency_count(manifest); + terminal_dependency_count = + ia_css_program_manifest_get_terminal_dependency_count(manifest); + + tmp_size = program_dependency_count*sizeof(vied_nci_resource_id_t); + size += tot_bytes_for_pow2_align(sizeof(uint64_t), tmp_size); + tmp_size = terminal_dependency_count*sizeof(uint8_t); + size += tot_bytes_for_pow2_align(sizeof(uint64_t), tmp_size); + +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_sizeof_process invalid argument\n"); + } + return size; +} + +ia_css_process_t *ia_css_process_create( + void *raw_mem, + const ia_css_program_manifest_t *manifest, + const ia_css_program_param_t *param, + const uint32_t program_idx) +{ + size_t tmp_size; + int retval = -1; + ia_css_process_t *process = NULL; + char *process_raw_ptr = (char *) raw_mem; + + /* size_t size = ia_css_sizeof_process(manifest, param); */ + uint8_t program_dependency_count; + uint8_t terminal_dependency_count; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_create(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(param != NULL); + verifexit(process_raw_ptr != NULL); + + process = (ia_css_process_t *) process_raw_ptr; + verifexit(process != NULL); + + process->kernel_bitmap = + ia_css_program_manifest_get_kernel_bitmap(manifest); + process->state = IA_CSS_PROCESS_CREATED; + + program_dependency_count = + ia_css_program_manifest_get_program_dependency_count(manifest); + terminal_dependency_count = + ia_css_program_manifest_get_terminal_dependency_count(manifest); + + /* A process requires at least one input or output */ + verifexit((program_dependency_count + + terminal_dependency_count) != 0); + + process_raw_ptr += sizeof(ia_css_process_t); + if (program_dependency_count != 0) { + process->cell_dependencies_offset = + (uint16_t) (process_raw_ptr - (char *)process); + tmp_size = + program_dependency_count * sizeof(vied_nci_resource_id_t); + process_raw_ptr += + tot_bytes_for_pow2_align(sizeof(uint64_t), tmp_size); + } else { + process->cell_dependencies_offset = 0; + } + + if (terminal_dependency_count != 0) { + process->terminal_dependencies_offset = + (uint16_t) (process_raw_ptr - (char *)process); + } + + process->size = (uint32_t)ia_css_sizeof_process(manifest, param); + + process->ID = ia_css_program_manifest_get_program_ID(manifest); + verifexit(process->ID != 0); + process->program_idx = program_idx; + + process->cell_dependency_count = program_dependency_count; + process->terminal_dependency_count = terminal_dependency_count; + + process->parent_offset = 0; + + verifexit(ia_css_process_clear_all(process) == 0); + + process->state = IA_CSS_PROCESS_READY; + retval = 0; + + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_create(): Created successfully process %p ID 0x%x\n", + process, process->ID); + +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_create invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_create failed (%i)\n", retval); + process = ia_css_process_destroy(process); + } + return process; +} + +ia_css_process_t *ia_css_process_destroy( + ia_css_process_t *process) +{ + + return process; +} +#endif + +int ia_css_process_set_cell( + ia_css_process_t *process, + const vied_nci_cell_ID_t cell_id) +{ + int retval = -1; + vied_nci_resource_bitmap_t bit_mask; + vied_nci_resource_bitmap_t resource_bitmap; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_cell(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + + verifexit(parent != NULL); + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + +/* Some programs are mapped on a fixed cell, + * when the process group is created + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_CREATED) || + /* If the process group has already been created, but no VP cell + * has been assigned to this process (i.e. not fixed in + * manifest), then we need to set the cell of this process + * while its parent state is READY (the ready state is set at + * the end of ia_css_process_group_create) + */ + (parent_state == IA_CSS_PROCESS_GROUP_READY))); + verifexit(state == IA_CSS_PROCESS_READY); + +/* Some programs are mapped on a fixed cell, thus check is not secure, + * but it will detect a preset, the process manager will do the secure check + */ + verifexit(ia_css_process_get_cell(process) == + VIED_NCI_N_CELL_ID); + + bit_mask = vied_nci_cell_bit_mask(cell_id); + resource_bitmap = ia_css_process_group_get_resource_bitmap(parent); + + verifexit(bit_mask != 0); + verifexit(vied_nci_is_bitmap_clear(bit_mask, resource_bitmap)); + + ia_css_process_cells_clear(process); + ia_css_process_cells_set_cell(process, 0, cell_id); + + resource_bitmap = vied_nci_bitmap_set(resource_bitmap, bit_mask); + + retval = ia_css_process_group_set_resource_bitmap( + parent, resource_bitmap); +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_cell invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_cell failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_clear_cell( + ia_css_process_t *process) +{ + int retval = -1; + vied_nci_cell_ID_t cell_id; + ia_css_process_group_t *parent; + vied_nci_resource_bitmap_t resource_bitmap; + vied_nci_resource_bitmap_t bit_mask; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_clear_cell(): enter:\n"); + verifexit(process != NULL); + + cell_id = ia_css_process_get_cell(process); + parent = ia_css_process_get_parent(process); + + verifexit(parent != NULL); + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) + || (parent_state == IA_CSS_PROCESS_GROUP_STARTED))); + verifexit(state == IA_CSS_PROCESS_READY); + + bit_mask = vied_nci_cell_bit_mask(cell_id); + resource_bitmap = ia_css_process_group_get_resource_bitmap(parent); + + verifexit(bit_mask != 0); + verifexit(vied_nci_is_bitmap_set(bit_mask, resource_bitmap)); + + ia_css_process_cells_clear(process); + + resource_bitmap = vied_nci_bitmap_clear(resource_bitmap, bit_mask); + + retval = ia_css_process_group_set_resource_bitmap( + parent, resource_bitmap); +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_clear_cell invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_clear_cell failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_set_int_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t offset) +{ + int retval = -1; + ia_css_process_group_t *parent; + vied_nci_cell_ID_t cell_id; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_int_mem(): enter:\n"); + + verifexit(process != NULL); + verifexit(mem_type_id < VIED_NCI_N_MEM_TYPE_ID); + + parent = ia_css_process_get_parent(process); + cell_id = ia_css_process_get_cell(process); + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + + /* TODO : separate process group start and run from + * process_group_exec_cmd() + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_RUNNING))); + verifexit(state == IA_CSS_PROCESS_READY); + + if (vied_nci_is_cell_mem_of_type(cell_id, mem_type_id, mem_type_id)) { + vied_nci_mem_ID_t mem_id = + vied_nci_cell_get_mem(cell_id, mem_type_id); + + process->int_mem_id[mem_type_id] = mem_id; + process->int_mem_offset[mem_type_id] = offset; + retval = 0; + } +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_int_mem failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_clear_int_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id) +{ + int retval = -1; + uint16_t mem_index; + ia_css_process_group_t *parent; + vied_nci_cell_ID_t cell_id; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_clear_int_mem(): enter:\n"); + + verifexit(process != NULL); + verifexit(mem_type_id < VIED_NCI_N_MEM_TYPE_ID); + + parent = ia_css_process_get_parent(process); + cell_id = ia_css_process_get_cell(process); + + /* We should have a check on NULL != parent but it parent is NULL + * ia_css_process_group_get_state will return + * IA_CSS_N_PROCESS_GROUP_STATES so it will be filtered anyway later. + */ + + /* verifexit(parent != NULL); */ + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) + || (parent_state == IA_CSS_PROCESS_GROUP_STARTED))); + verifexit(state == IA_CSS_PROCESS_READY); + +/* We could just clear the field, but lets check the state for + * consistency first + */ + for (mem_index = 0; mem_index < (int)VIED_NCI_N_MEM_TYPE_ID; + mem_index++) { + if (vied_nci_is_cell_mem_of_type( + cell_id, mem_index, mem_type_id)) { + vied_nci_mem_ID_t mem_id = + vied_nci_cell_get_mem(cell_id, mem_index); + int mem_of_type; + + mem_of_type = + vied_nci_is_mem_of_type(mem_id, mem_type_id); + + assert(mem_of_type); + assert((process->int_mem_id[mem_type_id] == mem_id) || + (process->int_mem_id[mem_type_id] == + VIED_NCI_N_MEM_ID)); + process->int_mem_id[mem_type_id] = VIED_NCI_N_MEM_ID; + process->int_mem_offset[mem_type_id] = + IA_CSS_PROCESS_INVALID_OFFSET; + retval = 0; + } + } + +EXIT: + if (NULL == process || mem_type_id >= VIED_NCI_N_MEM_TYPE_ID) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_clear_int_mem invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_clear_int_mem failed (%i)\n", retval); + } +return retval; +} + +int ia_css_process_set_ext_mem( + ia_css_process_t *process, + const vied_nci_mem_ID_t mem_id, + const vied_nci_resource_size_t offset) +{ + int retval = -1; + ia_css_process_group_t *parent; + vied_nci_cell_ID_t cell_id; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + vied_nci_mem_type_ID_t mem_type_id; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_ext_mem(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + cell_id = ia_css_process_get_cell(process); + + /* We should have a check on NULL != parent but it parent is NULL + * ia_css_process_group_get_state will return + * IA_CSS_N_PROCESS_GROUP_STATES so it will be filtered anyway later. + */ + + /* verifexit(parent != NULL); */ + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + + /* TODO : separate process group start and run from + * process_group_exec_cmd() + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_RUNNING))); + verifexit(state == IA_CSS_PROCESS_READY); + + /* Check that the memory actually exists, "vied_nci_has_cell_mem_of_id()" + * will return false on error + */ + + mem_type_id = vied_nci_mem_get_type(mem_id); + if (((!vied_nci_has_cell_mem_of_id(cell_id, mem_id) && + (mem_type_id != VIED_NCI_PMEM_TYPE_ID)) + || vied_nci_mem_is_ext_type(mem_type_id)) && + (mem_id < VIED_NCI_N_MEM_ID)) { + + verifexit(mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID); + process->ext_mem_id[mem_type_id] = mem_id; + process->ext_mem_offset[mem_type_id] = offset; + retval = 0; + } + +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_ext_mem invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_ext_mem failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_clear_ext_mem( + ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_clear_ext_mem(): enter:\n"); + + verifexit(process != NULL); + verifexit(mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID); + + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + verifexit(parent != NULL); + verifexit(state == IA_CSS_PROCESS_READY); + + parent_state = ia_css_process_group_get_state(parent); + + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED))); + + process->ext_mem_id[mem_type_id] = VIED_NCI_N_MEM_ID; + process->ext_mem_offset[mem_type_id] = IA_CSS_PROCESS_INVALID_OFFSET; + + retval = 0; +EXIT: + if (NULL == process || mem_type_id >= VIED_NCI_N_DATA_MEM_TYPE_ID) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_clear_ext_mem invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_clear_ext_mem failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_set_cells_bitmap( + ia_css_process_t *process, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + int array_index = 0; + int bit_index; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_cells_bitmap(): enter:\n"); + + verifexit(process != NULL); + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + parent_state = ia_css_process_group_get_state(parent); + + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_CREATED) || + (parent_state == IA_CSS_PROCESS_GROUP_READY))); + verifexit(state == IA_CSS_PROCESS_READY); + + for (bit_index = 0; bit_index < VIED_NCI_N_CELL_ID; bit_index++) { + if (vied_nci_is_bit_set_in_bitmap(bitmap, bit_index)) { + verifexit(array_index < IA_CSS_PROCESS_MAX_CELLS); + ia_css_process_cells_set_cell(process, + array_index, (vied_nci_cell_ID_t)bit_index); + array_index++; + } + } + for (; array_index < IA_CSS_PROCESS_MAX_CELLS; array_index++) { + ia_css_process_cells_set_cell(process, + array_index, VIED_NCI_N_CELL_ID); + } + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_cells_bitmap invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_cells_bitmap failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_set_dev_chn( + ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t offset) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_dev_chn(): enter:\n"); + + verifexit(process != NULL); + verifexit(dev_chn_id <= VIED_NCI_N_DEV_CHN_ID); + + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + parent_state = ia_css_process_group_get_state(parent); + + /* TODO : separate process group start and run from + * process_group_exec_cmd() + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_RUNNING))); + verifexit(state == IA_CSS_PROCESS_READY); + + process->dev_chn_offset[dev_chn_id] = offset; + + retval = 0; +EXIT: + if (NULL == process || dev_chn_id >= VIED_NCI_N_DEV_CHN_ID) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_dev_chn invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_dev_chn invalid argument\n"); + } + return retval; +} + +int ia_css_process_set_dfm_port_bitmap( + ia_css_process_t *process, + const vied_nci_dev_dfm_id_t dfm_dev_id, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_dfm_port(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + parent_state = ia_css_process_group_get_state(parent); + + /* TODO : separate process group start and run from + * process_group_exec_cmd() + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_RUNNING))); + verifexit(state == IA_CSS_PROCESS_READY); + +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_dev_id <= VIED_NCI_N_DEV_DFM_ID); + process->dfm_port_bitmap[dfm_dev_id] = bitmap; +#else + (void)bitmap; + (void)dfm_dev_id; +#endif + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_dfm_port invalid argument\n"); + } + return retval; +} + +int ia_css_process_set_dfm_active_port_bitmap( + ia_css_process_t *process, + const vied_nci_dev_dfm_id_t dfm_dev_id, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_dfm_active_port_bitmap(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + parent_state = ia_css_process_group_get_state(parent); + + /* TODO : separate process group start and run from + * process_group_exec_cmd() + */ + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) || + (parent_state == IA_CSS_PROCESS_GROUP_STARTED) || + (parent_state == IA_CSS_PROCESS_GROUP_RUNNING))); + verifexit(state == IA_CSS_PROCESS_READY); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_dev_id <= VIED_NCI_N_DEV_DFM_ID); + process->dfm_active_port_bitmap[dfm_dev_id] = bitmap; +#else + (void)bitmap; + (void)dfm_dev_id; +#endif + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_dfm_active_port_bitmap invalid argument\n"); + } + return retval; +} + +int ia_css_process_clear_dev_chn( + ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_clear_dev_chn(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + + /* We should have a check on NULL != parent but it parent is NULL + * ia_css_process_group_get_state will return + * IA_CSS_N_PROCESS_GROUP_STATES so it will be filtered anyway later. + */ + + /* verifexit(parent != NULL); */ + + parent_state = ia_css_process_group_get_state(parent); + state = ia_css_process_get_state(process); + + verifexit(((parent_state == IA_CSS_PROCESS_GROUP_BLOCKED) + || (parent_state == IA_CSS_PROCESS_GROUP_STARTED))); + verifexit(state == IA_CSS_PROCESS_READY); + + verifexit(dev_chn_id <= VIED_NCI_N_DEV_CHN_ID); + + process->dev_chn_offset[dev_chn_id] = IA_CSS_PROCESS_INVALID_OFFSET; + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_clear_dev_chn invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_clear_dev_chn failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_clear_all( + ia_css_process_t *process) +{ + int retval = -1; + ia_css_process_group_t *parent; + ia_css_process_group_state_t parent_state; + ia_css_process_state_t state; + int mem_index; + int dev_chn_index; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_clear_all(): enter:\n"); + + verifexit(process != NULL); + + parent = ia_css_process_get_parent(process); + state = ia_css_process_get_state(process); + + /* We should have a check on NULL != parent but it parent is NULL + * ia_css_process_group_get_state will return + * IA_CSS_N_PROCESS_GROUP_STATES so it will be filtered anyway later. + */ + + /* verifexit(parent != NULL); */ + + parent_state = ia_css_process_group_get_state(parent); + +/* Resource clear can only be called in excluded states contrary to set */ + verifexit((parent_state != IA_CSS_PROCESS_GROUP_RUNNING) || + (parent_state == IA_CSS_N_PROCESS_GROUP_STATES)); + verifexit((state == IA_CSS_PROCESS_CREATED) || + (state == IA_CSS_PROCESS_READY)); + + for (dev_chn_index = 0; dev_chn_index < VIED_NCI_N_DEV_CHN_ID; + dev_chn_index++) { + process->dev_chn_offset[dev_chn_index] = + IA_CSS_PROCESS_INVALID_OFFSET; + } +/* No difference whether a cell_id has been set or not, clear all */ + for (mem_index = 0; mem_index < VIED_NCI_N_DATA_MEM_TYPE_ID; + mem_index++) { + process->ext_mem_id[mem_index] = VIED_NCI_N_MEM_ID; + process->ext_mem_offset[mem_index] = + IA_CSS_PROCESS_INVALID_OFFSET; + } + for (mem_index = 0; mem_index < VIED_NCI_N_MEM_TYPE_ID; mem_index++) { + process->int_mem_id[mem_index] = VIED_NCI_N_MEM_ID; + process->int_mem_offset[mem_index] = + IA_CSS_PROCESS_INVALID_OFFSET; + } + + ia_css_process_cells_clear(process); + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_clear_all invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_clear_all failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_acquire( + ia_css_process_t *process) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_acquire(): enter:\n"); + + verifexit(process != NULL); + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_acquire invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_acquire failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_release( + ia_css_process_t *process) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_release(): enter:\n"); + + verifexit(process != NULL); + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_t invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_release failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_print(const ia_css_process_t *process, void *fid) +{ + int retval = -1; + int i, dev_chn_index; + uint16_t mem_index; + uint8_t cell_dependency_count, terminal_dependency_count; + vied_nci_cell_ID_t cell_id = ia_css_process_get_cell(process); + + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_print(process %p): enter:\n", process); + + verifexit(process != NULL); + + IA_CSS_TRACE_6(PSYSAPI_DYNAMIC, INFO, + "\tprocess %p, sizeof %d, programID %d, state %d, parent %p, cell %d\n", + process, + (int)ia_css_process_get_size(process), + (int)ia_css_process_get_program_ID(process), + (int)ia_css_process_get_state(process), + (void *)ia_css_process_get_parent(process), + (int)ia_css_process_get_cell(process)); + + for (mem_index = 0; mem_index < (int)VIED_NCI_N_MEM_TYPE_ID; + mem_index++) { + vied_nci_mem_ID_t mem_id = + (vied_nci_mem_ID_t)(process->int_mem_id[mem_index]); + if (cell_id == VIED_NCI_N_CELL_ID) { + verifexit(mem_id == VIED_NCI_N_MEM_ID); + continue; + } + verifexit(((mem_id == vied_nci_cell_get_mem(cell_id, mem_index)) + || (mem_id == VIED_NCI_N_MEM_ID))); + + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "\tinternal index %d, type %d, id %d offset 0x%x\n", + mem_index, + (int)vied_nci_cell_get_mem_type(cell_id, mem_index), + (int)mem_id, + process->int_mem_offset[mem_index]); + } + + for (mem_index = 0; mem_index < (int)VIED_NCI_N_DATA_MEM_TYPE_ID; + mem_index++) { + vied_nci_mem_ID_t mem_id = + (vied_nci_mem_ID_t)(process->ext_mem_id[mem_index]); + /* TODO: in case of an cells_bitmap = [], + * vied_nci_cell_get_mem_type will return a wrong result. + */ + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "\texternal index %d, type %d, id %d offset 0x%x\n", + mem_index, + (int)vied_nci_cell_get_mem_type(cell_id, mem_index), + (int)mem_id, + process->ext_mem_offset[mem_index]); + NOT_USED(mem_id); + } + for (dev_chn_index = 0; dev_chn_index < (int)VIED_NCI_N_DEV_CHN_ID; + dev_chn_index++) { + IA_CSS_TRACE_3(PSYSAPI_DYNAMIC, INFO, + "\tdevice channel index %d, type %d, offset 0x%x\n", + dev_chn_index, + (int)dev_chn_index, + process->dev_chn_offset[dev_chn_index]); + } +#if HAS_DFM + for (dev_chn_index = 0; dev_chn_index < (int)VIED_NCI_N_DEV_DFM_ID; + dev_chn_index++) { + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "\tdfm device index %d, type %d, bitmap 0x%x active_ports_bitmap 0x%x\n", + dev_chn_index, dev_chn_index, + process->dfm_port_bitmap[dev_chn_index], + process->dfm_active_port_bitmap[dev_chn_index]); + } +#endif + + for (i = 0; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "\tcells[%d] = 0x%x\n", + i, ia_css_process_cells_get_cell(process, i)); + } + + cell_dependency_count = + ia_css_process_get_cell_dependency_count(process); + if (cell_dependency_count == 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tcell_dependencies[%d] {};\n", cell_dependency_count); + } else { + vied_nci_resource_id_t cell_dependency; + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tcell_dependencies[%d] {", cell_dependency_count); + for (i = 0; i < (int)cell_dependency_count - 1; i++) { + cell_dependency = + ia_css_process_get_cell_dependency(process, i); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "%4d, ", cell_dependency); + } + cell_dependency = + ia_css_process_get_cell_dependency(process, i); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "%4d}\n", cell_dependency); + (void)cell_dependency; + } + + terminal_dependency_count = + ia_css_process_get_terminal_dependency_count(process); + if (terminal_dependency_count == 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tterminal_dependencies[%d] {};\n", + terminal_dependency_count); + } else { + uint8_t terminal_dependency; + + terminal_dependency_count = + ia_css_process_get_terminal_dependency_count(process); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tterminal_dependencies[%d] {", + terminal_dependency_count); + for (i = 0; i < (int)terminal_dependency_count - 1; i++) { + terminal_dependency = + ia_css_process_get_terminal_dependency(process, i); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "%4d, ", terminal_dependency); + } + terminal_dependency = + ia_css_process_get_terminal_dependency(process, i); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "%4d}\n", terminal_dependency); + (void)terminal_dependency; + } + + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_print invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_print failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_set_parent( + ia_css_process_t *process, + ia_css_process_group_t *parent) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_parent(): enter:\n"); + + verifexit(process != NULL); + verifexit(parent != NULL); + + process->parent_offset = (uint16_t) ((char *)parent - (char *)process); + retval = 0; +EXIT: + if (NULL == process || NULL == parent) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_set_parent invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_parent failed (%i)\n", retval); + } + return retval; +} + +int ia_css_process_set_cell_dependency( + const ia_css_process_t *process, + const unsigned int dep_index, + const vied_nci_resource_id_t id) +{ + int retval = -1; + uint8_t *process_dep_ptr; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_cell_dependency(): enter:\n"); + verifexit(process != NULL); + + process_dep_ptr = + (uint8_t *)process + process->cell_dependencies_offset + + dep_index*sizeof(vied_nci_resource_id_t); + + + *process_dep_ptr = id; + retval = 0; +EXIT: + return retval; +} + +int ia_css_process_set_terminal_dependency( + const ia_css_process_t *process, + const unsigned int dep_index, + const vied_nci_resource_id_t id) +{ + int retval = -1; + uint8_t *terminal_dep_ptr; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_terminal_dependency(): enter:\n"); + verifexit(process != NULL); + verifexit(ia_css_process_get_terminal_dependency_count(process) > dep_index); + + terminal_dep_ptr = + (uint8_t *)process + process->terminal_dependencies_offset + + dep_index*sizeof(uint8_t); + + *terminal_dep_ptr = id; + retval = 0; +EXIT: + return retval; +} + +int ia_css_process_cmd( + ia_css_process_t *process, + const ia_css_process_cmd_t cmd) +{ + int retval = -1; + ia_css_process_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, "ia_css_process_cmd(): enter:\n"); + + verifexit(process != NULL); + + state = ia_css_process_get_state(process); + + verifexit(state != IA_CSS_PROCESS_ERROR); + verifexit(state < IA_CSS_N_PROCESS_STATES); + + switch (cmd) { + case IA_CSS_PROCESS_CMD_NOP: + break; + case IA_CSS_PROCESS_CMD_ACQUIRE: + verifexit(state == IA_CSS_PROCESS_READY); + break; + case IA_CSS_PROCESS_CMD_RELEASE: + verifexit(state == IA_CSS_PROCESS_READY); + break; + case IA_CSS_PROCESS_CMD_START: + verifexit((state == IA_CSS_PROCESS_READY) + || (state == IA_CSS_PROCESS_STOPPED)); + process->state = IA_CSS_PROCESS_STARTED; + break; + case IA_CSS_PROCESS_CMD_LOAD: + verifexit(state == IA_CSS_PROCESS_STARTED); + process->state = IA_CSS_PROCESS_RUNNING; + break; + case IA_CSS_PROCESS_CMD_STOP: + verifexit((state == IA_CSS_PROCESS_RUNNING) + || (state == IA_CSS_PROCESS_SUSPENDED)); + process->state = IA_CSS_PROCESS_STOPPED; + break; + case IA_CSS_PROCESS_CMD_SUSPEND: + verifexit(state == IA_CSS_PROCESS_RUNNING); + process->state = IA_CSS_PROCESS_SUSPENDED; + break; + case IA_CSS_PROCESS_CMD_RESUME: + verifexit(state == IA_CSS_PROCESS_SUSPENDED); + process->state = IA_CSS_PROCESS_RUNNING; + break; + case IA_CSS_N_PROCESS_CMDS: /* Fall through */ + default: + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_cmd invalid cmd (0x%x)\n", cmd); + goto EXIT; + } + retval = 0; +EXIT: + if (process == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_cmd invalid argument process\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_cmd failed (%i)\n", retval); + } + return retval; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group.c new file mode 100644 index 0000000000000..9d17e8ca5384d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group.c @@ -0,0 +1,886 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_process_group.h" +#include "ia_css_psys_dynamic_storage_class.h" + +/* + * Functions to possibly inline + */ + +#ifndef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_process_group_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +/* + * Functions not to inline + */ + +/* This header is need for cpu memset to 0 +* and process groups are not created in SP +*/ +#if !defined(__VIED_CELL) +#include "cpu_mem_support.h" +#endif + +/* This source file is created with the intention of sharing and +* compiled for host and firmware. Since there is no native 64bit +* data type support for firmware this wouldn't compile for SP +* tile. The part of the file that is not compilable are marked +* with the following __VIED_CELL marker and this comment. Once we +* come up with a solution to address this issue this will be +* removed. +*/ +#if !defined(__VIED_CELL) +static bool ia_css_process_group_is_program_enabled( + const ia_css_program_manifest_t *program_manifest, + ia_css_kernel_bitmap_t enable_bitmap) +{ + ia_css_kernel_bitmap_t program_bitmap = + ia_css_program_manifest_get_kernel_bitmap(program_manifest); + ia_css_program_type_t program_type = + ia_css_program_manifest_get_type(program_manifest); + ia_css_kernel_bitmap_t program_enable_bitmap; + + if (!ia_css_is_kernel_bitmap_intersection_empty(enable_bitmap, + program_bitmap)) { + + if (program_type == IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB || + program_type == IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER || + program_type == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB) { + /* + * EXCLUSIVE_SUB programs are subsets of + * EXCLUSIVE_SUPER so the bits of the enable_bitmap + * that refer to those are those of their + * EXCLUSIVE_SUPER program (on which the depend) and + * not the subset that their own program_bitmap has + */ + if (program_type == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB || + program_type == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB) { + ia_css_kernel_bitmap_t super_program_bitmap; + + const ia_css_program_group_manifest_t * + prog_group_manifest = + ia_css_program_manifest_get_parent(program_manifest); + uint8_t super_prog_idx = + ia_css_program_manifest_get_program_dependency( + program_manifest, 0); + const ia_css_program_manifest_t * + super_program_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + prog_group_manifest, super_prog_idx); + + verifexit(super_program_manifest != NULL); + if (((program_type == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) && + (ia_css_program_manifest_get_type( + super_program_manifest) != + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER)) + || ((program_type == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB) && + (ia_css_program_manifest_get_type( + super_program_manifest) != + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER))) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_is_program_enabled(): Error\n"); + verifexit(0); + } + + super_program_bitmap = + ia_css_program_manifest_get_kernel_bitmap( + super_program_manifest); + program_enable_bitmap = + ia_css_kernel_bitmap_intersection( + enable_bitmap, + super_program_bitmap); + } else { + program_enable_bitmap = + ia_css_kernel_bitmap_intersection( + enable_bitmap, program_bitmap); + } + + if (ia_css_is_kernel_bitmap_equal( + program_enable_bitmap, program_bitmap)) { + return true; + } + } else if (program_type == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER) { + /* + * Virtual super programs are not selectable + * only the virtual sub programs + */ + return false; + } else { + return true; + } + } + +EXIT: + return false; +} + +static bool ia_css_process_group_is_terminal_enabled( + const ia_css_terminal_manifest_t *terminal_manifest, + ia_css_kernel_bitmap_t enable_bitmap) +{ + ia_css_terminal_type_t terminal_type; + + verifjmpexit(terminal_manifest != NULL); + terminal_type = ia_css_terminal_manifest_get_type(terminal_manifest); + + if (ia_css_is_terminal_manifest_data_terminal(terminal_manifest)) { + ia_css_data_terminal_manifest_t *data_term_manifest = + (ia_css_data_terminal_manifest_t *)terminal_manifest; + ia_css_kernel_bitmap_t term_bitmap = + ia_css_data_terminal_manifest_get_kernel_bitmap( + data_term_manifest); + /* + * Terminals depend on a kernel, + * if the kernel is present the program it contains and + * the terminal the program depends on are active + */ + if (!ia_css_is_kernel_bitmap_intersection_empty( + enable_bitmap, term_bitmap)) { + return true; + } + } else if (ia_css_is_terminal_manifest_spatial_parameter_terminal( + terminal_manifest)) { + ia_css_kernel_bitmap_t term_kernel_bitmap = ia_css_kernel_bitmap_clear(); + ia_css_spatial_param_terminal_manifest_t *spatial_term_man = + (ia_css_spatial_param_terminal_manifest_t *) + terminal_manifest; + + term_kernel_bitmap = + ia_css_kernel_bitmap_set( + term_kernel_bitmap, + spatial_term_man->kernel_id); + if (!ia_css_is_kernel_bitmap_intersection_empty( + enable_bitmap, term_kernel_bitmap)) { + return true; + } + + } else if (ia_css_is_terminal_manifest_parameter_terminal( + terminal_manifest) && terminal_type == + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN) { + return true; + + } else if (ia_css_is_terminal_manifest_parameter_terminal( + terminal_manifest) && terminal_type == + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT) { + /* + * For parameter out terminals, we disable the terminals + * if ALL the corresponding kernels are disabled, + * for parameter in terminals we cannot do this; + * even if kernels are disabled, it may be required that + * (HW) parameters must be supplied via the parameter + * in terminal (e.g. bypass bits). + */ + ia_css_kernel_bitmap_t term_kernel_bitmap = ia_css_kernel_bitmap_clear(); + ia_css_param_terminal_manifest_t *param_term_man = + (ia_css_param_terminal_manifest_t *)terminal_manifest; + ia_css_param_manifest_section_desc_t *section_desc; + unsigned int section = 0; + + for (section = 0; section < param_term_man-> + param_manifest_section_desc_count; section++) { + section_desc = + ia_css_param_terminal_manifest_get_prm_sct_desc( + param_term_man, section); + verifjmpexit(section_desc != NULL); + term_kernel_bitmap = ia_css_kernel_bitmap_set( + term_kernel_bitmap, + section_desc->kernel_id); + } + + if (!ia_css_is_kernel_bitmap_intersection_empty( + enable_bitmap, term_kernel_bitmap)) { + return true; + } + } else if (ia_css_is_terminal_manifest_program_terminal( + terminal_manifest)) { + return true; + } else if (ia_css_is_terminal_manifest_program_control_init_terminal( + terminal_manifest)) { + return true; + } +EXIT: + return false; +} + +size_t ia_css_sizeof_process_group( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + size_t size = 0, tmp_size; + int i, error_val = -1; + uint8_t process_count, process_num; + uint8_t terminal_count; + ia_css_kernel_bitmap_t enable_bitmap; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_sizeof_process_group(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + COMPILATION_ERROR_IF( + SIZE_OF_PROCESS_GROUP_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_process_group_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_process_group_t) % sizeof(uint64_t)); + + process_count = + ia_css_process_group_compute_process_count(manifest, param); + terminal_count = + ia_css_process_group_compute_terminal_count(manifest, param); + + verifexit(process_count != 0); + verifexit(terminal_count != 0); + + size += sizeof(ia_css_process_group_t); + + tmp_size = process_count * sizeof(uint16_t); + size += tot_bytes_for_pow2_align(sizeof(uint64_t), tmp_size); + + tmp_size = terminal_count * sizeof(uint16_t); + size += tot_bytes_for_pow2_align(sizeof(uint64_t), tmp_size); + + enable_bitmap = + ia_css_program_group_param_get_kernel_enable_bitmap(param); + process_num = 0; + for (i = 0; i < (int)ia_css_program_group_manifest_get_program_count( + manifest); i++) { + ia_css_program_manifest_t *program_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst(manifest, i); + ia_css_program_param_t *program_param = + ia_css_program_group_param_get_program_param(param, i); + + if (ia_css_process_group_is_program_enabled( + program_manifest, enable_bitmap)) { + verifexit(process_num < process_count); + size += ia_css_sizeof_process( + program_manifest, program_param); + process_num++; + } + } + + verifexit(process_num == process_count); + + for (i = 0; i < (int)ia_css_program_group_manifest_get_terminal_count( + manifest); i++) { + ia_css_terminal_manifest_t *terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst( + manifest, i); + + if (ia_css_process_group_is_terminal_enabled( + terminal_manifest, enable_bitmap)) { + size += ia_css_sizeof_terminal( + terminal_manifest, param); + } + } + + error_val = 0; + +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_sizeof_process_group invalid argument\n"); + } + if (error_val != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_sizeof_process_group ERROR(%d)\n", error_val); + } + return size; +} + +ia_css_process_group_t *ia_css_process_group_create( + void *process_grp_mem, + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + size_t size = ia_css_sizeof_process_group(manifest, param); + int retval = -1; + int ret; + int i; + ia_css_process_group_t *process_group = NULL; + uint8_t process_count, process_num; + uint8_t terminal_count, terminal_num; + uint16_t fragment_count; + char *process_grp_raw_ptr; + uint16_t *process_tab_ptr, *terminal_tab_ptr; + ia_css_kernel_bitmap_t enable_bitmap; + uint8_t manifest_terminal_count; + + IA_CSS_TRACE_3(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create(process_grp_mem %p, manifest %p, group_param %p): enter:\n", + process_grp_mem, manifest, param); + + verifexit(process_grp_mem != NULL); + verifexit(manifest != NULL); + verifexit(param != NULL); + verifexit(ia_css_is_program_group_manifest_valid(manifest)); + + process_group = (ia_css_process_group_t *)process_grp_mem; + ia_css_cpu_mem_set_zero(process_group, size); + process_grp_raw_ptr = (char *) process_group; + + process_group->state = IA_CSS_PROCESS_GROUP_CREATED; + + process_group->protocol_version = + ia_css_program_group_param_get_protocol_version(param); + + fragment_count = ia_css_program_group_param_get_fragment_count(param); + process_count = + ia_css_process_group_compute_process_count(manifest, param); + terminal_count = + ia_css_process_group_compute_terminal_count(manifest, param); + enable_bitmap = + ia_css_program_group_param_get_kernel_enable_bitmap(param); + + process_group->fragment_count = fragment_count; + process_group->process_count = process_count; + process_group->terminal_count = terminal_count; + + process_grp_raw_ptr += sizeof(ia_css_process_group_t); + process_tab_ptr = (uint16_t *) process_grp_raw_ptr; + process_group->processes_offset = + (uint16_t)(process_grp_raw_ptr - (char *)process_group); + + process_grp_raw_ptr += tot_bytes_for_pow2_align( + sizeof(uint64_t), process_count * sizeof(uint16_t)); + terminal_tab_ptr = (uint16_t *) process_grp_raw_ptr; + process_group->terminals_offset = + (uint16_t)(process_grp_raw_ptr - (char *)process_group); + + /* Move raw pointer to the first process */ + process_grp_raw_ptr += tot_bytes_for_pow2_align( + sizeof(uint64_t), terminal_count * sizeof(uint16_t)); + + /* Set default */ + verifexit(ia_css_process_group_set_fragment_limit( + process_group, fragment_count) == 0); + + /* Set process group terminal dependency list */ + /* This list is used during creating the process dependency list */ + manifest_terminal_count = + ia_css_program_group_manifest_get_terminal_count(manifest); + + terminal_num = 0; + for (i = 0; i < (int)manifest_terminal_count; i++) { + ia_css_terminal_manifest_t *t_manifest = + ia_css_program_group_manifest_get_term_mnfst( + manifest, i); + + verifexit(t_manifest != NULL); + if (ia_css_process_group_is_terminal_enabled( + t_manifest, enable_bitmap)) { + ia_css_terminal_t *terminal = NULL; + ia_css_terminal_param_t *terminal_param = + ia_css_program_group_param_get_terminal_param( + param, i); + + verifexit(terminal_param != NULL); + terminal_tab_ptr[terminal_num] = + (uint16_t)(process_grp_raw_ptr - + (char *)process_group); + terminal = ia_css_terminal_create( + process_grp_raw_ptr, t_manifest, + terminal_param, enable_bitmap); + verifexit(terminal != NULL); + verifexit((ia_css_terminal_set_parent( + terminal, process_group) == 0)); + verifexit((ia_css_terminal_set_terminal_manifest_index( + terminal, i) == 0)); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create: terminal_manifest_index %d\n", + i); + + process_grp_raw_ptr += ia_css_terminal_get_size( + terminal); + terminal_num++; + } + } + verifexit(terminal_num == terminal_count); + + process_num = 0; + for (i = 0; i < (int)ia_css_program_group_manifest_get_program_count( + manifest); i++) { + ia_css_process_t *process = NULL; + ia_css_program_manifest_t *program_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, i); + ia_css_program_param_t *program_param = + ia_css_program_group_param_get_program_param(param, i); + unsigned int prog_dep_index, proc_dep_index; + unsigned int term_dep_index, term_index; + + if (ia_css_process_group_is_program_enabled( + program_manifest, enable_bitmap)) { + + verifexit(process_num < process_count); + + process_tab_ptr[process_num] = + (uint16_t)(process_grp_raw_ptr - + (char *)process_group); + process = ia_css_process_create( + process_grp_raw_ptr, + program_manifest, + program_param, + i); + verifexit(process != NULL); + + ia_css_process_set_parent(process, process_group); + if (ia_css_has_program_manifest_fixed_cell( + program_manifest)) { + vied_nci_cell_ID_t cell_id = + ia_css_program_manifest_get_cell_ID( + program_manifest); + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create: cell_id %d\n", + cell_id); + ia_css_process_set_cell(process, cell_id); + } + + process_grp_raw_ptr += ia_css_process_get_size( + process); + /* + * Set process dependencies of process derived + * from program manifest + */ + for (prog_dep_index = 0; prog_dep_index < + ia_css_program_manifest_get_program_dependency_count( + program_manifest); prog_dep_index++) { + uint8_t dep_prog_idx = + ia_css_program_manifest_get_program_dependency( + program_manifest, prog_dep_index); + const ia_css_program_manifest_t * + dep_prg_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, dep_prog_idx); + ia_css_program_ID_t id = + ia_css_program_manifest_get_program_ID( + dep_prg_manifest); + + verifexit(id != 0); + for (proc_dep_index = 0; + proc_dep_index < process_num; + proc_dep_index++) { + ia_css_process_t *dep_process = + ia_css_process_group_get_process( + process_group, + proc_dep_index); + + ia_css_process_set_cell_dependency( + process, + prog_dep_index, 0); + + if (ia_css_process_get_program_ID( + dep_process) == id) { + ia_css_process_set_cell_dependency( + process, + prog_dep_index, + proc_dep_index); + break; + } + } + } + process_num++; + + /* + * Set terminal dependencies of process derived + * from program manifest + */ + for (term_dep_index = 0; term_dep_index < + ia_css_program_manifest_get_terminal_dependency_count( + program_manifest); term_dep_index++) { + uint8_t pm_term_index = + ia_css_program_manifest_get_terminal_dependency + (program_manifest, term_dep_index); + + verifexit(pm_term_index < manifest_terminal_count); + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create(): term_dep_index: %d, pm_term_index: %d\n", + term_dep_index, pm_term_index); + for (term_index = 0; + term_index < terminal_count; + term_index++) { + ia_css_terminal_t *terminal = + ia_css_process_group_get_terminal( + process_group, + term_index); + + if (ia_css_terminal_get_terminal_manifest_index + (terminal) == pm_term_index) { + ia_css_process_set_terminal_dependency( + process, + term_dep_index, + term_index); + IA_CSS_TRACE_3(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create() set_terminal_dependency(process: %d, dep_idx: %d, term_idx: %d)\n", + i, term_dep_index, term_index); + + break; + } + } + } + } + } + verifexit(process_num == process_count); + + process_group->size = + (uint32_t)ia_css_sizeof_process_group(manifest, param); + process_group->ID = + ia_css_program_group_manifest_get_program_group_ID(manifest); + + /* Initialize performance measurement fields to zero */ + process_group->pg_load_start_ts = 0; + process_group->pg_load_cycles = 0; + process_group->pg_init_cycles = 0; + process_group->pg_processing_cycles = 0; + + verifexit(process_group->ID != 0); + + ret = ia_css_process_group_on_create(process_group, manifest, param); + verifexit(ret == 0); + + process_group->state = IA_CSS_PROCESS_GROUP_READY; + retval = 0; + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_create(): Created successfully process group ID 0x%x\n", + process_group->ID); + +EXIT: + if (NULL == process_grp_mem || NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_create invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_create failed (%i)\n", retval); + process_group = ia_css_process_group_destroy(process_group); + } + return process_group; +} + +ia_css_process_group_t *ia_css_process_group_destroy( + ia_css_process_group_t *process_group) +{ + if (process_group != NULL) { + ia_css_process_group_on_destroy(process_group); + process_group = NULL; + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_destroy invalid argument\n"); + } + return process_group; +} + +int ia_css_process_group_submit( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_submit(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_SUBMIT); +} + +int ia_css_process_group_start( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_start(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_START); +} + +int ia_css_process_group_stop( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_stop(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_STOP); +} + +int ia_css_process_group_run( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_run(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_RUN); +} + +int ia_css_process_group_suspend( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_suspend(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_SUSPEND); +} + +int ia_css_process_group_resume( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_resume(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_RESUME); +} + +int ia_css_process_group_reset( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_reset(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_RESET); +} + +int ia_css_process_group_abort( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_abort(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_ABORT); +} + +int ia_css_process_group_disown( + ia_css_process_group_t *process_group) +{ + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_disown(): enter:\n"); + + return ia_css_process_group_exec_cmd(process_group, + IA_CSS_PROCESS_GROUP_CMD_DISOWN); +} + +extern uint64_t ia_css_process_group_get_token( + ia_css_process_group_t *process_group) +{ + uint64_t token = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_token(): enter:\n"); + + verifexit(process_group != NULL); + + token = process_group->token; + +EXIT: + if (process_group == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_get_token invalid argument\n"); + } + return token; +} + +int ia_css_process_group_set_token( + ia_css_process_group_t *process_group, + const uint64_t token) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_token(): enter:\n"); + + verifexit(process_group != NULL); + verifexit(token != 0); + + process_group->token = token; + + retval = 0; +EXIT: + if (NULL == process_group || 0 == token) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_set_token invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_token failed (%i)\n", + retval); + } + return retval; +} + +extern uint64_t ia_css_process_group_get_private_token( + ia_css_process_group_t *process_group) +{ + uint64_t token = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_private_token(): enter:\n"); + + verifexit(process_group != NULL); + + token = process_group->private_token; + +EXIT: + if (process_group == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_get_private_token invalid argument\n"); + } + return token; +} + +int ia_css_process_group_set_private_token( + ia_css_process_group_t *process_group, + const uint64_t token) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_private_token(): enter:\n"); + + verifexit(process_group != NULL); + verifexit(token != 0); + + process_group->private_token = token; + + retval = 0; +EXIT: + if (NULL == process_group || 0 == token) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_set_private_token invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_private_token failed (%i)\n", + retval); + } + return retval; +} + +uint8_t ia_css_process_group_compute_process_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + uint8_t process_count = 0; + ia_css_kernel_bitmap_t total_bitmap; + ia_css_kernel_bitmap_t enable_bitmap; + int i; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_compute_process_count(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + total_bitmap = + ia_css_program_group_manifest_get_kernel_bitmap(manifest); + enable_bitmap = + ia_css_program_group_param_get_kernel_enable_bitmap(param); + + verifexit(ia_css_is_program_group_manifest_valid(manifest)); + verifexit(ia_css_is_kernel_bitmap_subset(total_bitmap, enable_bitmap)); + verifexit(!ia_css_is_kernel_bitmap_empty(enable_bitmap)); + + for (i = 0; i < + (int)ia_css_program_group_manifest_get_program_count(manifest); + i++) { + ia_css_program_manifest_t *program_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, i); + ia_css_kernel_bitmap_t program_bitmap = + ia_css_program_manifest_get_kernel_bitmap( + program_manifest); + /* + * Programs can be orthogonal, + * a mutually exclusive subset, + * or a concurrent subset + */ + if (!ia_css_is_kernel_bitmap_intersection_empty(enable_bitmap, + program_bitmap)) { + ia_css_program_type_t program_type = + ia_css_program_manifest_get_type( + program_manifest); + /* + * An exclusive subnode < exclusive supernode, + * so simply don't count it + */ + if (program_type != + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB && + program_type != + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB) { + process_count++; + } + } + } + +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_compute_process_count invalid argument\n"); + } + return process_count; +} + +uint8_t ia_css_process_group_compute_terminal_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + uint8_t terminal_count = 0; + ia_css_kernel_bitmap_t total_bitmap, enable_bitmap; + int i; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_compute_terminal_count(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + total_bitmap = + ia_css_program_group_manifest_get_kernel_bitmap(manifest); + enable_bitmap = + ia_css_program_group_param_get_kernel_enable_bitmap(param); + + verifexit(ia_css_is_program_group_manifest_valid(manifest)); + verifexit(ia_css_is_kernel_bitmap_subset(total_bitmap, enable_bitmap)); + verifexit(!ia_css_is_kernel_bitmap_empty(enable_bitmap)); + + for (i = 0; i < + (int)ia_css_program_group_manifest_get_terminal_count( + manifest); i++) { + ia_css_terminal_manifest_t *tmanifest = + ia_css_program_group_manifest_get_term_mnfst( + manifest, i); + + if (ia_css_process_group_is_terminal_enabled( + tmanifest, enable_bitmap)) { + terminal_count++; + } + } + +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_process_group_compute_terminal_count invalid argument\n"); + } + return terminal_count; +} +#endif /* !defined(__VIED_CELL) */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group_impl.h new file mode 100644 index 0000000000000..0f1760f2873dc --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_group_impl.h @@ -0,0 +1,1538 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_GROUP_IMPL_H +#define __IA_CSS_PSYS_PROCESS_GROUP_IMPL_H + +#include +#include +#include "ia_css_psys_process_group_cmd_impl.h" +#include +#include +#include +#include +#include +#include +#include "ia_css_terminal_manifest_types.h" + +#include "ia_css_rbm.h" + +#include /* ia_css_kernel_bitmap_t */ + +#include +#include +#include "ia_css_rbm_manifest_types.h" +#include +#include +#include + +#include "ia_css_psys_dynamic_trace.h" + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint16_t ia_css_process_group_get_fragment_limit( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint16_t fragment_limit = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_fragment_limit(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + fragment_limit = process_group->fragment_limit; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_limit invalid argument\n"); + } + return fragment_limit; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_fragment_limit( + ia_css_process_group_t *process_group, + const uint16_t fragment_limit) +{ + DECLARE_ERRVAL + int retval = -1; + uint16_t fragment_state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_fragment_limit(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + retval = ia_css_process_group_get_fragment_state(process_group, + &fragment_state); + + verifexitval(retval == 0, EINVAL); + verifexitval(fragment_limit > fragment_state, EINVAL); + verifexitval(fragment_limit <= ia_css_process_group_get_fragment_count( + process_group), EINVAL); + + process_group->fragment_limit = fragment_limit; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_limit invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_limit failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_clear_fragment_limit( + ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_clear_fragment_limit(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + process_group->fragment_limit = 0; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_clear_fragment_limit invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_clear_fragment_limit failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_attach_buffer( + ia_css_process_group_t *process_group, + vied_vaddress_t buffer, + const ia_css_buffer_state_t buffer_state, + const unsigned int terminal_index) +{ + DECLARE_ERRVAL + int retval = -1; + ia_css_terminal_t *terminal = NULL; + + NOT_USED(buffer_state); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_attach_buffer(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + terminal = ia_css_process_group_get_terminal( + process_group, terminal_index); + + verifexitval(terminal != NULL, EINVAL); + verifexitval(ia_css_process_group_get_state(process_group) == + IA_CSS_PROCESS_GROUP_READY, EINVAL); + verifexitval(process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_LEGACY || + process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_PPG, EINVAL); + + if (process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_LEGACY) { + /* + * Legacy flow: + * Terminal address is part of the process group structure + */ + retval = ia_css_terminal_set_buffer( + terminal, buffer); + } else if (process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_PPG) { + /* + * PPG flow: + * Terminal address is part of external buffer set structure + */ + retval = ia_css_terminal_set_terminal_index( + terminal, terminal_index); + } + verifexitval(retval == 0, EFAULT); + + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "\tTerminal %p has buffer 0x%x\n", terminal, buffer); + + if (ia_css_is_terminal_data_terminal(terminal) == true) { + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + verifexitval(frame != NULL, EINVAL); + + retval = ia_css_frame_set_buffer_state(frame, buffer_state); + verifexitval(retval == 0, EINVAL); + } + + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_attach_buffer invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_attach_buffer failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_vaddress_t ia_css_process_group_detach_buffer( + ia_css_process_group_t *process_group, + const unsigned int terminal_index) +{ + DECLARE_ERRVAL + int retval = -1; + vied_vaddress_t buffer = VIED_NULL; + + ia_css_terminal_t *terminal = NULL; + ia_css_process_group_state_t state; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_detach_buffer(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + terminal = + ia_css_process_group_get_terminal( + process_group, terminal_index); + state = ia_css_process_group_get_state(process_group); + + verifexitval(terminal != NULL, EINVAL); + verifexitval(state == IA_CSS_PROCESS_GROUP_READY, EINVAL); + + buffer = ia_css_terminal_get_buffer(terminal); + + if (ia_css_is_terminal_data_terminal(terminal) == true) { + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + verifexitval(frame != NULL, EINVAL); + + retval = ia_css_frame_set_buffer_state(frame, IA_CSS_BUFFER_NULL); + verifexitval(retval == 0, EINVAL); + } + ia_css_terminal_set_buffer(terminal, VIED_NULL); + + retval = 0; +EXIT: + /* + * buffer pointer will appear on output, + * regardless of subsequent fails to avoid memory leaks + */ + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_detach_buffer invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_detach_buffer failed (%i)\n", + retval); + } + return buffer; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_attach_stream( + ia_css_process_group_t *process_group, + uint32_t stream, + const ia_css_buffer_state_t buffer_state, + const unsigned int terminal_index) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_attach_stream(): enter:\n"); + + NOT_USED(process_group); + NOT_USED(stream); + NOT_USED(buffer_state); + NOT_USED(terminal_index); + + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_attach_stream failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_detach_stream( + ia_css_process_group_t *process_group, + const unsigned int terminal_index) +{ + int retval = -1; + uint32_t stream = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_detach_stream(): enter:\n"); + + NOT_USED(process_group); + NOT_USED(terminal_index); + + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_detach_stream failed (%i)\n", + retval); + } + return stream; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_barrier( + ia_css_process_group_t *process_group, + const vied_nci_barrier_ID_t barrier_index) +{ + DECLARE_ERRVAL + int retval = -1; + vied_nci_resource_bitmap_t bit_mask; + vied_nci_resource_bitmap_t resource_bitmap; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_barrier(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + resource_bitmap = + ia_css_process_group_get_resource_bitmap(process_group); + + bit_mask = vied_nci_barrier_bit_mask(barrier_index); + + verifexitval(bit_mask != 0, EINVAL); + verifexitval(vied_nci_is_bitmap_clear(bit_mask, resource_bitmap), EINVAL); + + resource_bitmap = vied_nci_bitmap_set(resource_bitmap, bit_mask); + + retval = + ia_css_process_group_set_resource_bitmap( + process_group, resource_bitmap); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_barrier invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_barrier failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_clear_barrier( + ia_css_process_group_t *process_group, + const vied_nci_barrier_ID_t barrier_index) +{ + DECLARE_ERRVAL + int retval = -1; + vied_nci_resource_bitmap_t bit_mask, resource_bitmap; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_clear_barrier(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + resource_bitmap = + ia_css_process_group_get_resource_bitmap(process_group); + + bit_mask = vied_nci_barrier_bit_mask(barrier_index); + + verifexitval(bit_mask != 0, EINVAL); + verifexitval(vied_nci_is_bitmap_set(bit_mask, resource_bitmap), EINVAL); + + resource_bitmap = vied_nci_bitmap_clear(resource_bitmap, bit_mask); + + retval = + ia_css_process_group_set_resource_bitmap( + process_group, resource_bitmap); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_clear_barrier invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_clear_barrier failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_print( + const ia_css_process_group_t *process_group, + void *fid) +{ + DECLARE_ERRVAL + int retval = -1; + int i; + + uint8_t process_count; + uint8_t terminal_count; + vied_vaddress_t ipu_vaddress = VIED_NULL; + ia_css_rbm_t routing_bitmap; + + NOT_USED(fid); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_print(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + retval = ia_css_process_group_get_ipu_vaddress(process_group, &ipu_vaddress); + verifexitval(retval == 0, EINVAL); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "=============== Process group print start ===============\n"); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tprocess_group cpu address = %p\n", process_group); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tipu_virtual_address = %#x\n", ipu_vaddress); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tsizeof(process_group) = %d\n", + (int)ia_css_process_group_get_size(process_group)); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tfragment_count = %d\n", + (int)ia_css_process_group_get_fragment_count(process_group)); + + routing_bitmap = *ia_css_process_group_get_routing_bitmap(process_group); + for (i = 0; i < (int)IA_CSS_RBM_NOF_ELEMS; i++) { + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "\trouting_bitmap[index = %d] = 0x%X\n", + i, (int)routing_bitmap.data[i]); + } + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\tprogram_group(process_group) = %d\n", + (int)ia_css_process_group_get_program_group_ID(process_group)); + process_count = ia_css_process_group_get_process_count(process_group); + terminal_count = + ia_css_process_group_get_terminal_count(process_group); + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\t%d processes\n", (int)process_count); + for (i = 0; i < (int)process_count; i++) { + ia_css_process_t *process = + ia_css_process_group_get_process(process_group, i); + + retval = ia_css_process_print(process, fid); + verifjmpexit(retval == 0); + } + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "\t%d terminals\n", (int)terminal_count); + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_t *terminal = + ia_css_process_group_get_terminal(process_group, i); + + retval = ia_css_terminal_print(terminal, fid); + verifjmpexit(retval == 0); + } + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "=============== Process group print end ===============\n"); + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_print invalid argument\n"); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_process_group_valid( + const ia_css_process_group_t *process_group, + const ia_css_program_group_manifest_t *pg_manifest, + const ia_css_program_group_param_t *param) +{ + DECLARE_ERRVAL + bool invalid_flag = false; + uint8_t proc_idx; + uint8_t prog_idx; + uint8_t proc_term_idx; + uint8_t process_count; + uint8_t program_count; + uint8_t terminal_count; + uint8_t man_terminal_count; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_process_group_valid(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + verifexitval(pg_manifest != NULL, EFAULT); + NOT_USED(param); + + process_count = process_group->process_count; + terminal_count = process_group->terminal_count; + program_count = + ia_css_program_group_manifest_get_program_count(pg_manifest); + man_terminal_count = + ia_css_program_group_manifest_get_terminal_count(pg_manifest); + + /* Validate process group */ + invalid_flag = invalid_flag || + !(program_count >= process_count) || + !(man_terminal_count >= terminal_count) || + !(process_group->size > process_group->processes_offset) || + !(process_group->size > process_group->terminals_offset); + + /* Validate processes */ + for (proc_idx = 0; proc_idx < process_count; proc_idx++) { + const ia_css_process_t *process; + ia_css_program_ID_t prog_id; + bool no_match_found = true; + + process = ia_css_process_group_get_process( + process_group, proc_idx); + verifexitval(NULL != process, EFAULT); + prog_id = ia_css_process_get_program_ID(process); + for (prog_idx = 0; prog_idx < program_count; prog_idx++) { + ia_css_program_manifest_t *p_manifest = NULL; + + p_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + pg_manifest, prog_idx); + if (prog_id == + ia_css_program_manifest_get_program_ID( + p_manifest)) { + invalid_flag = invalid_flag || + !ia_css_is_process_valid( + process, p_manifest); + no_match_found = false; + break; + } + } + invalid_flag = invalid_flag || no_match_found; + } + + /* Validate terminals */ + for (proc_term_idx = 0; proc_term_idx < terminal_count; + proc_term_idx++) { + int man_term_idx; + const ia_css_terminal_t *terminal; + const ia_css_terminal_manifest_t *terminal_manifest; + + terminal = + ia_css_process_group_get_terminal( + process_group, proc_term_idx); + verifexitval(NULL != terminal, EFAULT); + man_term_idx = + ia_css_terminal_get_terminal_manifest_index(terminal); + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst( + pg_manifest, man_term_idx); + invalid_flag = invalid_flag || + !ia_css_is_terminal_valid(terminal, terminal_manifest); + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_process_group_valid() invalid argument\n"); + return false; + } else { + return (!invalid_flag); + } +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_can_process_group_submit( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + int i; + bool can_submit = false; + int retval = -1; + uint8_t terminal_count = + ia_css_process_group_get_terminal_count(process_group); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_can_process_group_submit(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_t *terminal = + ia_css_process_group_get_terminal(process_group, i); + vied_vaddress_t buffer; + ia_css_buffer_state_t buffer_state; + + verifexitval(terminal != NULL, EINVAL); + + if (process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_LEGACY) { + /* + * For legacy pg flow, buffer addresses are contained inside + * the process group structure, so these need to be validated + * on process group submission. + */ + buffer = ia_css_terminal_get_buffer(terminal); + IA_CSS_TRACE_3(PSYSAPI_DYNAMIC, INFO, + "\tH: Terminal number(%d) is %p having buffer 0x%x\n", + i, terminal, buffer); + } + + /* buffer_state is applicable only for data terminals*/ + if (ia_css_is_terminal_data_terminal(terminal) == true) { + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + + verifexitval(frame != NULL, EINVAL); + buffer_state = ia_css_frame_get_buffer_state(frame); + if ((buffer_state == IA_CSS_BUFFER_NULL) || + (buffer_state == IA_CSS_N_BUFFER_STATES)) { + break; + } + } else if ( + (ia_css_is_terminal_parameter_terminal(terminal) + != true) && + (ia_css_is_terminal_program_terminal(terminal) + != true) && + (ia_css_is_terminal_program_control_init_terminal(terminal) + != true) && + (ia_css_is_terminal_spatial_parameter_terminal( + terminal) != true)) { + /* neither data nor parameter terminal, so error.*/ + break; + } + + } + /* Only true if no check failed */ + can_submit = (i == terminal_count); + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_process_group_submit invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_process_group_submit failed (%i)\n", + retval); + } + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_can_process_group_submit(): leave:\n"); + return can_submit; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_can_enqueue_buffer_set( + const ia_css_process_group_t *process_group, + const ia_css_buffer_set_t *buffer_set) +{ + DECLARE_ERRVAL + int i; + bool can_enqueue = false; + int retval = -1; + uint8_t terminal_count; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_can_enqueue_buffer_set(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + verifexitval(buffer_set != NULL, EFAULT); + + terminal_count = + ia_css_process_group_get_terminal_count(process_group); + + /* + * For ppg flow, buffer addresses are contained in the + * external buffer set structure, so these need to be + * validated before enqueueing. + */ + verifexitval(process_group->protocol_version == + IA_CSS_PROCESS_GROUP_PROTOCOL_PPG, EFAULT); + + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_t *terminal = + ia_css_process_group_get_terminal(process_group, i); + vied_vaddress_t buffer; + ia_css_buffer_state_t buffer_state; + + verifexitval(terminal != NULL, EINVAL); + + buffer = ia_css_buffer_set_get_buffer(buffer_set, terminal); + IA_CSS_TRACE_3(PSYSAPI_DYNAMIC, INFO, + "\tH: Terminal number(%d) is %p having buffer 0x%x\n", + i, terminal, buffer); + + /* buffer_state is applicable only for data terminals*/ + if (ia_css_is_terminal_data_terminal(terminal) == true) { + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + + verifexitval(frame != NULL, EINVAL); + buffer_state = ia_css_frame_get_buffer_state(frame); + if ((buffer_state == IA_CSS_BUFFER_NULL) || + (buffer_state == IA_CSS_N_BUFFER_STATES)) { + break; + } + } else if ( + (ia_css_is_terminal_parameter_terminal(terminal) + != true) && + (ia_css_is_terminal_program_terminal(terminal) + != true) && + (ia_css_is_terminal_program_control_init_terminal(terminal) + != true) && + (ia_css_is_terminal_spatial_parameter_terminal( + terminal) != true)) { + /* neither data nor parameter terminal, so error.*/ + break; + } + } + /* Only true if no check failed */ + can_enqueue = (i == terminal_count); + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_enqueue_buffer_set invalid argument\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_enqueue_buffer_set failed (%i)\n", + retval); + } + return can_enqueue; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_can_process_group_start( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + int i; + bool can_start = false; + int retval = -1; + uint8_t terminal_count; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_can_process_group_start(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + terminal_count = + ia_css_process_group_get_terminal_count(process_group); + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_t *terminal = + ia_css_process_group_get_terminal(process_group, i); + ia_css_buffer_state_t buffer_state; + bool ok = false; + + verifexitval(terminal != NULL, EINVAL); + if (ia_css_is_terminal_data_terminal(terminal) == true) { + /* + * buffer_state is applicable only for data terminals + */ + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + bool is_input = ia_css_is_terminal_input(terminal); + /* + * check for NULL here. + * then invoke next 2 statements + */ + verifexitval(frame != NULL, EINVAL); + IA_CSS_TRACE_5(PSYSAPI_DYNAMIC, VERBOSE, + "\tTerminal %d: buffer_state %u, access_type %u, data_bytes %u, data %u\n", + i, frame->buffer_state, frame->access_type, + frame->data_bytes, frame->data); + buffer_state = ia_css_frame_get_buffer_state(frame); + + ok = ((is_input && + (buffer_state == IA_CSS_BUFFER_FULL)) || + (!is_input && (buffer_state == + IA_CSS_BUFFER_EMPTY))); + + } else if (ia_css_is_terminal_parameter_terminal(terminal) == + true) { + /* + * FIXME: + * is there any pre-requisite for param_terminal? + */ + ok = true; + } else if (ia_css_is_terminal_program_terminal(terminal) == + true) { + ok = true; + } else if (ia_css_is_terminal_program_control_init_terminal(terminal) == + true) { + ok = true; + } else if (ia_css_is_terminal_spatial_parameter_terminal( + terminal) == true) { + ok = true; + } else { + /* neither data nor parameter terminal, so error.*/ + break; + } + + if (!ok) + break; + } + /* Only true if no check failed */ + can_start = (i == terminal_count); + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_process_group_submit invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_can_process_group_start failed (%i)\n", + retval); + } + return can_start; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +size_t ia_css_process_group_get_size( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_size(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + size = process_group->size; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_size invalid argument\n"); + } + return size; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_group_state_t ia_css_process_group_get_state( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + ia_css_process_group_state_t state = IA_CSS_N_PROCESS_GROUP_STATES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_state(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + state = process_group->state; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_state invalid argument\n"); + } + return state; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +const ia_css_rbm_t *ia_css_process_group_get_routing_bitmap( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + const ia_css_rbm_t *rbm = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_routing_bitmap(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + rbm = &(process_group->routing_bitmap); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_routing_bitmap invalid argument\n"); + } + return rbm; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint16_t ia_css_process_group_get_fragment_count( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint16_t fragment_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_fragment_count(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + fragment_count = process_group->fragment_count; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_count invalid argument\n"); + } + return fragment_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_group_get_process_count( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint8_t process_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_process_count(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + process_count = process_group->process_count; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_process_count invalid argument\n"); + } + return process_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_group_get_terminal_count( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint8_t terminal_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_terminal_count(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + terminal_count = process_group->terminal_count; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_terminal_count invalid argument\n"); + } + return terminal_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_get_pg_load_start_ts( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint32_t pg_load_start_ts = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_pg_load_start_ts(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + pg_load_start_ts = process_group->pg_load_start_ts; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_pg_load_start_ts invalid argument\n"); + } + return pg_load_start_ts; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_get_pg_load_cycles( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint32_t pg_load_cycles = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_pg_load_cycles(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + pg_load_cycles = process_group->pg_load_cycles; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_pg_load_cycles invalid argument\n"); + } + return pg_load_cycles; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_get_pg_init_cycles( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint32_t pg_init_cycles = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_pg_init_cycles(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + pg_init_cycles = process_group->pg_init_cycles; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_pg_init_cycles invalid argument\n"); + } + return pg_init_cycles; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_get_pg_processing_cycles( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint32_t pg_processing_cycles = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_pg_processing_cycles(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + pg_processing_cycles = process_group->pg_processing_cycles; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_pg_processing_cycles invalid argument\n"); + } + return pg_processing_cycles; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_terminal_t *ia_css_process_group_get_terminal_from_type( + const ia_css_process_group_t *process_group, + const ia_css_terminal_type_t terminal_type) +{ + unsigned int proc_cnt; + ia_css_terminal_t *terminal = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_terminal_from_type(): enter:\n"); + + for (proc_cnt = 0; proc_cnt < (unsigned int)ia_css_process_group_get_terminal_count(process_group); proc_cnt++) { + terminal = ia_css_process_group_get_terminal(process_group, proc_cnt); + if (terminal == NULL) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_terminal_from_type() Failed to get terminal %d", proc_cnt); + goto EXIT; + } + if (ia_css_terminal_get_type(terminal) == terminal_type) { + return terminal; + } + terminal = NULL; /* If not the expected type, return NULL */ + } +EXIT: + return terminal; +} + +/* Returns the terminal or NULL if it was not found + For some of those maybe valid to not exist at all in the process group */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +const ia_css_terminal_t *ia_css_process_group_get_single_instance_terminal( + const ia_css_process_group_t *process_group, + ia_css_terminal_type_t term_type) +{ + int i, term_count; + + assert(process_group != NULL); + + /* Those below have at most one instance per process group */ + assert(term_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN || + term_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT || + term_type == IA_CSS_TERMINAL_TYPE_PROGRAM || + term_type == IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT); + + term_count = ia_css_process_group_get_terminal_count(process_group); + + for (i = 0; i < term_count; i++) { + const ia_css_terminal_t *terminal = ia_css_process_group_get_terminal(process_group, i); + + if (ia_css_terminal_get_type(terminal) == term_type) { + /* Only one parameter terminal per process group */ + return terminal; + } + } + + return NULL; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_terminal_t *ia_css_process_group_get_terminal( + const ia_css_process_group_t *process_grp, + const unsigned int terminal_num) +{ + DECLARE_ERRVAL + ia_css_terminal_t *terminal_ptr = NULL; + uint16_t *terminal_offset_table; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_terminal(): enter:\n"); + + verifexitval(process_grp != NULL, EFAULT); + verifexitval(terminal_num < process_grp->terminal_count, EINVAL); + + terminal_offset_table = + (uint16_t *)((char *)process_grp + + process_grp->terminals_offset); + terminal_ptr = + (ia_css_terminal_t *)((char *)process_grp + + terminal_offset_table[terminal_num]); + + verifexitval(terminal_ptr != NULL, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_terminal invalid argument\n"); + } + return terminal_ptr; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_t *ia_css_process_group_get_process( + const ia_css_process_group_t *process_grp, + const unsigned int process_num) +{ + DECLARE_ERRVAL + ia_css_process_t *process_ptr = NULL; + uint16_t *process_offset_table; + + verifexitval(process_grp != NULL, EFAULT); + verifexitval(process_num < process_grp->process_count, EINVAL); + + process_offset_table = + (uint16_t *)((char *)process_grp + + process_grp->processes_offset); + process_ptr = + (ia_css_process_t *)((char *)process_grp + + process_offset_table[process_num]); + + verifexitval(process_ptr != NULL, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_process invalid argument\n"); + } + return process_ptr; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_program_group_ID_t ia_css_process_group_get_program_group_ID( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + ia_css_program_group_ID_t id = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_program_group_ID(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + id = process_group->ID; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_program_group_ID invalid argument\n"); + } + return id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t ia_css_process_group_get_resource_bitmap( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t resource_bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_resource_bitmap(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + resource_bitmap = process_group->resource_bitmap; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_resource_bitmap invalid argument\n"); + } + return resource_bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_resource_bitmap( + ia_css_process_group_t *process_group, + const vied_nci_resource_bitmap_t resource_bitmap) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_resource_bitmap(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + process_group->resource_bitmap = resource_bitmap; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_resource_bitmap invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_resource_bitmap failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_routing_bitmap( + ia_css_process_group_t *process_group, + const ia_css_rbm_t rbm) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_routing_bitmap(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + process_group->routing_bitmap = rbm; + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_routing_bitmap invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_routing_bitmap failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_group_compute_cycle_count( + const ia_css_program_group_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + DECLARE_ERRVAL + uint32_t cycle_count = 0; + + NOT_USED(manifest); + NOT_USED(param); + + verifexitval(manifest != NULL, EFAULT); + verifexitval(param != NULL, EFAULT); + + cycle_count = 1; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_compute_cycle_count invalid argument\n"); + } + return cycle_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_fragment_state( + ia_css_process_group_t *process_group, + uint16_t fragment_state) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_process_group_set_fragment_state(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + verifexitval(fragment_state <= ia_css_process_group_get_fragment_count( + process_group), EINVAL); + + process_group->fragment_state = fragment_state; + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_fragment_state invalid argument process_group\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_fragment_state failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_get_fragment_state( + const ia_css_process_group_t *process_group, + uint16_t *fragment_state) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_fragment_state(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + verifexitval(fragment_state != NULL, EFAULT); + + *fragment_state = process_group->fragment_state; + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_state invalid argument\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_fragment_state failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_get_ipu_vaddress( + const ia_css_process_group_t *process_group, + vied_vaddress_t *ipu_vaddress) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_ipu_vaddress(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + verifexitval(ipu_vaddress != NULL, EFAULT); + + *ipu_vaddress = process_group->ipu_virtual_address; + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_ipu_vaddress invalid argument\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_ipu_vaddress failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_ipu_vaddress( + ia_css_process_group_t *process_group, + vied_vaddress_t ipu_vaddress) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_ipu_vaddress(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + process_group->ipu_virtual_address = ipu_vaddress; + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_ipu_vaddress invalid argument\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_ipu_vaddress failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_group_get_protocol_version( + const ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint8_t protocol_version = IA_CSS_PROCESS_GROUP_N_PROTOCOLS; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_protocol_version(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + protocol_version = process_group->protocol_version; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_protocol_version invalid argument\n"); + } + return protocol_version; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_group_get_base_queue_id( + ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint8_t queue_id = IA_CSS_N_PSYS_CMD_QUEUE_ID; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_base_queue_id(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + queue_id = process_group->base_queue_id; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_base_queue_id invalid argument\n"); + } + return queue_id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_base_queue_id( + ia_css_process_group_t *process_group, + uint8_t queue_id) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_base_queue_id(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + process_group->base_queue_id = queue_id; + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_base_queue_id invalid argument\n"); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_group_get_num_queues( + ia_css_process_group_t *process_group) +{ + DECLARE_ERRVAL + uint8_t num_queues = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_get_num_queues(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + num_queues = process_group->num_queues; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_get_num_queues invalid argument\n"); + } + return num_queues; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_group_set_num_queues( + ia_css_process_group_t *process_group, + uint8_t num_queues) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_group_set_num_queues(): enter:\n"); + + verifexitval(process_group != NULL, EFAULT); + + process_group->num_queues = num_queues; + retval = 0; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_group_set_num_queues invalid argument\n"); + } + return retval; +} + + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_process_group_has_vp(const ia_css_process_group_t *process_group) +{ + bool has_vp = false; + uint32_t i; + + uint8_t process_count = ia_css_process_group_get_process_count(process_group); + + for (i = 0; i < process_count; i++) { + ia_css_process_t *process; + vied_nci_cell_ID_t cell_id; + + process = ia_css_process_group_get_process(process_group, i); + cell_id = ia_css_process_get_cell(process); + + if (vied_nci_cell_get_type(cell_id) == VIED_NCI_VP_TYPE_ID) { + has_vp = true; + break; + } + } + + return has_vp; +} + +#endif /* __IA_CSS_PSYS_PROCESS_GROUP_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_impl.h new file mode 100644 index 0000000000000..e9a3ef6c6f3c6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_impl.h @@ -0,0 +1,638 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_IMPL_H +#define __IA_CSS_PSYS_PROCESS_IMPL_H + +#include + +#include +#include + +#include +#include +#include + +#include + +#include "ia_css_psys_dynamic_trace.h" +#include "ia_css_psys_process_private_types.h" + +/** Function only to be used in ia_css_psys_process_impl.h and ia_css_psys_process.h */ +STORAGE_CLASS_INLINE vied_nci_cell_ID_t ia_css_process_cells_get_cell(const ia_css_process_t *process, int index) +{ + assert(index < IA_CSS_PROCESS_MAX_CELLS); + if (index >= IA_CSS_PROCESS_MAX_CELLS) { + return VIED_NCI_N_CELL_ID; + } +#if IA_CSS_PROCESS_MAX_CELLS == 1 + return process->cell_id; +#else + return process->cells[index]; +#endif +} + +/** Function only to be used in ia_css_psys_process_impl.h and ia_css_psys_process.h */ +STORAGE_CLASS_INLINE void ia_css_process_cells_set_cell(ia_css_process_t *process, int index, vied_nci_cell_ID_t cell_id) +{ + assert(index < IA_CSS_PROCESS_MAX_CELLS); + if (index >= IA_CSS_PROCESS_MAX_CELLS) { + return; + } +#if IA_CSS_PROCESS_MAX_CELLS == 1 + process->cell_id = cell_id; +#else + process->cells[index] = cell_id; +#endif +} + +/** Function only to be used in ia_css_psys_process_impl.h and ia_css_psys_process */ +STORAGE_CLASS_INLINE void ia_css_process_cells_clear(ia_css_process_t *process) +{ + int i; + + for (i = 0; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + ia_css_process_cells_set_cell(process, i, VIED_NCI_N_CELL_ID); + } +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_cell_ID_t ia_css_process_get_cell( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + vied_nci_cell_ID_t cell_id = VIED_NCI_N_CELL_ID; + int i = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_cell(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + +#if IA_CSS_PROCESS_MAX_CELLS > 1 + for (i = 1; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + assert(ia_css_process_cells_get_cell(process, i) == VIED_NCI_N_CELL_ID); +#ifdef __HIVECC +#pragma hivecc unroll +#endif + } +#else + (void)i; +#endif + cell_id = ia_css_process_cells_get_cell(process, 0); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_cell invalid argument\n"); + } + return cell_id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_mem_ID_t ia_css_process_get_ext_mem_id( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type) +{ + DECLARE_ERRVAL + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_ext_mem(): enter:\n"); + + verifexitval(process != NULL && mem_type < VIED_NCI_N_DATA_MEM_TYPE_ID, EFAULT); + +EXIT: + if (!noerror()) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_ext_mem invalid argument\n"); + return IA_CSS_PROCESS_INVALID_OFFSET; + } + return process->ext_mem_id[mem_type]; +} + + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint32_t ia_css_process_get_program_idx( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_program_idx(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_program_idx invalid argument\n"); + return IA_CSS_PROCESS_INVALID_PROGRAM_IDX; + } + return process->program_idx; +} + + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_size_t ia_css_process_get_dev_chn( + const ia_css_process_t *process, + const vied_nci_dev_chn_ID_t dev_chn_id) +{ + DECLARE_ERRVAL + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_dev_chn(): enter:\n"); + + verifexitval(process != NULL && dev_chn_id < VIED_NCI_N_DEV_CHN_ID, EFAULT); + +EXIT: + if (!noerror()) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_dev_chn(): invalid arguments\n"); + return IA_CSS_PROCESS_INVALID_OFFSET; + } + return process->dev_chn_offset[dev_chn_id]; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_size_t ia_css_process_get_int_mem_offset( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_id) +{ + DECLARE_ERRVAL + vied_nci_resource_size_t int_mem_offset = IA_CSS_PROCESS_INVALID_OFFSET; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_int_mem_offset(): enter:\n"); + + verifexitval(process != NULL && mem_id < VIED_NCI_N_MEM_TYPE_ID, EFAULT); + +EXIT: + if (noerror()) { + int_mem_offset = process->int_mem_offset[mem_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_int_mem_offset invalid argument\n"); + } + + return int_mem_offset; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_size_t ia_css_process_get_ext_mem_offset( + const ia_css_process_t *process, + const vied_nci_mem_type_ID_t mem_type_id) +{ + DECLARE_ERRVAL + vied_nci_resource_size_t ext_mem_offset = IA_CSS_PROCESS_INVALID_OFFSET; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_ext_mem_offset(): enter:\n"); + + verifexitval(process != NULL && mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID, EFAULT); + +EXIT: + if (noerror()) { + ext_mem_offset = process->ext_mem_offset[mem_type_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_ext_mem_offset invalid argument\n"); + } + + return ext_mem_offset; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +size_t ia_css_process_get_size( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_size(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + +EXIT: + if (noerror()) { + size = process->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_size invalid argument\n"); + } + + return size; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_state_t ia_css_process_get_state( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + ia_css_process_state_t state = IA_CSS_N_PROCESS_STATES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_state(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + +EXIT: + if (noerror()) { + state = process->state; + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_state invalid argument\n"); + } + + return state; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_process_set_state( + ia_css_process_t *process, + ia_css_process_state_t state) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_set_state(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + + process->state = state; + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_set_state invalid argument\n"); + } + + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_get_cell_dependency_count( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + uint8_t cell_dependency_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_cell_dependency_count(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + cell_dependency_count = process->cell_dependency_count; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_cell_dependency_count invalid argument\n"); + } + return cell_dependency_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_get_terminal_dependency_count( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + uint8_t terminal_dependency_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_terminal_dependency_count(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + terminal_dependency_count = process->terminal_dependency_count; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_terminal_dependency_count invalid argument process\n"); + } + return terminal_dependency_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_group_t *ia_css_process_get_parent( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + ia_css_process_group_t *parent = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_parent(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + + parent = + (ia_css_process_group_t *) ((char *)process + process->parent_offset); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_parent invalid argument process\n"); + } + return parent; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_program_ID_t ia_css_process_get_program_ID( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + ia_css_program_ID_t id = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_program_ID(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + + id = process->ID; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_program_ID invalid argument process\n"); + } + return id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_id_t ia_css_process_get_cell_dependency( + const ia_css_process_t *process, + const unsigned int cell_num) +{ + DECLARE_ERRVAL + vied_nci_resource_id_t cell_dependency = + IA_CSS_PROCESS_INVALID_DEPENDENCY; + vied_nci_resource_id_t *cell_dep_ptr = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_cell_dependency(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + verifexitval(cell_num < process->cell_dependency_count, EFAULT); + + cell_dep_ptr = + (vied_nci_resource_id_t *) + ((char *)process + process->cell_dependencies_offset); + cell_dependency = *(cell_dep_ptr + cell_num); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_cell_dependency invalid argument\n"); + } + return cell_dependency; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_process_get_terminal_dependency( + const ia_css_process_t *process, + const unsigned int terminal_num) +{ + DECLARE_ERRVAL + uint8_t *ter_dep_ptr = NULL; + uint8_t ter_dep = IA_CSS_PROCESS_INVALID_DEPENDENCY; + + verifexitval(process != NULL, EFAULT); + verifexitval(terminal_num < process->terminal_dependency_count, EFAULT); + + ter_dep_ptr = (uint8_t *) ((char *)process + + process->terminal_dependencies_offset); + + ter_dep = *(ter_dep_ptr + terminal_num); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_terminal_dependency invalid argument\n"); + } + return ter_dep; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_kernel_bitmap_t ia_css_process_get_kernel_bitmap( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + ia_css_kernel_bitmap_t bitmap = ia_css_kernel_bitmap_clear(); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_kernel_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + + bitmap = process->kernel_bitmap; + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_kernel_bitmap invalid argument process\n"); + } + return bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t ia_css_process_get_cells_bitmap( + const ia_css_process_t *process) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t bitmap = 0; + vied_nci_cell_ID_t cell_id; + int i = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_cell_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); + + for (i = 0; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + cell_id = ia_css_process_cells_get_cell(process, i); + if (cell_id != VIED_NCI_N_CELL_ID) { + bitmap |= (1 << cell_id); + } +#ifdef __HIVECC +#pragma hivecc unroll +#endif + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_cells_bitmap invalid argument process\n"); + } + + return bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t *ia_css_process_get_dfm_port_bitmap_ptr( + ia_css_process_t *process) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t *p_bitmap = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_dfm_port_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + p_bitmap = &process->dfm_port_bitmap[0]; +#else + p_bitmap = NULL; +#endif +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_dfm_port_bitmap invalid argument process\n"); + } + + return p_bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t *ia_css_process_get_dfm_active_port_bitmap_ptr( + ia_css_process_t *process) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t *p_bitmap = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_dfm_port_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + p_bitmap = &process->dfm_active_port_bitmap[0]; +#else + p_bitmap = NULL; +#endif +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_dfm_port_bitmap invalid argument process\n"); + } + + return p_bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t ia_css_process_get_dfm_port_bitmap( + const ia_css_process_t *process, + vied_nci_dev_dfm_id_t dfm_res_id) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_dfm_port_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexitval(dfm_res_id < VIED_NCI_N_DEV_DFM_ID, EFAULT); + bitmap = process->dfm_port_bitmap[dfm_res_id]; +#else + bitmap = 0; + (void)dfm_res_id; +#endif +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_dfm_port_bitmap invalid argument process\n"); + } + + return bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_nci_resource_bitmap_t ia_css_process_get_dfm_active_port_bitmap( + const ia_css_process_t *process, + vied_nci_dev_dfm_id_t dfm_res_id) +{ + DECLARE_ERRVAL + vied_nci_resource_bitmap_t bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_process_get_dfm_active_port_bitmap(): enter:\n"); + + verifexitval(process != NULL, EFAULT); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexitval(dfm_res_id < VIED_NCI_N_DEV_DFM_ID, EFAULT); + bitmap = process->dfm_active_port_bitmap[dfm_res_id]; +#else + bitmap = 0; + (void)dfm_res_id; +#endif +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_process_get_dfm_active_port_bitmap invalid argument process\n"); + } + return bitmap; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_process_valid( + const ia_css_process_t *process, + const ia_css_program_manifest_t *p_manifest) +{ + DECLARE_ERRVAL + bool invalid_flag = false; + ia_css_program_ID_t prog_id; + ia_css_kernel_bitmap_t prog_kernel_bitmap; + + verifexitval(NULL != process, EFAULT); + verifexitval(NULL != p_manifest, EFAULT); + + prog_id = ia_css_process_get_program_ID(process); + verifjmpexit(prog_id == + ia_css_program_manifest_get_program_ID(p_manifest)); + + prog_kernel_bitmap = + ia_css_program_manifest_get_kernel_bitmap(p_manifest); + + invalid_flag = (process->size <= process->cell_dependencies_offset) || + (process->size <= process->terminal_dependencies_offset) || + !ia_css_is_kernel_bitmap_subset(prog_kernel_bitmap, + process->kernel_bitmap); + + if (ia_css_has_program_manifest_fixed_cell(p_manifest)) { + vied_nci_cell_ID_t cell_id; + + cell_id = ia_css_program_manifest_get_cell_ID(p_manifest); + invalid_flag = invalid_flag || + (cell_id != (vied_nci_cell_ID_t)(ia_css_process_get_cell(process))); + } + invalid_flag = invalid_flag || + ((process->cell_dependency_count + + process->terminal_dependency_count) == 0) || + (process->cell_dependency_count != + ia_css_program_manifest_get_program_dependency_count(p_manifest)) || + (process->terminal_dependency_count != + ia_css_program_manifest_get_terminal_dependency_count(p_manifest)); + + /* TODO: to be removed once all PGs pass validation */ + if (invalid_flag == true) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_is_process_valid(): false\n"); + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_process_valid() invalid argument\n"); + return false; + } else { + return (!invalid_flag); + } +} + +#endif /* __IA_CSS_PSYS_PROCESS_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_private_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_private_types.h new file mode 100644 index 0000000000000..ae0affde97187 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_process_private_types.h @@ -0,0 +1,87 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROCESS_PRIVATE_TYPES_H +#define __IA_CSS_PSYS_PROCESS_PRIVATE_TYPES_H + +#include "ia_css_psys_process_types.h" +#include "vied_nci_psys_resource_model.h" + +#define N_UINT32_IN_PROCESS_STRUCT 2 +#define N_UINT16_IN_PROCESS_STRUCT 3 +#define N_UINT8_IN_PROCESS_STRUCT 2 + +#define SIZE_OF_PROCESS_STRUCT_BITS \ + (IA_CSS_KERNEL_BITMAP_BITS \ + + (N_UINT32_IN_PROCESS_STRUCT * 32) \ + + IA_CSS_PROGRAM_ID_BITS \ + + (VIED_NCI_RESOURCE_BITMAP_BITS * VIED_NCI_N_DEV_DFM_ID) \ + + (VIED_NCI_RESOURCE_BITMAP_BITS * VIED_NCI_N_DEV_DFM_ID) \ + + IA_CSS_PROCESS_STATE_BITS \ + + (N_UINT16_IN_PROCESS_STRUCT * 16) \ + + (VIED_NCI_N_MEM_TYPE_ID * VIED_NCI_RESOURCE_SIZE_BITS) \ + + (VIED_NCI_N_DATA_MEM_TYPE_ID * VIED_NCI_RESOURCE_SIZE_BITS) \ + + (VIED_NCI_N_DEV_CHN_ID * VIED_NCI_RESOURCE_SIZE_BITS) \ + + (IA_CSS_PROCESS_MAX_CELLS * VIED_NCI_RESOURCE_ID_BITS) \ + + (VIED_NCI_N_MEM_TYPE_ID * VIED_NCI_RESOURCE_ID_BITS) \ + + (VIED_NCI_N_DATA_MEM_TYPE_ID * VIED_NCI_RESOURCE_ID_BITS) \ + + (N_UINT8_IN_PROCESS_STRUCT * 8) \ + + (N_PADDING_UINT8_IN_PROCESS_STRUCT * 8)) + +struct ia_css_process_s { + /**< Indicate which kernels lead to this process being used */ + ia_css_kernel_bitmap_t kernel_bitmap; + uint32_t size; /**< Size of this structure */ + ia_css_program_ID_t ID; /**< Referal ID to a specific program FW */ + uint32_t program_idx; /**< Program Index into the PG manifest */ +#if (VIED_NCI_N_DEV_DFM_ID > 0) + /**< DFM port allocated to this process */ + vied_nci_resource_bitmap_t dfm_port_bitmap[VIED_NCI_N_DEV_DFM_ID]; + /**< Active DFM ports which need a kick */ + vied_nci_resource_bitmap_t dfm_active_port_bitmap[VIED_NCI_N_DEV_DFM_ID]; +#endif + /**< State of the process FSM dependent on the parent FSM */ + ia_css_process_state_t state; + int16_t parent_offset; /**< Reference to the process group */ + /**< Array[dependency_count] of ID's of the cells that provide input */ + uint16_t cell_dependencies_offset; + /**< Array[terminal_dependency_count] of indices of connected terminals */ + uint16_t terminal_dependencies_offset; + /**< (internal) Memory allocation offset given to this process */ + vied_nci_resource_size_t int_mem_offset[VIED_NCI_N_MEM_TYPE_ID]; + /**< (external) Memory allocation offset given to this process */ + vied_nci_resource_size_t ext_mem_offset[VIED_NCI_N_DATA_MEM_TYPE_ID]; + /**< Device channel allocation offset given to this process */ + vied_nci_resource_size_t dev_chn_offset[VIED_NCI_N_DEV_CHN_ID]; + /**< Cells (VP, ACB) allocated for the process*/ +#if IA_CSS_PROCESS_MAX_CELLS == 1 + vied_nci_resource_id_t cell_id; +#else + vied_nci_resource_id_t cells[IA_CSS_PROCESS_MAX_CELLS]; +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ + /**< (internal) Memory ID; This is redundant, derived from cell_id */ + vied_nci_resource_id_t int_mem_id[VIED_NCI_N_MEM_TYPE_ID]; + /**< (external) Memory ID */ + vied_nci_resource_id_t ext_mem_id[VIED_NCI_N_DATA_MEM_TYPE_ID]; + /**< Number of processes (mapped on cells) this process depends on */ + uint8_t cell_dependency_count; + /**< Number of terminals this process depends on */ + uint8_t terminal_dependency_count; + /**< Padding bytes for 64bit alignment*/ +#if (N_PADDING_UINT8_IN_PROCESS_STRUCT > 0) + uint8_t padding[N_PADDING_UINT8_IN_PROCESS_STRUCT]; +#endif /*(N_PADDING_UINT8_IN_PROCESS_STRUCT > 0)*/ +}; + +#endif /* __IA_CSS_PSYS_PROCESS_PRIVATE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal.c new file mode 100644 index 0000000000000..632d6134b1471 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal.c @@ -0,0 +1,604 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_dynamic_storage_class.h" +#include "ia_css_psys_terminal_private_types.h" +#include "ia_css_terminal_types.h" + +/* + * Functions to possibly inline + */ + +#ifndef __IA_CSS_PSYS_DYNAMIC_INLINE__ +#include "ia_css_psys_terminal_impl.h" +#endif /* __IA_CSS_PSYS_DYNAMIC_INLINE__ */ + +STORAGE_CLASS_INLINE void __terminal_dummy_check_alignment(void) +{ + COMPILATION_ERROR_IF( + SIZE_OF_PARAM_TERMINAL_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_param_terminal_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_param_terminal_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PARAM_SEC_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_param_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_param_section_desc_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_SPATIAL_PARAM_TERM_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_spatial_param_terminal_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_spatial_param_terminal_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAME_GRID_PARAM_SEC_STRUCT_BITS != + (CHAR_BIT * sizeof( + ia_css_frame_grid_param_section_desc_t))); + + COMPILATION_ERROR_IF(0 != sizeof( + ia_css_frame_grid_param_section_desc_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAG_GRID_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_fragment_grid_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_fragment_grid_desc_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_SLICED_PARAM_TERM_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_sliced_param_terminal_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_sliced_param_terminal_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAGMENT_SLICE_DESC_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_fragment_slice_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_fragment_slice_desc_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_SLICE_PARAM_SECTION_DESC_STRUCT_BITS != + (CHAR_BIT * sizeof( + ia_css_slice_param_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_slice_param_section_desc_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_TERM_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_program_terminal_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_terminal_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAG_SEQ_INFO_STRUCT_BITS != + (CHAR_BIT * sizeof( + ia_css_kernel_fragment_sequencer_info_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_kernel_fragment_sequencer_info_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAG_SEQ_COMMANDS_STRUCT_BITS != + (CHAR_BIT * sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_kernel_fragment_sequencer_command_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAG_PARAM_SEC_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_fragment_param_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_fragment_param_section_desc_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_CONTROL_INIT_LOAD_SECTION_DESC_STRUCT_BITS != + (CHAR_BIT * + sizeof(ia_css_program_control_init_load_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_control_init_load_section_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_CONTROL_INIT_CONNECT_SECTION_DESC_STRUCT_BITS != + (CHAR_BIT * + sizeof(ia_css_program_control_init_connect_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_control_init_connect_section_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROGRAM_DESC_CONTROL_INFO_STRUCT_BITS != + (CHAR_BIT * + sizeof(struct ia_css_program_desc_control_info_s))); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_CONTROL_INIT_PROG_DESC_STRUCT_BITS != + (CHAR_BIT * + sizeof(ia_css_program_control_init_program_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_control_init_program_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_CONTROL_INIT_TERM_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_program_control_init_terminal_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_control_init_terminal_t) % + sizeof(uint64_t)); +} + +/* + * Functions not to inline + */ + +/* + * This source file is created with the intention of sharing and + * compiled for host and firmware. Since there is no native 64bit + * data type support for firmware this wouldn't compile for SP + * tile. The part of the file that is not compilable are marked + * with the following __VIED_CELL marker and this comment. Once we + * come up with a solution to address this issue this will be + * removed. + */ +#if !defined(__VIED_CELL) +size_t ia_css_sizeof_terminal( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + size_t size = 0; + uint16_t fragment_count = + ia_css_program_group_param_get_fragment_count(param); + + COMPILATION_ERROR_IF( + SIZE_OF_DATA_TERMINAL_STRUCT_BITS != + (CHAR_BIT * sizeof(ia_css_data_terminal_t))); + + COMPILATION_ERROR_IF( + 0 != sizeof(ia_css_data_terminal_t)%sizeof(uint64_t)); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_sizeof_terminal(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + if (ia_css_is_terminal_manifest_parameter_terminal(manifest)) { + const ia_css_param_terminal_manifest_t *param_term_man = + (const ia_css_param_terminal_manifest_t *)manifest; + if (ia_css_terminal_manifest_get_type(manifest) == + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN) { + size = ia_css_param_in_terminal_get_descriptor_size( + param_term_man->param_manifest_section_desc_count); + } else if (ia_css_terminal_manifest_get_type(manifest) == + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT) { + size = ia_css_param_out_terminal_get_descriptor_size( + param_term_man->param_manifest_section_desc_count, + fragment_count); + } else { + assert(NULL == "Invalid parameter terminal type"); + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_sizeof_terminal(): Invalid parameter terminal type:\n"); + verifjmpexit(0); + } + } else if (ia_css_is_terminal_manifest_data_terminal(manifest)) { + size += sizeof(ia_css_data_terminal_t); + size += fragment_count * sizeof(ia_css_fragment_descriptor_t); + } else if (ia_css_is_terminal_manifest_program_terminal(manifest)) { + ia_css_program_terminal_manifest_t *prog_term_man = + (ia_css_program_terminal_manifest_t *)manifest; + + size = ia_css_program_terminal_get_descriptor_size( + fragment_count, + prog_term_man-> + fragment_param_manifest_section_desc_count, + prog_term_man-> + kernel_fragment_sequencer_info_manifest_info_count, + (fragment_count * prog_term_man-> + max_kernel_fragment_sequencer_command_desc)); + } else if (ia_css_is_terminal_manifest_spatial_parameter_terminal( + manifest)) { + ia_css_spatial_param_terminal_manifest_t *spatial_param_term = + (ia_css_spatial_param_terminal_manifest_t *)manifest; + size = ia_css_spatial_param_terminal_get_descriptor_size( + spatial_param_term-> + frame_grid_param_manifest_section_desc_count, + fragment_count); + } else if (ia_css_is_terminal_manifest_program_control_init_terminal( + manifest)) { + ia_css_program_control_init_terminal_manifest_t *progctrlinit_term_man = + (ia_css_program_control_init_terminal_manifest_t *)manifest; + + size = ia_css_program_control_init_terminal_get_descriptor_size( + progctrlinit_term_man); + } +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_sizeof_terminal invalid argument\n"); + } + return size; +} + +ia_css_terminal_t *ia_css_terminal_create( + void *raw_mem, + const ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_param_t *terminal_param, + ia_css_kernel_bitmap_t enable_bitmap) +{ + char *terminal_raw_ptr; + ia_css_terminal_t *terminal = NULL; + uint16_t fragment_count; + int i, j; + int retval = -1; + ia_css_program_group_param_t *param; + + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "ia_css_terminal_create(manifest %p, terminal_param %p): enter:\n", + manifest, terminal_param); + + param = ia_css_terminal_param_get_parent(terminal_param); + fragment_count = ia_css_program_group_param_get_fragment_count(param); + + verifexit(manifest != NULL); + verifexit(param != NULL); + + terminal_raw_ptr = (char *) raw_mem; + + terminal = (ia_css_terminal_t *) terminal_raw_ptr; + verifexit(terminal != NULL); + + terminal->size = (uint16_t)ia_css_sizeof_terminal(manifest, param); + verifexit(ia_css_terminal_set_type( + terminal, ia_css_terminal_manifest_get_type(manifest)) == 0); + + terminal->ID = ia_css_terminal_manifest_get_ID(manifest); + + verifexit(ia_css_terminal_set_buffer(terminal, + VIED_NULL) == 0); + + if (ia_css_is_terminal_manifest_data_terminal(manifest) == true) { + ia_css_data_terminal_t *dterminal = + (ia_css_data_terminal_t *)terminal; + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame(dterminal); + ia_css_kernel_bitmap_t intersection = + ia_css_kernel_bitmap_intersection(enable_bitmap, + ia_css_data_terminal_manifest_get_kernel_bitmap( + (const ia_css_data_terminal_manifest_t *)manifest)); + + verifexit(frame != NULL); + verifexit(ia_css_frame_set_buffer_state( + frame, IA_CSS_BUFFER_NULL) == 0); + verifexit(ia_css_is_kernel_bitmap_onehot(intersection) == + true); + + terminal_raw_ptr += sizeof(ia_css_data_terminal_t); + dterminal->fragment_descriptor_offset = + (uint16_t) (terminal_raw_ptr - (char *)terminal); + + dterminal->kernel_id = 0; + while (!ia_css_is_kernel_bitmap_empty(intersection)) { + intersection = ia_css_kernel_bitmap_shift( + intersection); + dterminal->kernel_id++; + } + assert(dterminal->kernel_id > 0); + dterminal->kernel_id -= 1; + + /* some terminal and fragment initialization */ + dterminal->frame_descriptor.frame_format_type = + terminal_param->frame_format_type; + for (i = 0; i < IA_CSS_N_DATA_DIMENSION; i++) { + dterminal->frame_descriptor.dimension[i] = + terminal_param->dimensions[i]; + } + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION] = + terminal_param->stride; + dterminal->frame_descriptor.bpp = terminal_param->bpp; + dterminal->frame_descriptor.bpe = terminal_param->bpe; + switch (dterminal->frame_descriptor.frame_format_type) { + case IA_CSS_DATA_FORMAT_UYVY: + case IA_CSS_DATA_FORMAT_YUYV: + case IA_CSS_DATA_FORMAT_Y800: + case IA_CSS_DATA_FORMAT_RGB565: + case IA_CSS_DATA_FORMAT_RGBA888: + case IA_CSS_DATA_FORMAT_BAYER_GRBG: + case IA_CSS_DATA_FORMAT_BAYER_RGGB: + case IA_CSS_DATA_FORMAT_BAYER_BGGR: + case IA_CSS_DATA_FORMAT_BAYER_GBRG: + case IA_CSS_DATA_FORMAT_RAW: + case IA_CSS_DATA_FORMAT_RAW_PACKED: + case IA_CSS_DATA_FORMAT_YYUVYY_VECTORIZED: + case IA_CSS_DATA_FORMAT_PAF: + dterminal->frame_descriptor.plane_count = 1; + dterminal->frame_descriptor.plane_offsets[0] = 0; + break; + case IA_CSS_DATA_FORMAT_NV12: + case IA_CSS_DATA_FORMAT_NV21: + case IA_CSS_DATA_FORMAT_NV16: + case IA_CSS_DATA_FORMAT_NV61: + dterminal->frame_descriptor.plane_count = 2; + dterminal->frame_descriptor.plane_offsets[0] = 0; + dterminal->frame_descriptor.plane_offsets[1] = + dterminal->frame_descriptor.plane_offsets[0] + + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION] * + dterminal->frame_descriptor.dimension[IA_CSS_ROW_DIMENSION]; + break; + case IA_CSS_DATA_FORMAT_YUV444: + case IA_CSS_DATA_FORMAT_RGB888: + case IA_CSS_DATA_FORMAT_YUV420_VECTORIZED: + dterminal->frame_descriptor.plane_count = 3; + dterminal->frame_descriptor.plane_offsets[0] = 0; + dterminal->frame_descriptor.plane_offsets[1] = + dterminal->frame_descriptor.plane_offsets[0] + + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION] * + dterminal->frame_descriptor.dimension[IA_CSS_ROW_DIMENSION]; + dterminal->frame_descriptor.plane_offsets[2] = + dterminal->frame_descriptor.plane_offsets[1] + + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION] * + dterminal->frame_descriptor.dimension[IA_CSS_ROW_DIMENSION]; + break; + case IA_CSS_DATA_FORMAT_YUV420: + dterminal->frame_descriptor.plane_count = 3; + dterminal->frame_descriptor.plane_offsets[0] = 0; + dterminal->frame_descriptor.plane_offsets[1] = + dterminal->frame_descriptor.plane_offsets[0] + + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION] * + dterminal->frame_descriptor.dimension[IA_CSS_ROW_DIMENSION]; + dterminal->frame_descriptor.plane_offsets[2] = + dterminal->frame_descriptor.plane_offsets[1] + + dterminal->frame_descriptor.stride[IA_CSS_COL_DIMENSION]/2 * + dterminal->frame_descriptor.dimension[IA_CSS_ROW_DIMENSION]/2; + break; + default: + /* Unset, resulting in potential terminal connect issues */ + dterminal->frame_descriptor.plane_count = 1; + dterminal->frame_descriptor.plane_offsets[0] = 0; + break; + } + /* + * Initial solution for single fragment initialization + * TODO: + * where to get the fragment description params from??? + */ + if (fragment_count > 0) { + ia_css_fragment_descriptor_t *fragment_descriptor = + (ia_css_fragment_descriptor_t *) + terminal_raw_ptr; + + fragment_descriptor->index[IA_CSS_COL_DIMENSION] = + terminal_param->index[IA_CSS_COL_DIMENSION]; + fragment_descriptor->index[IA_CSS_ROW_DIMENSION] = + terminal_param->index[IA_CSS_ROW_DIMENSION]; + fragment_descriptor->offset[0] = + terminal_param->offset; + for (i = 0; i < IA_CSS_N_DATA_DIMENSION; i++) { + fragment_descriptor->dimension[i] = + terminal_param->fragment_dimensions[i]; + } + } + /* end fragment stuff */ + } else if (ia_css_is_terminal_manifest_parameter_terminal(manifest) == + true) { + ia_css_param_terminal_t *pterminal = + (ia_css_param_terminal_t *)terminal; + uint16_t section_count = + ((const ia_css_param_terminal_manifest_t *)manifest)-> + param_manifest_section_desc_count; + size_t curr_offset = 0; + + pterminal->param_section_desc_offset = + sizeof(ia_css_param_terminal_t); + + for (i = 0; i < section_count; i++) { + ia_css_param_section_desc_t *section = + ia_css_param_in_terminal_get_param_section_desc( + pterminal, i); + const ia_css_param_manifest_section_desc_t * + man_section = + ia_css_param_terminal_manifest_get_prm_sct_desc( + (const ia_css_param_terminal_manifest_t *)manifest, i); + + verifjmpexit(man_section != NULL); + verifjmpexit(section != NULL); + + section->mem_size = man_section->max_mem_size; + section->mem_offset = curr_offset; + curr_offset += man_section->max_mem_size; + } + } else if (ia_css_is_terminal_manifest_program_terminal(manifest) == + true && + ia_css_terminal_manifest_get_type(manifest) == + IA_CSS_TERMINAL_TYPE_PROGRAM) { /* for program terminal */ + ia_css_program_terminal_t *prog_terminal = + (ia_css_program_terminal_t *)terminal; + const ia_css_program_terminal_manifest_t *prog_terminal_man = + (const ia_css_program_terminal_manifest_t *)manifest; + ia_css_kernel_fragment_sequencer_info_desc_t + *sequencer_info_desc_base = NULL; + uint16_t section_count = prog_terminal_man-> + fragment_param_manifest_section_desc_count; + uint16_t manifest_info_count = + prog_terminal_man-> + kernel_fragment_sequencer_info_manifest_info_count; + /* information needs to come from user or manifest once + * the size sizeof function is updated. + */ + uint16_t nof_command_objs = 0; + size_t curr_offset = 0; + + prog_terminal->kernel_fragment_sequencer_info_desc_offset = + sizeof(ia_css_program_terminal_t); + prog_terminal->fragment_param_section_desc_offset = + prog_terminal-> + kernel_fragment_sequencer_info_desc_offset + + (fragment_count * manifest_info_count * + sizeof(ia_css_kernel_fragment_sequencer_info_desc_t)) + + (nof_command_objs * + sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t)); + + NOT_USED(sequencer_info_desc_base); + for (i = 0; i < fragment_count; i++) { + for (j = 0; j < section_count; j++) { + ia_css_fragment_param_section_desc_t *section = + ia_css_program_terminal_get_frgmnt_prm_sct_desc( + prog_terminal, i, j, section_count); + const ia_css_fragment_param_manifest_section_desc_t * + man_section = +ia_css_program_terminal_manifest_get_frgmnt_prm_sct_desc + (prog_terminal_man, j); + + verifjmpexit(man_section != NULL); + verifjmpexit(section != NULL); + + section->mem_size = man_section->max_mem_size; + section->mem_offset = curr_offset; + curr_offset += man_section->max_mem_size; + } + + sequencer_info_desc_base = + ia_css_program_terminal_get_kernel_frgmnt_seq_info_desc( + prog_terminal, i, 0, + manifest_info_count); + + /* + * This offset cannot be initialized properly + * since the number of commands in every sequencer + * is not known at this point + */ + /*for (j = 0; j < manifest_info_count; j++) { + sequencer_info_desc_base[j]. + command_desc_offset = + prog_terminal-> + kernel_fragment_sequencer_info_desc_offset + + (manifest_info_count * + sizeof( + ia_css_kernel_fragment_sequencer_info_desc_t) + + (nof_command_objs * + sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t + )); + }*/ + } + } else if (ia_css_is_terminal_manifest_spatial_parameter_terminal( + manifest) == true) { + ia_css_spatial_param_terminal_t *spatial_param_terminal = + (ia_css_spatial_param_terminal_t *)terminal; + ia_css_spatial_param_terminal_manifest_t * + spatia_param_terminal_man = + (ia_css_spatial_param_terminal_manifest_t *)manifest; + + /* Initialize the spatial terminal structure */ + spatial_param_terminal->fragment_grid_desc_offset = + sizeof(ia_css_spatial_param_terminal_t); + spatial_param_terminal->frame_grid_param_section_desc_offset = + spatial_param_terminal->fragment_grid_desc_offset + + (fragment_count * sizeof(ia_css_fragment_grid_desc_t)); + spatial_param_terminal->kernel_id = + spatia_param_terminal_man->kernel_id; + } else if (ia_css_is_terminal_manifest_sliced_terminal(manifest) == + true) { + ia_css_sliced_param_terminal_t *sliced_param_terminal = + (ia_css_sliced_param_terminal_t *)terminal; + ia_css_sliced_param_terminal_manifest_t + *sliced_param_terminal_man = + (ia_css_sliced_param_terminal_manifest_t *)manifest; + + /* Initialize the sliced terminal structure */ + sliced_param_terminal->fragment_slice_desc_offset = + sizeof(ia_css_sliced_param_terminal_t); + sliced_param_terminal->kernel_id = + sliced_param_terminal_man->kernel_id; + } else if (ia_css_is_terminal_manifest_program_control_init_terminal( + manifest) == true) { + verifjmpexit(ia_css_program_control_init_terminal_init( + (ia_css_program_control_init_terminal_t *) + terminal, + (const ia_css_program_control_init_terminal_manifest_t *) + manifest) == 0); + } else { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_create failed, not a data or param terminal. Returning (%i)\n", + EFAULT); + goto EXIT; + } + + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_terminal_create(): Created successfully terminal %p\n", + terminal); + + retval = 0; +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_terminal_create invalid argument\n"); + } + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_create failed (%i)\n", retval); + terminal = ia_css_terminal_destroy(terminal); + } + return terminal; +} + +ia_css_terminal_t *ia_css_terminal_destroy( + ia_css_terminal_t *terminal) +{ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_terminal_destroy(terminal %p): enter:\n", terminal); + return terminal; +} + +uint16_t ia_css_param_terminal_compute_section_count( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param) /* Delete 2nd argument*/ +{ + uint16_t section_count = 0; + + NOT_USED(param); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_param_terminal_compute_section_count(): enter:\n"); + + verifexit(manifest != NULL); + section_count = ((const ia_css_param_terminal_manifest_t *)manifest)-> + param_manifest_section_desc_count; +EXIT: + if (NULL == manifest || NULL == param) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_param_terminal_compute_section_count: invalid argument\n"); + } + return section_count; +} +#endif /* !defined(__VIED_CELL) */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_impl.h new file mode 100644 index 0000000000000..b65813b40266c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_impl.h @@ -0,0 +1,1867 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_IMPL_H +#define __IA_CSS_PSYS_TERMINAL_IMPL_H + +#include + +#include +#include + +#include +#include + +#include + + +#include +#include /* for verifexit, verifjmpexit */ +#include /* for COMPILATION_ERROR_IF */ +#include /* for NOT_USED */ +#include "ia_css_psys_terminal_private_types.h" +#include "ia_css_terminal_manifest_types.h" +#include "ia_css_psys_dynamic_trace.h" +#include "ia_css_psys_manifest_types.h" +#include "ia_css_psys_program_group_private.h" +#include "ia_css_terminal_types.h" + +STORAGE_CLASS_INLINE int ia_css_data_terminal_print(const ia_css_terminal_t *terminal, + void *fid) +{ + + DECLARE_ERRVAL + int retval = -1; + int i; + ia_css_data_terminal_t *dterminal = (ia_css_data_terminal_t *)terminal; + uint16_t fragment_count = + ia_css_data_terminal_get_fragment_count(dterminal); + verifexitval(fragment_count != 0, EINVAL); + + retval = ia_css_frame_descriptor_print( + ia_css_data_terminal_get_frame_descriptor(dterminal), + fid); + verifexitval(retval == 0, EINVAL); + + retval = ia_css_frame_print( + ia_css_data_terminal_get_frame(dterminal), fid); + verifexitval(retval == 0, EINVAL); + + for (i = 0; i < (int)fragment_count; i++) { + retval = ia_css_fragment_descriptor_print( + ia_css_data_terminal_get_fragment_descriptor( + dterminal, i), fid); + verifexitval(retval == 0, EINVAL); + } + + retval = 0; +EXIT: + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_print failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_print( + const ia_css_terminal_t *terminal, + void *fid) +{ + DECLARE_ERRVAL + int retval = -1; + ia_css_terminal_type_t term_type = ia_css_terminal_get_type(terminal); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, INFO, + "ia_css_terminal_print(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "\tTerminal %p sizeof %d, typeof %d, parent %p\n", + terminal, + (int)ia_css_terminal_get_size(terminal), + (int)ia_css_terminal_get_type(terminal), + (void *)ia_css_terminal_get_parent(terminal)); + + switch (term_type) { + case IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT: + ia_css_program_control_init_terminal_print( + (ia_css_program_control_init_terminal_t *)terminal); + break; + case IA_CSS_TERMINAL_TYPE_DATA_IN: + case IA_CSS_TERMINAL_TYPE_DATA_OUT: + ia_css_data_terminal_print(terminal, fid); + break; + default: + /* other terminal prints are currently not supported */ + break; + } + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_print invalid argument terminal\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_print failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_input( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + bool is_input = false; + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_input(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + terminal_type = ia_css_terminal_get_type(terminal); + + switch (terminal_type) { + case IA_CSS_TERMINAL_TYPE_DATA_IN: /* Fall through */ + case IA_CSS_TERMINAL_TYPE_STATE_IN: /* Fall through */ + case IA_CSS_TERMINAL_TYPE_PARAM_STREAM: /* Fall through */ + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN: + case IA_CSS_TERMINAL_TYPE_PROGRAM: + case IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT: + is_input = true; + break; + case IA_CSS_TERMINAL_TYPE_DATA_OUT: /* Fall through */ + case IA_CSS_TERMINAL_TYPE_STATE_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + is_input = false; + break; + default: + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_input: Unknown terminal type (%d)\n", + terminal_type); + goto EXIT; + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_input invalid argument\n"); + } + return is_input; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +size_t ia_css_terminal_get_size( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_size(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + size = terminal->size; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_size invalid argument\n"); + } + return size; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_terminal_type_t ia_css_terminal_get_type( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_type(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + terminal_type = terminal->terminal_type; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_type invalid argument\n"); + } + return terminal_type; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_type( + ia_css_terminal_t *terminal, + const ia_css_terminal_type_t terminal_type) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_set_type(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + terminal->terminal_type = terminal_type; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_type invalid argument terminal\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_type failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint16_t ia_css_terminal_get_terminal_manifest_index( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + uint16_t terminal_manifest_index; + + terminal_manifest_index = 0xffff; + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_terminal_manifest_index(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + terminal_manifest_index = terminal->tm_index; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_terminal_manifest_index: invalid argument\n"); + } + return terminal_manifest_index; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_terminal_manifest_index( + ia_css_terminal_t *terminal, + const uint16_t terminal_manifest_index) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_set_terminal_manifest_index(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + terminal->tm_index = terminal_manifest_index; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_terminal_manifest_index: invalid argument terminal\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_terminal_manifest_index: failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_terminal_ID_t ia_css_terminal_get_ID( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_ID_t retval = IA_CSS_TERMINAL_INVALID_ID; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_ID(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + retval = terminal->ID; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_ID invalid argument\n"); + retval = 0; + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_data_terminal_get_kernel_id( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + uint8_t retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_kernel_id(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + retval = dterminal->kernel_id; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_kernel_id: invalid argument\n"); + retval = 0; + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_connection_type_t ia_css_data_terminal_get_connection_type( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + ia_css_connection_type_t connection_type = IA_CSS_N_CONNECTION_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_connection_type(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + connection_type = dterminal->connection_type; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_connection_type: invalid argument\n"); + } + return connection_type; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_data_terminal_get_link_id( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + uint8_t link_id = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_link_id(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + link_id = dterminal->link_id; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_link_id: invalid argument\n"); + } + return link_id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_data_terminal_set_link_id( + ia_css_data_terminal_t *dterminal, + const uint8_t link_id) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_set_link_id(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + dterminal->link_id = link_id; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_set_link_id: invalid argument terminal\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_set_link_id: failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_data_terminal_set_connection_type( + ia_css_data_terminal_t *dterminal, + const ia_css_connection_type_t connection_type) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_set_connection_type(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + dterminal->connection_type = connection_type; + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_set_connection_type: invalid argument dterminal\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_set_connection_type failed (%i)\n", + retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_group_t *ia_css_terminal_get_parent( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_process_group_t *parent = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_parent(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + parent = (ia_css_process_group_t *) ((char *)terminal + + terminal->parent_offset); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_parent invalid argument\n"); + } + return parent; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_parent( + ia_css_terminal_t *terminal, + ia_css_process_group_t *parent) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_set_parent(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + verifexitval(parent != NULL, EFAULT); + + terminal->parent_offset = (uint16_t) ((char *)parent - + (char *)terminal); + + retval = 0; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_parent invalid argument\n"); + } + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_parent failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_frame_t *ia_css_data_terminal_get_frame( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + ia_css_frame_t *frame = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_frame(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + frame = (ia_css_frame_t *)(&(dterminal->frame)); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_frame invalid argument\n"); + } + return frame; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_frame_descriptor_t *ia_css_data_terminal_get_frame_descriptor( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + ia_css_frame_descriptor_t *frame_descriptor = NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_frame_descriptor(): enter:\n"); + + verifexitval(dterminal != NULL, EFAULT); + + frame_descriptor = + (ia_css_frame_descriptor_t *)(&(dterminal->frame_descriptor)); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_frame_descriptor: invalid argument\n"); + } + return frame_descriptor; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_fragment_descriptor_t *ia_css_data_terminal_get_fragment_descriptor( + const ia_css_data_terminal_t *dterminal, + const unsigned int fragment_index) +{ + DECLARE_ERRVAL + ia_css_fragment_descriptor_t *fragment_descriptor = NULL; + uint16_t fragment_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_frame_descriptor(): enter:\n"); + + fragment_count = ia_css_data_terminal_get_fragment_count(dterminal); + + verifexitval(dterminal != NULL, EFAULT); + verifexitval(fragment_count != 0, EINVAL); + verifexitval(fragment_index < fragment_count, EINVAL); + + fragment_descriptor = (ia_css_fragment_descriptor_t *) + ((char *)dterminal + dterminal->fragment_descriptor_offset); + + fragment_descriptor += fragment_index; +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_frame_descriptor: invalid argument\n"); + } + return fragment_descriptor; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint16_t ia_css_data_terminal_get_fragment_count( + const ia_css_data_terminal_t *dterminal) +{ + DECLARE_ERRVAL + ia_css_process_group_t *parent; + uint16_t fragment_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_get_fragment_count(): enter:\n"); + + parent = ia_css_terminal_get_parent((ia_css_terminal_t *)dterminal); + + verifexitval(dterminal != NULL, EFAULT); + verifexitval(parent != NULL, EFAULT); + + fragment_count = ia_css_process_group_get_fragment_count(parent); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_get_fragment_count: invalid argument\n"); + } + return fragment_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_parameter_terminal( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_parameter_terminal(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + /* will return an error value on error */ + terminal_type = ia_css_terminal_get_type(terminal); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_parameter_terminal: invalid argument\n"); + } + return (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT); +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_data_terminal( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_data_terminal(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + /* will return an error value on error */ + terminal_type = ia_css_terminal_get_type(terminal); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_data_terminal invalid argument\n"); + } + return (terminal_type == IA_CSS_TERMINAL_TYPE_DATA_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_DATA_OUT); +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_program_terminal( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_program_terminal(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + /* will return an error value on error */ + terminal_type = ia_css_terminal_get_type(terminal); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_program_terminal: invalid argument\n"); + } + return (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM); +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_program_control_init_terminal( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_program_control_init_terminal(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + /* will return an error value on error */ + terminal_type = ia_css_terminal_get_type(terminal); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_program_control_init_terminal: invalid argument\n"); + } + return (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT); +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_spatial_parameter_terminal( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_spatial_parameter_terminal(): enter:\n"); + + verifexitval(terminal != NULL, EFAULT); + + /* will return an error value on error */ + terminal_type = ia_css_terminal_get_type(terminal); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_spatial_param_terminal: invalid argument\n"); + } + return (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT); +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_data_terminal_compute_plane_count( + const ia_css_terminal_manifest_t *manifest, + const ia_css_program_group_param_t *param) +{ + DECLARE_ERRVAL + uint8_t plane_count = 1; + + NOT_USED(manifest); + NOT_USED(param); + + verifexitval(manifest != NULL, EFAULT); + verifexitval(param != NULL, EFAULT); + /* TODO: Implementation Missing*/ + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_data_terminal_compute_plane_count(): enter:\n"); +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_data_terminal_compute_plane_count: invalid argument\n"); + } + return plane_count; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +vied_vaddress_t ia_css_terminal_get_buffer( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + vied_vaddress_t buffer = VIED_NULL; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_buffer(): enter:\n"); + + if (ia_css_is_terminal_data_terminal(terminal)) { + ia_css_frame_t *frame = ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + + verifexitval(frame != NULL, EFAULT); + buffer = ia_css_frame_get_buffer(frame); + } else if (ia_css_is_terminal_parameter_terminal(terminal)) { + const ia_css_param_terminal_t *param_terminal = + (const ia_css_param_terminal_t *)terminal; + + buffer = param_terminal->param_payload.buffer; + } else if (ia_css_is_terminal_program_terminal(terminal)) { + const ia_css_program_terminal_t *program_terminal = + (const ia_css_program_terminal_t *)terminal; + + buffer = program_terminal->param_payload.buffer; + } else if (ia_css_is_terminal_program_control_init_terminal(terminal)) { + const ia_css_program_control_init_terminal_t *program_ctrl_init_terminal = + (const ia_css_program_control_init_terminal_t *)terminal; + + buffer = program_ctrl_init_terminal->param_payload.buffer; + } else if (ia_css_is_terminal_spatial_parameter_terminal(terminal)) { + const ia_css_spatial_param_terminal_t *spatial_terminal = + (const ia_css_spatial_param_terminal_t *)terminal; + + buffer = spatial_terminal->param_payload.buffer; + } +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_buffer: invalid argument terminal\n"); + } + return buffer; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_buffer( + ia_css_terminal_t *terminal, + vied_vaddress_t buffer) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_set_buffer(): enter:\n"); + + if (ia_css_is_terminal_data_terminal(terminal) == true) { + /* Currently using Frames inside data terminal , + * TODO: start directly using data. + */ + ia_css_data_terminal_t *dterminal = + (ia_css_data_terminal_t *)terminal; + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame(dterminal); + + verifexitval(frame != NULL, EFAULT); + retval = ia_css_frame_set_buffer(frame, buffer); + verifexitval(retval == 0, EINVAL); + } else if (ia_css_is_terminal_parameter_terminal(terminal) == true) { + ia_css_param_terminal_t *pterminal = + (ia_css_param_terminal_t *)terminal; + + pterminal->param_payload.buffer = buffer; + retval = 0; + } else if (ia_css_is_terminal_program_terminal(terminal) == true) { + ia_css_program_terminal_t *pterminal = + (ia_css_program_terminal_t *)terminal; + + pterminal->param_payload.buffer = buffer; + retval = 0; + } else if (ia_css_is_terminal_program_control_init_terminal(terminal) == true) { + ia_css_program_control_init_terminal_t *pterminal = + (ia_css_program_control_init_terminal_t *)terminal; + + pterminal->param_payload.buffer = buffer; + retval = 0; + } else if (ia_css_is_terminal_spatial_parameter_terminal(terminal) == + true) { + ia_css_spatial_param_terminal_t *pterminal = + (ia_css_spatial_param_terminal_t *)terminal; + + pterminal->param_payload.buffer = buffer; + retval = 0; + } else { + return retval; + } + + retval = 0; +EXIT: + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_buffer failed (%i)\n", retval); + } + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_get_terminal_index( + const ia_css_terminal_t *terminal) +{ + DECLARE_ERRVAL + int terminal_index = -1; + + verifexitval(terminal != NULL, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_get_terminal_index(): enter:\n"); + + if (ia_css_is_terminal_data_terminal(terminal)) { + ia_css_frame_t *frame = ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + + verifexitval(frame != NULL, EFAULT); + terminal_index = ia_css_frame_get_data_index(frame); + } else { + if (ia_css_is_terminal_parameter_terminal(terminal)) { + const ia_css_param_terminal_t *param_terminal = + (const ia_css_param_terminal_t *)terminal; + + terminal_index = param_terminal->param_payload.terminal_index; + } else if (ia_css_is_terminal_program_terminal(terminal)) { + const ia_css_program_terminal_t *program_terminal = + (const ia_css_program_terminal_t *)terminal; + + terminal_index = program_terminal->param_payload.terminal_index; + } else if (ia_css_is_terminal_program_control_init_terminal(terminal)) { + const ia_css_program_control_init_terminal_t *program_ctrl_init_terminal = + (const ia_css_program_control_init_terminal_t *)terminal; + + terminal_index = program_ctrl_init_terminal->param_payload.terminal_index; + } else if (ia_css_is_terminal_spatial_parameter_terminal(terminal)) { + const ia_css_spatial_param_terminal_t *spatial_terminal = + (const ia_css_spatial_param_terminal_t *)terminal; + + terminal_index = spatial_terminal->param_payload.terminal_index; + } else { + verifjmpexit(0); + } + } +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_get_terminal_index: invalid argument\n"); + } + return terminal_index; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int ia_css_terminal_set_terminal_index( + ia_css_terminal_t *terminal, + unsigned int terminal_index) +{ + DECLARE_ERRVAL + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_terminal_set_terminal_index(): enter:\n"); + + if (ia_css_is_terminal_data_terminal(terminal) == true) { + /* Currently using Frames inside data terminal , + * TODO: start directly using data. + */ + ia_css_data_terminal_t *dterminal = + (ia_css_data_terminal_t *)terminal; + ia_css_frame_t *frame = + ia_css_data_terminal_get_frame(dterminal); + + verifexitval(frame != NULL, EFAULT); + retval = ia_css_frame_set_data_index(frame, terminal_index); + verifexitval(retval == 0, EINVAL); + } else { + if (ia_css_is_terminal_parameter_terminal(terminal) == true) { + ia_css_param_terminal_t *pterminal = + (ia_css_param_terminal_t *)terminal; + + pterminal->param_payload.terminal_index = terminal_index; + retval = 0; + } else if (ia_css_is_terminal_program_terminal(terminal) == true) { + ia_css_program_terminal_t *pterminal = + (ia_css_program_terminal_t *)terminal; + + pterminal->param_payload.terminal_index = terminal_index; + retval = 0; + } else if (ia_css_is_terminal_program_control_init_terminal(terminal) + == true) { + ia_css_program_control_init_terminal_t *pterminal = + (ia_css_program_control_init_terminal_t *)terminal; + + pterminal->param_payload.terminal_index = terminal_index; + retval = 0; + } else if (ia_css_is_terminal_spatial_parameter_terminal(terminal) == + true) { + ia_css_spatial_param_terminal_t *pterminal = + (ia_css_spatial_param_terminal_t *)terminal; + + pterminal->param_payload.terminal_index = terminal_index; + retval = 0; + } else { + return retval; + } + } + + retval = 0; +EXIT: + if (!noerror()) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, ERROR, + "ia_css_terminal_set_terminal_index failed (%i)\n", + retval); + } + return retval; +} + +STORAGE_CLASS_INLINE bool ia_css_is_data_terminal_valid( + const ia_css_terminal_t *terminal, + const ia_css_terminal_manifest_t *terminal_manifest, + const uint16_t nof_fragments) +{ + DECLARE_ERRVAL + bool invalid_flag = false; + + const ia_css_data_terminal_t *dterminal = + (ia_css_data_terminal_t *)terminal; + const ia_css_data_terminal_manifest_t *dt_manifest = + (ia_css_data_terminal_manifest_t *)terminal_manifest; + const ia_css_frame_descriptor_t *frame_descriptor; + ia_css_frame_format_bitmap_t man_frame_format_bitmap; + ia_css_frame_format_bitmap_t proc_frame_format_bitmap; + uint16_t max_value[IA_CSS_N_DATA_DIMENSION]; + uint16_t min_value[IA_CSS_N_DATA_DIMENSION]; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_data_terminal_valid enter\n"); + + frame_descriptor = + ia_css_data_terminal_get_frame_descriptor(dterminal); + verifexitval(frame_descriptor != NULL, EFAULT); + man_frame_format_bitmap = + ia_css_data_terminal_manifest_get_frame_format_bitmap( + dt_manifest); + proc_frame_format_bitmap = + ia_css_frame_format_bit_mask( + frame_descriptor->frame_format_type); + /* + * TODO: Replace by 'validation of frame format type'. + * Currently frame format type is not correctly set by manifest, + * waiting for HSD 1804260604 + */ + if (man_frame_format_bitmap > 0) { + if ((man_frame_format_bitmap & + proc_frame_format_bitmap) == 0) { + uint32_t *bitmap_arr = + (uint32_t *)&man_frame_format_bitmap; + + NOT_USED(bitmap_arr); + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Frame format type not defined in manifest\n"); + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + " man bitmap_arr[]: %d,%d\n", + bitmap_arr[1], bitmap_arr[0]); + bitmap_arr = (uint32_t *)&proc_frame_format_bitmap; + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + " proc bitmap_arr[]: %d,%d\n", + bitmap_arr[1], bitmap_arr[0]); + } + } else { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Frame format bitmap not defined in manifest\n"); + } + ia_css_data_terminal_manifest_get_min_size(dt_manifest, min_value); + /* + * TODO: Replace by validation of Minimal frame column dimensions. + * Currently not correctly set by manifest yet, + * waiting for HSD 1804260604 + */ + if ((frame_descriptor->dimension[IA_CSS_COL_DIMENSION] < + min_value[IA_CSS_COL_DIMENSION])) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Minimal frame column dimensions not set correctly (by manifest)\n"); + } + /* + * TODO: Replace by validation of Minimal frame row dimensions. + * Currently not correctly set by manifest yet, + * waiting for HSD 1804260604 + */ + if (frame_descriptor->dimension[IA_CSS_ROW_DIMENSION] < + min_value[IA_CSS_ROW_DIMENSION]) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Minimal frame row dimensions not set correctly (by manifest)\n"); + } + + ia_css_data_terminal_manifest_get_max_size(dt_manifest, max_value); + /* + * TODO: Replace by validation of Maximal frame column dimensions. + * Currently not correctly set by manifest yet, + * waiting for HSD 1804260604 + */ + if (frame_descriptor->dimension[IA_CSS_COL_DIMENSION] > + max_value[IA_CSS_COL_DIMENSION]) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Maximal frame column dimensions not set correctly (by manifest)\n"); + } + /* + * TODO: Replace by validation of Maximal frame row dimensions. + * Currently not correctly set by manifest yet, + * waiting for HSD 1804260604 + */ + if (frame_descriptor->dimension[IA_CSS_ROW_DIMENSION] > + max_value[IA_CSS_ROW_DIMENSION]) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "Maximal frame row dimensions not set correctly (by manifest)\n"); + } + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, VERBOSE, "min_value: [%d,%d]\n", + min_value[IA_CSS_COL_DIMENSION], + min_value[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, VERBOSE, "max_value: [%d,%d]\n", + max_value[IA_CSS_COL_DIMENSION], + max_value[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, VERBOSE, "frame dim: [%d,%d]\n", + frame_descriptor->dimension[IA_CSS_COL_DIMENSION], + frame_descriptor->dimension[IA_CSS_ROW_DIMENSION]); + /* + * TODO: Add validation of fragment dimensions. + * Currently not set by manifest yet, waiting for HSD 1804260604 + */ + NOT_USED(nof_fragments); + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_data_terminal_valid() invalid argument\n"); + return false; + } else { + return (!invalid_flag); + } +} + +STORAGE_CLASS_INLINE void ia_css_program_terminal_seq_info_print( + const ia_css_kernel_fragment_sequencer_info_manifest_desc_t + *man_seq_info_desc, + const ia_css_kernel_fragment_sequencer_info_desc_t + *term_seq_info_desc) +{ + NOT_USED(man_seq_info_desc); + NOT_USED(term_seq_info_desc); + + /* slice dimension column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_slice_dimension: %d\n", + term_seq_info_desc-> + fragment_grid_slice_dimension[IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_slice_dimension: %d\n", + man_seq_info_desc-> + max_fragment_grid_slice_dimension[IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_slice_dimension: %d\n", + man_seq_info_desc-> + min_fragment_grid_slice_dimension[IA_CSS_COL_DIMENSION]); + + /* slice dimension row */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_slice_dimension: %d\n", + term_seq_info_desc-> + fragment_grid_slice_dimension[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_slice_dimension: %d\n", + man_seq_info_desc-> + max_fragment_grid_slice_dimension[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_slice_dimension: %d\n", + man_seq_info_desc-> + min_fragment_grid_slice_dimension[IA_CSS_ROW_DIMENSION]); + + /* slice count column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_slice_count: %d\n", + term_seq_info_desc-> + fragment_grid_slice_count[IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_slice_count: %d\n", + man_seq_info_desc-> + max_fragment_grid_slice_count[IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_slice_count: %d\n", + man_seq_info_desc-> + min_fragment_grid_slice_count[IA_CSS_COL_DIMENSION]); + + /* slice count row */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_slice_count: %d\n", + term_seq_info_desc-> + fragment_grid_slice_count[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_slice_count: %d\n", + man_seq_info_desc-> + max_fragment_grid_slice_count[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_slice_count: %d\n", + man_seq_info_desc-> + min_fragment_grid_slice_count[IA_CSS_ROW_DIMENSION]); + + /* decimation factor column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_point_decimation_factor: %d\n", + term_seq_info_desc-> + fragment_grid_point_decimation_factor[IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_point_decimation_factor: %d\n", + man_seq_info_desc-> + max_fragment_grid_point_decimation_factor[IA_CSS_COL_DIMENSION] + ); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_point_decimation_factor: %d\n", + man_seq_info_desc-> + min_fragment_grid_point_decimation_factor[IA_CSS_COL_DIMENSION] + ); + + /* decimation factor row */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_point_decimation_factor: %d\n", + term_seq_info_desc-> + fragment_grid_point_decimation_factor[IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_point_decimation_factor: %d\n", + man_seq_info_desc-> + max_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_point_decimation_factor: %d\n", + man_seq_info_desc-> + min_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + + /* index column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_overlay_pixel_topleft_index: %d\n", + term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_overlay_pixel_topleft_index: %d\n", + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_overlay_pixel_topleft_index: %d\n", + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION]); + + /* index row */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_overlay_pixel_topleft_index: %d\n", + term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_overlay_pixel_topleft_index: %d\n", + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_overlay_pixel_topleft_index: %d\n", + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + + /* dimension column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_overlay_pixel_dimension: %d\n", + term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_overlay_pixel_dimension: %d\n", + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_overlay_pixel_dimension: %d\n", + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION]); + + /* dimension column */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "fragment_grid_overlay_pixel_dimension: %d\n", + term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "max_fragment_grid_overlay_pixel_dimension: %d\n", + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, VERBOSE, + "min_fragment_grid_overlay_pixel_dimension: %d\n", + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); +} + +STORAGE_CLASS_INLINE bool ia_css_is_program_terminal_valid( + const ia_css_terminal_t *terminal, + const ia_css_terminal_manifest_t *terminal_manifest, + const uint16_t nof_fragments) +{ + DECLARE_ERRVAL + bool invalid_flag = false; + uint16_t frag_idx; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_program_terminal_valid enter\n"); + + for (frag_idx = 0; frag_idx < nof_fragments; frag_idx++) { + uint16_t frag_seq_info_count, seq_idx; + const ia_css_program_terminal_t *prog_term; + const ia_css_program_terminal_manifest_t *prog_term_man; + + prog_term = (const ia_css_program_terminal_t *)terminal; + prog_term_man = + (const ia_css_program_terminal_manifest_t *) + terminal_manifest; + frag_seq_info_count = + prog_term_man-> + kernel_fragment_sequencer_info_manifest_info_count; + + for (seq_idx = 0; seq_idx < frag_seq_info_count; seq_idx++) { + const ia_css_kernel_fragment_sequencer_info_desc_t + *term_seq_info_desc; + const + ia_css_kernel_fragment_sequencer_info_manifest_desc_t * + man_seq_info_desc; + + term_seq_info_desc = + ia_css_program_terminal_get_kernel_frgmnt_seq_info_desc( + prog_term, frag_idx, seq_idx, + frag_seq_info_count); + verifexitval(term_seq_info_desc != NULL, EFAULT); + man_seq_info_desc = + ia_css_program_terminal_manifest_get_kernel_frgmnt_seq_info_desc + (prog_term_man, seq_idx); + verifexitval(man_seq_info_desc != NULL, EFAULT); + + ia_css_program_terminal_seq_info_print( + man_seq_info_desc, term_seq_info_desc); + /* slice dimension column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION]); + + /* slice dimension row */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION]); + + /* slice count column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION]); + + /* slice count row */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION]); + + /* decimation factor column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION]); + + /* decimation factor row */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + + /* index column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION]); + + /* index row */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + + /* dimension column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION]); + + /* dimension column */ + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION] > + man_seq_info_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + invalid_flag = invalid_flag || + (term_seq_info_desc-> + fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION] < + man_seq_info_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + } + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_program_terminal_valid() invalid argument\n"); + return false; + } + if (invalid_flag == true) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, WARNING, + "ia_css_is_program_terminal_valid(): validation failed\n"); + /* TODO: program terminal parameters not correctly defined, + * disable validation result until issues has been solved + */ + return true; + } + return (!invalid_flag); +} + +STORAGE_CLASS_INLINE bool ia_css_is_sliced_terminal_valid( + const ia_css_terminal_t *terminal, + const ia_css_terminal_manifest_t *terminal_manifest, + const uint16_t nof_fragments) +{ + DECLARE_ERRVAL + bool invalid_flag = false; + uint16_t frag_idx; + + uint16_t slice_idx, section_idx; + + const ia_css_sliced_param_terminal_t *sliced_term = + (const ia_css_sliced_param_terminal_t *)terminal; + const ia_css_sliced_param_terminal_manifest_t *sliced_term_man = + (const ia_css_sliced_param_terminal_manifest_t *) + terminal_manifest; + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_sliced_terminal_valid enter\n"); + + for (frag_idx = 0; frag_idx < nof_fragments; frag_idx++) { + const ia_css_fragment_slice_desc_t *fragment_slice_desc = + ia_css_sliced_param_terminal_get_fragment_slice_desc( + sliced_term, frag_idx); + + verifexitval(fragment_slice_desc != NULL, EFAULT); + + for (slice_idx = 0; + slice_idx < fragment_slice_desc->slice_count; + slice_idx++) { + for (section_idx = 0; + section_idx < + sliced_term_man->sliced_param_section_count; + section_idx++) { + const + ia_css_sliced_param_manifest_section_desc_t * + slice_man_section_desc; + const ia_css_slice_param_section_desc_t * + slice_section_desc; + + slice_man_section_desc = + ia_css_sliced_param_terminal_manifest_get_sliced_prm_sct_desc( + sliced_term_man, section_idx); + slice_section_desc = + ia_css_sliced_param_terminal_get_slice_param_section_desc( + sliced_term, frag_idx, + slice_idx, section_idx, + sliced_term_man-> + sliced_param_section_count); + verifexitval(slice_man_section_desc != NULL, EFAULT); + verifexitval(slice_section_desc != NULL, EFAULT); + + invalid_flag = invalid_flag || + (slice_section_desc->mem_size > + slice_man_section_desc->max_mem_size); + } + } + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_sliced_terminal_valid() invalid argument\n"); + return false; + } else { + return (!invalid_flag); + } + +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +bool ia_css_is_terminal_valid( + const ia_css_terminal_t *terminal, + const ia_css_terminal_manifest_t *terminal_manifest) +{ + DECLARE_ERRVAL + bool is_valid = false; + uint16_t nof_fragments; + ia_css_terminal_type_t terminal_type = IA_CSS_TERMINAL_INVALID_ID; + + verifexitval(NULL != terminal, EFAULT); + verifexitval(NULL != terminal_manifest, EFAULT); + + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, VERBOSE, + "ia_css_is_terminal_valid enter\n"); + + nof_fragments = ia_css_data_terminal_get_fragment_count( + (const ia_css_data_terminal_t *)terminal); + terminal_type = ia_css_terminal_get_type(terminal); + + switch (terminal_type) { + case IA_CSS_TERMINAL_TYPE_DATA_IN: + case IA_CSS_TERMINAL_TYPE_DATA_OUT: + is_valid = ia_css_is_data_terminal_valid(terminal, + terminal_manifest, nof_fragments); + break; + case IA_CSS_TERMINAL_TYPE_PROGRAM: + is_valid = ia_css_is_program_terminal_valid(terminal, + terminal_manifest, nof_fragments); + break; + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + case IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT: + /* Nothing to be validated for cached and spatial + * parameters, return valid + */ + is_valid = true; + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT: + is_valid = ia_css_is_sliced_terminal_valid(terminal, + terminal_manifest, nof_fragments); + break; + default: + /* Terminal type unknown, return invalid */ + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, WARNING, + "ia_css_is_terminal_valid() Terminal type %x unknown\n", + (int)terminal_type); + is_valid = false; + break; + } + +EXIT: + if (haserror(EFAULT)) { + IA_CSS_TRACE_0(PSYSAPI_DYNAMIC, ERROR, + "ia_css_is_terminal_valid() invalid argument\n"); + return false; + } + /* TODO: to be removed once all PGs pass validation */ + if (is_valid == false) { + IA_CSS_TRACE_1(PSYSAPI_DYNAMIC, INFO, + "ia_css_is_terminal_valid(): type: %d validation failed\n", + terminal_type); + } + return is_valid; +} + +/* ================= Program Control Init Terminal - START ================= */ +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +int +ia_css_program_control_init_terminal_init( + ia_css_program_control_init_terminal_t *terminal, + const ia_css_program_control_init_terminal_manifest_t *manifest) +{ + int retval = -1; + unsigned int i; + unsigned int base_load_sec; + unsigned int base_connect_sec; + unsigned int load_index = 0; + unsigned int connect_index = 0; + unsigned int load_section_count = 0; + unsigned int connect_section_count = 0; + + ia_css_program_control_init_manifest_program_desc_t *man_progs; + + verifjmpexit(terminal != NULL); + + man_progs = + ia_css_program_control_init_terminal_manifest_get_program_desc(manifest, 0); + verifjmpexit(man_progs != NULL); + + for (i = 0; i < manifest->program_count; i++) { + load_section_count += man_progs[i].load_section_count; + connect_section_count += man_progs[i].connect_section_count; + } + + terminal->program_count = manifest->program_count; + terminal->program_section_desc_offset = + sizeof(ia_css_program_control_init_terminal_t); + + base_load_sec = /* base_load_sec relative to first program */ + terminal->program_count * + sizeof(ia_css_program_control_init_program_desc_t); + + base_connect_sec = base_load_sec + + load_section_count * + sizeof(ia_css_program_control_init_load_section_desc_t); + + for (i = 0; i < terminal->program_count; i++) { + ia_css_program_control_init_program_desc_t *prog; + + prog = ia_css_program_control_init_terminal_get_program_desc( + terminal, i); + verifjmpexit(prog != NULL); + + prog->load_section_count = man_progs[i].load_section_count; + prog->connect_section_count = man_progs[i].connect_section_count; + + prog->load_section_desc_offset = + base_load_sec + + load_index * + sizeof(ia_css_program_control_init_load_section_desc_t) - + i * sizeof(ia_css_program_control_init_program_desc_t); + prog->connect_section_desc_offset = + base_connect_sec + + connect_index * + sizeof(ia_css_program_control_init_connect_section_desc_t) - + i * sizeof(ia_css_program_control_init_program_desc_t); + + load_index += man_progs[i].load_section_count; + connect_index += man_progs[i].connect_section_count; + } + retval = 0; +EXIT: + return retval; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +unsigned int +ia_css_program_control_init_terminal_get_descriptor_size( + const ia_css_program_control_init_terminal_manifest_t *manifest) +{ + unsigned int i; + unsigned int size = 0; + unsigned int load_section_count = 0; + unsigned int connect_section_count = 0; + ia_css_program_control_init_manifest_program_desc_t *man_progs; + + verifjmpexit(manifest != NULL); + + man_progs = + ia_css_program_control_init_terminal_manifest_get_program_desc( + manifest, 0); + verifjmpexit(man_progs != NULL); + + for (i = 0; i < manifest->program_count; i++) { + load_section_count += man_progs[i].load_section_count; + connect_section_count += man_progs[i].connect_section_count; + } + + size = sizeof(ia_css_program_control_init_terminal_t) + + manifest->program_count * + sizeof(struct ia_css_program_control_init_program_desc_s) + + load_section_count * + sizeof(struct ia_css_program_control_init_load_section_desc_s) + + connect_section_count * + sizeof(struct ia_css_program_control_init_connect_section_desc_s); +EXIT: + return size; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +void ia_css_program_control_init_terminal_print( + const ia_css_program_control_init_terminal_t *terminal) +{ + unsigned int prog_idx, sec_idx; + ia_css_program_control_init_program_desc_t *prog; + ia_css_program_control_init_load_section_desc_t *load_sec; + ia_css_program_control_init_connect_section_desc_t *connect_sec; + + verifjmpexit(terminal != NULL); + + IA_CSS_TRACE_2(PSYSAPI_DYNAMIC, INFO, + "program_count: %d, payload_fragment_stride: %d\n", + terminal->program_count, + terminal->payload_fragment_stride); + + for (prog_idx = 0; prog_idx < terminal->program_count; prog_idx++) { + prog = ia_css_program_control_init_terminal_get_program_desc( + terminal, prog_idx); + verifjmpexit(prog != NULL); + + for (sec_idx = 0; sec_idx < prog->load_section_count; sec_idx++) { + load_sec = + ia_css_program_control_init_terminal_get_load_section_desc( + prog, sec_idx); + verifjmpexit(load_sec != NULL); + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "load_section>> device_descriptor_id: 0x%x, mem_offset: %d, mem_size: %d, mode_bitmask: %x\n", + load_sec->device_descriptor_id.data, + load_sec->mem_offset, + load_sec->mem_size, + load_sec->mode_bitmask); + } + for (sec_idx = 0; sec_idx < prog->connect_section_count; sec_idx++) { + connect_sec = + ia_css_program_control_init_terminal_get_connect_section_desc( + prog, sec_idx); + verifjmpexit(connect_sec != NULL); + IA_CSS_TRACE_4(PSYSAPI_DYNAMIC, INFO, + "connect_section>> device_descriptor_id: 0x%x, connect_terminal_ID: %d, connect_section_idx: %d, mode_bitmask: %x\n", + connect_sec->device_descriptor_id.data, + connect_sec->connect_terminal_ID, + connect_sec->connect_section_idx, + connect_sec->mode_bitmask); + } + } +EXIT: + return; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_program_control_init_program_desc_t * +ia_css_program_control_init_terminal_get_program_desc( + const ia_css_program_control_init_terminal_t *prog_ctrl_init_terminal, + const unsigned int program_index) +{ + ia_css_program_control_init_program_desc_t *program_desc_base; + ia_css_program_control_init_program_desc_t *program_desc = NULL; + + verifjmpexit(prog_ctrl_init_terminal != NULL); + verifjmpexit(program_index < prog_ctrl_init_terminal->program_count); + + program_desc_base = (ia_css_program_control_init_program_desc_t *) + (((const char *)prog_ctrl_init_terminal) + + prog_ctrl_init_terminal->program_section_desc_offset); + program_desc = &(program_desc_base[program_index]); + +EXIT: + return program_desc; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_process_id_t ia_css_program_control_init_terminal_get_process_id( + const ia_css_program_control_init_program_desc_t *program_desc) +{ + ia_css_process_id_t process_id = 0; + + verifjmpexit(program_desc != NULL); + + process_id = program_desc->control_info.process_id; + +EXIT: + return process_id; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +uint8_t ia_css_program_control_init_terminal_get_num_done_events( + const ia_css_program_control_init_program_desc_t *program_desc) +{ + uint8_t num_done_events = 0; + + verifjmpexit(program_desc != NULL); + + num_done_events = program_desc->control_info.num_done_events; + +EXIT: + return num_done_events; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +void ia_css_program_control_init_terminal_set_control_info( + ia_css_program_control_init_program_desc_t *program_desc, + ia_css_process_id_t process_id, + uint8_t num_done_events) +{ + verifjmpexit(program_desc != NULL); + + program_desc->control_info.process_id = process_id; + program_desc->control_info.num_done_events = num_done_events; + +EXIT: + return; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_program_control_init_load_section_desc_t * +ia_css_program_control_init_terminal_get_load_section_desc( + const ia_css_program_control_init_program_desc_t *program_desc, + const unsigned int load_section_index) +{ + ia_css_program_control_init_load_section_desc_t *load_section_desc_base; + ia_css_program_control_init_load_section_desc_t *load_section_desc = NULL; + + verifjmpexit(program_desc != NULL); + verifjmpexit(load_section_index < program_desc->load_section_count); + + load_section_desc_base = (ia_css_program_control_init_load_section_desc_t *) + (((const char *)program_desc) + + program_desc->load_section_desc_offset); + load_section_desc = &(load_section_desc_base[load_section_index]); + +EXIT: + return load_section_desc; +} + +IA_CSS_PSYS_DYNAMIC_STORAGE_CLASS_C +ia_css_program_control_init_connect_section_desc_t * +ia_css_program_control_init_terminal_get_connect_section_desc( + const ia_css_program_control_init_program_desc_t *program_desc, + const unsigned int connect_section_index) +{ + ia_css_program_control_init_connect_section_desc_t *connect_sec_desc_base; + ia_css_program_control_init_connect_section_desc_t *connect_sec_desc = NULL; + + verifjmpexit(program_desc != NULL); + verifjmpexit(connect_section_index < program_desc->connect_section_count); + + connect_sec_desc_base = + (ia_css_program_control_init_connect_section_desc_t *) + (((const char *)program_desc) + + program_desc->connect_section_desc_offset); + connect_sec_desc = &(connect_sec_desc_base[connect_section_index]); + +EXIT: + return connect_sec_desc; +} + +/* ================= Program Control Init Terminal - END ================= */ + +#endif /* __IA_CSS_PSYS_TERMINAL_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_private_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_private_types.h new file mode 100644 index 0000000000000..a815fdfb8eaf5 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/dynamic/src/ia_css_psys_terminal_private_types.h @@ -0,0 +1,186 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_PRIVATE_TYPES_H +#define __IA_CSS_PSYS_TERMINAL_PRIVATE_TYPES_H + +#include "ia_css_terminal_types.h" +#include "ia_css_program_group_data.h" +#include "ia_css_psys_manifest_types.h" + +#define N_UINT16_IN_DATA_TERMINAL_STRUCT 1 +#define N_UINT8_IN_DATA_TERMINAL_STRUCT 3 +#define N_PADDING_UINT8_IN_DATA_TERMINAL_STRUCT 3 + +/* ========================= Data terminal - START ========================= */ + +#define SIZE_OF_DATA_TERMINAL_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_FRAME_DESCRIPTOR_STRUCT_BITS \ + + IA_CSS_FRAME_STRUCT_BITS \ + + IA_CSS_STREAM_STRUCT_BITS \ + + IA_CSS_UINT32_T_BITS \ + + IA_CSS_CONNECTION_TYPE_BITS \ + + (N_UINT16_IN_DATA_TERMINAL_STRUCT * 16) \ + + (N_UINT8_IN_DATA_TERMINAL_STRUCT * 8) \ + + (N_PADDING_UINT8_IN_DATA_TERMINAL_STRUCT * 8)) + +/* + * The (data) terminal can be attached to a buffer or a stream. + * The stream interface is not necessarily limited to strict in-order access. + * For a stream the restriction is that contrary to a buffer it cannot be + * addressed directly, i.e. it behaves as a port, + * but it may support stream_pos() and/or seek() operations + */ +struct ia_css_data_terminal_s { + /**< Data terminal base */ + ia_css_terminal_t base; + /**< Properties of the data attached to the terminal */ + ia_css_frame_descriptor_t frame_descriptor; + /**< Data buffer handle attached to the terminal */ + ia_css_frame_t frame; + /**< (exclusive) Data stream handle attached to the terminal + * if the data is sourced over a device port + */ + ia_css_stream_t stream; + /**< Reserved */ + uint32_t reserved; + /**< Connection {buffer, stream, ...} */ + ia_css_connection_type_t connection_type; + /**< Array[fragment_count] (fragment_count being equal for all + * terminals in a subgraph) of fragment descriptors + */ + uint16_t fragment_descriptor_offset; + /**< Kernel id where this terminal is connected to */ + uint8_t kernel_id; + /**< Indicate to which subgraph this terminal belongs + * for common constraints + */ + uint8_t subgraph_id; + /* Link ID of the data terminal */ + uint8_t link_id; + /**< Padding for 64bit alignment */ + uint8_t padding[N_PADDING_UINT8_IN_DATA_TERMINAL_STRUCT]; +}; +/* ========================== Data terminal - END ========================== */ + +/* ================= Program Control Init Terminal - START ================= */ +#define SIZE_OF_PROG_CONTROL_INIT_LOAD_SECTION_DESC_STRUCT_BITS \ + (DEVICE_DESCRIPTOR_ID_BITS \ + + (3 * IA_CSS_UINT32_T_BITS) \ + ) +struct ia_css_program_control_init_load_section_desc_s { + /* Offset of the parameter allocation in memory */ + uint32_t mem_offset; + /* Memory allocation size needs of this parameter */ + uint32_t mem_size; + /* Device descriptor */ + device_descriptor_id_t device_descriptor_id; /* 32 bits */ + /* (Applicable to) mode bitmask */ + uint32_t mode_bitmask; +}; + +#define MODE_BITMASK_MEMORY (1u << IA_CSS_CONNECTION_MEMORY) +#define MODE_BITMASK_MEMORY_STREAM (1u << IA_CSS_CONNECTION_MEMORY_STREAM) +#define MODE_BITMASK_STREAM (1u << IA_CSS_CONNECTION_STREAM) +#define MODE_BITMASK_DONT_CARE (MODE_BITMASK_MEMORY | MODE_BITMASK_MEMORY_STREAM | MODE_BITMASK_STREAM) + +#define N_PADDING_UINT8_IN_PROG_CTRL_INIT_CONNECT_SECT_STRUCT (5) +#define SIZE_OF_PROG_CONTROL_INIT_CONNECT_SECTION_DESC_STRUCT_BITS \ + (DEVICE_DESCRIPTOR_ID_BITS \ + + (1 * IA_CSS_UINT32_T_BITS) \ + + (1 * IA_CSS_UINT16_T_BITS) \ + + IA_CSS_TERMINAL_ID_BITS \ + + (N_PADDING_UINT8_IN_PROG_CTRL_INIT_CONNECT_SECT_STRUCT * \ + IA_CSS_UINT8_T_BITS) \ + ) +struct ia_css_program_control_init_connect_section_desc_s { + /* Device descriptor */ + device_descriptor_id_t device_descriptor_id; /* 32 bits */ + /* (Applicable to) mode bitmask */ + uint32_t mode_bitmask; + /* Connected terminal section (plane) index */ + uint16_t connect_section_idx; + /* Absolute referral ID for the connected terminal */ + ia_css_terminal_ID_t connect_terminal_ID; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PROG_CTRL_INIT_CONNECT_SECT_STRUCT]; +}; + +#define N_PADDING_UINT8_IN_PROG_DESC_CONTROL_INFO (1) +#define N_PADDING_UINT8_IN_PROG_CTRL_INIT_PROGRAM_DESC_STRUCT (4) +#define SIZE_OF_PROGRAM_DESC_CONTROL_INFO_STRUCT_BITS \ + ((1 * IA_CSS_UINT16_T_BITS) \ + + (1 * IA_CSS_UINT8_T_BITS) \ + + (N_PADDING_UINT8_IN_PROG_DESC_CONTROL_INFO * IA_CSS_UINT8_T_BITS)) + +#define SIZE_OF_PROG_CONTROL_INIT_PROG_DESC_STRUCT_BITS \ + ((4 * IA_CSS_UINT16_T_BITS) \ + + (SIZE_OF_PROGRAM_DESC_CONTROL_INFO_STRUCT_BITS) \ + + (N_PADDING_UINT8_IN_PROG_CTRL_INIT_PROGRAM_DESC_STRUCT * \ + IA_CSS_UINT8_T_BITS)) + +struct ia_css_program_desc_control_info_s { + /* 12-bit process identifier */ + ia_css_process_id_t process_id; + /* number of done acks required to close the process */ + uint8_t num_done_events; + uint8_t padding[N_PADDING_UINT8_IN_PROG_DESC_CONTROL_INFO]; +}; + +struct ia_css_program_control_init_program_desc_s { + /* Number of load sections in this program */ + uint16_t load_section_count; + /* Points to variable size array of + * ia_css_program_control_init_load_section_desc_s + * in relation to its program_desc + */ + uint16_t load_section_desc_offset; + /* Number of connect sections in this program */ + uint16_t connect_section_count; + /* Points to variable size array of + * ia_css_program_control_init_connect_section_desc_s + * in relation to its program_desc + */ + uint16_t connect_section_desc_offset; + struct ia_css_program_desc_control_info_s control_info; + /* align to 64 bits */ + uint8_t padding[N_PADDING_UINT8_IN_PROG_CTRL_INIT_PROGRAM_DESC_STRUCT]; +}; + +#define SIZE_OF_PROG_CONTROL_INIT_TERM_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + + (1 * IA_CSS_UINT32_T_BITS) \ + + (2 * IA_CSS_UINT16_T_BITS) \ + ) +struct ia_css_program_control_init_terminal_s { + /* Parameter terminal base */ + ia_css_terminal_t base; + /* Parameter buffer handle attached to the terminal */ + ia_css_param_payload_t param_payload; + /* Fragment stride for the payload, used to find the base + * of the payload for a given fragment + */ + uint32_t payload_fragment_stride; + /* Points to the variable array of + * ia_css_program_control_init_program_desc_s + */ + uint16_t program_section_desc_offset; + /* Number of instantiated programs in program group (processes) */ + uint16_t program_count; +}; +/* ================= Program Control Init Terminal - END ================= */ + +#endif /* __IA_CSS_PSYS_TERMINAL_PRIVATE_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi.h new file mode 100644 index 0000000000000..4c8fd33b331ca --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi.h @@ -0,0 +1,23 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYSAPI_H +#define __IA_CSS_PSYSAPI_H + +#include +#include +#include +#include + +#endif /* __IA_CSS_PSYSAPI_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_fw_version.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_fw_version.h new file mode 100644 index 0000000000000..5658a2988a08d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_fw_version.h @@ -0,0 +1,33 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_PSYSAPI_FW_VERSION_H +#define __IA_CSS_PSYSAPI_FW_VERSION_H + +/* PSYSAPI FW VERSION is taken from Makefile for FW tests */ +#define BXT_FW_RELEASE_VERSION PSYS_FIRMWARE_VERSION + +enum ia_css_process_group_protocol_version { + /* + * Legacy protocol + */ + IA_CSS_PROCESS_GROUP_PROTOCOL_LEGACY = 0, + /* + * Persistent process group support protocol + */ + IA_CSS_PROCESS_GROUP_PROTOCOL_PPG, + IA_CSS_PROCESS_GROUP_N_PROTOCOLS +}; + +#endif /* __IA_CSS_PSYSAPI_FW_VERSION_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_trace.h new file mode 100644 index 0000000000000..e35ec24c77b36 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/interface/ia_css_psysapi_trace.h @@ -0,0 +1,78 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYSAPI_TRACE_H +#define __IA_CSS_PSYSAPI_TRACE_H + +#include "ia_css_trace.h" + +#define PSYSAPI_TRACE_LOG_LEVEL_OFF 0 +#define PSYSAPI_TRACE_LOG_LEVEL_NORMAL 1 +#define PSYSAPI_TRACE_LOG_LEVEL_DEBUG 2 + +/* PSYSAPI and all the submodules in PSYSAPI will have the default tracing + * level set to the PSYSAPI_TRACE_CONFIG level. If not defined in the + * psysapi.mk fill it will be set by default to no trace + * (PSYSAPI_TRACE_LOG_LEVEL_OFF) + */ +#define PSYSAPI_TRACE_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +#if !defined(PSYSAPI_TRACE_CONFIG) + #define PSYSAPI_TRACE_CONFIG PSYSAPI_TRACE_CONFIG_DEFAULT +#endif + +/* Module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_TRACE_CONFIG)) + /* Module specific trace setting */ + #if PSYSAPI_TRACE_CONFIG == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_TRACE_CONFIG == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_TRACE_CONFIG == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_TRACE_CONFIG Tracing level defined" + #endif +#else + #error "PSYSAPI_TRACE_CONFIG not defined" +#endif + +/* Overriding submodules in PSYSAPI with a specific tracing level */ +/* #define PSYSAPI_DYNAMIC_TRACING_OVERRIDE TRACE_LOG_LEVEL_VERBOSE */ + +#endif /* __IA_CSS_PSYSAPI_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_kernel_bitmap.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_kernel_bitmap.h new file mode 100644 index 0000000000000..3fec775eb019d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_kernel_bitmap.h @@ -0,0 +1,223 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_KERNEL_BITMAP_H +#define __IA_CSS_KERNEL_BITMAP_H + +/*! \file */ + +/** @file ia_css_kernel_bitmap.h + * + * The types and operations to make logic decisions given kernel bitmaps + * "ia_css_kernel_bitmap_t" can be larger than native types + */ + +#include +#include "vied_nci_psys_resource_model.h" + +#define IA_CSS_KERNEL_BITMAP_BITS 64 +#define IA_CSS_KERNEL_BITMAP_ELEM_TYPE uint32_t +#define IA_CSS_KERNEL_BITMAP_ELEM_BITS \ + (sizeof(IA_CSS_KERNEL_BITMAP_ELEM_TYPE)*8) +#define IA_CSS_KERNEL_BITMAP_NOF_ELEMS \ + ((IA_CSS_KERNEL_BITMAP_BITS) / (IA_CSS_KERNEL_BITMAP_ELEM_BITS)) + +/** An element is a 32 bit unsigned integer. 64 bit integers might cause + * problems in the compiler. + */ +typedef struct { + IA_CSS_KERNEL_BITMAP_ELEM_TYPE data[IA_CSS_KERNEL_BITMAP_NOF_ELEMS]; +} ia_css_kernel_bitmap_elems_t; + +/** Users should make no assumption about the actual type of + * ia_css_kernel_bitmap_t. + * Users should use IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS in + * case they erroneously assume that this type is uint64_t and they + * cannot change their implementation. + */ +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS +typedef ia_css_kernel_bitmap_elems_t ia_css_kernel_bitmap_t; +#else +typedef uint64_t ia_css_kernel_bitmap_t; +#if IA_CSS_KERNEL_BITMAP_BITS > 64 +#error IA_CSS_KERNEL_BITMAP_BITS > 64 not supported \ + with IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS +#endif +#endif + +/*! Print the bits of a kernel bitmap + + @return < 0 on error + */ +extern int ia_css_kernel_bitmap_print( + const ia_css_kernel_bitmap_t bitmap, + void *fid); + +/*! Create an empty kernel bitmap + + @return bitmap = 0 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_clear(void); + +/*! Creates the complement of a kernel bitmap + * @param bitmap[in] kernel bitmap + * @return ~bitmap + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_complement( + const ia_css_kernel_bitmap_t bitmap); + +/*! Create the union of two kernel bitmaps + + @param bitmap0[in] kernel bitmap 0 + @param bitmap1[in] kernel bitmap 1 + + @return bitmap0 | bitmap1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_union( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1); + +/*! Create the intersection of two kernel bitmaps + + @param bitmap0[in] kernel bitmap 0 + @param bitmap1[in] kernel bitmap 1 + + @return bitmap0 & bitmap1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_intersection( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1); + +/*! Check if the kernel bitmaps is empty + + @param bitmap[in] kernel bitmap + + @return bitmap == 0 + */ +extern bool ia_css_is_kernel_bitmap_empty( + const ia_css_kernel_bitmap_t bitmap); + +/*! Check if the intersection of two kernel bitmaps is empty + + @param bitmap0[in] kernel bitmap 0 + @param bitmap1[in] kernel bitmap 1 + + @return (bitmap0 & bitmap1) == 0 + */ +extern bool ia_css_is_kernel_bitmap_intersection_empty( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1); + +/*! Check if the second kernel bitmap is a subset of the first (or equal) + + @param bitmap0[in] kernel bitmap 0 + @param bitmap1[in] kernel bitmap 1 + + Note: An empty set is always a subset, this function + returns true if bitmap 1 is empty + + @return (bitmap0 & bitmap1) == bitmap1 + */ +extern bool ia_css_is_kernel_bitmap_subset( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1); + +/*! Check if the kernel bitmaps are equal + + @param bitmap0[in] kernel bitmap 0 + @param bitmap1[in] kernel bitmap 1 + + @return bitmap0 == bitmap1 + */ +extern bool ia_css_is_kernel_bitmap_equal( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1); + +/*! Right shift kernel bitmap + + @param bitmap0[in] kernel bitmap 0 + + @return bitmap0 >> 1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_shift( + const ia_css_kernel_bitmap_t bitmap); + +/*! Check if the kernel bitmaps contains only a single element + + @param bitmap[in] kernel bitmap + + @return weight(bitmap) == 1 + */ +extern bool ia_css_is_kernel_bitmap_onehot( + const ia_css_kernel_bitmap_t bitmap); + +/*! Checks whether a specific kernel bit is set + * @return bitmap[index] == 1 + */ +extern int ia_css_is_kernel_bitmap_set( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index); + +/*! Create the union of a kernel bitmap with a onehot bitmap + * with a bit set at index + + @return bitmap[index] |= 1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_set( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index); + +/*! Creates kernel bitmap using a uint64 value. + * @return bitmap with the same bits set as in value (provided that width of bitmap is sufficient). + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_create_from_uint64( + const uint64_t value); + +/*! Converts an ia_css_kernel_bitmap_t type to uint64_t. Note that if + * ia_css_kernel_bitmap_t contains more then 64 bits, only the lowest 64 bits + * are returned. + * @return uint64_t representation of value +*/ +extern uint64_t ia_css_kernel_bitmap_to_uint64( + const ia_css_kernel_bitmap_t value); + +/*! Creates a kernel bitmap with the bit at index 'index' removed. + * @return ~(1 << index) & bitmap + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_unset( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index); + +/*! Set a previously clear field of a kernel bitmap at index + + @return if bitmap[index] == 0, bitmap[index] -> 1, else 0 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bitmap_set_unique( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index); + +/*! Create a onehot kernel bitmap with a bit set at index + + @return bitmap[index] = 1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_bit_mask( + const unsigned int index); + +/*! Create a random bitmap + + @return bitmap[index] = 1 + */ +extern ia_css_kernel_bitmap_t ia_css_kernel_ran_bitmap(void); + +#endif /* __IA_CSS_KERNEL_BITMAP_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_psys_kernel_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_psys_kernel_trace.h new file mode 100644 index 0000000000000..1ba29c7ab77ec --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/kernel/interface/ia_css_psys_kernel_trace.h @@ -0,0 +1,103 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_KERNEL_TRACE_H +#define __IA_CSS_PSYS_KERNEL_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_KERNEL_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_KERNEL_TRACING_OVERRIDE)) + #define PSYS_KERNEL_TRACE_LEVEL_CONFIG \ + PSYS_KERNEL_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_KERNEL_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_KERNEL_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_KERNEL_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_KERNEL_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_KERNEL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_KERNEL_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_KERNEL_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_KERNEL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_KERNEL_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_KERNEL_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_KERNEL_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_KERNEL_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_KERNEL_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_KERNEL_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_KERNEL_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_KERNEL_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_KERNEL_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_KERNEL_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_KERNEL_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_KERNEL_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/kernel/src/ia_css_kernel_bitmap.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/kernel/src/ia_css_kernel_bitmap.c new file mode 100644 index 0000000000000..7e99217e301e4 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/kernel/src/ia_css_kernel_bitmap.c @@ -0,0 +1,418 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include +#include +#include +#include +#include "ia_css_psys_kernel_trace.h" + +static int ia_css_kernel_bitmap_compute_weight( + const ia_css_kernel_bitmap_t bitmap); + +bool ia_css_is_kernel_bitmap_intersection_empty( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1) +{ + ia_css_kernel_bitmap_t intersection; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_intersection_empty(): enter:\n"); + + intersection = ia_css_kernel_bitmap_intersection(bitmap0, bitmap1); + return ia_css_is_kernel_bitmap_empty(intersection); +} + +bool ia_css_is_kernel_bitmap_empty( + const ia_css_kernel_bitmap_t bitmap) +{ + unsigned int i; + bool is_empty = true; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_empty(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + is_empty &= bitmap.data[i] == 0; + } +#else + NOT_USED(i); + is_empty = (bitmap == 0); +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return is_empty; +} + +bool ia_css_is_kernel_bitmap_equal( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1) +{ + unsigned int i; + bool is_equal = true; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_equal(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + is_equal = is_equal && (bitmap0.data[i] == bitmap1.data[i]); + } +#else + NOT_USED(i); + is_equal = (bitmap0 == bitmap1); +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return is_equal; +} + +bool ia_css_is_kernel_bitmap_onehot( + const ia_css_kernel_bitmap_t bitmap) +{ + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_onehot(): enter:\n"); + return ia_css_kernel_bitmap_compute_weight(bitmap) == 1; +} + +bool ia_css_is_kernel_bitmap_subset( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1) +{ + ia_css_kernel_bitmap_t intersection; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_subset(): enter:\n"); + + intersection = ia_css_kernel_bitmap_intersection(bitmap0, bitmap1); + return ia_css_is_kernel_bitmap_equal(intersection, bitmap1); +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_clear(void) +{ + unsigned int i; + ia_css_kernel_bitmap_t bitmap; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_clear(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + bitmap.data[i] = 0; + } +#else + NOT_USED(i); + bitmap = 0; +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return bitmap; +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_complement( + const ia_css_kernel_bitmap_t bitmap) +{ + unsigned int i; + ia_css_kernel_bitmap_t result; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_complement(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + result.data[i] = ~bitmap.data[i]; + } +#else + NOT_USED(i); + result = ~bitmap; +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return result; +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_union( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1) +{ + unsigned int i; + ia_css_kernel_bitmap_t result; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_union(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + result.data[i] = (bitmap0.data[i] | bitmap1.data[i]); + } +#else + NOT_USED(i); + result = (bitmap0 | bitmap1); +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return result; +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_intersection( + const ia_css_kernel_bitmap_t bitmap0, + const ia_css_kernel_bitmap_t bitmap1) +{ + unsigned int i; + ia_css_kernel_bitmap_t result; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_intersection(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + result.data[i] = (bitmap0.data[i] & bitmap1.data[i]); + } +#else + NOT_USED(i); + result = (bitmap0 & bitmap1); +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return result; +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_set( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index) +{ + ia_css_kernel_bitmap_t bit_mask; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_set(): enter:\n"); + + bit_mask = ia_css_kernel_bit_mask(index); + return ia_css_kernel_bitmap_union(bitmap, bit_mask); +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_create_from_uint64( + const uint64_t value) +{ + unsigned int i; + ia_css_kernel_bitmap_t result; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_create_from_uint64(): enter:\n"); + +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + result = ia_css_kernel_bitmap_clear(); + for (i = 0; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + /* masking is done implictly, the MSB bits of casting will be chopped off */ + result.data[i] = (IA_CSS_KERNEL_BITMAP_ELEM_TYPE) + (value >> (i * IA_CSS_KERNEL_BITMAP_ELEM_BITS)); + } +#if IA_CSS_KERNEL_BITMAP_BITS < 64 + if ((value >> IA_CSS_KERNEL_BITMAP_BITS) != 0) { + IA_CSS_TRACE_0(PSYSAPI_KERNEL, ERROR, + "ia_css_kernel_bitmap_create_from_uint64(): kernel bitmap is not wide enough to encode value\n"); + assert(0); + } +#endif +#else + NOT_USED(i); + result = value; +#endif /* IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS */ + return result; +} + +uint64_t ia_css_kernel_bitmap_to_uint64( + const ia_css_kernel_bitmap_t value) +{ + const unsigned int bits64 = sizeof(uint64_t) * 8; + const unsigned int nof_elems_bits64 = bits64 / IA_CSS_KERNEL_BITMAP_ELEM_BITS; + unsigned int i; + uint64_t res = 0; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_to_uint64(): enter:\n"); + + assert((bits64 % IA_CSS_KERNEL_BITMAP_ELEM_BITS) == 0); + assert(nof_elems_bits64 > 0); + +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = 0; i < nof_elems_bits64; i++) { + res |= ((uint64_t)(value.data[i]) << (i * IA_CSS_KERNEL_BITMAP_ELEM_BITS)); + } + for (i = nof_elems_bits64; i < IA_CSS_KERNEL_BITMAP_NOF_ELEMS; i++) { + assert(value.data[i] == 0); + } + return res; +#else + (void)i; + (void)res; + (void)nof_elems_bits64; + return (uint64_t)value; +#endif /* IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS */ +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_unset( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index) +{ + ia_css_kernel_bitmap_t result; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_unset(): enter:\n"); + + result = ia_css_kernel_bit_mask(index); + result = ia_css_kernel_bitmap_complement(result); + return ia_css_kernel_bitmap_intersection(bitmap, result); +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_set_unique( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index) +{ + ia_css_kernel_bitmap_t ret; + ia_css_kernel_bitmap_t bit_mask; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_set_unique(): enter:\n"); + + ret = ia_css_kernel_bitmap_clear(); + bit_mask = ia_css_kernel_bit_mask(index); + + if (ia_css_is_kernel_bitmap_intersection_empty(bitmap, bit_mask) + && !ia_css_is_kernel_bitmap_empty(bit_mask)) { + ret = ia_css_kernel_bitmap_union(bitmap, bit_mask); + } + return ret; +} + +ia_css_kernel_bitmap_t ia_css_kernel_bit_mask( + const unsigned int index) +{ + unsigned int elem_index; + unsigned int elem_bit_index; + ia_css_kernel_bitmap_t bit_mask = ia_css_kernel_bitmap_clear(); + + /* Assert disabled for staging, because some PGs do not satisfy this condition */ + /* assert(index < IA_CSS_KERNEL_BITMAP_BITS); */ + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bit_mask(): enter:\n"); +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + if (index < IA_CSS_KERNEL_BITMAP_BITS) { + elem_index = index / IA_CSS_KERNEL_BITMAP_ELEM_BITS; + elem_bit_index = index % IA_CSS_KERNEL_BITMAP_ELEM_BITS; + assert(elem_index < IA_CSS_KERNEL_BITMAP_NOF_ELEMS); + + bit_mask.data[elem_index] = 1 << elem_bit_index; + } +#else + NOT_USED(elem_index); + NOT_USED(elem_bit_index); + if (index < IA_CSS_KERNEL_BITMAP_BITS) { + bit_mask = (ia_css_kernel_bitmap_t)1 << index; + } +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return bit_mask; +} + + +static int ia_css_kernel_bitmap_compute_weight( + const ia_css_kernel_bitmap_t bitmap) +{ + ia_css_kernel_bitmap_t loc_bitmap; + int weight = 0; + int i; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_compute_weight(): enter:\n"); + + loc_bitmap = bitmap; + + /* In fact; do not need the iterator "i" */ + for (i = 0; (i < IA_CSS_KERNEL_BITMAP_BITS) && + !ia_css_is_kernel_bitmap_empty(loc_bitmap); i++) { + weight += ia_css_is_kernel_bitmap_set(loc_bitmap, 0); + loc_bitmap = ia_css_kernel_bitmap_shift(loc_bitmap); + } + + return weight; +} + +int ia_css_is_kernel_bitmap_set( + const ia_css_kernel_bitmap_t bitmap, + const unsigned int index) +{ + unsigned int elem_index; + unsigned int elem_bit_index; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_is_kernel_bitmap_set(): enter:\n"); + + /* Assert disabled for staging, because some PGs do not satisfy this condition */ + /* assert(index < IA_CSS_KERNEL_BITMAP_BITS); */ + +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + elem_index = index / IA_CSS_KERNEL_BITMAP_ELEM_BITS; + elem_bit_index = index % IA_CSS_KERNEL_BITMAP_ELEM_BITS; + assert(elem_index < IA_CSS_KERNEL_BITMAP_NOF_ELEMS); + return (((bitmap.data[elem_index] >> elem_bit_index) & 0x1) == 1); +#else + NOT_USED(elem_index); + NOT_USED(elem_bit_index); + return (((bitmap >> index) & 0x1) == 1); +#endif /* IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS */ +} + +ia_css_kernel_bitmap_t ia_css_kernel_bitmap_shift( + const ia_css_kernel_bitmap_t bitmap) +{ + int i; + unsigned int lsb_current_elem = 0; + unsigned int lsb_previous_elem = 0; + ia_css_kernel_bitmap_t loc_bitmap; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, VERBOSE, + "ia_css_kernel_bitmap_shift(): enter:\n"); + + loc_bitmap = bitmap; + +#ifndef IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + for (i = IA_CSS_KERNEL_BITMAP_NOF_ELEMS - 1; i >= 0; i--) { + lsb_current_elem = bitmap.data[i] & 0x01; + loc_bitmap.data[i] >>= 1; + loc_bitmap.data[i] |= (lsb_previous_elem << (IA_CSS_KERNEL_BITMAP_ELEM_BITS - 1)); + lsb_previous_elem = lsb_current_elem; + } +#else + NOT_USED(i); + NOT_USED(lsb_current_elem); + NOT_USED(lsb_previous_elem); + loc_bitmap >>= 1; +#endif /* IA_CSS_KERNEL_BITMAP_USE_ELEMS */ + return loc_bitmap; +} + +int ia_css_kernel_bitmap_print( + const ia_css_kernel_bitmap_t bitmap, + void *fid) +{ + int retval = -1; + int bit; + unsigned int bit_index = 0; + ia_css_kernel_bitmap_t loc_bitmap; + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, INFO, + "ia_css_kernel_bitmap_print(): enter:\n"); + + NOT_USED(fid); + NOT_USED(bit); + + IA_CSS_TRACE_0(PSYSAPI_KERNEL, INFO, "kernel bitmap {\n"); + + loc_bitmap = bitmap; + + for (bit_index = 0; (bit_index < IA_CSS_KERNEL_BITMAP_BITS) && + !ia_css_is_kernel_bitmap_empty(loc_bitmap); bit_index++) { + + bit = ia_css_is_kernel_bitmap_set(loc_bitmap, 0); + loc_bitmap = ia_css_kernel_bitmap_shift(loc_bitmap); + IA_CSS_TRACE_2(PSYSAPI_KERNEL, INFO, "\t%d\t = %d\n", bit_index, bit); + } + IA_CSS_TRACE_0(PSYSAPI_KERNEL, INFO, "}\n"); + + retval = 0; + return retval; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.h new file mode 100644 index 0000000000000..485dd63e5a861 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.h @@ -0,0 +1,293 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_PARAM_H +#define __IA_CSS_PROGRAM_GROUP_PARAM_H + +/*! \file */ + +/** @file ia_css_program_group_param.h + * + * Define the methods on the program group parameter object that are not part + * of a single interface + */ +#include + +#include + +#include /* ia_css_kernel_bitmap_t */ + +#include + +/*! Get the stored size of the program group parameter object + + @param param[in] program group parameter object + + @return size, 0 on error + */ +extern size_t ia_css_program_group_param_get_size( + const ia_css_program_group_param_t *param); + +/*! initialize program_group_param + + @param blob[in] program group parameter object + @param program_count[in] number of terminals. + @param terminal_count[in] number of terminals. + @param fragment_count[in] number of terminals. + + @return 0 if success, else failure. + */ +extern int ia_css_program_group_param_init( + ia_css_program_group_param_t *blob, + const uint8_t program_count, + const uint8_t terminal_count, + const uint16_t fragment_count, + const enum ia_css_frame_format_type *frame_format_types); +/*! Get the program parameter object from a program group parameter object + + @param program_group_param[in] program group parameter object + @param i[in] program parameter index + + @return program parameter pointer, NULL on error + */ +extern ia_css_program_param_t *ia_css_program_group_param_get_program_param( + const ia_css_program_group_param_t *param, + const int i); + +/*! Get the terminal parameter object from a program group parameter object + + @param program_group_param[in] program group parameter object + @param i[in] terminal parameter index + + @return terminal parameter pointer, NULL on error + */ +extern ia_css_terminal_param_t *ia_css_program_group_param_get_terminal_param( + const ia_css_program_group_param_t *param, + const int i); + +/*! Get the fragment count from a program group parameter object + + @param program_group_param[in] program group parameter object + + @return fragment count, 0 on error + */ +extern uint16_t ia_css_program_group_param_get_fragment_count( + const ia_css_program_group_param_t *param); + +/*! Get the program count from a program group parameter object + + @param program_group_param[in] program group parameter object + + @return program count, 0 on error + */ +extern uint8_t ia_css_program_group_param_get_program_count( + const ia_css_program_group_param_t *param); + +/*! Get the terminal count from a program group parameter object + + @param program_group_param[in] program group parameter object + + @return terminal count, 0 on error + */ +extern uint8_t ia_css_program_group_param_get_terminal_count( + const ia_css_program_group_param_t *param); + +/*! Set the protocol version in a program group parameter object + + @param program_group_param[in] program group parameter object + @param protocol_version[in] protocol version + + @return nonzero on error +*/ +extern int +ia_css_program_group_param_set_protocol_version( + ia_css_program_group_param_t *param, + uint8_t protocol_version); + +/*! Get the protocol version from a program group parameter object + + @param program_group_param[in] program group parameter object + + @return protocol version +*/ +extern uint8_t +ia_css_program_group_param_get_protocol_version( + const ia_css_program_group_param_t *param); + +/*! Set the kernel enable bitmap from a program group parameter object + + @param param[in] program group parameter object + @param bitmap[in] kernel enable bitmap + + @return non-zero on error + */ +extern int ia_css_program_group_param_set_kernel_enable_bitmap( + ia_css_program_group_param_t *param, + const ia_css_kernel_bitmap_t bitmap); + +/*! Get the kernel enable bitmap from a program group parameter object + + @param program_group_param[in] program group parameter object + + @return kernel enable bitmap, 0 on error +*/ +extern ia_css_kernel_bitmap_t +ia_css_program_group_param_get_kernel_enable_bitmap( + const ia_css_program_group_param_t *param); + +/*! Get the stored size of the program parameter object + + @param param[in] program parameter object + + @return size, 0 on error + */ +extern size_t ia_css_program_param_get_size( + const ia_css_program_param_t *param); + +/*! Set the kernel enable bitmap from a program parameter object + + @param program_param[in] program parameter object + @param bitmap[in] kernel enable bitmap + + @return non-zero on error + */ +extern int ia_css_program_param_set_kernel_enable_bitmap( + ia_css_program_param_t *program_param, + const ia_css_kernel_bitmap_t bitmap); + +/*! Get the kernel enable bitmap from a program parameter object + + @param program_param[in] program parameter object + + Note: This function returns in fact the kernel enable of the program group + parameters + + @return kernel enable bitmap, 0 on error + */ +extern ia_css_kernel_bitmap_t ia_css_program_param_get_kernel_enable_bitmap( + const ia_css_program_param_t *param); + +/*! Get the stored size of the terminal parameter object + + @param param[in] terminal parameter object + + @return size, 0 on error + */ +extern size_t ia_css_terminal_param_get_size( + const ia_css_terminal_param_t *param); + +/*! Get the kernel enable bitmap from a terminal parameter object + + @param terminal_param[in] terminal parameter object + + Note: This function returns in fact the kernel enable of the program group + parameters + + @return kernel enable bitmap, 0 on error + */ +extern ia_css_kernel_bitmap_t ia_css_terminal_param_get_kernel_enable_bitmap( + const ia_css_terminal_param_t *param); + +/*! Get the parent object for this terminal param. + + @param terminal_param[in] terminal parameter object + + @return parent program group param object + */ +extern ia_css_program_group_param_t *ia_css_terminal_param_get_parent( + const ia_css_terminal_param_t *param); + +/*! Get the data format type associated with the terminal. + + @param terminal_param[in] terminal parameter object + + @return data format type (ia_css_data_format_type_t) + */ +extern ia_css_frame_format_type_t ia_css_terminal_param_get_frame_format_type( + const ia_css_terminal_param_t *terminal_param); + +/*! Set the data format type associated with the terminal. + + @param terminal_param[in] terminal parameter object + @param data_format_type[in] data format type + + @return non-zero on error. + */ +extern int ia_css_terminal_param_set_frame_format_type( + ia_css_terminal_param_t *terminal_param, + const ia_css_frame_format_type_t data_format_type); + +/*! Get bits per pixel on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + + @return bits per pixel + */ +extern uint8_t ia_css_terminal_param_get_bpp( + const ia_css_terminal_param_t *terminal_param); + +/*! Set bits per pixel on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + @param bpp[in] bits per pixel + + @return non-zero on error. + */ +extern int ia_css_terminal_param_set_bpp( + ia_css_terminal_param_t *terminal_param, + const uint8_t bpp); + +/*! Get dimensions on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + @param dimensions[out] dimension array + + @return non-zero on error. + */ +extern int ia_css_terminal_param_get_dimensions( + const ia_css_terminal_param_t *terminal_param, + uint16_t dimensions[IA_CSS_N_DATA_DIMENSION]); + +/*! Set dimensions on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + @param dimensions[in] dimension array + + @return non-zero on error. + */ +extern int ia_css_terminal_param_set_dimensions( + ia_css_terminal_param_t *terminal_param, + const uint16_t dimensions[IA_CSS_N_DATA_DIMENSION]); + +/*! Get stride on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + + @return stride of the frame to be attached. + */ +extern uint32_t ia_css_terminal_param_get_stride( + const ia_css_terminal_param_t *terminal_param); + +/*! Set stride on the frame associated with the terminal. + + @param terminal_param[in] terminal parameter object + @param stride[in] stride + + @return non-zero on error. + */ +extern int ia_css_terminal_param_set_stride( + ia_css_terminal_param_t *terminal_param, + const uint32_t stride); + +#endif /* __IA_CSS_PROGRAM_GROUP_PARAM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.sim.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.sim.h new file mode 100644 index 0000000000000..7821f8147a1a0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param.sim.h @@ -0,0 +1,153 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_PARAM_SIM_H +#define __IA_CSS_PROGRAM_GROUP_PARAM_SIM_H + +/*! \file */ + +/** @file ia_css_program_group_param.sim.h + * + * Define the methods on the program group parameter object: Simulation only + */ +#include + +#include + +#include + +/* Simulation */ + +/*! Create a program group parameter object from specification + + @param specification[in] specification (index) + @param manifest[in] program group manifest + + @return NULL on error + */ +extern ia_css_program_group_param_t *ia_css_program_group_param_create( + const unsigned int specification, + const ia_css_program_group_manifest_t *manifest); + +/*! Destroy the program group parameter object + + @param program_group_param[in] program group parameter object + + @return NULL + */ +extern ia_css_program_group_param_t *ia_css_program_group_param_destroy( + ia_css_program_group_param_t *param); + +/*! Compute the size of storage required for allocating + * the program group parameter object + + @param program_count[in] Number of programs in the process group + @param terminal_count[in] Number of terminals on the process group + @param fragment_count[in] Number of fragments on the terminals of + the process group + + @return 0 on error + */ +size_t ia_css_sizeof_program_group_param( + const uint8_t program_count, + const uint8_t terminal_count, + const uint16_t fragment_count); + +/*! Allocate (the store of) a program group parameter object + + @param program_count[in] Number of programs in the process group + @param terminal_count[in] Number of terminals on the process group + @param fragment_count[in] Number of fragments on the terminals of + the process group + + @return program group parameter pointer, NULL on error + */ +extern ia_css_program_group_param_t *ia_css_program_group_param_alloc( + const uint8_t program_count, + const uint8_t terminal_count, + const uint16_t fragment_count); + +/*! Free (the store of) a program group parameter object + + @param program_group_param[in] program group parameter object + + @return NULL + */ +extern ia_css_program_group_param_t *ia_css_program_group_param_free( + ia_css_program_group_param_t *param); + +/*! Print the program group parameter object to file/stream + + @param param[in] program group parameter object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_program_group_param_print( + const ia_css_program_group_param_t *param, + void *fid); + +/*! Allocate (the store of) a program parameter object + + @return program parameter pointer, NULL on error + */ +extern ia_css_program_param_t *ia_css_program_param_alloc(void); + +/*! Free (the store of) a program parameter object + + @param param[in] program parameter object + + @return NULL + */ +extern ia_css_program_param_t *ia_css_program_param_free( + ia_css_program_param_t *param); + +/*! Print the program parameter object to file/stream + + @param param[in] program parameter object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_program_param_print( + const ia_css_program_param_t *param, + void *fid); + +/*! Allocate (the store of) a terminal parameter object + + @return terminal parameter pointer, NULL on error + */ +extern ia_css_terminal_param_t *ia_css_terminal_param_alloc(void); + +/*! Free (the store of) a terminal parameter object + + @param param[in] terminal parameter object + + @return NULL + */ +extern ia_css_terminal_param_t *ia_css_terminal_param_free( + ia_css_terminal_param_t *param); + +/*! Print the terminal parameter object to file/stream + + @param param[in] terminal parameter object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_terminal_param_print( + const ia_css_terminal_param_t *param, + void *fid); + +#endif /* __IA_CSS_PROGRAM_GROUP_PARAM_SIM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param_types.h new file mode 100644 index 0000000000000..34f57584a227f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_program_group_param_types.h @@ -0,0 +1,64 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_PARAM_TYPES_H +#define __IA_CSS_PROGRAM_GROUP_PARAM_TYPES_H + +/*! \file */ + +/** @file ia_css_program_group_param_types.h + * + * Define the parameter objects that are necessary to create the process + * groups i.e. enable parameters and parameters to set-up frame descriptors + */ + +#include +#include /* ia_css_kernel_bitmap_t */ +#include + +#include +/*! make this public so that driver can populate, + * size, bpp, dimensions for all terminals. + * + * Currently one API is provided to get frame_format_type. + * + * frame_format_type is set during ia_css_terminal_param_init(). + * Value for that is const and binary specific. + */ +struct ia_css_terminal_param_s { + uint32_t size; /**< Size of this structure */ + /**< Indicates if this is a generic type or inbuild + * with variable size descriptor + */ + ia_css_frame_format_type_t frame_format_type; + /**< offset to add to reach parent. This is negative value.*/ + int32_t parent_offset; + uint16_t dimensions[IA_CSS_N_DATA_DIMENSION];/**< Logical dimensions */ + /**< Mapping to the index field of the terminal descriptor */ + uint16_t index[IA_CSS_N_DATA_DIMENSION]; + /**< Logical fragment dimension, + * TODO: fragment dimensions can be different per fragment + */ + uint16_t fragment_dimensions[IA_CSS_N_DATA_DIMENSION]; + uint32_t stride;/**< Stride of a frame */ + uint16_t offset;/**< Offset in bytes to first fragment */ + uint8_t bpp; /**< Bits per pixel */ + uint8_t bpe; /**< Bits per element */ +}; + +typedef struct ia_css_program_group_param_s ia_css_program_group_param_t; +typedef struct ia_css_program_param_s ia_css_program_param_t; +typedef struct ia_css_terminal_param_s ia_css_terminal_param_t; + +#endif /* __IA_CSS_PROGRAM_GROUP_PARAM_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_psys_param_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_psys_param_trace.h new file mode 100644 index 0000000000000..f59dfbf165e4d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/interface/ia_css_psys_param_trace.h @@ -0,0 +1,102 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PARAM_TRACE_H +#define __IA_CSS_PSYS_PARAM_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_PARAM_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_PARAM_TRACING_OVERRIDE)) + #define PSYS_PARAM_TRACE_LEVEL_CONFIG PSYS_PARAM_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_PARAM_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_PARAM_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_PARAM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_PARAM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_PARAM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_PARAM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_PARAM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_PARAM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_PARAM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_PARAM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_PARAM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_PARAM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_PARAM_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_PARAM_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_PARAM_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_PARAM_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_PARAM_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_PARAM_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_PARAM_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_PARAM_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param.c new file mode 100644 index 0000000000000..e6fe2bfa8a7be --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param.c @@ -0,0 +1,771 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ia_css_psys_param_trace.h" + +static int +ia_css_terminal_param_init(ia_css_terminal_param_t *terminal_param, + uint32_t offset, + enum ia_css_frame_format_type frame_format_type); + +static int +ia_css_program_param_init(ia_css_program_param_t *program_param, + int32_t offset); + +size_t ia_css_sizeof_program_group_param( + const uint8_t program_count, + const uint8_t terminal_count, + const uint16_t fragment_count) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_sizeof_program_group_param(): enter:\n"); + + verifexit(program_count != 0); + verifexit(terminal_count != 0); + verifexit(fragment_count != 0); + + size += sizeof(ia_css_program_group_param_t); + size += program_count * fragment_count * sizeof(ia_css_program_param_t); + size += terminal_count * sizeof(ia_css_terminal_param_t); +EXIT: + if (0 == program_count || 0 == terminal_count || 0 == fragment_count) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_sizeof_program_group_param invalid argument\n"); + } + return size; +} + +size_t ia_css_program_group_param_get_size( + const ia_css_program_group_param_t *program_group_param) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_size(): enter:\n"); + + if (program_group_param != NULL) { + size = program_group_param->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_size invalid argument\n"); + } + return size; +} + +size_t ia_css_program_param_get_size( + const ia_css_program_param_t *param) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_param_get_size(): enter:\n"); + + if (param != NULL) { + size = param->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_param_get_size invalid argument\n"); + } + return size; +} + +ia_css_program_param_t *ia_css_program_group_param_get_program_param( + const ia_css_program_group_param_t *param, + const int i) +{ + ia_css_program_param_t *program_param = NULL; + ia_css_program_param_t *program_param_base; + int program_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_program_param(): enter:\n"); + + verifexit(param != NULL); + + program_count = + (int)ia_css_program_group_param_get_program_count(param); + + verifexit(i < program_count); + + program_param_base = (ia_css_program_param_t *) + (((char *)param) + param->program_param_offset); + + program_param = &program_param_base[i]; + +EXIT: + if (NULL == param || i >= program_count) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_program_param invalid argument\n"); + } + return program_param; +} + +size_t ia_css_terminal_param_get_size( + const ia_css_terminal_param_t *param) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_size(): enter:\n"); + + if (param != NULL) { + size = param->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_terminal_param_get_size invalid argument\n"); + } + + return size; +} + +ia_css_terminal_param_t *ia_css_program_group_param_get_terminal_param( + const ia_css_program_group_param_t *param, + const int i) +{ + ia_css_terminal_param_t *terminal_param = NULL; + ia_css_terminal_param_t *terminal_param_base; + int program_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_terminal_param(): enter:\n"); + + verifexit(param != NULL); + + program_count = + (int)ia_css_program_group_param_get_terminal_count(param); + + verifexit(i < program_count); + + terminal_param_base = (ia_css_terminal_param_t *) + (((char *)param) + param->terminal_param_offset); + terminal_param = &terminal_param_base[i]; +EXIT: + if (NULL == param || i >= program_count) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_terminal_param invalid argument\n"); + } + return terminal_param; +} + +uint8_t ia_css_program_group_param_get_program_count( + const ia_css_program_group_param_t *param) +{ + uint8_t program_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_program_count(): enter:\n"); + + if (param != NULL) { + program_count = param->program_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_program_count invalid argument\n"); + } + return program_count; +} + +uint8_t ia_css_program_group_param_get_terminal_count( + const ia_css_program_group_param_t *param) +{ + uint8_t terminal_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_terminal_count(): enter:\n"); + + if (param != NULL) { + terminal_count = param->terminal_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_terminal_count invalid argument\n"); + } + return terminal_count; +} + +uint16_t ia_css_program_group_param_get_fragment_count( + const ia_css_program_group_param_t *param) +{ + uint8_t fragment_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_fragment_count(): enter:\n"); + + if (param != NULL) { + fragment_count = (uint8_t)param->fragment_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_fragment_count invalid argument\n"); + } + return fragment_count; +} + +int ia_css_program_group_param_set_protocol_version( + ia_css_program_group_param_t *param, + uint8_t protocol_version) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_set_protocol_version(): enter:\n"); + + if (param != NULL) { + param->protocol_version = protocol_version; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_group_param_set_protocol_version failed (%i)\n", + retval); + } + return retval; +} + +uint8_t ia_css_program_group_param_get_protocol_version( + const ia_css_program_group_param_t *param) +{ + uint8_t protocol_version = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_protocol_version(): enter:\n"); + + if (param != NULL) { + protocol_version = param->protocol_version; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_protocol_version invalid argument\n"); + } + return protocol_version; +} + +int ia_css_program_group_param_set_kernel_enable_bitmap( + ia_css_program_group_param_t *param, + const ia_css_kernel_bitmap_t bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_set_kernel_enable_bitmap(): enter:\n"); + + if (param != NULL) { + param->kernel_enable_bitmap = bitmap; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_group_param_set_kernel_enable_bitmap failed (%i)\n", + retval); + } + return retval; +} + +ia_css_kernel_bitmap_t ia_css_program_group_param_get_kernel_enable_bitmap( + const ia_css_program_group_param_t *param) +{ + ia_css_kernel_bitmap_t bitmap = ia_css_kernel_bitmap_clear(); + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_group_param_get_kernel_enable_bitmap(): enter:\n"); + + if (param != NULL) { + bitmap = param->kernel_enable_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_group_param_get_kernel_enable_bitmap invalid argument\n"); + } + return bitmap; +} + +int ia_css_program_param_set_kernel_enable_bitmap( + ia_css_program_param_t *program_param, + const ia_css_kernel_bitmap_t bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_param_set_kernel_enable_bitmap(): enter:\n"); + + if (program_param != NULL) { + program_param->kernel_enable_bitmap = bitmap; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_param_set_kernel_enable_bitmap failed (%i)\n", + retval); + } + return retval; +} + +ia_css_kernel_bitmap_t ia_css_program_param_get_kernel_enable_bitmap( + const ia_css_program_param_t *program_param) +{ + ia_css_kernel_bitmap_t bitmap = ia_css_kernel_bitmap_clear(); + char *base; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_program_param_get_kernel_enable_bitmap(): enter:\n"); + + verifexit(program_param != NULL); + verifexit(program_param->parent_offset != 0); + + base = (char *)((char *)program_param + program_param->parent_offset); + bitmap = ((ia_css_program_group_param_t *)base)->kernel_enable_bitmap; +EXIT: + if (NULL == program_param || 0 == program_param->parent_offset) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_program_param_get_kernel_enable_bitmap invalid argument\n"); + } + return bitmap; +} + +ia_css_kernel_bitmap_t ia_css_terminal_param_get_kernel_enable_bitmap( + const ia_css_terminal_param_t *param) +{ + ia_css_kernel_bitmap_t bitmap = ia_css_kernel_bitmap_clear(); + char *base; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_kernel_enable_bitmap(): enter:\n"); + + verifexit(param != NULL); + verifexit(param->parent_offset != 0); + + base = (char *)((char *)param + param->parent_offset); + bitmap = ((ia_css_program_group_param_t *)base)->kernel_enable_bitmap; +EXIT: + if (NULL == param || 0 == param->parent_offset) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_terminal_param_get_kernel_enable_bitmap invalid argument\n"); + } + return bitmap; +} + +ia_css_frame_format_type_t ia_css_terminal_param_get_frame_format_type( + const ia_css_terminal_param_t *param) +{ + ia_css_frame_format_type_t ft = IA_CSS_N_FRAME_FORMAT_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_frame_format_type(): enter:\n"); + + verifexit(param != NULL); + + ft = param->frame_format_type; +EXIT: + if (param == NULL) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_terminal_param_get_frame_format_type invalid argument\n"); + } + return ft; +} + +int ia_css_terminal_param_set_frame_format_type( + ia_css_terminal_param_t *param, + const ia_css_frame_format_type_t data_format_type) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_set_frame_format_type(): enter:\n"); + + if (param != NULL) { + param->frame_format_type = data_format_type; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_set_frame_format_type failed (%i)\n", + retval); + } + return retval; +} + +uint8_t ia_css_terminal_param_get_bpp( + const ia_css_terminal_param_t *param) +{ + uint8_t bpp = 0; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_bpp(): enter:\n"); + + verifexit(param != NULL); + + bpp = param->bpp; + +EXIT: + if (param == NULL) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_terminal_param_get_bpp invalid argument\n"); + } + return bpp; +} + +int ia_css_terminal_param_set_bpp( + ia_css_terminal_param_t *param, + const uint8_t bpp) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_set_bpp(): enter:\n"); + + if (param != NULL) { + param->bpp = bpp; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_set_bpp failed (%i)\n", retval); + } + return retval; +} + +int ia_css_terminal_param_get_dimensions( + const ia_css_terminal_param_t *param, + uint16_t dimensions[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_dimensions(): enter:\n"); + + if (param != NULL) { + dimensions[IA_CSS_COL_DIMENSION] = + param->dimensions[IA_CSS_COL_DIMENSION]; + dimensions[IA_CSS_ROW_DIMENSION] = + param->dimensions[IA_CSS_ROW_DIMENSION]; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_get_dimensions failed (%i)\n", retval); + } + return retval; +} + +int ia_css_terminal_param_set_dimensions( + ia_css_terminal_param_t *param, + const uint16_t dimensions[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_set_dimensions(): enter:\n"); + + if (param != NULL) { + param->dimensions[IA_CSS_COL_DIMENSION] = + dimensions[IA_CSS_COL_DIMENSION]; + param->dimensions[IA_CSS_ROW_DIMENSION] = + dimensions[IA_CSS_ROW_DIMENSION]; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_set_dimensions failed (%i)\n", retval); + } + return retval; +} + +int ia_css_terminal_param_set_stride( + ia_css_terminal_param_t *param, + const uint32_t stride) +{ + int retval = -1; + + verifexit(param != NULL); + param->stride = stride; + retval = 0; + +EXIT: + return retval; +} + +uint32_t ia_css_terminal_param_get_stride( + const ia_css_terminal_param_t *param) +{ + uint32_t stride = 0; + + verifexit(param != NULL); + stride = param->stride; + +EXIT: + return stride; +} + + +static int ia_css_program_param_init( + ia_css_program_param_t *program_param, + int32_t offset) +{ + int retval = -1; + + COMPILATION_ERROR_IF( + SIZE_OF_PROGRAM_PARAM_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_program_param_t))); + verifexit(program_param != NULL); + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_program_param_init(): enter:\n"); + + program_param->size = sizeof(ia_css_program_param_t); + /* parent is at negative offset from current program.*/ + program_param->parent_offset = -offset; + /*TODO: Kernel_bitmap setting. ?*/ + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_param_init failed (%i)\n", retval); + } + return retval; +} + +static int +ia_css_terminal_param_init(ia_css_terminal_param_t *terminal_param, + uint32_t offset, + enum ia_css_frame_format_type frame_format_type) +{ + int retval = -1; + + COMPILATION_ERROR_IF( + SIZE_OF_TERMINAL_PARAM_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_terminal_param_t))); + verifexit(terminal_param != NULL); + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_terminal_param_init(): enter:\n"); + + terminal_param->size = sizeof(ia_css_terminal_param_t); + /* parent is at negative offset from current program.*/ + terminal_param->parent_offset = -((int32_t)offset); + /*TODO: Kernel_bitmap setting. ?*/ + terminal_param->frame_format_type = frame_format_type; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_init failed (%i)\n", retval); + } + return retval; +} + +ia_css_program_group_param_t * +ia_css_terminal_param_get_parent( + const ia_css_terminal_param_t *param) +{ + ia_css_program_group_param_t *parent = NULL; + char *base; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, VERBOSE, + "ia_css_terminal_param_get_parent(): enter:\n"); + + verifexit(param != NULL); + + base = (char *)((char *)param + param->parent_offset); + + parent = (ia_css_program_group_param_t *)(base); +EXIT: + if (param == NULL) { + IA_CSS_TRACE_0(PSYSAPI_PARAM, WARNING, + "ia_css_terminal_param_get_parent invalid argument\n"); + } + return parent; +} + +int ia_css_program_group_param_init( + ia_css_program_group_param_t *blob, + const uint8_t program_count, + const uint8_t terminal_count, + const uint16_t fragment_count, + const enum ia_css_frame_format_type *frame_format_types) +{ + int i = 0; + char *param_base; + uint32_t offset; + int retval = -1; + + COMPILATION_ERROR_IF( + SIZE_OF_PROGRAM_GROUP_PARAM_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_program_group_param_t))); + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_program_group_param_init(): enter:\n"); + + assert(blob != 0); + + verifexit(blob != NULL); + verifexit(frame_format_types != NULL); + + blob->program_count = program_count; + blob->fragment_count = fragment_count; + blob->terminal_count = terminal_count; + blob->program_param_offset = sizeof(ia_css_program_group_param_t); + blob->terminal_param_offset = blob->program_param_offset + + sizeof(ia_css_program_param_t) * program_count; + + param_base = (char *)((char *)blob + blob->program_param_offset); + offset = blob->program_param_offset; + + for (i = 0; i < program_count; i++) { + ia_css_program_param_init( + (ia_css_program_param_t *)param_base, offset); + offset += sizeof(ia_css_program_param_t); + param_base += sizeof(ia_css_program_param_t); + } + + param_base = (char *)((char *)blob + blob->terminal_param_offset); + offset = blob->terminal_param_offset; + + for (i = 0; i < terminal_count; i++) { + ia_css_terminal_param_init( + (ia_css_terminal_param_t *)param_base, + offset, + frame_format_types[i]); + + offset += sizeof(ia_css_terminal_param_t); + param_base += sizeof(ia_css_terminal_param_t); + } + + /* + * For now, set legacy flow by default. This can be removed as soon + * as all hosts/drivers explicitly set the protocol version. + */ + blob->protocol_version = IA_CSS_PROCESS_GROUP_PROTOCOL_LEGACY; + + blob->size = (uint32_t)ia_css_sizeof_program_group_param(program_count, + terminal_count, + fragment_count); + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_group_param_init failed (%i)\n", retval); + } + return retval; +} + +int ia_css_program_group_param_print( + const ia_css_program_group_param_t *param, + void *fid) +{ + int retval = -1; + int i; + uint8_t program_count, terminal_count; + ia_css_kernel_bitmap_t bitmap; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_program_group_param_print(): enter:\n"); + + verifexit(param != NULL); + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, + "sizeof(program_group_param) = %d\n", + (int)ia_css_program_group_param_get_size(param)); + + program_count = ia_css_program_group_param_get_program_count(param); + terminal_count = ia_css_program_group_param_get_terminal_count(param); + + bitmap = ia_css_program_group_param_get_kernel_enable_bitmap(param); + verifexit(ia_css_kernel_bitmap_print(bitmap, fid) == 0); + + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, + "%d program params\n", (int)program_count); + for (i = 0; i < (int)program_count; i++) { + ia_css_program_param_t *program_param = + ia_css_program_group_param_get_program_param(param, i); + + retval = ia_css_program_param_print(program_param, fid); + verifjmpexit(retval == 0); + } + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, "%d terminal params\n", + (int)terminal_count); + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_param_t *terminal_param = + ia_css_program_group_param_get_terminal_param(param, i); + + retval = ia_css_terminal_param_print(terminal_param, fid); + verifjmpexit(retval == 0); + } + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_group_param_print failed (%i)\n", retval); + } + return retval; +} + +int ia_css_terminal_param_print( + const ia_css_terminal_param_t *param, + void *fid) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_terminal_param_print(): enter:\n"); + + verifexit(param != NULL); + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, + "sizeof(terminal_param) = %d\n", + (int)ia_css_terminal_param_get_size(param)); + + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, + "\tframe_format_type = %d\n", param->frame_format_type); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_terminal_param_print failed (%i)\n", retval); + } + return retval; +} + +int ia_css_program_param_print( + const ia_css_program_param_t *param, + void *fid) +{ + int retval = -1; + ia_css_kernel_bitmap_t bitmap; + + IA_CSS_TRACE_0(PSYSAPI_PARAM, INFO, + "ia_css_program_param_print(): enter:\n"); + + verifexit(param != NULL); + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_PARAM, INFO, "sizeof(program_param) = %d\n", + (int)ia_css_program_param_get_size(param)); + + bitmap = ia_css_program_param_get_kernel_enable_bitmap(param); + verifexit(ia_css_kernel_bitmap_print(bitmap, fid) == 0); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_PARAM, ERROR, + "ia_css_program_param_print failed (%i)\n", retval); + } + return retval; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param_private.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param_private.h new file mode 100644 index 0000000000000..6672737e51a14 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/param/src/ia_css_program_group_param_private.h @@ -0,0 +1,80 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PROGRAM_GROUP_PARAM_PRIVATE_H +#define __IA_CSS_PROGRAM_GROUP_PARAM_PRIVATE_H + +#include +#include +#include +#include +#include +#include +#include + +#define N_PADDING_UINT8_IN_PROGRAM_GROUP_PARAM_STRUCT 7 +#define SIZE_OF_PROGRAM_GROUP_PARAM_STRUCT_IN_BITS \ + (IA_CSS_KERNEL_BITMAP_BITS \ + + (3 * IA_CSS_UINT32_T_BITS) \ + + IA_CSS_UINT16_T_BITS \ + + (3 * IA_CSS_UINT8_T_BITS) \ + + (N_PADDING_UINT8_IN_PROGRAM_GROUP_PARAM_STRUCT * IA_CSS_UINT8_T_BITS)) + +/* tentative; co-design with ISP algorithm */ +struct ia_css_program_group_param_s { + /* The enable bits for each individual kernel */ + ia_css_kernel_bitmap_t kernel_enable_bitmap; + /* Size of this structure */ + uint32_t size; + uint32_t program_param_offset; + uint32_t terminal_param_offset; + /* Number of (explicit) fragments to use in a frame */ + uint16_t fragment_count; + /* Number of active programs */ + uint8_t program_count; + /* Number of active terminals */ + uint8_t terminal_count; + /* Program group protocol version */ + uint8_t protocol_version; + uint8_t padding[N_PADDING_UINT8_IN_PROGRAM_GROUP_PARAM_STRUCT]; +}; + +#define SIZE_OF_PROGRAM_PARAM_STRUCT_IN_BITS \ + (IA_CSS_KERNEL_BITMAP_BITS \ + + IA_CSS_UINT32_T_BITS \ + + IA_CSS_INT32_T_BITS) + +/* private */ +struct ia_css_program_param_s { + /* What to use this one for ? */ + ia_css_kernel_bitmap_t kernel_enable_bitmap; + /* Size of this structure */ + uint32_t size; + /* offset to add to reach parent. This is negative value.*/ + int32_t parent_offset; +}; + +#define SIZE_OF_TERMINAL_PARAM_STRUCT_IN_BITS \ + (IA_CSS_UINT32_T_BITS \ + + IA_CSS_FRAME_FORMAT_TYPE_BITS \ + + IA_CSS_INT32_T_BITS \ + + (IA_CSS_UINT16_T_BITS * IA_CSS_N_DATA_DIMENSION) \ + + (IA_CSS_UINT16_T_BITS * IA_CSS_N_DATA_DIMENSION) \ + + (IA_CSS_UINT16_T_BITS * IA_CSS_N_DATA_DIMENSION) \ + + IA_CSS_INT32_T_BITS \ + + IA_CSS_UINT16_T_BITS \ + + IA_CSS_UINT8_T_BITS \ + + (IA_CSS_UINT8_T_BITS * 1)) + +#endif /* __IA_CSS_PROGRAM_GROUP_PARAM_PRIVATE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/psys_server_manifest/cnlB0/ia_css_psys_server_manifest.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/psys_server_manifest/cnlB0/ia_css_psys_server_manifest.c new file mode 100644 index 0000000000000..7543b93f279b1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/psys_server_manifest/cnlB0/ia_css_psys_server_manifest.c @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_server_manifest.h" + +/** + * Manifest of resources in use by PSYS itself + */ + +const vied_nci_resource_spec_t psys_server_manifest = { + /* internal memory */ + { /* resource id size offset*/ + {VIED_NCI_GMEM_TYPE_ID, 0, 0}, + {VIED_NCI_DMEM_TYPE_ID, VIED_NCI_DMEM0_MAX_SIZE, 0}, + {VIED_NCI_VMEM_TYPE_ID, 0, 0}, + {VIED_NCI_BAMEM_TYPE_ID, 0, 0}, + {VIED_NCI_PMEM_TYPE_ID, 0, 0} + }, + /* external memory */ + { /* resource id size offset*/ + {VIED_NCI_N_MEM_ID, 0, 0}, + {VIED_NCI_N_MEM_ID, 0, 0}, + {VIED_NCI_N_MEM_ID, 0, 0}, + {VIED_NCI_N_MEM_ID, 0, 0} + }, + /* device channel */ + { /* resource id size offset*/ + {VIED_NCI_DEV_CHN_DMA_EXT0_ID, + PSYS_SERVER_DMA_CHANNEL_SIZE, + PSYS_SERVER_DMA_CHANNEL_OFFSET}, + {VIED_NCI_DEV_CHN_GDC_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_EXT1_READ_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_EXT1_WRITE_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_INTERNAL_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_IPFD_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_ISA_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_FW_ID, 0, 0}, + {VIED_NCI_DEV_CHN_DMA_CMPRS_ID, 0, 0} + } +}; diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/psys_server_manifest/cnlB0/ia_css_psys_server_manifest.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/psys_server_manifest/cnlB0/ia_css_psys_server_manifest.h new file mode 100644 index 0000000000000..b4c7fbc32d5ba --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/psys_server_manifest/cnlB0/ia_css_psys_server_manifest.h @@ -0,0 +1,29 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_SERVER_MANIFEST_H +#define __IA_CSS_PSYS_SERVER_MANIFEST_H + +#include "vied_nci_psys_resource_model.h" + +/** + * Manifest of resources in use by PSYS itself + */ + +#define PSYS_SERVER_DMA_CHANNEL_SIZE 2 +#define PSYS_SERVER_DMA_CHANNEL_OFFSET 28 + +extern const vied_nci_resource_spec_t psys_server_manifest; + +#endif /* __IA_CSS_PSYS_SERVER_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/psysapi.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/psysapi.mk new file mode 100644 index 0000000000000..e1977cbe2ca2a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/psysapi.mk @@ -0,0 +1,122 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is PSYSAPI +# +ifdef _H_PSYSAPI_MK +$(error ERROR: psysapi.mk included multiple times, please check makefile) +else +_H_PSYSAPI_MK=1 +endif + +include $(MODULES_DIR)/config/psys/subsystem_$(IPU_SYSVER).mk + +PSYSAPI_DIR = $${MODULES_DIR}/psysapi + +PSYSAPI_PROCESS_HOST_FILES = $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_process.c +PSYSAPI_PROCESS_HOST_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_process_group.c +PSYSAPI_PROCESS_HOST_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_buffer_set.c +PSYSAPI_PROCESS_HOST_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_terminal.c +PSYSAPI_PROCESS_HOST_FILES += $(PSYSAPI_DIR)/param/src/ia_css_program_group_param.c + +# Use PSYS_MANIFEST_HOST_FILES when only accessing manifest functions +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_program_group_manifest.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_program_manifest.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_terminal_manifest.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/sim/src/vied_nci_psys_system.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/kernel/src/ia_css_kernel_bitmap.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/data/src/ia_css_program_group_data.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/vied_nci_psys_resource_model.c +PSYSAPI_MANIFEST_HOST_FILES += $(PSYSAPI_DIR)/psys_server_manifest/$(PSYS_SERVER_MANIFEST_VERSION)/ia_css_psys_server_manifest.c + +# Use only kernel bitmap functionality from PSYS API +PSYSAPI_KERNEL_BITMAP_FILES += $(PSYSAPI_DIR)/kernel/src/ia_css_kernel_bitmap.c +PSYSAPI_KERNEL_BITMAP_CPPFLAGS += -I$(PSYSAPI_DIR)/kernel/interface +PSYSAPI_KERNEL_BITMAP_CPPFLAGS += -I$(PSYSAPI_DIR)/interface + +# Use PSYSAPI_HOST_FILES when program and process group are both needed +PSYSAPI_HOST_FILES = $(PSYSAPI_PROCESS_HOST_FILES) $(PSYSAPI_MANIFEST_HOST_FILES) + +# Use PSYSAPI_PROCESS_GROUP_HOST_FILES when program and process group are both needed but there is no +# implementation (yet) of the user customization functions defined in ia_css_psys_process_group_cmd_impl.h. +# Dummy implementations are provided in $(PSYSAPI_DIR)/sim/src/ia_css_psys_process_group_cmd_impl.c +PSYSAPI_PROCESS_GROUP_HOST_FILES = $(PSYSAPI_HOST_FILES) +PSYSAPI_PROCESS_GROUP_HOST_FILES += $(PSYSAPI_DIR)/sim/src/ia_css_psys_process_group_cmd_impl.c + +# for now disabled, implementation for now provided by psys api impl +#PSYSAPI_HOST_FILES += $(PSYSAPI_DIR)/device/src/ia_css_psys_device.c + +PSYSAPI_HOST_CPPFLAGS = -I$(PSYSAPI_DIR)/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/device/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/device/interface/$(IPU_SYSVER) +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/dynamic/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/dynamic/src +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/data/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/data/src +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/static/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/static/src +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/kernel/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/param/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/param/src +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/sim/interface +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/sim/src +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION) +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/private +PSYSAPI_HOST_CPPFLAGS += -I$(PSYSAPI_DIR)/psys_server_manifest/$(PSYS_SERVER_MANIFEST_VERSION) + +PSYSAPI_FW_CPPFLAGS = $(PSYSAPI_HOST_CPPFLAGS) +PSYSAPI_FW_CPPFLAGS += -I$(PSYSAPI_DIR)/static/interface +PSYSAPI_FW_CPPFLAGS += -I$(PSYSAPI_DIR)/static/src +PSYSAPI_FW_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION) +PSYSAPI_FW_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/private +PSYSAPI_FW_CPPFLAGS += -I$(PSYSAPI_DIR)/psys_server_manifest/$(PSYS_SERVER_MANIFEST_VERSION) +PSYSAPI_SYSTEM_GLOBAL_CPPFLAGS += -I$(PSYSAPI_DIR)/sim/interface +PSYSAPI_SYSTEM_GLOBAL_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION) +PSYSAPI_SYSTEM_GLOBAL_CPPFLAGS += -I$(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/private +PSYSAPI_SYSTEM_GLOBAL_CPPFLAGS += -I$(PSYSAPI_DIR)/psys_server_manifest/$(PSYS_SERVER_MANIFEST_VERSION) + +# Defining the trace level for the PSYSAPI +PSYSAPI_HOST_CPPFLAGS += -DPSYSAPI_TRACE_CONFIG=PSYSAPI_TRACE_LOG_LEVEL_NORMAL +# Enable/Disable 'late binding' support and it's additional queues +PSYSAPI_HOST_CPPFLAGS += -DHAS_LATE_BINDING_SUPPORT=$(PSYS_HAS_LATE_BINDING_SUPPORT) + +#Example: how to switch to a different log level for a sub-module +#PSYSAPI_HOST_CPPFLAGS += -DPSYSAPI_DYNAMIC_TRACING_OVERRIDE=PSYSAPI_TRACE_LOG_LEVEL_DEBUG + +# enable host side implementation +# TODO: better name for the flag to enable the impl... +PSYSAPI_HOST_CPPFLAGS += -D__X86_SIM__ + +# Files for Firmware +PSYSAPI_FW_FILES = $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_process.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_process_group.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_terminal.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/dynamic/src/ia_css_psys_buffer_set.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/param/src/ia_css_program_group_param.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/data/src/ia_css_program_group_data.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/sim/src/vied_nci_psys_system.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/sim/src/ia_css_psys_sim_data.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_program_group_manifest.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_program_manifest.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/static/src/ia_css_psys_terminal_manifest.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/vied_nci_psys_resource_model.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/psys_server_manifest/$(PSYS_SERVER_MANIFEST_VERSION)/ia_css_psys_server_manifest.c +PSYSAPI_FW_FILES += $(PSYSAPI_DIR)/kernel/src/ia_css_kernel_bitmap.c + +# resource model +PSYSAPI_RESOURCE_MODEL_FILES = $(PSYSAPI_DIR)/resource_model/$(PSYS_RESOURCE_MODEL_VERSION)/vied_nci_psys_resource_model.c + +ifeq ($(PSYS_HAS_DUAL_CMD_CTX_SUPPORT), 1) +PSYSAPI_HOST_CPPFLAGS += -DHAS_DUAL_CMD_CTX_SUPPORT=$(PSYS_HAS_DUAL_CMD_CTX_SUPPORT) +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/resource_model/cnlB0/vied_nci_psys_resource_model.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/resource_model/cnlB0/vied_nci_psys_resource_model.c new file mode 100644 index 0000000000000..20bfb729e6417 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/resource_model/cnlB0/vied_nci_psys_resource_model.c @@ -0,0 +1,323 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "vied_nci_psys_resource_model.h" + +/* + * Cell types by cell IDs + */ +const vied_nci_cell_type_ID_t vied_nci_cell_type[VIED_NCI_N_CELL_ID] = { + VIED_NCI_SP_CTRL_TYPE_ID, + VIED_NCI_SP_SERVER_TYPE_ID, + VIED_NCI_SP_SERVER_TYPE_ID, + VIED_NCI_VP_TYPE_ID, + VIED_NCI_VP_TYPE_ID, + VIED_NCI_VP_TYPE_ID, + VIED_NCI_VP_TYPE_ID, + VIED_NCI_ACC_ISA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_OSA_TYPE_ID, + VIED_NCI_GDC_TYPE_ID, + VIED_NCI_GDC_TYPE_ID +}; + +/* + * Memory types by memory IDs + */ +const vied_nci_mem_type_ID_t vied_nci_mem_type[VIED_NCI_N_MEM_ID] = { + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_GMEM_TYPE_ID,/* VMEM4 is GMEM according to vied_nci_cell_mem */ + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID +}; + +/* + * Cell mem count by cell type ID + */ +const uint16_t vied_nci_N_cell_mem[VIED_NCI_N_CELL_TYPE_ID] = { + VIED_NCI_N_SP_CTRL_MEM, + VIED_NCI_N_SP_SERVER_MEM, + VIED_NCI_N_VP_MEM, + VIED_NCI_N_ACC_PSA_MEM, + VIED_NCI_N_ACC_ISA_MEM, + VIED_NCI_N_ACC_OSA_MEM +}; + +/* + * Cell mem type by cell type ID and memory index + */ +const vied_nci_mem_type_ID_t +vied_nci_cell_mem_type[VIED_NCI_N_CELL_TYPE_ID][VIED_NCI_N_MEM_TYPE_ID] = { + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + }, + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + }, + { + VIED_NCI_GMEM_TYPE_ID, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID + }, + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + }, + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + }, + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + }, + { + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID + } +}; + +/* + * Ext mem ID by memory index + */ +const vied_nci_mem_ID_t +vied_nci_ext_mem[VIED_NCI_N_MEM_TYPE_ID] = { + VIED_NCI_VMEM4_ID, /* VIED_NCI_GMEM_TYPE_ID */ + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID +}; + +/* + * Cell mem ID by cell ID and memory index + */ +const vied_nci_mem_ID_t +vied_nci_cell_mem[VIED_NCI_N_CELL_ID][VIED_NCI_N_MEM_TYPE_ID] = { + { + VIED_NCI_N_MEM_ID, + VIED_NCI_DMEM0_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_DMEM1_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_DMEM2_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_VMEM4_ID, + VIED_NCI_DMEM4_ID, + VIED_NCI_VMEM0_ID, + VIED_NCI_BAMEM0_ID, + VIED_NCI_PMEM0_ID + }, + { + VIED_NCI_VMEM4_ID, + VIED_NCI_DMEM5_ID, + VIED_NCI_VMEM1_ID, + VIED_NCI_BAMEM1_ID, + VIED_NCI_PMEM1_ID + }, + { + VIED_NCI_VMEM4_ID, + VIED_NCI_DMEM6_ID, + VIED_NCI_VMEM2_ID, + VIED_NCI_BAMEM2_ID, + VIED_NCI_PMEM2_ID + }, + { + VIED_NCI_VMEM4_ID, + VIED_NCI_DMEM7_ID, + VIED_NCI_VMEM3_ID, + VIED_NCI_BAMEM3_ID, + VIED_NCI_PMEM3_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + }, + { + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID, + VIED_NCI_N_MEM_ID + } +}; + +/* + * Memory sizes by mem ID + */ +const uint16_t vied_nci_mem_size[VIED_NCI_N_MEM_ID] = { + VIED_NCI_VMEM0_MAX_SIZE, + VIED_NCI_VMEM1_MAX_SIZE, + VIED_NCI_VMEM2_MAX_SIZE, + VIED_NCI_VMEM3_MAX_SIZE, + VIED_NCI_VMEM4_MAX_SIZE, + VIED_NCI_BAMEM0_MAX_SIZE, + VIED_NCI_BAMEM1_MAX_SIZE, + VIED_NCI_BAMEM2_MAX_SIZE, + VIED_NCI_BAMEM3_MAX_SIZE, + VIED_NCI_DMEM0_MAX_SIZE, + VIED_NCI_DMEM1_MAX_SIZE, + VIED_NCI_DMEM2_MAX_SIZE, + VIED_NCI_DMEM3_MAX_SIZE, + VIED_NCI_DMEM4_MAX_SIZE, + VIED_NCI_DMEM5_MAX_SIZE, + VIED_NCI_DMEM6_MAX_SIZE, + VIED_NCI_DMEM7_MAX_SIZE, + VIED_NCI_PMEM0_MAX_SIZE, + VIED_NCI_PMEM1_MAX_SIZE, + VIED_NCI_PMEM2_MAX_SIZE, + VIED_NCI_PMEM3_MAX_SIZE +}; + +/* + * Memory word sizes by mem type ID + */ +const uint16_t vied_nci_mem_word_size[VIED_NCI_N_DATA_MEM_TYPE_ID] = { + VIED_NCI_GMEM_WORD_SIZE, + VIED_NCI_DMEM_WORD_SIZE, + VIED_NCI_VMEM_WORD_SIZE, + VIED_NCI_BAMEM_WORD_SIZE +}; + +/* + * Number of channels by device ID + */ +const uint16_t vied_nci_dev_chn_size[VIED_NCI_N_DEV_CHN_ID] = { + VIED_NCI_DEV_CHN_DMA_EXT0_MAX_SIZE, + VIED_NCI_DEV_CHN_GDC_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_EXT1_READ_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_EXT1_WRITE_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_INTERNAL_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_IPFD_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_ISA_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_FW_MAX_SIZE, + VIED_NCI_DEV_CHN_DMA_CMPRS_MAX_SIZE +}; diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/resource_model/cnlB0/vied_nci_psys_resource_model.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/resource_model/cnlB0/vied_nci_psys_resource_model.h new file mode 100644 index 0000000000000..6249d8af3effc --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/resource_model/cnlB0/vied_nci_psys_resource_model.h @@ -0,0 +1,300 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __VIED_NCI_PSYS_RESOURCE_MODEL_H +#define __VIED_NCI_PSYS_RESOURCE_MODEL_H + +#include "type_support.h" +#include "storage_class.h" + +#define HAS_DFM 0 +#define NON_RELOC_RESOURCE_SUPPORT 0 +#define IA_CSS_KERNEL_BITMAP_DO_NOT_USE_ELEMS + +/* Defines for the routing bitmap in the program group manifest. + */ +#define VIED_NCI_RBM_MAX_MUX_COUNT 0 +#define VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT 0 +#define VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT 0 +#define N_PADDING_UINT8_IN_RBM_MANIFEST 2 + +/* The amount of padding bytes needed to make + * ia_css_process_s structure 64 bit aligned + */ +#define N_PADDING_UINT8_IN_PROCESS_STRUCT 2 +#define N_PADDING_UINT8_IN_PROGRAM_GROUP_MANFEST 0 + +/** + * Resource model for CNL B0 + */ + +/* + * Cell IDs + */ +typedef enum { + VIED_NCI_SP0_ID = 0, + VIED_NCI_SP1_ID, + VIED_NCI_SP2_ID, + VIED_NCI_VP0_ID, + VIED_NCI_VP1_ID, + VIED_NCI_VP2_ID, + VIED_NCI_VP3_ID, + VIED_NCI_ACC0_ID, + VIED_NCI_ACC1_ID, + VIED_NCI_ACC2_ID, + VIED_NCI_ACC3_ID, + VIED_NCI_ACC4_ID, + VIED_NCI_ACC5_ID, + VIED_NCI_ACC6_ID, + VIED_NCI_ACC7_ID, + VIED_NCI_GDC0_ID, + VIED_NCI_GDC1_ID, + VIED_NCI_N_CELL_ID +} vied_nci_cell_ID_t; + +/* + * Barrier bits (to model process group dependencies) + */ +typedef enum { + VIED_NCI_BARRIER0_ID, + VIED_NCI_BARRIER1_ID, + VIED_NCI_BARRIER2_ID, + VIED_NCI_BARRIER3_ID, + VIED_NCI_BARRIER4_ID, + VIED_NCI_BARRIER5_ID, + VIED_NCI_BARRIER6_ID, + VIED_NCI_BARRIER7_ID, + VIED_NCI_N_BARRIER_ID +} vied_nci_barrier_ID_t; + +/* + * Cell types + */ +typedef enum { + VIED_NCI_SP_CTRL_TYPE_ID = 0, + VIED_NCI_SP_SERVER_TYPE_ID, + VIED_NCI_VP_TYPE_ID, + VIED_NCI_ACC_PSA_TYPE_ID, + VIED_NCI_ACC_ISA_TYPE_ID, + VIED_NCI_ACC_OSA_TYPE_ID, + VIED_NCI_GDC_TYPE_ID, + VIED_NCI_N_CELL_TYPE_ID +} vied_nci_cell_type_ID_t; + +/* + * Memory IDs + */ +typedef enum { + VIED_NCI_VMEM0_ID = 0, + VIED_NCI_VMEM1_ID, + VIED_NCI_VMEM2_ID, + VIED_NCI_VMEM3_ID, + VIED_NCI_VMEM4_ID, + VIED_NCI_BAMEM0_ID, + VIED_NCI_BAMEM1_ID, + VIED_NCI_BAMEM2_ID, + VIED_NCI_BAMEM3_ID, + VIED_NCI_DMEM0_ID, + VIED_NCI_DMEM1_ID, + VIED_NCI_DMEM2_ID, + VIED_NCI_DMEM3_ID, + VIED_NCI_DMEM4_ID, + VIED_NCI_DMEM5_ID, + VIED_NCI_DMEM6_ID, + VIED_NCI_DMEM7_ID, + VIED_NCI_PMEM0_ID, + VIED_NCI_PMEM1_ID, + VIED_NCI_PMEM2_ID, + VIED_NCI_PMEM3_ID, + VIED_NCI_N_MEM_ID +} vied_nci_mem_ID_t; + +/* + * Memory types + */ +typedef enum { + VIED_NCI_GMEM_TYPE_ID = 0, + VIED_NCI_DMEM_TYPE_ID, + VIED_NCI_VMEM_TYPE_ID, + VIED_NCI_BAMEM_TYPE_ID, + VIED_NCI_PMEM_TYPE_ID, + VIED_NCI_N_MEM_TYPE_ID +} vied_nci_mem_type_ID_t; + +/* Excluding PMEM */ +#define VIED_NCI_N_DATA_MEM_TYPE_ID (VIED_NCI_N_MEM_TYPE_ID - 1) + +#define VIED_NCI_N_SP_CTRL_MEM 2 +#define VIED_NCI_N_SP_SERVER_MEM 2 +#define VIED_NCI_N_VP_MEM 4 +#define VIED_NCI_N_ACC_PSA_MEM 0 +#define VIED_NCI_N_ACC_ISA_MEM 0 +#define VIED_NCI_N_ACC_OSA_MEM 0 + +#define VIED_NCI_N_VP_CELL 4 +#define VIED_NCI_N_ACC_CELL 8 + +/* + * Device IDs + */ +typedef enum { + VIED_NCI_DEV_CHN_DMA_EXT0_ID = 0, + VIED_NCI_DEV_CHN_GDC_ID, + VIED_NCI_DEV_CHN_DMA_EXT1_READ_ID, + VIED_NCI_DEV_CHN_DMA_EXT1_WRITE_ID, + VIED_NCI_DEV_CHN_DMA_INTERNAL_ID, + VIED_NCI_DEV_CHN_DMA_IPFD_ID, + VIED_NCI_DEV_CHN_DMA_ISA_ID, + VIED_NCI_DEV_CHN_DMA_FW_ID, + VIED_NCI_DEV_CHN_DMA_CMPRS_ID, + VIED_NCI_N_DEV_CHN_ID +} vied_nci_dev_chn_ID_t; + +typedef enum { + DFM_IS_NOT_AVAILABLE +} vied_nci_dev_dfm_id_t; + +#define VIED_NCI_N_DEV_DFM_ID 0 +/* + * Memory size (previously in vied_nci_psys_system.c) + * VMEM: in words, 64 Byte per word. + * BAMEM: in words, 64 Byte per word + * DMEM: in words, 4 Byte per word. + * PMEM: in words, 64 Byte per word. + */ +#define VIED_NCI_GMEM_WORD_SIZE 64 +#define VIED_NCI_DMEM_WORD_SIZE 4 +#define VIED_NCI_VMEM_WORD_SIZE 64 +#define VIED_NCI_BAMEM_WORD_SIZE 64 + +#define VIED_NCI_VMEM0_MAX_SIZE (0x0800) +#define VIED_NCI_VMEM1_MAX_SIZE (0x0800) +#define VIED_NCI_VMEM2_MAX_SIZE (0x0800) +#define VIED_NCI_VMEM3_MAX_SIZE (0x0800) +#define VIED_NCI_VMEM4_MAX_SIZE (0x0800) +#define VIED_NCI_BAMEM0_MAX_SIZE (0x0400) +#define VIED_NCI_BAMEM1_MAX_SIZE (0x0400) +#define VIED_NCI_BAMEM2_MAX_SIZE (0x0400) +#define VIED_NCI_BAMEM3_MAX_SIZE (0x0400) +#define VIED_NCI_DMEM0_MAX_SIZE (0x4000) +#define VIED_NCI_DMEM1_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM2_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM3_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM4_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM5_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM6_MAX_SIZE (0x1000) +#define VIED_NCI_DMEM7_MAX_SIZE (0x1000) +#define VIED_NCI_PMEM0_MAX_SIZE (0x0500) +#define VIED_NCI_PMEM1_MAX_SIZE (0x0500) +#define VIED_NCI_PMEM2_MAX_SIZE (0x0500) +#define VIED_NCI_PMEM3_MAX_SIZE (0x0500) + +/* + * Number of channels per device + */ +#define VIED_NCI_DEV_CHN_DMA_EXT0_MAX_SIZE (30) +#define VIED_NCI_DEV_CHN_GDC_MAX_SIZE (4) +#define VIED_NCI_DEV_CHN_DMA_EXT1_READ_MAX_SIZE (30) +#define VIED_NCI_DEV_CHN_DMA_EXT1_WRITE_MAX_SIZE (20) +#define VIED_NCI_DEV_CHN_DMA_INTERNAL_MAX_SIZE (2) +#define VIED_NCI_DEV_CHN_DMA_IPFD_MAX_SIZE (5) +#define VIED_NCI_DEV_CHN_DMA_ISA_MAX_SIZE (2) +#define VIED_NCI_DEV_CHN_DMA_FW_MAX_SIZE (1) +#define VIED_NCI_DEV_CHN_DMA_CMPRS_MAX_SIZE (6) + +/* + * Storage of the resource and resource type enumerators + */ +#define VIED_NCI_RESOURCE_ID_BITS 8 +typedef uint8_t vied_nci_resource_id_t; + +#define VIED_NCI_RESOURCE_SIZE_BITS 16 +typedef uint16_t vied_nci_resource_size_t; + +#define VIED_NCI_RESOURCE_BITMAP_BITS 32 +typedef uint32_t vied_nci_resource_bitmap_t; + +#define IA_CSS_PROCESS_INVALID_DEPENDENCY ((vied_nci_resource_id_t)(-1)) +#define IA_CSS_PROCESS_INVALID_OFFSET ((vied_nci_resource_size_t)(-1)) +#define IA_CSS_PROCESS_MAX_CELLS 1 + +/* + * Resource specifications + * Note that the FAS uses the terminology local/remote memory. In the PSYS API, + * these are called internal/external memory. + */ + +/* resource spec for internal (local) memory */ +struct vied_nci_resource_spec_int_mem_s { + vied_nci_resource_id_t type_id; + vied_nci_resource_size_t size; + vied_nci_resource_size_t offset; +}; + +typedef struct vied_nci_resource_spec_int_mem_s + vied_nci_resource_spec_int_mem_t; + +/* resource spec for external (remote) memory */ +struct vied_nci_resource_spec_ext_mem_s { + vied_nci_resource_id_t type_id; + vied_nci_resource_size_t size; + vied_nci_resource_size_t offset; +}; + +typedef struct vied_nci_resource_spec_ext_mem_s + vied_nci_resource_spec_ext_mem_t; + +/* resource spec for device channel */ +struct vied_nci_resource_spec_dev_chn_s { + vied_nci_resource_id_t type_id; + vied_nci_resource_size_t size; + vied_nci_resource_size_t offset; +}; + +typedef struct vied_nci_resource_spec_dev_chn_s + vied_nci_resource_spec_dev_chn_t; + +/* resource spec for all contiguous resources */ +struct vied_nci_resource_spec_s { + vied_nci_resource_spec_int_mem_t int_mem[VIED_NCI_N_MEM_TYPE_ID]; + vied_nci_resource_spec_ext_mem_t ext_mem[VIED_NCI_N_DATA_MEM_TYPE_ID]; + vied_nci_resource_spec_dev_chn_t dev_chn[VIED_NCI_N_DEV_CHN_ID]; +}; + +typedef struct vied_nci_resource_spec_s vied_nci_resource_spec_t; + +#ifndef PIPE_GENERATION + +extern const vied_nci_cell_type_ID_t vied_nci_cell_type[VIED_NCI_N_CELL_ID]; +extern const vied_nci_mem_type_ID_t vied_nci_mem_type[VIED_NCI_N_MEM_ID]; +extern const uint16_t vied_nci_N_cell_mem[VIED_NCI_N_CELL_TYPE_ID]; +extern const vied_nci_mem_type_ID_t + vied_nci_cell_mem_type[VIED_NCI_N_CELL_TYPE_ID][VIED_NCI_N_MEM_TYPE_ID]; +extern const vied_nci_mem_ID_t + vied_nci_ext_mem[VIED_NCI_N_MEM_TYPE_ID]; +extern const vied_nci_mem_ID_t + vied_nci_cell_mem[VIED_NCI_N_CELL_ID][VIED_NCI_N_MEM_TYPE_ID]; +extern const uint16_t vied_nci_mem_size[VIED_NCI_N_MEM_ID]; +extern const uint16_t vied_nci_mem_word_size[VIED_NCI_N_DATA_MEM_TYPE_ID]; +extern const uint16_t vied_nci_dev_chn_size[VIED_NCI_N_DEV_CHN_ID]; + +STORAGE_CLASS_INLINE +uint32_t vied_nci_mem_is_ext_type(const vied_nci_mem_type_ID_t mem_type_id) +{ + return((mem_type_id == VIED_NCI_GMEM_TYPE_ID)); +} + +#endif /* PIPE_GENERATION */ + +#endif /* __VIED_NCI_PSYS_RESOURCE_MODEL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_data.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_data.h new file mode 100644 index 0000000000000..5b053a27686bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_data.h @@ -0,0 +1,50 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_SIM_DATA_H +#define __IA_CSS_PSYS_SIM_DATA_H + +/*! Set the seed if the random number generator + + @param seed[in] Random number generator seed + */ +extern void ia_css_psys_ran_set_seed(const unsigned int seed); + +/*! Generate a random number of a specified bit depth + + @param bit_depth[in] The number of bits of the random output + + @return out, weight(out) <= bit_depth, 0 on error + */ +extern unsigned int ia_css_psys_ran_var(const unsigned int bit_depth); + +/*! Generate a random number of a specified range + + @param range[in] The range of the random output + + @return 0 <= out < range, 0 on error + */ +extern unsigned int ia_css_psys_ran_val(const unsigned int range); + +/*! Generate a random number in a specified interval + + @param lo[in] The lower bound of the random output range + @param hi[in] The higher bound of the random output range + + @return lo <= out < hi, 0 on error + */ +extern unsigned int ia_css_psys_ran_interval(const unsigned int lo, + const unsigned int hi); + +#endif /* __IA_CSS_PSYS_SIM_DATA_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_storage_class.h new file mode 100644 index 0000000000000..61095257ec550 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_storage_class.h @@ -0,0 +1,28 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_SIM_STORAGE_CLASS_H +#define __IA_CSS_PSYS_SIM_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __IA_CSS_PSYS_SIM_INLINE__ +#define IA_CSS_PSYS_SIM_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PSYS_SIM_STORAGE_CLASS_C +#else +#define IA_CSS_PSYS_SIM_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PSYS_SIM_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PSYS_SIM_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_trace.h new file mode 100644 index 0000000000000..423ff19802707 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/ia_css_psys_sim_trace.h @@ -0,0 +1,95 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_SIM_TRACE_H +#define __IA_CSS_PSYS_SIM_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_SIM_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_SIM_TRACING_OVERRIDE)) + #define PSYS_SIM_TRACE_LEVEL_CONFIG PSYS_SIM_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_SIM_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_SIM_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_SIM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_SIM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_SIM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_SIM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_SIM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_SIM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_SIM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_SIM_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_SIM_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_SIM_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_SIM_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_SIM_TRACE_METHOD PSYSAPI_TRACE_METHOD + #define PSYSAPI_SIM_TRACE_LEVEL_ASSERT PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_SIM_TRACE_LEVEL_ERROR PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_SIM_TRACE_LEVEL_WARNING PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_SIM_TRACE_LEVEL_INFO PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_SIM_TRACE_LEVEL_DEBUG PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_SIM_TRACE_LEVEL_VERBOSE PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_SIM_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/vied_nci_psys_system_global.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/vied_nci_psys_system_global.h new file mode 100644 index 0000000000000..69f218baf66c1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/interface/vied_nci_psys_system_global.h @@ -0,0 +1,180 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __VIED_NCI_PSYS_SYSTEM_GLOBAL_H +#define __VIED_NCI_PSYS_SYSTEM_GLOBAL_H + +#include +#include "ia_css_base_types.h" +#include "ia_css_psys_sim_storage_class.h" +#include "vied_nci_psys_resource_model.h" + +/* + * Key system types + */ +/* Subsystem internal physical address */ +#define VIED_ADDRESS_BITS 32 + +/* typedef uint32_t vied_address_t; */ + +/* Subsystem internal virtual address */ + +/* Subsystem internal data bus */ +#define VIED_DATA_BITS 32 +typedef uint32_t vied_data_t; + +#define VIED_NULL ((vied_vaddress_t)0) + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bit_mask( + const unsigned int index); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_set( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_clear( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_bitmap_empty( + const vied_nci_resource_bitmap_t bitmap); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_bitmap_set( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_bit_set_in_bitmap( + const vied_nci_resource_bitmap_t bitmap, + const unsigned int index); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_bitmap_clear( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +int vied_nci_bitmap_compute_weight( + const vied_nci_resource_bitmap_t bitmap); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_union( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_intersection( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_xor( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_set_unique( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitfield_mask( + const unsigned int position, + const unsigned int size); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bitmap_set_bitfield( +const vied_nci_resource_bitmap_t bitmap, +const unsigned int index, +const unsigned int size); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_bit_mask_set_unique( + const vied_nci_resource_bitmap_t bitmap, + const unsigned int index); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_cell_bit_mask( + const vied_nci_cell_ID_t cell_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_resource_bitmap_t vied_nci_barrier_bit_mask( + const vied_nci_barrier_ID_t barrier_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_cell_type_ID_t vied_nci_cell_get_type( + const vied_nci_cell_ID_t cell_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_mem_type_ID_t vied_nci_mem_get_type( + const vied_nci_mem_ID_t mem_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +uint16_t vied_nci_mem_get_size( + const vied_nci_mem_ID_t mem_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +uint16_t vied_nci_dev_chn_get_size( + const vied_nci_dev_chn_ID_t dev_chn_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_cell_of_type( + const vied_nci_cell_ID_t cell_id, + const vied_nci_cell_type_ID_t cell_type_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_mem_of_type( + const vied_nci_mem_ID_t mem_id, + const vied_nci_mem_type_ID_t mem_type_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_is_cell_mem_of_type( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index, + const vied_nci_mem_type_ID_t mem_type_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +bool vied_nci_has_cell_mem_of_id( + const vied_nci_cell_ID_t cell_id, + const vied_nci_mem_ID_t mem_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +uint16_t vied_nci_cell_get_mem_count( + const vied_nci_cell_ID_t cell_id); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_mem_type_ID_t vied_nci_cell_get_mem_type( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_mem_ID_t vied_nci_cell_get_mem( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index); + +IA_CSS_PSYS_SIM_STORAGE_CLASS_H +vied_nci_mem_type_ID_t vied_nci_cell_type_get_mem_type( + const vied_nci_cell_type_ID_t cell_type_id, + const uint16_t mem_index); + +#ifdef __IA_CSS_PSYS_SIM_INLINE__ +#include "psys_system_global_impl.h" +#endif /* __IA_CSS_PSYS_SIM_INLINE__ */ + +#endif /* __VIED_NCI_PSYS_SYSTEM_GLOBAL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/src/ia_css_psys_sim_data.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/src/ia_css_psys_sim_data.c new file mode 100644 index 0000000000000..6dccac8238719 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/src/ia_css_psys_sim_data.c @@ -0,0 +1,91 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include + +#include "ia_css_psys_sim_trace.h" + +static unsigned int ia_css_psys_ran_seed; + +void ia_css_psys_ran_set_seed(const unsigned int seed) +{ + ia_css_psys_ran_seed = seed; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "ia_css_psys_ran_set_seed(): enter:\n"); + +} + +static unsigned int ia_css_psys_ran_int (void) +{ + ia_css_psys_ran_seed = 1664525UL * ia_css_psys_ran_seed + 1013904223UL; + return ia_css_psys_ran_seed; +} + +unsigned int ia_css_psys_ran_var(const unsigned int bit_depth) +{ + unsigned int out; + unsigned int tmp; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, "ia_css_psys_ran_var(): enter:\n"); + + tmp = ia_css_psys_ran_int(); + + if (bit_depth > 32) + out = tmp; + else if (bit_depth == 0) + out = 0; + else + out = (unsigned short)(tmp >> (32 - bit_depth)); + + return out; +} + +unsigned int ia_css_psys_ran_val(const unsigned int range) +{ + unsigned int out; + unsigned int tmp; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, "ia_css_psys_ran_val(): enter:\n"); + + tmp = ia_css_psys_ran_int(); + + if (range > 1) + out = tmp % range; + else + out = 0; + + return out; +} + +unsigned int ia_css_psys_ran_interval(const unsigned int lo, + const unsigned int hi) +{ + unsigned int out; + unsigned int tmp; + unsigned int range = hi - lo; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "ia_css_psys_ran_interval(): enter:\n"); + + tmp = ia_css_psys_ran_int(); + + if ((range > 1) && (lo < hi)) + out = lo + (tmp % range); + else + out = 0; + + return out; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/src/psys_system_global_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/src/psys_system_global_impl.h new file mode 100644 index 0000000000000..ff51175548ec0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/src/psys_system_global_impl.h @@ -0,0 +1,485 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PSYS_SYSTEM_GLOBAL_IMPL_H +#define __PSYS_SYSTEM_GLOBAL_IMPL_H + +#include + +#include "ia_css_psys_sim_trace.h" +#include + +/* Use vied_bits instead, however for test purposes we uses explicit type + * checking + */ +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bit_mask( + const unsigned int index) +{ + vied_nci_resource_bitmap_t bit_mask = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, "vied_nci_bit_mask(): enter:\n"); + + if (index < VIED_NCI_RESOURCE_BITMAP_BITS) + bit_mask = (vied_nci_resource_bitmap_t)1 << index; + + return bit_mask; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_set( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask) +{ + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, "vied_nci_bitmap_set(): enter:\n"); + +/* + assert(vied_nci_is_bitmap_one_hot(bit_mask)); +*/ + return bitmap | bit_mask; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_clear( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask) +{ + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bitmap_clear(): enter:\n"); + +/* + assert(vied_nci_is_bitmap_one_hot(bit_mask)); +*/ + return bitmap & (~bit_mask); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitfield_mask( + const unsigned int position, + const unsigned int size) +{ + vied_nci_resource_bitmap_t bit_mask = 0; + vied_nci_resource_bitmap_t ones = (vied_nci_resource_bitmap_t)-1; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bitfield_mask(): enter:\n"); + + if (position < VIED_NCI_RESOURCE_BITMAP_BITS) + bit_mask = (ones >> (sizeof(vied_nci_resource_bitmap_t) - size)) << position; + + return bit_mask; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_set_bitfield( + const vied_nci_resource_bitmap_t bitmap, + const unsigned int index, + const unsigned int size) +{ + vied_nci_resource_bitmap_t ret = 0; + vied_nci_resource_bitmap_t bit_mask = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bit_mask_set_bitfield(): enter:\n"); + + bit_mask = vied_nci_bitfield_mask(index, size); + ret = vied_nci_bitmap_set(bitmap, bit_mask); + + return ret; +} + + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_set_unique( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask) +{ + vied_nci_resource_bitmap_t ret = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bitmap_set_unique(): enter:\n"); + + if ((bitmap & bit_mask) == 0) + ret = bitmap | bit_mask; + + return ret; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bit_mask_set_unique( + const vied_nci_resource_bitmap_t bitmap, + const unsigned int index) +{ + vied_nci_resource_bitmap_t ret = 0; + vied_nci_resource_bitmap_t bit_mask; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bit_mask_set_unique(): enter:\n"); + + bit_mask = vied_nci_bit_mask(index); + + if (((bitmap & bit_mask) == 0) && (bit_mask != 0)) + ret = bitmap | bit_mask; + + return ret; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_bitmap_empty( + const vied_nci_resource_bitmap_t bitmap) +{ + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_bitmap_empty(): enter:\n"); + + return (bitmap == 0); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_bitmap_set( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask) +{ + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_bitmap_set(): enter:\n"); + +/* + assert(vied_nci_is_bitmap_one_hot(bit_mask)); +*/ + return !vied_nci_is_bitmap_clear(bitmap, bit_mask); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_bit_set_in_bitmap( + const vied_nci_resource_bitmap_t bitmap, + const unsigned int index) +{ + + vied_nci_resource_bitmap_t bitmask; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_bit_set_in_bitmap(): enter:\n"); + bitmask = vied_nci_bit_mask(index); + return vied_nci_is_bitmap_set(bitmap, bitmask); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_bitmap_clear( + const vied_nci_resource_bitmap_t bitmap, + const vied_nci_resource_bitmap_t bit_mask) +{ + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_bitmap_clear(): enter:\n"); + +/* + assert(vied_nci_is_bitmap_one_hot(bit_mask)); +*/ + return ((bitmap & bit_mask) == 0); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +int vied_nci_bitmap_compute_weight( + const vied_nci_resource_bitmap_t bitmap) +{ + vied_nci_resource_bitmap_t loc_bitmap = bitmap; + int weight = 0; + int i; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bitmap_compute_weight(): enter:\n"); + + /* Do not need the iterator "i" */ + for (i = 0; (i < VIED_NCI_RESOURCE_BITMAP_BITS) && + (loc_bitmap != 0); i++) { + weight += loc_bitmap & 0x01; + loc_bitmap >>= 1; + } + + return weight; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_union( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_bitmap_union(): enter:\n"); + return (bitmap0 | bitmap1); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_intersection( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "ia_css_kernel_bitmap_intersection(): enter:\n"); + return (bitmap0 & bitmap1); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_bitmap_xor( + const vied_nci_resource_bitmap_t bitmap0, + const vied_nci_resource_bitmap_t bitmap1) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, "vied_nci_bitmap_xor(): enter:\n"); + return (bitmap0 ^ bitmap1); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_cell_bit_mask( + const vied_nci_cell_ID_t cell_id) +{ + vied_nci_resource_bitmap_t bit_mask = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_bit_mask(): enter:\n"); + + if ((cell_id < VIED_NCI_N_CELL_ID) && + (cell_id < VIED_NCI_RESOURCE_BITMAP_BITS)) { + bit_mask = (vied_nci_resource_bitmap_t)1 << cell_id; + } + return bit_mask; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_resource_bitmap_t vied_nci_barrier_bit_mask( + const vied_nci_barrier_ID_t barrier_id) +{ + vied_nci_resource_bitmap_t bit_mask = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_barrier_bit_mask(): enter:\n"); + + if ((barrier_id < VIED_NCI_N_BARRIER_ID) && + ((barrier_id + VIED_NCI_N_CELL_ID) < VIED_NCI_RESOURCE_BITMAP_BITS)) { + bit_mask = (vied_nci_resource_bitmap_t)1 << + (barrier_id + VIED_NCI_N_CELL_ID); + } + return bit_mask; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_cell_type_ID_t vied_nci_cell_get_type( + const vied_nci_cell_ID_t cell_id) +{ + vied_nci_cell_type_ID_t cell_type = VIED_NCI_N_CELL_TYPE_ID; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_get_type(): enter:\n"); + + if (cell_id < VIED_NCI_N_CELL_ID) { + cell_type = vied_nci_cell_type[cell_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_SIM, WARNING, + "vied_nci_cell_get_type(): invalid argument\n"); + } + + return cell_type; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_mem_type_ID_t vied_nci_mem_get_type( + const vied_nci_mem_ID_t mem_id) +{ + vied_nci_mem_type_ID_t mem_type = VIED_NCI_N_MEM_TYPE_ID; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_mem_get_type(): enter:\n"); + + if (mem_id < VIED_NCI_N_MEM_ID) { + mem_type = vied_nci_mem_type[mem_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_SIM, WARNING, + "vied_nci_mem_get_type(): invalid argument\n"); + } + + return mem_type; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +uint16_t vied_nci_mem_get_size( + const vied_nci_mem_ID_t mem_id) +{ + uint16_t mem_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_mem_get_size(): enter:\n"); + + if (mem_id < VIED_NCI_N_MEM_ID) { + mem_size = vied_nci_mem_size[mem_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_SIM, WARNING, + "vied_nci_mem_get_size(): invalid argument\n"); + } + + return mem_size; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +uint16_t vied_nci_dev_chn_get_size( + const vied_nci_dev_chn_ID_t dev_chn_id) +{ + uint16_t dev_chn_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_dev_chn_get_size(): enter:\n"); + + if (dev_chn_id < VIED_NCI_N_DEV_CHN_ID) { + dev_chn_size = vied_nci_dev_chn_size[dev_chn_id]; + } else { + IA_CSS_TRACE_0(PSYSAPI_SIM, WARNING, + "vied_nci_dev_chn_get_size(): invalid argument\n"); + } + + return dev_chn_size; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_cell_of_type( + const vied_nci_cell_ID_t cell_id, + const vied_nci_cell_type_ID_t cell_type_id) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_cell_of_type(): enter:\n"); + + return ((vied_nci_cell_get_type(cell_id) == + cell_type_id) && (cell_type_id != + VIED_NCI_N_CELL_TYPE_ID)); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_mem_of_type( + const vied_nci_mem_ID_t mem_id, + const vied_nci_mem_type_ID_t mem_type_id) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_mem_of_type(): enter:\n"); + + return ((vied_nci_mem_get_type(mem_id) == mem_type_id) && + (mem_type_id != VIED_NCI_N_MEM_TYPE_ID)); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_is_cell_mem_of_type( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index, + const vied_nci_mem_type_ID_t mem_type_id) +{ + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_is_cell_mem_of_type(): enter:\n"); + + return ((vied_nci_cell_get_mem_type(cell_id, mem_index) == mem_type_id) + && (mem_type_id != VIED_NCI_N_MEM_TYPE_ID)); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +bool vied_nci_has_cell_mem_of_id( + const vied_nci_cell_ID_t cell_id, + const vied_nci_mem_ID_t mem_id) +{ + uint16_t mem_index; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_has_cell_mem_of_id(): enter:\n"); + + for (mem_index = 0; mem_index < VIED_NCI_N_MEM_TYPE_ID; mem_index++) { + if ((vied_nci_cell_get_mem(cell_id, mem_index) == mem_id) && + (mem_id != VIED_NCI_N_MEM_ID)) { + break; + } + } + + return (mem_index < VIED_NCI_N_MEM_TYPE_ID); +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +uint16_t vied_nci_cell_get_mem_count( + const vied_nci_cell_ID_t cell_id) +{ + uint16_t mem_count = 0; + vied_nci_cell_type_ID_t cell_type; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_get_mem_count(): enter:\n"); + + cell_type = vied_nci_cell_get_type(cell_id); + + if (cell_type < VIED_NCI_N_CELL_TYPE_ID) + mem_count = vied_nci_N_cell_mem[cell_type]; + + return mem_count; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_mem_type_ID_t vied_nci_cell_get_mem_type( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index) +{ + vied_nci_mem_type_ID_t mem_type = VIED_NCI_N_MEM_TYPE_ID; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_get_mem_type(): enter:\n"); + + if ((cell_id < VIED_NCI_N_CELL_ID) && + (mem_index < VIED_NCI_N_MEM_TYPE_ID)) { + mem_type = vied_nci_cell_mem_type[ + vied_nci_cell_get_type(cell_id)][mem_index]; + } + + return mem_type; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_mem_ID_t vied_nci_cell_get_mem( + const vied_nci_cell_ID_t cell_id, + const uint16_t mem_index) +{ + vied_nci_mem_ID_t mem_id = VIED_NCI_N_MEM_ID; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_get_mem(): enter:\n"); + + if ((cell_id < VIED_NCI_N_CELL_ID) && + (mem_index < VIED_NCI_N_MEM_TYPE_ID)) { + mem_id = vied_nci_cell_mem[cell_id][mem_index]; + } + + return mem_id; +} + +IA_CSS_PSYS_SIM_STORAGE_CLASS_C +vied_nci_mem_type_ID_t vied_nci_cell_type_get_mem_type( + const vied_nci_cell_type_ID_t cell_type_id, + const uint16_t mem_index) +{ + vied_nci_mem_type_ID_t mem_type = VIED_NCI_N_MEM_TYPE_ID; + + IA_CSS_TRACE_0(PSYSAPI_SIM, VERBOSE, + "vied_nci_cell_type_get_mem_type(): enter:\n"); + + if ((cell_type_id < VIED_NCI_N_CELL_TYPE_ID) + && (mem_index < VIED_NCI_N_MEM_TYPE_ID)) { + mem_type = vied_nci_cell_mem_type[cell_type_id][mem_index]; + } + + return mem_type; +} + +#endif /* __PSYS_SYSTEM_GLOBAL_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/src/vied_nci_psys_system.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/src/vied_nci_psys_system.c new file mode 100644 index 0000000000000..2cb52c1e0e9c9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/sim/src/vied_nci_psys_system.c @@ -0,0 +1,29 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_sim_storage_class.h" + +/* + * Functions to possibly inline + */ + +#ifdef __IA_CSS_PSYS_SIM_INLINE__ +STORAGE_CLASS_INLINE int +__ia_css_psys_system_global_avoid_warning_on_empty_file(void) +{ + return 0; +} +#else /* __IA_CSS_PSYS_SIM_INLINE__ */ +#include "psys_system_global_impl.h" +#endif /* __IA_CSS_PSYS_SIM_INLINE__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_manifest_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_manifest_types.h new file mode 100644 index 0000000000000..4a2f96e9405e8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_manifest_types.h @@ -0,0 +1,102 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_MANIFEST_TYPES_H +#define __IA_CSS_PSYS_MANIFEST_TYPES_H + +/*! \file */ + +/** @file ia_css_psys_manifest_types.h + * + * The types belonging to the terminal/program/ + * program group manifest static module + */ + +#include +#include "vied_nci_psys_resource_model.h" + + +/* This value is used in the manifest to indicate that the resource + * offset field must be ignored and the resource is relocatable + */ +#define IA_CSS_PROGRAM_MANIFEST_RESOURCE_OFFSET_IS_RELOCATABLE ((vied_nci_resource_size_t)(-1)) + +/* + * Connection type defining the interface source/sink + * + * Note that the connection type does not define the + * real-time configuration of the system, i.e. it + * does not describe whether a source and sink + * program group or sub-system operate synchronously + * that is a program script property {online, offline} + * (see FAS 5.16.3) + */ +#define IA_CSS_CONNECTION_BITMAP_BITS 8 +typedef uint8_t ia_css_connection_bitmap_t; + +#define IA_CSS_CONNECTION_TYPE_BITS 32 +typedef enum ia_css_connection_type { + /**< The terminal is in DDR */ + IA_CSS_CONNECTION_MEMORY = 0, + /**< The terminal is a (watermark) queued stream over DDR */ + IA_CSS_CONNECTION_MEMORY_STREAM, + /* The terminal is a device port */ + IA_CSS_CONNECTION_STREAM, + IA_CSS_N_CONNECTION_TYPES +} ia_css_connection_type_t; + +#define IA_CSS_PROGRAM_TYPE_BITS 32 +typedef enum ia_css_program_type { + IA_CSS_PROGRAM_TYPE_SINGULAR = 0, + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB, + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER, + IA_CSS_PROGRAM_TYPE_PARALLEL_SUB, + IA_CSS_PROGRAM_TYPE_PARALLEL_SUPER, + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB, + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER, +/* + * Future extension; A bitmap coding starts making more sense + * + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB_PARALLEL_SUB, + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB_PARALLEL_SUPER, + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER_PARALLEL_SUB, + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER_PARALLEL_SUPER, + */ + IA_CSS_N_PROGRAM_TYPES +} ia_css_program_type_t; + +#define IA_CSS_PROGRAM_GROUP_ID_BITS 32 +typedef uint32_t ia_css_program_group_ID_t; +#define IA_CSS_PROGRAM_ID_BITS 32 +typedef uint32_t ia_css_program_ID_t; + +#define IA_CSS_PROGRAM_INVALID_ID ((uint32_t)(-1)) +#define IA_CSS_PROGRAM_GROUP_INVALID_ID ((uint32_t)(-1)) + +typedef struct ia_css_program_group_manifest_s +ia_css_program_group_manifest_t; +typedef struct ia_css_program_manifest_s +ia_css_program_manifest_t; +typedef struct ia_css_data_terminal_manifest_s +ia_css_data_terminal_manifest_t; + +/* ============ Program Control Init Terminal Manifest - START ============ */ +typedef struct ia_css_program_control_init_manifest_program_desc_s + ia_css_program_control_init_manifest_program_desc_t; + +typedef struct ia_css_program_control_init_terminal_manifest_s + ia_css_program_control_init_terminal_manifest_t; +/* ============ Program Control Init Terminal Manifest - END ============ */ + +#endif /* __IA_CSS_PSYS_MANIFEST_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.h new file mode 100644 index 0000000000000..ee8321ea1f12b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.h @@ -0,0 +1,311 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_H +#define __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_H + +#include "ia_css_psys_static_storage_class.h" + +/*! \file */ + +/** @file ia_css_psys_program_group_manifest.h + * + * Define the methods on the program group manifest object that are not part of + * a single interface + */ + +#include + +#include /* uint8_t */ + +#include + +#include + +#include /* ia_css_kernel_bitmap_t */ +#include "ia_css_terminal_manifest.h" +#include "ia_css_rbm_manifest_types.h" + +#define IA_CSS_PROGRAM_GROUP_INVALID_ALIGNMENT ((uint8_t)(-1)) + +/*! Get the stored size of the program group manifest object + + @param manifest[in] program group manifest object + + @return size, 0 on invalid argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +size_t ia_css_program_group_manifest_get_size( + const ia_css_program_group_manifest_t *manifest); + +/*! Get the program group ID of the program group manifest object + + @param manifest[in] program group manifest object + + @return program group ID, IA_CSS_PROGRAM_GROUP_INVALID_ID on invalid argument +*/ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_program_group_ID_t +ia_css_program_group_manifest_get_program_group_ID( + const ia_css_program_group_manifest_t *manifest); + +/*! Set the program group ID of the program group manifest object + + @param manifest[in] program group manifest object + + @param program group ID + + @return 0 on success, -1 on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +int ia_css_program_group_manifest_set_program_group_ID( + ia_css_program_group_manifest_t *manifest, + ia_css_program_group_ID_t id); + +/*! Get the storage alignment constraint of the program group binary data + + @param manifest[in] program group manifest object + + @return alignment, IA_CSS_PROGRAM_GROUP_INVALID_ALIGNMENT on invalid manifest + argument +*/ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +uint8_t ia_css_program_group_manifest_get_alignment( + const ia_css_program_group_manifest_t *manifest); + +/*! Set the storage alignment constraint of the program group binary data + + @param manifest[in] program group manifest object + @param alignment[in] alignment desired + + @return < 0 on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +int ia_css_program_group_manifest_set_alignment( + ia_css_program_group_manifest_t *manifest, + const uint8_t alignment); + +/*! Get the kernel enable bitmap of the program group + + @param manifest[in] program group manifest object + + @return bitmap, 0 on invalid manifest argument + */ +extern ia_css_kernel_bitmap_t +ia_css_program_group_manifest_get_kernel_bitmap( + const ia_css_program_group_manifest_t *manifest); + +/*! Set the kernel enable bitmap of the program group + + @param manifest[in] program group manifest object + @param kernel bitmap[in] kernel enable bitmap + + @return < 0 on invalid manifest argument + */ +extern int ia_css_program_group_manifest_set_kernel_bitmap( + ia_css_program_group_manifest_t *manifest, + const ia_css_kernel_bitmap_t bitmap); + +/*! Get the number of programs in the program group manifest object + + @param manifest[in] program group manifest object + + @return program count, 0 on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +uint8_t ia_css_program_group_manifest_get_program_count( + const ia_css_program_group_manifest_t *manifest); + +/*! Get the number of terminals in the program group manifest object + + @param manifest[in] program group manifest object + + @return terminal count, 0 on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +uint8_t ia_css_program_group_manifest_get_terminal_count( + const ia_css_program_group_manifest_t *manifest); + +/*! Get the (pointer to) private data blob in the manifest + + @param manifest[in] program group manifest object + + @return private data blob, NULL on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +void *ia_css_program_group_manifest_get_private_data( + const ia_css_program_group_manifest_t *manifest); + +/*! Get the (pointer to) routing bitmap (rbm) manifest + + @param manifest[in] program group manifest object + + @return rbm manifest, NULL on invalid manifest argument + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_rbm_manifest_t * +ia_css_program_group_manifest_get_rbm_manifest( + const ia_css_program_group_manifest_t *manifest); + +/*! Get the (pointer to) indexed program manifest in the program group manifest + * object + + @param manifest[in] program group manifest object + @param program_index[in] index of the program manifest object + + @return program manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_program_manifest_t * +ia_css_program_group_manifest_get_prgrm_mnfst( + const ia_css_program_group_manifest_t *manifest, + const unsigned int program_index); + +/*! Get the (pointer to) indexed terminal manifest in the program group + * manifest object + + @param manifest[in] program group manifest object + @param program_index[in] index of the terminal manifest object + + @return terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_terminal_manifest_t * +ia_css_program_group_manifest_get_term_mnfst( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! Get the (pointer to) indexed data terminal manifest in the program group + * manifest object + + @param manifest[in] program group manifest object + @param program_index[in] index of the terminal manifest object + + @return data terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_data_terminal_manifest_t * +ia_css_program_group_manifest_get_data_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! Get the (pointer to) indexed parameter terminal manifest in the program + * group manifest object + + @param manifest[in] program group manifest object + @param program_index[in] index of the terminal manifest object + + @return parameter terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_param_terminal_manifest_t * +ia_css_program_group_manifest_get_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! Get the (pointer to) indexed spatial param terminal manifest in the program + * group manifest object + + @param manifest[in] program group manifest object + @param program_index[in] index of the terminal manifest object + + @return spatial param terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_spatial_param_terminal_manifest_t * +ia_css_program_group_manifest_get_spatial_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! Get the (pointer to) indexed sliced param terminal manifest in the program + * group manifest object + + @param manifest[in] program group manifest object + @param program_index[in] index of the terminal manifest object + + @return sliced param terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_sliced_param_terminal_manifest_t * +ia_css_program_group_manifest_get_sliced_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! Get the (pointer to) indexed program terminal manifest in the program group + * manifest object + + @parammanifest[in]program group manifest object + @paramprogram_index[in]index of the terminal manifest object + + @return program terminal manifest, NULL on invalid arguments + */ +IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +ia_css_program_terminal_manifest_t * +ia_css_program_group_manifest_get_program_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index); + +/*! initialize program group manifest + + @param manifest[in] program group manifest object + @param program_count[in] number of programs. + @param terminal_count[in] number of terminals. + @param program_deps[in] program dependencies for programs in pg. + @param terminal_deps[in] terminal dependencies for programs in pg. + @param terminal_type[in] array of terminal types, binary specific + static frame data + @param cached_in_param_section_count[in]Number of parameter terminal sections + @param cached_out_param_section_count[in] Number of parameter out terminal + @param spatial_param_section_count[in] Array[spatial_terminal_count] + with sections per cached out + terminal + @param sliced_in_param_section_count[in] Array[sliced_in_terminal_count] + with sections per sliced in + terminal + @param sliced_out_param_section_count[in] Array[sliced_out_terminal_count] + with sections per sliced out + terminal + @param fragment_param_section_count[in] Number of fragment parameter + sections of the program init + terminal, + @param kernel_fragment_seq_count[in] Number of kernel fragment + seqence info. + @param progctrlinit_load_section_counts[in] Number of progctrinit load + sections (size of array is program_count) + @param progctrlinit_connect_section_counts[in] Number of progctrinit connect + sections (size of array is program_count) + @return none; + */ +extern void ia_css_program_group_manifest_init( + ia_css_program_group_manifest_t *blob, + const uint8_t program_count, + const uint8_t terminal_count, + const uint8_t *program_dependencies, + const uint8_t *terminal_dependencies, + const ia_css_terminal_type_t *terminal_type, + const uint16_t cached_in_param_section_count, + const uint16_t cached_out_param_section_count, + const uint16_t *spatial_param_section_count, + const uint16_t fragment_param_section_count, + const uint16_t *sliced_in_param_section_count, + const uint16_t *sliced_out_param_section_count, + const uint16_t kernel_fragment_seq_count, + const uint16_t *progctrlinit_load_section_counts, + const uint16_t *progctrlinit_connect_section_counts); + +#ifdef __IA_CSS_PSYS_STATIC_INLINE__ +#include "ia_css_psys_program_group_manifest_impl.h" +#endif /* __IA_CSS_PSYS_STATIC_INLINE__ */ + +#endif /* __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.hsys.user.h new file mode 100644 index 0000000000000..ce802ff5dd8d3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.hsys.user.h @@ -0,0 +1,69 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_HSYS_USER_H +#define __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_program_group_manifest.hsys.user.h + * + * Define the methods on the program group manifest object: Hsys user interface + */ + +#include + +#include /* bool */ + +/*! Print the program group manifest object to file/stream + + @param manifest[in] program group manifest object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_program_group_manifest_print( + const ia_css_program_group_manifest_t *manifest, + void *fid); + +/*! Read the program group manifest object from file/stream + + @param fid[in] file/stream handle + + @return NULL on error + */ +extern ia_css_program_group_manifest_t *ia_css_program_group_manifest_read( + void *fid); + +/*! Write the program group manifest object to file/stream + + @param manifest[in] program group manifest object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_program_group_manifest_write( + const ia_css_program_group_manifest_t *manifest, + void *fid); + +/*! Boolean test if the program group manifest is valid + + @param manifest[in] program group manifest + + @return true if program group manifest is correct, false on error + */ +extern bool ia_css_is_program_group_manifest_valid( + const ia_css_program_group_manifest_t *manifest); + +#endif /* __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.sim.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.sim.h new file mode 100644 index 0000000000000..242f02108dd84 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_group_manifest.sim.h @@ -0,0 +1,127 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_SIM_H +#define __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_SIM_H + +/*! \file */ + +/** @file ia_css_psys_program_group_manifest.sim.h + * + * Define the methods on the program group manifest object: Simulation only + */ + +#include + +#include /* uint8_t */ +#include "ia_css_terminal_defs.h" + +/*! Create a program group manifest object from specification + + @param specification[in] specification (index) + + @return NULL on error + */ +extern ia_css_program_group_manifest_t *ia_css_program_group_manifest_create( + const unsigned int specification); + +/*! Destroy the program group manifest object + + @param manifest[in] program group manifest + + @return NULL + */ +extern ia_css_program_group_manifest_t *ia_css_program_group_manifest_destroy( + ia_css_program_group_manifest_t *manifest); + +/*! Compute the size of storage required for allocating + * the program group (PG) manifest object + + @param program_count[in] Number of programs in the PG + @param terminal_count[in] Number of terminals on the PG + @param program_dependency_count[in] Array[program_count] with the PG + @param terminal_dependency_count[in] Array[program_count] with the + terminal dependencies + @param terminal_type[in] Array[terminal_count] with the + terminal type + @param cached_in_param_section_count[in] Number of parameter + in terminal sections + @param cached_out_param_section_count[in] Number of parameter + out terminal sections + @param sliced_param_section_count[in] Array[sliced_terminal_count] + with sections per + sliced in terminal + @param sliced_out_param_section_count[in] Array[sliced_terminal_count] + with sections per + sliced out terminal + @param spatial_param_section_count[in] Array[spatial_terminal_count] + with sections per + spatial terminal + @param fragment_param_section_count[in] Number of fragment parameter + sections of the + program init terminal, + @param kernel_fragment_seq_count[in] Number of + kernel_fragment_seq_count. + @param progctrlinit_load_section_counts[in] Number of progctrinit load + sections (size of array is program_count) + @param progctrlinit_connect_section_counts[in] Number of progctrinit connect + sections (size of array is program_count) + @return 0 on error + */ +size_t ia_css_sizeof_program_group_manifest( + const uint8_t program_count, + const uint8_t terminal_count, + const uint8_t *program_dependency_count, + const uint8_t *terminal_dependency_count, + const ia_css_terminal_type_t *terminal_type, + const uint16_t cached_in_param_section_count, + const uint16_t cached_out_param_section_count, + const uint16_t *spatial_param_section_count, + const uint16_t fragment_param_section_count, + const uint16_t *sliced_param_section_count, + const uint16_t *sliced_out_param_section_count, + const uint16_t kernel_fragment_seq_count, + const uint16_t *progctrlinit_load_section_counts, + const uint16_t *progctrlinit_connect_section_counts); + +/*! Create (the storage for) the program group manifest object + + @param program_count[in] Number of programs in the program group + @param terminal_count[in] Number of terminals on the program group + @param program_dependency_count[in] Array[program_count] with the + program dependencies + @param terminal_dependency_count[in] Array[program_count] with the + terminal dependencies + @param terminal_type[in] Array[terminal_count] with the + terminal type + + @return NULL on error + */ +extern ia_css_program_group_manifest_t *ia_css_program_group_manifest_alloc( + const uint8_t program_count, + const uint8_t terminal_count, + const uint8_t *program_dependency_count, + const uint8_t *terminal_dependency_count, + const ia_css_terminal_type_t *terminal_type); + +/*! Free (the storage of) the program group manifest object + + @param manifest[in] program group manifest + + @return NULL + */ +extern ia_css_program_group_manifest_t *ia_css_program_group_manifest_free( + ia_css_program_group_manifest_t *manifest); + +#endif /* __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_SIM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.h new file mode 100644 index 0000000000000..b7333671ed4fc --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.h @@ -0,0 +1,488 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_MANIFEST_H +#define __IA_CSS_PSYS_PROGRAM_MANIFEST_H + +/*! \file */ + +/** @file ia_css_psys_program_manifest.h + * + * Define the methods on the program manifest object that are not part of a + * single interface + */ + +#include + +#include /* uint8_t */ + +#include + +#include + +#include /* ia_css_kernel_bitmap_t */ + +/* + * Resources needs + */ +#include + +#define IA_CSS_PROGRAM_INVALID_DEPENDENCY ((uint8_t)(-1)) + +/*! Check if the program manifest object specifies a fixed cell allocation + + @param manifest[in] program manifest object + + @return has_fixed_cell, false on invalid argument + */ +extern bool ia_css_has_program_manifest_fixed_cell( + const ia_css_program_manifest_t *manifest); + +/*! Get the stored size of the program manifest object + + @param manifest[in] program manifest object + + @return size, 0 on invalid argument + */ +extern size_t ia_css_program_manifest_get_size( + const ia_css_program_manifest_t *manifest); + +/*! Get the program ID of the program manifest object + + @param manifest[in] program manifest object + + @return program ID, IA_CSS_PROGRAM_INVALID_ID on invalid argument + */ +extern ia_css_program_ID_t ia_css_program_manifest_get_program_ID( + const ia_css_program_manifest_t *manifest); + +/*! Set the program ID of the program manifest object + + @param manifest[in] program manifest object + + @param program ID + + @return 0 on success, -1 on invalid manifest argument + */ +extern int ia_css_program_manifest_set_program_ID( + ia_css_program_manifest_t *manifest, + ia_css_program_ID_t id); + +/*! Get the (pointer to) the program group manifest parent of the program + * manifest object + + @param manifest[in] program manifest object + + @return the pointer to the parent, NULL on invalid manifest argument + */ +extern ia_css_program_group_manifest_t *ia_css_program_manifest_get_parent( + const ia_css_program_manifest_t *manifest); + +/*! Set the (pointer to) the program group manifest parent of the program + * manifest object + + @param manifest[in] program manifest object + @param program_offset[in] this program's offset from + program_group_manifest's base address. + + @return < 0 on invalid manifest argument + */ +extern int ia_css_program_manifest_set_parent_offset( + ia_css_program_manifest_t *manifest, + int32_t program_offset); + +/*! Get the type of the program manifest object + + @param manifest[in] program manifest object + + @return program type, limit value (IA_CSS_N_PROGRAM_TYPES) on invalid manifest + argument +*/ +extern ia_css_program_type_t ia_css_program_manifest_get_type( + const ia_css_program_manifest_t *manifest); + +/*! Set the type of the program manifest object + + @param manifest[in] program manifest object + @param program_type[in] program type + + @return < 0 on invalid manifest argument + */ +extern int ia_css_program_manifest_set_type( + ia_css_program_manifest_t *manifest, + const ia_css_program_type_t program_type); + +/*! Set the cell id of the program manifest object + + @param manifest[in] program manifest object + @param program_cell_id[in] program cell id + + @return < 0 on invalid manifest argument + */ +extern int ia_css_program_manifest_set_cell_ID( + ia_css_program_manifest_t *manifest, + const vied_nci_cell_ID_t cell_id); + +/*! Set the cell type of the program manifest object + + @param manifest[in] program manifest object + @param program_cell_type[in] program cell type + + @return < 0 on invalid manifest argument + */ +extern int ia_css_program_manifest_set_cell_type_ID( + ia_css_program_manifest_t *manifest, + const vied_nci_cell_type_ID_t cell_type_id); + +/*! Set cells bitmap for the program + + @param manifest[in] program manifest object + @param bitmap[in] bitmap + + @return 0 when not applicable and/or invalid arguments + */ +extern int ia_css_program_manifest_set_cells_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_resource_bitmap_t bitmap); + +/*! Get cells bitmap for the program + + @param manifest[in] program manifest object + + @return 0 when not applicable and/or invalid arguments + */ +extern vied_nci_resource_bitmap_t ia_css_program_manifest_get_cells_bitmap( + const ia_css_program_manifest_t *manifest); + +/*! Set DFM port bitmap for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + @param bitmap[in] bitmap + + @return 0 when not applicable and/or invalid arguments + */ +extern int ia_css_program_manifest_set_dfm_port_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const vied_nci_resource_bitmap_t bitmap); + +/*! Get bitmap of DFM ports requested for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + + @return DFM port bitmap + */ +extern vied_nci_resource_bitmap_t ia_css_program_manifest_get_dfm_port_bitmap( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id); + + +/*! Set active DFM port specification bitmap for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + @param bitmap[in] bitmap + + @return 0 when not applicable and/or invalid arguments + */ +extern int ia_css_program_manifest_set_dfm_active_port_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const vied_nci_resource_bitmap_t bitmap); + +/*! Get active DFM port specification bitmap for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + + @return 0 when not applicable and/or invalid arguments + */ +extern vied_nci_resource_bitmap_t ia_css_program_manifest_get_dfm_active_port_bitmap( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id); + +/*! Set DFM device relocatability specification for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + @param is_relocatable[in] 1 if dfm device ports are relocatable, 0 otherwise + + @return 0 when not applicable and/or invalid arguments + */ +extern int ia_css_program_manifest_set_is_dfm_relocatable( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const uint8_t is_relocatable); + +/*! Get DFM device relocatability specification for the program + + @param manifest[in] program manifest object + @param dfm_type_id[in] DFM resource type ID + + @return 1 if dfm device ports are relocatable, 0 otherwise + */ +extern uint8_t ia_css_program_manifest_get_is_dfm_relocatable( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id); + + +/*! Get the memory resource (size) specification for a memory + that belongs to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type ID + + @return 0 when not applicable and/or invalid arguments + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_int_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Set the memory resource (size) specification for a memory + that belongs to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type id + @param int_mem_size[in] internal memory size + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_int_mem_size( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t int_mem_size); + +/*! Get the memory resource (size) specification for a memory + that does not belong to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type ID + + @return 0 when not applicable and/or invalid arguments + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_ext_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Set the memory resource (size) specification for a memory + that does not belong to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type id + @param ext_mem_size[in] external memory size + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_ext_mem_size( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t ext_mem_size); + +/*! Get a device channel resource (size) specification + + @param manifest[in] program manifest object + @param dev_chn_id[in] device channel ID + + @return 0 when not applicable and/or invalid arguments + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_dev_chn_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id); + +/*! Set a device channel resource (size) specification + + @param manifest[in] program manifest object + @param dev_chn_id[in] device channel ID + @param dev_chn_size[in] device channel size + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_dev_chn_size( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t dev_chn_size); + +/*! Set a device channel resource (offset) specification + + @param manifest[in] program manifest object + @param dev_chn_id[in] device channel ID + @param dev_chn_offset[in] device channel offset + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_dev_chn_offset( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t dev_chn_offset); + + +/*! Set the memory resource (offset) specification for a memory + that does not belong to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type id + @param ext_mem_offset[in] external memory offset + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_ext_mem_offset( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t ext_mem_offset); + +/*! Get a device channel resource (offset) specification + + @param manifest[in] program manifest object + @param dev_chn_id[in] device channel ID + + @return Valid fixed offset (if value is greater or equal to 0) or + IA_CSS_PROGRAM_MANIFEST_RESOURCE_OFFSET_IS_RELOCATABLE if offset + is relocatable + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_dev_chn_offset( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id); + +/*! Get the memory resource (offset) specification for a memory + that does not belong to the cell where the program will be mapped. + + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type ID + + @return Valid fixed offset (if value is greater or equal to 0) or + IA_CSS_PROGRAM_MANIFEST_RESOURCE_OFFSET_IS_RELOCATABLE if offset + is relocatable + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_ext_mem_offset( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id); + + +/*! Get the kernel composition of the program manifest object + + @param manifest[in] program manifest object + + @return bitmap, 0 on invalid arguments + */ +extern ia_css_kernel_bitmap_t ia_css_program_manifest_get_kernel_bitmap( + const ia_css_program_manifest_t *manifest); + +/*! Set the kernel dependency of the program manifest object + + @param manifest[in] program manifest object + @param kernel_bitmap[in] kernel composition bitmap + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_kernel_bitmap( + ia_css_program_manifest_t *manifest, + const ia_css_kernel_bitmap_t kernel_bitmap); + +/*! Get the number of programs this programs depends on from the program group + * manifest object + + @param manifest[in] program manifest object + + @return program dependency count + */ +extern uint8_t ia_css_program_manifest_get_program_dependency_count( + const ia_css_program_manifest_t *manifest); + +/*! Get the index of the program which the programs at this index depends on + from the program manifest object + + @param manifest[in] program manifest object + + @return program dependency, + IA_CSS_PROGRAM_INVALID_DEPENDENCY on invalid arguments + */ +extern uint8_t ia_css_program_manifest_get_program_dependency( + const ia_css_program_manifest_t *manifest, + const unsigned int index); + +/*! Set the index of the program which the programs at this index depends on + in the program manifest object + + @param manifest[in] program manifest object + + @return program dependency + */ +extern int ia_css_program_manifest_set_program_dependency( + ia_css_program_manifest_t *manifest, + const uint8_t program_dependency, + const unsigned int index); + +/*! Get the number of terminals this programs depends on from the program group + * manifest object + + @param manifest[in] program manifest object + + @return program dependency count + */ +extern uint8_t ia_css_program_manifest_get_terminal_dependency_count( + const ia_css_program_manifest_t *manifest); + +/*! Get the index of the terminal which the programs at this index depends on + from the program manifest object + + @param manifest[in] program manifest object + + @return terminal dependency, IA_CSS_PROGRAM_INVALID_DEPENDENCY on error + */ +uint8_t ia_css_program_manifest_get_terminal_dependency( + const ia_css_program_manifest_t *manifest, + const unsigned int index); + +/*! Set the index of the terminal which the programs at this index depends on + in the program manifest object + + @param manifest[in] program manifest object + + @return < 0 on invalid arguments + */ +extern int ia_css_program_manifest_set_terminal_dependency( + ia_css_program_manifest_t *manifest, + const uint8_t terminal_dependency, + const unsigned int index); + +/*! Check if the program manifest object specifies a subnode program + + @param manifest[in] program manifest object + + @return is_subnode, false on invalid argument + */ +extern bool ia_css_is_program_manifest_subnode_program_type( + const ia_css_program_manifest_t *manifest); + +/*! Check if the program manifest object specifies a supernode program + + @param manifest[in] program manifest object + + @return is_supernode, false on invalid argument + */ +extern bool ia_css_is_program_manifest_supernode_program_type( + const ia_css_program_manifest_t *manifest); +/*! Check if the program manifest object specifies a singular program + + @param manifest[in] program manifest object + + @return is_singular, false on invalid argument + */ +extern bool ia_css_is_program_manifest_singular_program_type( + const ia_css_program_manifest_t *manifest); + +#endif /* __IA_CSS_PSYS_PROGRAM_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.kernel.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.kernel.h new file mode 100644 index 0000000000000..9d737b75a576b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.kernel.h @@ -0,0 +1,96 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_KERNEL_H +#define __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_KERNEL_H + +/*! \file */ + +/** @file ia_css_psys_program_manifest.hsys.kernel.h + * + * Define the methods on the program manifest object: Hsys kernel interface + */ + +#include + +#include + +#include /* uint8_t */ + +/* + * Resources needs + */ + +/*! Get the cell ID from the program manifest object + + @param manifest[in] program manifest object + + Note: If the cell ID is specified, the program this manifest belongs to + must be mapped on that instance. If the cell ID is invalid (limit value) + then the cell type ID must be specified instead + + @return cell ID, limit value if not specified + */ +extern vied_nci_cell_ID_t ia_css_program_manifest_get_cell_ID( + const ia_css_program_manifest_t *manifest); + +/*! Get the cell type ID from the program manifest object + + @param manifest[in] program manifest object + + Note: If the cell type ID is specified, the program this manifest belongs + to can be mapped on any instance of this clee type. If the cell type ID is + invalid (limit value) then a specific cell ID must be specified instead + + @return cell ID, limit value if not specified + */ +extern vied_nci_cell_type_ID_t ia_css_program_manifest_get_cell_type_ID( + const ia_css_program_manifest_t *manifest); + +/*! Get the memory resource (size) specification for a memory + that belongs to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type ID + + @return 0 when not applicable + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_int_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Get the memory resource (size) specification for a memory + that does not belong to the cell where the program will be mapped + + @param manifest[in] program manifest object + @param mem_type_id[in] mem type ID + + @return 0 when not applicable + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_ext_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id); + +/*! Get a device channel resource (size) specification + + @param manifest[in] program manifest object + @param dev_chn_id[in] device channel ID + + @return 0 when not applicable + */ +extern vied_nci_resource_size_t ia_css_program_manifest_get_dev_chn_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id); + +#endif /* __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_KERNEL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.user.h new file mode 100644 index 0000000000000..087c84b7106e5 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.hsys.user.h @@ -0,0 +1,38 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_USER_H +#define __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_program_manifest.hsys.user.h + * + * Define the methods on the program manifest object: Hsys user interface + */ + +#include + +/*! Print the program manifest object to file/stream + + @param manifest[in] program manifest object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_program_manifest_print( + const ia_css_program_manifest_t *manifest, + void *fid); + +#endif /* __IA_CSS_PSYS_PROGRAM_MANIFEST_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.sim.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.sim.h new file mode 100644 index 0000000000000..0c2cef11f30eb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_program_manifest.sim.h @@ -0,0 +1,61 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_MANIFEST_SIM_H +#define __IA_CSS_PSYS_PROGRAM_MANIFEST_SIM_H + +/*! \file */ + +/** @file ia_css_psys_program_manifest.sim.h + * + * Define the methods on the program manifest object: Simulation only + */ + +#include + +#include /* uint8_t */ + +/*! Compute the size of storage required for allocating + * the program manifest object + + @param program_dependency_count[in] Number of programs this one depends on + @param terminal_dependency_count[in] Number of terminals this one depends on + + @return 0 on error + */ +extern size_t ia_css_sizeof_program_manifest( + const uint8_t program_dependency_count, + const uint8_t terminal_dependency_count); + +/*! Create (the storage for) the program manifest object + + @param program_dependency_count[in] Number of programs this one depends on + @param terminal_dependency_count[in] Number of terminals this one depends on + + @return NULL on error + */ +extern ia_css_program_manifest_t *ia_css_program_manifest_alloc( + const uint8_t program_dependency_count, + const uint8_t terminal_dependency_count); + +/*! Destroy (the storage of) the program manifest object + + @param manifest[in] program manifest + + @return NULL + */ +extern ia_css_program_manifest_t *ia_css_program_manifest_free( + ia_css_program_manifest_t *manifest); + +#endif /* __IA_CSS_PSYS_PROGRAM_MANIFEST_SIM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_storage_class.h new file mode 100644 index 0000000000000..f3c832b5a4a33 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_storage_class.h @@ -0,0 +1,28 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_STATIC_STORAGE_CLASS_H +#define __IA_CSS_PSYS_STATIC_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __IA_CSS_PSYS_STATIC_INLINE__ +#define IA_CSS_PSYS_STATIC_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +#else +#define IA_CSS_PSYS_STATIC_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PSYS_STATIC_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PSYS_STATIC_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_trace.h new file mode 100644 index 0000000000000..7c5612cd09690 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_static_trace.h @@ -0,0 +1,103 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_STATIC_TRACE_H +#define __IA_CSS_PSYS_STATIC_TRACE_H + +#include "ia_css_psysapi_trace.h" + +#define PSYS_STATIC_TRACE_LEVEL_CONFIG_DEFAULT PSYSAPI_TRACE_LOG_LEVEL_OFF + +/* Default sub-module tracing config */ +#if (!defined(PSYSAPI_STATIC_TRACING_OVERRIDE)) + #define PSYS_STATIC_TRACE_LEVEL_CONFIG \ + PSYS_STATIC_TRACE_LEVEL_CONFIG_DEFAULT +#endif + +/* Module/sub-module specific trace setting will be used if + * the trace level is not specified from the module or + PSYSAPI_STATIC_TRACING_OVERRIDE is defined + */ +#if (defined(PSYSAPI_STATIC_TRACING_OVERRIDE)) + /* Module/sub-module specific trace setting */ + #if PSYSAPI_STATIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_OFF + /* PSYSAPI_TRACE_LOG_LEVEL_OFF */ + #define PSYSAPI_STATIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_STATIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_STATIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_NORMAL + /* PSYSAPI_TRACE_LOG_LEVEL_NORMAL */ + #define PSYSAPI_STATIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_STATIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_DISABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_DISABLED + #elif PSYSAPI_STATIC_TRACING_OVERRIDE == PSYSAPI_TRACE_LOG_LEVEL_DEBUG + /* PSYSAPI_TRACE_LOG_LEVEL_DEBUG */ + #define PSYSAPI_STATIC_TRACE_METHOD \ + IA_CSS_TRACE_METHOD_NATIVE + #define PSYSAPI_STATIC_TRACE_LEVEL_ASSERT \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_ERROR \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_WARNING \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_INFO \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_DEBUG \ + IA_CSS_TRACE_LEVEL_ENABLED + #define PSYSAPI_STATIC_TRACE_LEVEL_VERBOSE \ + IA_CSS_TRACE_LEVEL_ENABLED + #else + #error "No PSYSAPI_DATA Tracing level defined" + #endif +#else + /* Inherit Module trace setting */ + #define PSYSAPI_STATIC_TRACE_METHOD \ + PSYSAPI_TRACE_METHOD + #define PSYSAPI_STATIC_TRACE_LEVEL_ASSERT \ + PSYSAPI_TRACE_LEVEL_ASSERT + #define PSYSAPI_STATIC_TRACE_LEVEL_ERROR \ + PSYSAPI_TRACE_LEVEL_ERROR + #define PSYSAPI_STATIC_TRACE_LEVEL_WARNING \ + PSYSAPI_TRACE_LEVEL_WARNING + #define PSYSAPI_STATIC_TRACE_LEVEL_INFO \ + PSYSAPI_TRACE_LEVEL_INFO + #define PSYSAPI_STATIC_TRACE_LEVEL_DEBUG \ + PSYSAPI_TRACE_LEVEL_DEBUG + #define PSYSAPI_STATIC_TRACE_LEVEL_VERBOSE \ + PSYSAPI_TRACE_LEVEL_VERBOSE +#endif + +#endif /* __IA_CSS_PSYSAPI_STATIC_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.h new file mode 100644 index 0000000000000..0fa62b32e1a74 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.h @@ -0,0 +1,423 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_MANIFEST_H +#define __IA_CSS_PSYS_TERMINAL_MANIFEST_H + +/*! \file */ + +/** @file ia_css_psys_terminal_manifest.h + * + * Define the methods on the terminal manifest object that are not part of a + * single interface + */ + +#include + +#include + +#include + +#include /* ia_css_frame_format_bitmap_t */ +#include /* ia_css_kernel_bitmap_t */ + +#include /* size_t */ +#include "ia_css_terminal_manifest.h" +#include "ia_css_terminal_manifest_base_types.h" + + +/*! Check if the terminal manifest object specifies a spatial param terminal + * type + + @param manifest[in] terminal manifest object + + @return is_parameter_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_spatial_parameter_terminal( + const ia_css_terminal_manifest_t *manifest); + +/*! Check if the terminal manifest object specifies a program terminal type + + @param manifest[in] terminal manifest object + + @return is_parameter_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_program_terminal( + const ia_css_terminal_manifest_t *manifest); + + +/*! Check if the terminal manifest object specifies a program control init terminal type + * + * @param manifest[in] terminal manifest object + * + * @return is_parameter_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_program_control_init_terminal( + const ia_css_terminal_manifest_t *manifest); + +/*! Check if the terminal manifest object specifies a (cached) parameter + * terminal type + + @param manifest[in] terminal manifest object + + @return is_parameter_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_parameter_terminal( + const ia_css_terminal_manifest_t *manifest); + +/*! Check if the terminal manifest object specifies a (sliced) parameter + * terminal type + + @param manifest[in] terminal manifest object + + @return is_parameter_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_sliced_terminal( + const ia_css_terminal_manifest_t *manifest); + +/*! Check if the terminal manifest object specifies a data terminal type + + @param manifest[in] terminal manifest object + + @return is_data_terminal, false on invalid manifest argument + */ +extern bool ia_css_is_terminal_manifest_data_terminal( + const ia_css_terminal_manifest_t *manifest); + +/*! Get the stored size of the terminal manifest object + + @param manifest[in] terminal manifest object + + @return size, 0 on invalid manifest argument + */ +extern size_t ia_css_terminal_manifest_get_size( + const ia_css_terminal_manifest_t *manifest); + +/*! Get the (pointer to) the program group manifest parent of the terminal + * manifest object + + @param manifest[in] terminal manifest object + + @return the pointer to the parent, NULL on invalid manifest argument + */ +extern ia_css_program_group_manifest_t *ia_css_terminal_manifest_get_parent( + const ia_css_terminal_manifest_t *manifest); + +/*! Set the (pointer to) the program group manifest parent of the terminal + * manifest object + + @param manifest[in] terminal manifest object + @param terminal_offset[in] this terminal's offset from + program_group_manifest base address. + + @return < 0 on invalid arguments + */ +extern int ia_css_terminal_manifest_set_parent_offset( + ia_css_terminal_manifest_t *manifest, + int32_t terminal_offset); + +/*! Get the type of the terminal manifest object + + @param manifest[in] terminal manifest object + + @return terminal type, limit value (IA_CSS_N_TERMINAL_TYPES) on invalid + manifest argument +*/ +extern ia_css_terminal_type_t ia_css_terminal_manifest_get_type( + const ia_css_terminal_manifest_t *manifest); + +/*! Set the type of the terminal manifest object + + @param manifest[in] terminal manifest object + @param terminal_type[in] terminal type + + @return < 0 on invalid manifest argument + */ +extern int ia_css_terminal_manifest_set_type( + ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_type_t terminal_type); + +/*! Set the ID of the terminal manifest object + + @param manifest[in] terminal manifest object + @param ID[in] terminal ID + + @return < 0 on invalid manifest argument + */ +int ia_css_terminal_manifest_set_ID( + ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_ID_t ID); + +/*! Get the type of the terminal manifest object + + @param manifest[in] terminal manifest object + + @return terminal id, IA_CSS_TERMINAL_INVALID_ID on invalid manifest argument + */ +extern ia_css_terminal_ID_t ia_css_terminal_manifest_get_ID( + const ia_css_terminal_manifest_t *manifest); + +/*! Get the supported frame types of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + + @return frame format bitmap, 0 on invalid manifest argument +*/ +extern ia_css_frame_format_bitmap_t + ia_css_data_terminal_manifest_get_frame_format_bitmap( + const ia_css_data_terminal_manifest_t *manifest); + +/*! Set the chosen frame type for the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param bitmap[in] frame format bitmap + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_frame_format_bitmap( + ia_css_data_terminal_manifest_t *manifest, + ia_css_frame_format_bitmap_t bitmap); + +/*! Check if the (data) terminal manifest object supports compression + + @param manifest[in] (data) terminal manifest object + + @return compression_support, true if compression is supported + */ +extern bool ia_css_data_terminal_manifest_can_support_compression( + const ia_css_data_terminal_manifest_t *manifest); + +/*! Set the compression support feature of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param compression_support[in] set true to support compression + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_compression_support( + ia_css_data_terminal_manifest_t *manifest, + bool compression_support); + +/*! Set the supported connection types of the terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param bitmap[in] connection bitmap + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_connection_bitmap( + ia_css_data_terminal_manifest_t *manifest, ia_css_connection_bitmap_t bitmap); + +/*! Get the connection bitmap of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + + @return connection bitmap, 0 on invalid manifest argument +*/ +extern ia_css_connection_bitmap_t + ia_css_data_terminal_manifest_get_connection_bitmap( + const ia_css_data_terminal_manifest_t *manifest); + +/*! Get the kernel dependency of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + + @return kernel bitmap, 0 on invalid manifest argument + */ +extern ia_css_kernel_bitmap_t ia_css_data_terminal_manifest_get_kernel_bitmap( + const ia_css_data_terminal_manifest_t *manifest); + +/*! Set the kernel dependency of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param kernel_bitmap[in] kernel dependency bitmap + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_kernel_bitmap( + ia_css_data_terminal_manifest_t *manifest, + const ia_css_kernel_bitmap_t kernel_bitmap); + +/*! Set the unique kernel dependency of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param index[in] kernel dependency bitmap index + + @return < 0 on invalid argument(s) + */ +extern int ia_css_data_terminal_manifest_set_kernel_bitmap_unique( + ia_css_data_terminal_manifest_t *manifest, + const unsigned int index); + +/*! Set the min size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param min_size[in] Minimum size of the frame array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_min_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t min_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Set the max size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param max_size[in] Maximum size of the frame array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_max_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t max_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Get the min size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param min_size[in] Minimum size of the frame array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_get_min_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t min_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Get the max size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param max_size[in] Maximum size of the frame array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_get_max_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t max_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Set the min fragment size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param min_size[in] Minimum size of the fragment array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_min_fragment_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t min_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Set the max fragment size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param max_size[in] Maximum size of the fragment array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_set_max_fragment_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t max_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Get the min fragment size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param min_size[in] Minimum size of the fragment array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_get_min_fragment_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t min_size[IA_CSS_N_DATA_DIMENSION]); + +/*! Get the max fragment size of the (data) terminal manifest object + + @param manifest[in] (data) terminal manifest object + @param max_size[in] Maximum size of the fragment array + + @return < 0 on invalid manifest argument + */ +extern int ia_css_data_terminal_manifest_get_max_fragment_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t max_size[IA_CSS_N_DATA_DIMENSION]); + +/*! + * Get the program control init connect section count for program prog. + * @param prog[in] program control init terminal program desc + * @return number of connect section for program prog. + */ + +extern +unsigned int ia_css_program_control_init_terminal_manifest_get_connect_section_count( + const ia_css_program_control_init_manifest_program_desc_t *prog); + + +/*! + * Get the program control init load section count for program prog. + * @param prog[in] program control init terminal program desc + * @return number of load section for program prog. + */ + +extern +unsigned int ia_css_program_control_init_terminal_manifest_get_load_section_count( + const ia_css_program_control_init_manifest_program_desc_t *prog); + +/*! + * Get the program control init terminal manifest size. + * @param nof_programs[in] Number of programs. + * @param nof_load_sections[in] Array of size nof_programs, + * encoding the number of load sections. + * @param nof_connect_sections[in] Array of size nof_programs, + * encoding the number of connect sections. + * @return < 0 on invalid manifest argument + */ +extern +unsigned int ia_css_program_control_init_terminal_manifest_get_size( + const uint16_t nof_programs, + const uint16_t *nof_load_sections, + const uint16_t *nof_connect_sections); + +/*! + * Get the program control init terminal manifest program desc. + * @param terminal[in] Program control init terminal. + * @param program[in] Number of programs. + * @return program control init terminal program desc (or NULL if error). + */ +extern +ia_css_program_control_init_manifest_program_desc_t * +ia_css_program_control_init_terminal_manifest_get_program_desc( + const ia_css_program_control_init_terminal_manifest_t *terminal, + unsigned int program); + +/*! + * Initialize the program control init terminal manifest. + * @param nof_programs[in] Number of programs + * @param nof_load_sections[in] Array of size nof_programs, + * encoding the number of load sections. + * @param nof_connect_sections[in] Array of size nof_programs, + * encoding the number of connect sections. + * @return < 0 on invalid manifest argument + */ +extern +int ia_css_program_control_init_terminal_manifest_init( + ia_css_program_control_init_terminal_manifest_t *terminal, + const uint16_t nof_programs, + const uint16_t *nof_load_sections, + const uint16_t *nof_connect_sections); + +/*! + * Pretty prints the program control init terminal manifest. + * @param terminal[in] Program control init terminal. + */ +extern +void ia_css_program_control_init_terminal_manifest_print( + ia_css_program_control_init_terminal_manifest_t *terminal); + +#endif /* __IA_CSS_PSYS_TERMINAL_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.hsys.user.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.hsys.user.h new file mode 100644 index 0000000000000..1d2f06f3cbce9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.hsys.user.h @@ -0,0 +1,38 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_MANIFEST_HSYS_USER_H +#define __IA_CSS_PSYS_TERMINAL_MANIFEST_HSYS_USER_H + +/*! \file */ + +/** @file ia_css_psys_terminal.hsys.user.h + * + * Define the methods on the termianl manifest object: Hsys user interface + */ + +#include + +/*! Print the terminal manifest object to file/stream + + @param manifest[in] terminal manifest object + @param fid[out] file/stream handle + + @return < 0 on error + */ +extern int ia_css_terminal_manifest_print( + const ia_css_terminal_manifest_t *manifest, + void *fid); + +#endif /* __IA_CSS_PSYS_TERMINAL_MANIFEST_HSYS_USER_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.sim.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.sim.h new file mode 100644 index 0000000000000..f7da810d82f19 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/interface/ia_css_psys_terminal_manifest.sim.h @@ -0,0 +1,48 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_TERMINAL_MANIFEST_SIM_H +#define __IA_CSS_PSYS_TERMINAL_MANIFEST_SIM_H + +/*! \file */ + +/** @file ia_css_psys_terminal_manifest.sim.h + * + * Define the methods on the terminal manifest object: Simulation only + */ + +#include /* size_t */ +#include "ia_css_terminal.h" +#include "ia_css_terminal_manifest.h" +#include "ia_css_terminal_defs.h" + +/*! Create (the storage for) the terminal manifest object + + @param terminal_type[in] type of the terminal manifest {parameter, data} + + @return NULL on error + */ +extern ia_css_terminal_manifest_t *ia_css_terminal_manifest_alloc( + const ia_css_terminal_type_t terminal_type); + +/*! Destroy (the storage of) the terminal manifest object + + @param manifest[in] terminal manifest + + @return NULL + */ +extern ia_css_terminal_manifest_t *ia_css_terminal_manifest_free( + ia_css_terminal_manifest_t *manifest); + +#endif /* __IA_CSS_PSYS_TERMINAL_MANIFEST_SIM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest.c new file mode 100644 index 0000000000000..443096c721011 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest.c @@ -0,0 +1,1038 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_psys_static_storage_class.h" +#include "ia_css_psys_program_group_manifest.h" +#include "ia_css_rbm_manifest.h" + +/* + * Functions to possibly inline + */ + +#ifndef __IA_CSS_PSYS_STATIC_INLINE__ +#include "ia_css_psys_program_group_manifest_impl.h" +#endif /* __IA_CSS_PSYS_STATIC_INLINE__ */ + +/* + * Functions not to inline + */ + +/* + * We need to refactor those files in order to + * build in the firmware only what is needed, + * switches are put current to workaround compilation problems + * in the firmware (for example lack of uint64_t support) + * supported in the firmware + */ +#if !defined(__HIVECC) +size_t ia_css_sizeof_program_group_manifest( + const uint8_t program_count, + const uint8_t terminal_count, + const uint8_t *program_dependency_count, + const uint8_t *terminal_dependency_count, + const ia_css_terminal_type_t *terminal_type, + const uint16_t cached_in_param_section_count, + const uint16_t cached_out_param_section_count, + const uint16_t *spatial_param_section_count, + const uint16_t fragment_param_section_count, + const uint16_t *sliced_param_section_count, + const uint16_t *sliced_out_param_section_count, + const uint16_t kernel_fragment_seq_count, + const uint16_t *progctrlinit_load_section_counts, + const uint16_t *progctrlinit_connect_section_counts) +{ + size_t size = 0; + int i = 0; + int j = 0; + int m = 0; + int n = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_sizeof_program_group_manifest(): enter:\n"); + + verifexit(program_count != 0); + verifexit(program_dependency_count != NULL); + verifexit(terminal_dependency_count != NULL); + + size += sizeof(ia_css_program_group_manifest_t); + + /* Private payload in the program group manifest */ + size += ceil_mul(sizeof(struct ia_css_psys_private_pg_data), + sizeof(uint64_t)); + /* RBM manifest in the program group manifest */ + size += ceil_mul(sizeof(ia_css_rbm_manifest_t), + sizeof(uint64_t)); + + for (i = 0; i < (int)program_count; i++) { + size += ia_css_sizeof_program_manifest( + program_dependency_count[i], + terminal_dependency_count[i]); + } + + for (i = 0; i < (int)terminal_count; i++) { + switch (terminal_type[i]) { + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN: + size += ia_css_param_terminal_manifest_get_size( + cached_in_param_section_count); + break; + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT: + size += ia_css_param_terminal_manifest_get_size( + cached_out_param_section_count); + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + size += ia_css_spatial_param_terminal_manifest_get_size( + spatial_param_section_count[j]); + j++; + break; + case IA_CSS_TERMINAL_TYPE_PROGRAM: + size += ia_css_program_terminal_manifest_get_size( + fragment_param_section_count, + kernel_fragment_seq_count); + break; + case IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT: + size += ia_css_program_control_init_terminal_manifest_get_size( + program_count, + progctrlinit_load_section_counts, + progctrlinit_connect_section_counts); + break; + case IA_CSS_TERMINAL_TYPE_DATA_IN: + case IA_CSS_TERMINAL_TYPE_DATA_OUT: + size += sizeof(ia_css_data_terminal_manifest_t); + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN: + size += ia_css_sliced_param_terminal_manifest_get_size( + sliced_param_section_count[m]); + m++; + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT: + size += ia_css_sliced_param_terminal_manifest_get_size( + sliced_out_param_section_count[n]); + n++; + break; + default: + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_sizeof_program_group_manifest invalid argument\n"); + } + } + +EXIT: + if (0 == program_count || 0 == terminal_count || + NULL == program_dependency_count || + NULL == terminal_dependency_count) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_sizeof_program_group_manifest invalid argument\n"); + } + return size; +} + +/* + * Currently, the design of XNR kernel inside the *_pregdc program group, + * does not fit the exact model as is being asserted on in + * ia_css_is_program_group_manifest_valid. We therefore disable some checks. + * Further investigation is needed to determine whether *_pregdc program group + * can be canged or that the model must be changed. + * #define USE_SIMPLIFIED_GRAPH_MODEL 1 allows multiple programs to be + * connected to the same terminal, and it allows a kernel be mapped over + * multiple programs. + */ +#define USE_SIMPLIFIED_GRAPH_MODEL 1 + +/* + * Model and/or check refinements + * - Parallel programs do not yet have mutual exclusive alternatives + * - The pgram dependencies do not need to be acyclic + * - Parallel programs need to have an equal kernel requirement + */ +bool ia_css_is_program_group_manifest_valid( + const ia_css_program_group_manifest_t *manifest) +{ + int i; + bool is_valid = false; + uint8_t terminal_count; + uint8_t program_count; + ia_css_kernel_bitmap_t total_bitmap; + ia_css_kernel_bitmap_t check_bitmap; + ia_css_kernel_bitmap_t terminal_bitmap; + /* + * Use a standard bitmap type for the minimum logic to check the DAG, + * generic functions can be used for the kernel enable bitmaps; Later + */ + vied_nci_resource_bitmap_t resource_bitmap; + int terminal_bitmap_weight; + bool has_parameter_terminal_in = false; + bool has_parameter_terminal_out = false; + bool has_program_control_init_terminal = false; + bool has_program_terminal = false; + bool has_program_terminal_sequencer_info = false; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_program_group_manifest_valid(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(ia_css_program_group_manifest_get_size(manifest) != 0); + verifexit(ia_css_program_group_manifest_get_alignment(manifest) != 0); + verifexit(ia_css_program_group_manifest_get_program_group_ID(manifest) != 0); + + terminal_count = + ia_css_program_group_manifest_get_terminal_count(manifest); + program_count = + ia_css_program_group_manifest_get_program_count(manifest); + total_bitmap = + ia_css_program_group_manifest_get_kernel_bitmap(manifest); + check_bitmap = ia_css_kernel_bitmap_clear(); + resource_bitmap = vied_nci_bit_mask(VIED_NCI_RESOURCE_BITMAP_BITS); + terminal_bitmap = ia_css_kernel_bitmap_clear(); + + verifexit(program_count != 0); + verifexit(terminal_count != 0); + verifexit(!ia_css_is_kernel_bitmap_empty(total_bitmap)); + verifexit(vied_nci_is_bitmap_empty(resource_bitmap)); + + /* Check the kernel bitmaps for terminals */ + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_manifest_t *terminal_manifest_i = + ia_css_program_group_manifest_get_term_mnfst( + manifest, i); + bool is_parameter_in = + (IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN == + ia_css_terminal_manifest_get_type( + terminal_manifest_i)); + bool is_parameter_out = + (IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT == + ia_css_terminal_manifest_get_type( + terminal_manifest_i)); + bool is_data = + ia_css_is_terminal_manifest_data_terminal( + terminal_manifest_i); + bool is_program = + ia_css_is_terminal_manifest_program_terminal( + terminal_manifest_i); + bool is_spatial_param = + ia_css_is_terminal_manifest_spatial_parameter_terminal( + terminal_manifest_i); + bool is_program_control_init = + ia_css_is_terminal_manifest_program_control_init_terminal( + terminal_manifest_i); + + if (is_parameter_in) { + /* + * There can be only one cached in parameter terminal + * it serves kernels, not programs + */ + verifexit(!has_parameter_terminal_in); + has_parameter_terminal_in = is_parameter_in; + } else if (is_parameter_out) { + /* + * There can be only one cached out parameter terminal + * it serves kernels, not programs + */ + verifexit(!has_parameter_terminal_out); + has_parameter_terminal_out = is_parameter_out; + } else if (is_data) { + ia_css_data_terminal_manifest_t *dterminal_manifest_i = + (ia_css_data_terminal_manifest_t *) + terminal_manifest_i; + ia_css_kernel_bitmap_t terminal_bitmap_i = + ia_css_data_terminal_manifest_get_kernel_bitmap( + dterminal_manifest_i); + /* + * A terminal must depend on kernels that are a subset + * of the total, correction, it can only depend on one + * kernel + */ + verifexit(!ia_css_is_kernel_bitmap_empty( + terminal_bitmap_i)); + verifexit(ia_css_is_kernel_bitmap_subset( + total_bitmap, terminal_bitmap_i)); + verifexit(ia_css_is_kernel_bitmap_onehot( + terminal_bitmap_i)); + } else if (is_program) { + verifexit(!has_program_terminal); + verifexit(terminal_manifest_i); + has_program_terminal = is_program; + has_program_terminal_sequencer_info = + (((ia_css_program_terminal_manifest_t *) + terminal_manifest_i)-> + kernel_fragment_sequencer_info_manifest_info_count + != 0); + } else if (is_program_control_init) { + has_program_control_init_terminal = is_program_control_init; + } else { + const ia_css_spatial_param_terminal_manifest_t + *spatial_param_man = + (const ia_css_spatial_param_terminal_manifest_t *) + terminal_manifest_i; + verifexit(spatial_param_man); + verifexit(is_spatial_param); + + terminal_bitmap = + ia_css_kernel_bitmap_set(terminal_bitmap, + spatial_param_man->kernel_id); + verifexit(!ia_css_is_kernel_bitmap_empty(terminal_bitmap)); + verifexit(ia_css_is_kernel_bitmap_subset( + total_bitmap, terminal_bitmap)); + } + } + + /* Check the kernel bitmaps for programs */ + for (i = 0; i < (int)program_count; i++) { + int j; + ia_css_program_manifest_t *program_manifest_i = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, i); + ia_css_program_type_t program_type_i = + ia_css_program_manifest_get_type(program_manifest_i); + ia_css_kernel_bitmap_t program_bitmap_i = + ia_css_program_manifest_get_kernel_bitmap( + program_manifest_i); + uint8_t program_dependency_count_i = + ia_css_program_manifest_get_program_dependency_count( + program_manifest_i); + uint8_t terminal_dependency_count_i = + ia_css_program_manifest_get_terminal_dependency_count( + program_manifest_i); + uint8_t program_dependency_i0 = + ia_css_program_manifest_get_program_dependency( + program_manifest_i, 0); + bool is_sub_i = + ia_css_is_program_manifest_subnode_program_type( + program_manifest_i); + bool is_exclusive_sub_i = + (program_type_i == IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB); + bool is_virtual_sub_i = + (program_type_i == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB); + bool is_super_i = + ia_css_is_program_manifest_supernode_program_type( + program_manifest_i); + + /* + * A program must have kernels that + * are a subset of the total + */ + verifexit(!ia_css_is_kernel_bitmap_empty( + program_bitmap_i)); + verifexit(ia_css_is_kernel_bitmap_subset( + total_bitmap, program_bitmap_i)); + verifexit((program_type_i != IA_CSS_N_PROGRAM_TYPES)); + verifexit((program_dependency_count_i + terminal_dependency_count_i) != 0); + /* + * Checks for subnodes + * - Parallel subnodes cannot depend on terminals + * - Exclusive subnodes must depend on + * fewer terminals than the supernode + * - Subnodes only depend on a supernode of the same type + * - Must have a subset of the supernode's kernels + * (but not equal) + * - This tests only positive cases + * Checks for singular or supernodes + * - Cannot depend on exclusive subnodes + * - No intersection between kernels + * (too strict for multiple instances ?) + */ + if (is_sub_i) { + /* Subnode */ + ia_css_program_manifest_t *program_manifest_k = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, program_dependency_i0); + ia_css_program_type_t program_type_k = + ia_css_program_manifest_get_type( + program_manifest_k); + ia_css_kernel_bitmap_t program_bitmap_k = + ia_css_program_manifest_get_kernel_bitmap( + program_manifest_k); + + verifexit(program_dependency_count_i == 1); + if (is_exclusive_sub_i || is_virtual_sub_i) { + verifexit(terminal_dependency_count_i <= + ia_css_program_manifest_get_terminal_dependency_count( + program_manifest_k)); + } else { + verifexit(terminal_dependency_count_i == 0); + } + verifexit(program_type_k == + (is_exclusive_sub_i ? + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER : + is_virtual_sub_i ? + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER : + IA_CSS_PROGRAM_TYPE_PARALLEL_SUPER)); + verifexit(!ia_css_is_kernel_bitmap_equal( + program_bitmap_k, program_bitmap_i)); + verifexit(ia_css_is_kernel_bitmap_subset( + program_bitmap_k, program_bitmap_i)); + } else { + /* Singular or Supernode */ + int k; + + for (k = 0; k < program_dependency_count_i; k++) { + uint8_t program_dependency_k = + ia_css_program_manifest_get_program_dependency( + program_manifest_i, k); + ia_css_program_manifest_t *program_manifest_k = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, (int)program_dependency_k); + ia_css_program_type_t program_type_k = + ia_css_program_manifest_get_type( + program_manifest_k); + ia_css_kernel_bitmap_t program_bitmap_k = + ia_css_program_manifest_get_kernel_bitmap( + program_manifest_k); + + verifexit(program_dependency_k < + program_count); + verifexit((program_type_k != + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) && + (program_type_k != + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB)); +#if USE_SIMPLIFIED_GRAPH_MODEL == 0 + verifexit(ia_css_is_kernel_bitmap_intersection_empty( + program_bitmap_i, program_bitmap_k)); +#else + (void)program_bitmap_k; +#endif + } + } + + /* Check for relations */ + for (j = 0; j < (int)program_count; j++) { + int k; + ia_css_program_manifest_t *program_manifest_j = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, j); + ia_css_program_type_t program_type_j = + ia_css_program_manifest_get_type(program_manifest_j); + ia_css_kernel_bitmap_t program_bitmap_j = + ia_css_program_manifest_get_kernel_bitmap( + program_manifest_j); + uint8_t program_dependency_count_j = + ia_css_program_manifest_get_program_dependency_count( + program_manifest_j); + uint8_t program_dependency_j0 = + ia_css_program_manifest_get_program_dependency( + program_manifest_j, 0); + bool is_sub_j = + ia_css_is_program_manifest_subnode_program_type( + program_manifest_j); + bool is_super_j = + ia_css_is_program_manifest_supernode_program_type( + program_manifest_j); + bool is_virtual_sub_j = + (program_type_j == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB); + bool is_j_subset_i = + ia_css_is_kernel_bitmap_subset( + program_bitmap_i, program_bitmap_j); + bool is_i_subset_j = + ia_css_is_kernel_bitmap_subset( + program_bitmap_j, program_bitmap_i); + + /* Test below would fail for i==j */ + if (i == j) + continue; + + /* Empty sets are always subsets, but meaningless */ + verifexit(!ia_css_is_kernel_bitmap_empty( + program_bitmap_j)); + + /* + * Checks for mutual subnodes + * - Parallel subnodes must have an equal + * set of kernels + * - Exclusive and virtual subnodes must + * have an unequal set of kernels + * Checks for subnodes + * - Subnodes must have a subset of kernels + */ + if (((program_type_i == + IA_CSS_PROGRAM_TYPE_PARALLEL_SUB) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_PARALLEL_SUB)) || + ((program_type_i == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB)) || + ((program_type_i == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB))) { + + verifexit(program_dependency_count_j == 1); + verifexit(program_dependency_i0 != i); + verifexit(program_dependency_j0 != i); + + if (program_dependency_i0 == + program_dependency_j0) { + verifexit(is_sub_i); + /* + * Subnodes are subsets, + * not for virtual nodes + */ + if (!is_virtual_sub_i) + verifexit( + ((is_j_subset_i || + is_i_subset_j))); + /* + * That must be equal for + * parallel subnodes, + * must be unequal for + * exlusive and virtual subnodes + */ + verifexit( + ((is_j_subset_i && is_i_subset_j) ^ + (is_exclusive_sub_i | + is_virtual_sub_i))); + + } + if (is_j_subset_i || is_i_subset_j) { + verifexit(program_dependency_i0 == + program_dependency_j0); + } + } + + if (((program_type_i == + IA_CSS_PROGRAM_TYPE_PARALLEL_SUPER) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_PARALLEL_SUB)) || + ((program_type_i == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB)) || + ((program_type_i == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER) && + (program_type_j == + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB))) { + + verifexit(program_dependency_count_j == 1); + verifexit(!is_i_subset_j); + + if (program_dependency_j0 == i) { + verifexit(program_dependency_i0 != + program_dependency_j0); + verifexit(is_super_i); + verifexit(is_j_subset_i); + + } + if (is_j_subset_i) { + verifexit(program_dependency_j0 == i); + } + } + + /* + * Checks for dependent nodes + * - Cannot depend on exclusive subnodes + * - No intersection between kernels + * (too strict for multiple instances ?) + * unless a subnode + */ + for (k = 0; k < (int)program_dependency_count_j; k++) { + uint8_t program_dependency_k = + ia_css_program_manifest_get_program_dependency( + program_manifest_j, k); + + verifexit((program_dependency_k < + program_count)); + if (program_dependency_k == i) { + /* program[j] depends on program[i] */ + verifexit((i != j)); + verifexit((program_type_i != + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) && + (program_type_i != + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB)); + verifexit(USE_SIMPLIFIED_GRAPH_MODEL || + (ia_css_is_kernel_bitmap_intersection_empty( + program_bitmap_i, program_bitmap_j) ^ is_sub_j)); + } + } + + /* + * Checks for supernodes and subnodes + * - Detect nodes that kernel-wise are subsets, + * but not connected to the correct supernode + * - We do not (yet) detect if programs properly + * depend on all parallel nodes + */ + if (!ia_css_is_kernel_bitmap_intersection_empty( + program_bitmap_i, program_bitmap_j)) { + /* + * This test will pass if + * the program manifest is NULL, + * but that's no concern here + */ +#if USE_SIMPLIFIED_GRAPH_MODEL == 0 + verifexit(!ia_css_is_program_manifest_singular_program_type( + program_manifest_i)); + verifexit(!ia_css_is_program_manifest_singular_program_type( + program_manifest_j)); + if (!is_virtual_sub_j) + verifexit((is_j_subset_i || is_i_subset_j)); +#else + (void)is_virtual_sub_j; +#endif + if (is_super_i) { + verifexit(is_sub_j); + verifexit(program_dependency_j0 == i); + } + if (is_super_j) { + verifexit(is_sub_i); + verifexit(program_dependency_i0 == j); + } + } + } + check_bitmap = ia_css_kernel_bitmap_union( + check_bitmap, program_bitmap_i); + /* + * A terminal can be bound to only a single + * (of multiple concurrent) program(s), + * i.e. the one that holds the iterator to control it + * Only singular and super nodes can depend on a terminal. + * This loop accumulates all terminal + * dependencies over all programs + */ + for (j = 0; j < (int)terminal_dependency_count_i; j++) { + uint8_t terminal_dependency = + ia_css_program_manifest_get_terminal_dependency( + program_manifest_i, j); + + verifexit(terminal_dependency < terminal_count); + if ((program_type_i != + IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) && + (program_type_i != + IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB)) { + /* If the subnode always came after the */ + /* supernode we could check for presence */ + resource_bitmap = + vied_nci_bit_mask_set_unique( + resource_bitmap, + terminal_dependency); +#if USE_SIMPLIFIED_GRAPH_MODEL == 0 + verifexit(!vied_nci_is_bitmap_empty( + resource_bitmap)); +#endif + } + } + } + verifexit(ia_css_is_kernel_bitmap_equal( + total_bitmap, check_bitmap)); + + terminal_bitmap_weight = + vied_nci_bitmap_compute_weight(resource_bitmap); + verifexit(terminal_bitmap_weight >= 0); + if (has_parameter_terminal_in || + has_parameter_terminal_out || + has_program_terminal || + has_program_control_init_terminal) { + int skip_terminal_count = 0; + + if (has_parameter_terminal_in) + skip_terminal_count++; + if (has_parameter_terminal_out) + skip_terminal_count++; + if (has_program_control_init_terminal) { + skip_terminal_count++; + } + if (has_program_terminal) + skip_terminal_count++; + if (has_program_terminal_sequencer_info) + skip_terminal_count--; +#if USE_SIMPLIFIED_GRAPH_MODEL == 0 + verifexit((terminal_bitmap_weight == + (terminal_count - skip_terminal_count))); +#endif + } else + verifexit((terminal_bitmap_weight == terminal_count)); + + is_valid = true; +EXIT: + if (is_valid == false) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_is_program_group_manifest_valid: failed\n"); + } + return is_valid; +} + +int ia_css_program_group_manifest_set_kernel_bitmap( + ia_css_program_group_manifest_t *manifest, + const ia_css_kernel_bitmap_t bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_set_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + manifest->kernel_bitmap = bitmap; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_set_kernel_bitmap invalid argument\n"); + } + return retval; +} + +ia_css_kernel_bitmap_t ia_css_program_group_manifest_get_kernel_bitmap( + const ia_css_program_group_manifest_t *manifest) +{ + ia_css_kernel_bitmap_t bitmap = ia_css_kernel_bitmap_clear(); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + bitmap = manifest->kernel_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_kernel_bitmap invalid argument\n"); + } + return bitmap; +} + +void ia_css_program_group_manifest_init( + ia_css_program_group_manifest_t *blob, + const uint8_t program_count, + const uint8_t terminal_count, + const uint8_t *program_dependencies, + const uint8_t *terminal_dependencies, + const ia_css_terminal_type_t *terminal_type, + const uint16_t cached_in_param_section_count, + const uint16_t cached_out_param_section_count, + const uint16_t *spatial_param_section_count, + const uint16_t fragment_param_section_count, + const uint16_t *sliced_in_param_section_count, + const uint16_t *sliced_out_param_section_count, + const uint16_t kernel_fragment_seq_count, + const uint16_t *progctrlinit_load_section_counts, + const uint16_t *progctrlinit_connect_section_counts) +{ + int i = 0; + int j = 0; + int m = 0; + int n = 0; + int result; + uint32_t offset = 0; + char *prg_manifest_base, *terminal_manifest_base; + size_t program_size = 0; + + /* + * assert(blob != NULL); + */ + COMPILATION_ERROR_IF( + SIZE_OF_DATA_TERMINAL_MANIFEST_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_data_terminal_manifest_t))); + COMPILATION_ERROR_IF( + SIZE_OF_PROGRAM_GROUP_MANIFEST_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_program_group_manifest_t))); + COMPILATION_ERROR_IF( + SIZE_OF_PROGRAM_MANIFEST_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_program_manifest_t))); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, + "ia_css_program_group_manifest_init(): enter:\n"); + + for (i = 0; i < (int)program_count; i++) { + program_size += + ia_css_sizeof_program_manifest(program_dependencies[i], + terminal_dependencies[i]); + } + + /* A program group ID cannot be zero */ + blob->ID = 1; + blob->program_count = program_count; + blob->terminal_count = terminal_count; + blob->program_manifest_offset = sizeof(ia_css_program_group_manifest_t); + blob->terminal_manifest_offset = + (uint32_t)blob->program_manifest_offset + program_size; + + prg_manifest_base = (char *) + (((char *)blob) + blob->program_manifest_offset); + offset = blob->program_manifest_offset; + for (i = 0; i < (int)program_count; i++) { + ia_css_program_manifest_init( + (ia_css_program_manifest_t *)prg_manifest_base, + program_dependencies[i], terminal_dependencies[i]); + ia_css_program_manifest_set_parent_offset( + (ia_css_program_manifest_t *)prg_manifest_base, offset); + program_size = + ia_css_sizeof_program_manifest(program_dependencies[i], + terminal_dependencies[i]); + prg_manifest_base += program_size; + offset += (uint32_t)program_size; + } + + offset = blob->terminal_manifest_offset; + terminal_manifest_base = (char *) (((char *)blob) + offset); + for (i = 0; i < (int)terminal_count; i++) { + size_t terminal_size = 0; + ia_css_terminal_manifest_t *term_manifest = + (ia_css_terminal_manifest_t *)terminal_manifest_base; + + ia_css_terminal_manifest_set_parent_offset( + (ia_css_terminal_manifest_t *) + terminal_manifest_base, + offset); + switch (terminal_type[i]) { + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN: + result = ia_css_param_terminal_manifest_init( + (ia_css_param_terminal_manifest_t *) + term_manifest, + cached_in_param_section_count); + if (result == 0) { + terminal_size = + ia_css_param_terminal_manifest_get_size( + cached_in_param_section_count); + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_param_terminal_manifest_init failed in cached in terminal\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT: + result = ia_css_param_terminal_manifest_init( + (ia_css_param_terminal_manifest_t *) + term_manifest, + cached_out_param_section_count); + if (result == 0) { + terminal_size = + ia_css_param_terminal_manifest_get_size( + cached_out_param_section_count); + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_param_terminal_manifest_init failed\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + result = ia_css_spatial_param_terminal_manifest_init( + (ia_css_spatial_param_terminal_manifest_t *) + term_manifest, + spatial_param_section_count[j]); + if (result == 0) { + terminal_size = + ia_css_spatial_param_terminal_manifest_get_size( + spatial_param_section_count[j]); + j++; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_spatial_param_terminal_manifest_init failed in spatial terminal\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_PROGRAM: + result = ia_css_program_terminal_manifest_init( + (ia_css_program_terminal_manifest_t *) + term_manifest, + fragment_param_section_count, + kernel_fragment_seq_count); + if (result == 0) { + terminal_size = + ia_css_program_terminal_manifest_get_size( + fragment_param_section_count, + kernel_fragment_seq_count); + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_program_terminal_manifest_init failed in program terminal\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT: + result = ia_css_program_control_init_terminal_manifest_init( + (ia_css_program_control_init_terminal_manifest_t *) + term_manifest, + program_count, + progctrlinit_load_section_counts, + progctrlinit_connect_section_counts); + if (result == 0) { + terminal_size = + ia_css_program_control_init_terminal_manifest_get_size( + program_count, + NULL, + NULL); + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_program_control_init_terminal_manifest_init failed\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_DATA_IN: + case IA_CSS_TERMINAL_TYPE_DATA_OUT: + terminal_size = sizeof(ia_css_data_terminal_manifest_t); + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN: + result = ia_css_sliced_param_terminal_manifest_init( + (ia_css_sliced_param_terminal_manifest_t *) + term_manifest, + sliced_in_param_section_count[m]); + if (result == 0) { + terminal_size = + ia_css_sliced_param_terminal_manifest_get_size( + sliced_in_param_section_count[m]); + m++; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_param_terminal_manifest_init in sliced terminal failed\n"); + } + break; + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT: + result = ia_css_sliced_param_terminal_manifest_init( + (ia_css_sliced_param_terminal_manifest_t *) + term_manifest, + sliced_out_param_section_count[n]); + if (result == 0) { + terminal_size = + ia_css_sliced_param_terminal_manifest_get_size( + sliced_out_param_section_count[n]); + n++; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_param_terminal_manifest_init in sliced out terminal failed\n"); + } + break; + default: + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_init invalid argument\n"); + } + term_manifest->size = (uint16_t)terminal_size; + term_manifest->terminal_type = terminal_type[i]; + terminal_manifest_base += terminal_size; + offset += (uint32_t)terminal_size; + } + + /* Set the private program group manifest blob offset */ + blob->private_data_offset = offset; + offset += ceil_mul(sizeof(struct ia_css_psys_private_pg_data), + sizeof(uint64_t)); + + /* Set the RBM manifest blob offset */ + blob->rbm_manifest_offset = offset; + offset += ceil_mul(sizeof(ia_css_rbm_manifest_t), + sizeof(uint64_t)); + + assert(offset <= UINT16_MAX); + blob->size = (uint16_t)offset; +} + +int ia_css_program_group_manifest_print( + const ia_css_program_group_manifest_t *manifest, + void *fid) +{ + int retval = -1; + int i; + uint8_t program_count, terminal_count; + ia_css_kernel_bitmap_t bitmap; + struct ia_css_psys_private_pg_data *priv_data; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, + "ia_css_program_group_manifest_print(): enter:\n"); + + NOT_USED(fid); + + verifexit(manifest != NULL); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "sizeof(manifest) = %d\n", + (int)ia_css_program_group_manifest_get_size(manifest)); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "alignment(manifest) = %d\n", + (int)ia_css_program_group_manifest_get_alignment(manifest)); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "program group ID = %d\n", + (int)ia_css_program_group_manifest_get_program_group_ID( + manifest)); + + program_count = + ia_css_program_group_manifest_get_program_count(manifest); + terminal_count = + ia_css_program_group_manifest_get_terminal_count(manifest); + + bitmap = ia_css_program_group_manifest_get_kernel_bitmap(manifest); + verifexit(ia_css_kernel_bitmap_print(bitmap, fid) == 0); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "%d program manifests\n", (int)program_count); + for (i = 0; i < (int)program_count; i++) { + ia_css_program_manifest_t *program_manifest = + ia_css_program_group_manifest_get_prgrm_mnfst( + manifest, i); + + retval = ia_css_program_manifest_print(program_manifest, fid); + verifjmpexit(retval == 0); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "%d terminal manifests\n", (int)terminal_count); + for (i = 0; i < (int)terminal_count; i++) { + ia_css_terminal_manifest_t *terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst( + manifest, i); + + retval = ia_css_terminal_manifest_print( + terminal_manifest, fid); + verifjmpexit(retval == 0); + } + + priv_data = + (struct ia_css_psys_private_pg_data *) + ia_css_program_group_manifest_get_private_data(manifest); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "private_data_offset %d\n", manifest->private_data_offset); + + for (i = 0; i < IPU_DEVICE_GP_PSA_MUX_NUM_MUX; i++) { + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "PSA MUX id %d mux val %d\n", i, + priv_data->psa_mux_conf[i]); + + } + + for (i = 0; i < IPU_DEVICE_GP_ISA_STATIC_MUX_NUM_MUX; i++) { + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "ISA MUX id %d mux val %d\n", i, + priv_data->isa_mux_conf[i]); + + } + + for (i = 0; i < IPU_DEVICE_ACB_NUM_ACB; i++) { + + if (priv_data->acb_route[i].in_select != + NCI_ACB_PORT_INVALID) { + + assert(priv_data->acb_route[i].in_select != + NCI_ACB_PORT_INVALID && + priv_data->acb_route[i].out_select != + NCI_ACB_PORT_INVALID); + + IA_CSS_TRACE_3(PSYSAPI_STATIC, INFO, + "Route Cell id %d In %d Out %d\n", i, + priv_data->acb_route[i].in_select, + priv_data->acb_route[i].out_select); + } + + } + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: buffer_base_addr 0x%x\n", + priv_data->input_buffer_info.buffer_base_addr); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: bpe = %d\n", + priv_data->input_buffer_info.bpe); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: buffer_width = %d\n", + priv_data->input_buffer_info.buffer_width); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: buffer_height = %d\n", + priv_data->input_buffer_info.buffer_height); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: num_of_buffers = %d\n", + priv_data->input_buffer_info.num_of_buffers); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "Input Buffer: dfm_port_addr = 0x%x\n", + priv_data->input_buffer_info.dfm_port_addr); + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_group_manifest_print failed (%i)\n", + retval); + } + return retval; +} +#endif /* !defined(__HIVECC) */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest_impl.h new file mode 100644 index 0000000000000..a3a729b0d104a --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_manifest_impl.h @@ -0,0 +1,415 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_IMPL_H +#define __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_IMPL_H + +#include +#include +#include +#include +#include "ia_css_psys_program_group_private.h" +#include "ia_css_terminal_manifest_types.h" +#include "ia_css_psys_private_pg_data.h" +#include /* Safer bit mask functions */ +#include "ia_css_psys_static_trace.h" +#include "ia_css_rbm_manifest_types.h" +#include +#include +#include + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +size_t ia_css_program_group_manifest_get_size( + const ia_css_program_group_manifest_t *manifest) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_size(): enter:\n"); + + if (manifest != NULL) { + size = manifest->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_size invalid argument\n"); + } + return size; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_program_group_ID_t +ia_css_program_group_manifest_get_program_group_ID( + const ia_css_program_group_manifest_t *manifest) +{ + ia_css_program_group_ID_t id = IA_CSS_PROGRAM_GROUP_INVALID_ID; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_program_group_ID(): enter:\n"); + + if (manifest != NULL) { + id = manifest->ID; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_program_group_ID invalid argument\n"); + } + return id; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +int ia_css_program_group_manifest_set_program_group_ID( + ia_css_program_group_manifest_t *manifest, + ia_css_program_group_ID_t id) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_set_program_group_ID(): enter:\n"); + + if (manifest != NULL) { + manifest->ID = id; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_set_program_group_ID invalid argument\n"); + } + return retval; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +int ia_css_program_group_manifest_set_alignment( + ia_css_program_group_manifest_t *manifest, + const uint8_t alignment) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_set_alignment(): enter:\n"); + + if (manifest != NULL) { + manifest->alignment = alignment; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_set_alignment invalid argument\n"); + } + return retval; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +uint8_t ia_css_program_group_manifest_get_alignment( + const ia_css_program_group_manifest_t *manifest) +{ + uint8_t alignment = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_alignment(): enter:\n"); + + if (manifest != NULL) { + alignment = manifest->alignment; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_alignment invalid argument\n"); + } + return alignment; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +void *ia_css_program_group_manifest_get_private_data( + const ia_css_program_group_manifest_t *manifest) +{ + void *private_data = NULL; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_private_data(%p): enter:\n", + manifest); + + verifexit(manifest != NULL); + + private_data = (void *)((const char *)manifest + + manifest->private_data_offset); +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_private_data invalid argument\n"); + } + return private_data; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_rbm_manifest_t *ia_css_program_group_manifest_get_rbm_manifest( + const ia_css_program_group_manifest_t *manifest) +{ + ia_css_rbm_manifest_t *rbm_manifest = NULL; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_rbm_manifest(%p): enter:\n", + manifest); + + verifexit(manifest != NULL); + + rbm_manifest = (ia_css_rbm_manifest_t *)((const char *)manifest + + manifest->rbm_manifest_offset); + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_rbm_manifest invalid argument\n"); + } + return rbm_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_program_manifest_t * +ia_css_program_group_manifest_get_prgrm_mnfst( + const ia_css_program_group_manifest_t *manifest, + const unsigned int program_index) +{ + ia_css_program_manifest_t *prg_manifest_base; + uint8_t *program_manifest = NULL; + uint8_t program_count; + unsigned int i; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_prgrm_mnfst(%p,%d): enter:\n", + manifest, program_index); + + program_count = + ia_css_program_group_manifest_get_program_count(manifest); + + verifexit(manifest != NULL); + verifexit(program_index < program_count); + + prg_manifest_base = (ia_css_program_manifest_t *)((char *)manifest + + manifest->program_manifest_offset); + if (program_index < program_count) { + program_manifest = (uint8_t *)prg_manifest_base; + for (i = 0; i < program_index; i++) { + program_manifest += ((ia_css_program_manifest_t *) + program_manifest)->size; + } + } + +EXIT: + if (NULL == manifest || program_index >= program_count) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_prgrm_mnfst invalid argument\n"); + } + return (ia_css_program_manifest_t *)program_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_data_terminal_manifest_t * +ia_css_program_group_manifest_get_data_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_data_terminal_manifest_t *data_terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_data_terminal_manifest(%p, %d): enter:\n", + manifest, (int)terminal_index); + + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst(manifest, + terminal_index); + + verifexit(ia_css_is_terminal_manifest_data_terminal(terminal_manifest)); + + data_terminal_manifest = + (ia_css_data_terminal_manifest_t *)terminal_manifest; +EXIT: + return data_terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_param_terminal_manifest_t * +ia_css_program_group_manifest_get_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_param_terminal_manifest_t *param_terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_param_terminal_manifest(%p, %d): enter:\n", + manifest, (int)terminal_index); + + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst(manifest, + terminal_index); + + verifexit(ia_css_is_terminal_manifest_parameter_terminal( + terminal_manifest)); + param_terminal_manifest = + (ia_css_param_terminal_manifest_t *)terminal_manifest; +EXIT: + return param_terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_spatial_param_terminal_manifest_t * +ia_css_program_group_manifest_get_spatial_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_spatial_param_terminal_manifest_t * + spatial_param_terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_spatial_param_terminal_manifest(%p, %d): enter:\n", + manifest, (int)terminal_index); + + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst(manifest, + terminal_index); + + verifexit(ia_css_is_terminal_manifest_spatial_parameter_terminal( + terminal_manifest)); + + spatial_param_terminal_manifest = + (ia_css_spatial_param_terminal_manifest_t *)terminal_manifest; +EXIT: + return spatial_param_terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_sliced_param_terminal_manifest_t * +ia_css_program_group_manifest_get_sliced_param_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_sliced_param_terminal_manifest_t * + sliced_param_terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_sliced_param_terminal_manifest(%p, %d): enter:\n", + manifest, (int)terminal_index); + + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst(manifest, + terminal_index); + + verifexit(ia_css_is_terminal_manifest_sliced_terminal( + terminal_manifest)); + + sliced_param_terminal_manifest = + (ia_css_sliced_param_terminal_manifest_t *)terminal_manifest; +EXIT: + return sliced_param_terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_program_terminal_manifest_t * +ia_css_program_group_manifest_get_program_terminal_manifest( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_program_terminal_manifest_t *program_terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_program_terminal_manifest(%p, %d): enter:\n", + manifest, (int)terminal_index); + + terminal_manifest = + ia_css_program_group_manifest_get_term_mnfst(manifest, + terminal_index); + + verifexit(ia_css_is_terminal_manifest_program_terminal( + terminal_manifest)); + + program_terminal_manifest = + (ia_css_program_terminal_manifest_t *)terminal_manifest; + EXIT: + return program_terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +ia_css_terminal_manifest_t * +ia_css_program_group_manifest_get_term_mnfst( + const ia_css_program_group_manifest_t *manifest, + const unsigned int terminal_index) +{ + ia_css_terminal_manifest_t *terminal_manifest = NULL; + ia_css_terminal_manifest_t *terminal_manifest_base; + uint8_t terminal_count; + uint8_t i = 0; + uint32_t offset; + + IA_CSS_TRACE_2(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_term_mnfst(%p,%d): enter:\n", + manifest, (int)terminal_index); + + verifexit(manifest != NULL); + + terminal_count = + ia_css_program_group_manifest_get_terminal_count(manifest); + + verifexit(terminal_index < terminal_count); + + terminal_manifest_base = + (ia_css_terminal_manifest_t *)((char *)manifest + + manifest->terminal_manifest_offset); + terminal_manifest = terminal_manifest_base; + while (i < terminal_index) { + offset = + (uint32_t)ia_css_terminal_manifest_get_size(terminal_manifest); + terminal_manifest = (ia_css_terminal_manifest_t *) + ((char *)terminal_manifest + offset); + i++; + } +EXIT: + return terminal_manifest; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +uint8_t ia_css_program_group_manifest_get_program_count( + const ia_css_program_group_manifest_t *manifest) +{ + uint8_t program_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_program_count(): enter:\n"); + + if (manifest != NULL) { + program_count = manifest->program_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_program_count invalid argument\n"); + } + return program_count; +} + +IA_CSS_PSYS_STATIC_STORAGE_CLASS_C +uint8_t ia_css_program_group_manifest_get_terminal_count( + const ia_css_program_group_manifest_t *manifest) +{ + uint8_t terminal_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_group_manifest_get_terminal_count(): enter:\n"); + + if (manifest != NULL) { + terminal_count = manifest->terminal_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_group_manifest_get_terminal_count invalid argument\n"); + } + return terminal_count; +} + +#endif /* __IA_CSS_PSYS_PROGRAM_GROUP_MANIFEST_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_private.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_private.h new file mode 100644 index 0000000000000..502d59def6e90 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_group_private.h @@ -0,0 +1,212 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PSYS_PROGRAM_GROUP_PRIVATE_H +#define __IA_CSS_PSYS_PROGRAM_GROUP_PRIVATE_H + +#include "ia_css_psys_manifest_types.h" +#include "ia_css_terminal_manifest_types.h" +#include "ia_css_kernel_bitmap.h" +#include "ia_css_program_group_data.h" +#include "vied_nci_psys_resource_model.h" +#include "ia_css_rbm_manifest_types.h" +#include +#include +#include + +#define SIZE_OF_PROGRAM_GROUP_MANIFEST_STRUCT_IN_BITS \ + ((IA_CSS_KERNEL_BITMAP_BITS) \ + + (IA_CSS_PROGRAM_GROUP_ID_BITS) \ + + (5 * IA_CSS_UINT16_T_BITS) \ + + (5 * IA_CSS_UINT8_T_BITS) \ + + (5 * IA_CSS_UINT8_T_BITS)) + +struct ia_css_program_group_manifest_s { + /**< Indicate kernels are present in this program group */ + ia_css_kernel_bitmap_t kernel_bitmap; + /**< Referral ID to program group FW */ + ia_css_program_group_ID_t ID; + uint16_t program_manifest_offset; + uint16_t terminal_manifest_offset; + /**< Offset to private data (not part of the official API) */ + uint16_t private_data_offset; + /**< Offset to RBM manifest */ + uint16_t rbm_manifest_offset; + /**< Size of this structure */ + uint16_t size; + /**< Storage alignment requirement (in uint8_t) */ + uint8_t alignment; + /**< Total number of kernels in this program group */ + uint8_t kernel_count; + /**< Total number of program in this program group */ + uint8_t program_count; + /**< Total number of terminals on this program group */ + uint8_t terminal_count; + /**< Total number of independent subgraphs in this program group */ + uint8_t subgraph_count; + /**< Padding; esnures that rbm_manifest starts on 64bit alignment */ + uint8_t reserved[5]; +}; + +#define SIZE_OF_PROGRAM_MANIFEST_STRUCT_IN_BITS \ + (IA_CSS_KERNEL_BITMAP_BITS \ + + IA_CSS_PROGRAM_ID_BITS \ + + IA_CSS_PROGRAM_TYPE_BITS \ + + (3 * IA_CSS_UINT32_T_BITS) \ + + (VIED_NCI_RESOURCE_BITMAP_BITS * VIED_NCI_N_DEV_DFM_ID) \ + + (VIED_NCI_RESOURCE_BITMAP_BITS * VIED_NCI_N_DEV_DFM_ID) \ + + IA_CSS_UINT16_T_BITS \ + + (VIED_NCI_RESOURCE_SIZE_BITS * VIED_NCI_N_MEM_TYPE_ID) \ + + (VIED_NCI_RESOURCE_SIZE_BITS * VIED_NCI_N_DATA_MEM_TYPE_ID * 2) \ + + (VIED_NCI_RESOURCE_SIZE_BITS * VIED_NCI_N_DEV_CHN_ID * 2) \ + + (IA_CSS_UINT8_T_BITS * VIED_NCI_N_DEV_DFM_ID) \ + + (IA_CSS_PROCESS_MAX_CELLS * VIED_NCI_RESOURCE_ID_BITS) \ + + (VIED_NCI_RESOURCE_ID_BITS) \ + + (2 * IA_CSS_UINT8_T_BITS) \ + + (N_PADDING_UINT8_IN_PROGRAM_GROUP_MANFEST * IA_CSS_UINT8_T_BITS)) +/* + * This structure contains only the information required for resource + * management and construction of the process group. + * The header for the program binary load is separate + */ + +struct ia_css_program_manifest_s { + /**< Indicate which kernels lead to this program being used */ + ia_css_kernel_bitmap_t kernel_bitmap; + /**< Referral ID to a specific program FW, valid ID's != 0 */ + ia_css_program_ID_t ID; + /**< Specification of for exclusive or parallel programs */ + ia_css_program_type_t program_type; + /**< offset to add to reach parent. This is negative value.*/ + int32_t parent_offset; + uint32_t program_dependency_offset; + uint32_t terminal_dependency_offset; +#if (VIED_NCI_N_DEV_DFM_ID > 0) + /**< DFM port allocation of this program */ + vied_nci_resource_bitmap_t dfm_port_bitmap[VIED_NCI_N_DEV_DFM_ID]; + /**< Active DFM ports which need a kick + * If an empty port is configured to run in active mode, the empty + * port and the corresponding full port(s) in the stream must be kicked. + * The empty port must always be kicked aster the full port. + */ + vied_nci_resource_bitmap_t dfm_active_port_bitmap[VIED_NCI_N_DEV_DFM_ID]; +#endif + /**< Size of this structure */ + uint16_t size; + /**< (internal) Memory allocation size needs of this program */ + vied_nci_resource_size_t int_mem_size[VIED_NCI_N_MEM_TYPE_ID]; + /**< (external) Memory allocation size needs of this program */ + vied_nci_resource_size_t ext_mem_size[VIED_NCI_N_DATA_MEM_TYPE_ID]; + vied_nci_resource_size_t ext_mem_offset[VIED_NCI_N_DATA_MEM_TYPE_ID]; + /**< Device channel allocation size needs of this program */ + vied_nci_resource_size_t dev_chn_size[VIED_NCI_N_DEV_CHN_ID]; + vied_nci_resource_size_t dev_chn_offset[VIED_NCI_N_DEV_CHN_ID]; +#if (VIED_NCI_N_DEV_DFM_ID > 0) + /**< DFM ports are relocatable if value is set to 1. + * The flag is per dfm port type. + * This will not be supported for now. + */ + uint8_t is_dfm_relocatable[VIED_NCI_N_DEV_DFM_ID]; +#endif + /** Array of all the cells this program needs */ +#if IA_CSS_PROCESS_MAX_CELLS == 1 + vied_nci_resource_id_t cell_id; +#else + vied_nci_resource_id_t cells[IA_CSS_PROCESS_MAX_CELLS]; +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ + /**< (exclusive) indication of a cell type to be used by this program */ + vied_nci_resource_id_t cell_type_id; + + /**< Number of programs this program depends on */ + uint8_t program_dependency_count; + /**< Number of terminals this program depends on */ + uint8_t terminal_dependency_count; + /**< Padding bytes for 64bit alignment*/ +#if N_PADDING_UINT8_IN_PROGRAM_GROUP_MANFEST > 0 + /*hivecc does not allow an array of zero length*/ + uint8_t padding[N_PADDING_UINT8_IN_PROGRAM_GROUP_MANFEST]; +#endif +}; + +/* + *Calculation for manual size check for struct ia_css_data_terminal_manifest_s + */ +#define SIZE_OF_DATA_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + (SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + + IA_CSS_FRAME_FORMAT_BITMAP_BITS \ + + IA_CSS_CONNECTION_BITMAP_BITS \ + + IA_CSS_KERNEL_BITMAP_BITS \ + + (4 * (IA_CSS_UINT16_T_BITS * IA_CSS_N_DATA_DIMENSION)) \ + + IA_CSS_UINT16_T_BITS \ + + IA_CSS_UINT8_T_BITS \ + + (4*IA_CSS_UINT8_T_BITS)) +/* + * Inherited data terminal class + */ +struct ia_css_data_terminal_manifest_s { + /**< Data terminal base */ + ia_css_terminal_manifest_t base; + /**< Supported (4CC / MIPI / parameter) formats */ + ia_css_frame_format_bitmap_t frame_format_bitmap; + /**< Indicate which kernels lead to this terminal being used */ + ia_css_kernel_bitmap_t kernel_bitmap; + /**< Minimum size of the frame */ + uint16_t min_size[IA_CSS_N_DATA_DIMENSION]; + /**< Maximum size of the frame */ + uint16_t max_size[IA_CSS_N_DATA_DIMENSION]; + /**< Minimum size of a fragment that the program port can accept */ + uint16_t min_fragment_size[IA_CSS_N_DATA_DIMENSION]; + /**< Maximum size of a fragment that the program port can accept */ + uint16_t max_fragment_size[IA_CSS_N_DATA_DIMENSION]; + /**< Indicate if this terminal is derived from a principal terminal */ + uint16_t terminal_dependency; + /**< Indicate what (streaming) interface types this terminal supports */ + ia_css_connection_bitmap_t connection_bitmap; + /**< Indicates if compression is supported on the data associated with + * this terminal. '1' indicates compression is supported, + * '0' otherwise + */ + uint8_t compression_support; + uint8_t reserved[4]; +}; + +/* ============ Program Control Init Terminal Manifest - START ============ */ +#define N_PADDING_UINT8_IN_PROGCTRLINIT_MANIFEST_PROGRAM_DESC_STRUCT 4 +struct ia_css_program_control_init_manifest_program_desc_s { + uint16_t load_section_count; + uint16_t connect_section_count; + uint8_t padding[N_PADDING_UINT8_IN_PROGCTRLINIT_MANIFEST_PROGRAM_DESC_STRUCT]; +}; + +#define N_PADDING_UINT8_IN_PROGCTRLINIT_TERMINAL_MANIFEST_STRUCT 2 +struct ia_css_program_control_init_terminal_manifest_s { + ia_css_terminal_manifest_t base; + /* Number of programs in program group */ + uint32_t program_count; + /* + * Points to array of ia_css_program_control_init_terminal_program_desc_t + * with size program_count. + */ + uint16_t program_desc_offset; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PROGCTRLINIT_TERMINAL_MANIFEST_STRUCT]; +}; +/* ============ Program Control Init Terminal Manifest - END ============ */ + +extern void ia_css_program_manifest_init( + ia_css_program_manifest_t *blob, + const uint8_t program_dependency_count, + const uint8_t terminal_dependency_count); + +#endif /* __IA_CSS_PSYS_PROGRAM_GROUP_PRIVATE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_manifest.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_manifest.c new file mode 100644 index 0000000000000..67eae346e81a1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_program_manifest.c @@ -0,0 +1,1240 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include +#include +/* for ia_css_kernel_bitmap_t, ia_css_kernel_bitmap_print */ +#include + +#include +#include "ia_css_psys_program_group_private.h" +#include "ia_css_psys_static_trace.h" + +#include +#include + +size_t ia_css_sizeof_program_manifest( + const uint8_t program_dependency_count, + const uint8_t terminal_dependency_count) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_sizeof_program_manifest(): enter:\n"); + + size += sizeof(ia_css_program_manifest_t); + size += program_dependency_count * sizeof(uint8_t); + size += terminal_dependency_count * sizeof(uint8_t); + size = ceil_mul(size, sizeof(uint64_t)); + + return size; +} + +bool ia_css_has_program_manifest_fixed_cell( + const ia_css_program_manifest_t *manifest) +{ + bool has_fixed_cell = false; + + vied_nci_cell_ID_t cell_id; + vied_nci_cell_type_ID_t cell_type_id; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_has_program_manifest_fixed_cell(): enter:\n"); + + verifexit(manifest != NULL); + + cell_id = ia_css_program_manifest_get_cell_ID(manifest); + cell_type_id = ia_css_program_manifest_get_cell_type_ID(manifest); + + has_fixed_cell = ((cell_id != VIED_NCI_N_CELL_ID) && + (cell_type_id == VIED_NCI_N_CELL_TYPE_ID)); + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_has_program_manifest_fixed_cell invalid argument\n"); + } + return has_fixed_cell; +} + +size_t ia_css_program_manifest_get_size( + const ia_css_program_manifest_t *manifest) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_size(): enter:\n"); + + if (manifest != NULL) { + size = manifest->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_size invalid argument\n"); + } + + return size; +} + +ia_css_program_ID_t ia_css_program_manifest_get_program_ID( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_ID_t program_id = IA_CSS_PROGRAM_INVALID_ID; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_program_ID(): enter:\n"); + + if (manifest != NULL) { + program_id = manifest->ID; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_program_ID invalid argument\n"); + } + return program_id; +} + +int ia_css_program_manifest_set_program_ID( + ia_css_program_manifest_t *manifest, + ia_css_program_ID_t id) +{ + int ret = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_program_ID(): enter:\n"); + + if (manifest != NULL) { + manifest->ID = id; + ret = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_program_ID failed (%i)\n", ret); + } + return ret; +} + +ia_css_program_group_manifest_t *ia_css_program_manifest_get_parent( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_group_manifest_t *parent = NULL; + char *base; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_parent(): enter:\n"); + + verifexit(manifest != NULL); + + base = (char *)((char *)manifest + manifest->parent_offset); + + parent = (ia_css_program_group_manifest_t *) (base); +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_parent invalid argument\n"); + } + return parent; +} + +int ia_css_program_manifest_set_parent_offset( + ia_css_program_manifest_t *manifest, + int32_t program_offset) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_parent_offset(): enter:\n"); + + verifexit(manifest != NULL); + + /* parent is at negative offset away from current program offset*/ + manifest->parent_offset = -program_offset; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_parent_offset failed (%i)\n", + retval); + } + return retval; +} + +ia_css_program_type_t ia_css_program_manifest_get_type( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_type_t program_type = IA_CSS_N_PROGRAM_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_type(): enter:\n"); + + if (manifest != NULL) { + program_type = manifest->program_type; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_type invalid argument\n"); + } + return program_type; +} + +int ia_css_program_manifest_set_type( + ia_css_program_manifest_t *manifest, + const ia_css_program_type_t program_type) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_type(): enter:\n"); + + if (manifest != NULL) { + manifest->program_type = program_type; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_type failed (%i)\n", retval); + } + return retval; +} + +ia_css_kernel_bitmap_t ia_css_program_manifest_get_kernel_bitmap( + const ia_css_program_manifest_t *manifest) +{ + ia_css_kernel_bitmap_t kernel_bitmap = ia_css_kernel_bitmap_clear(); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + kernel_bitmap = manifest->kernel_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_kernel_bitmap invalid argument\n"); + } + return kernel_bitmap; +} + +int ia_css_program_manifest_set_kernel_bitmap( + ia_css_program_manifest_t *manifest, + const ia_css_kernel_bitmap_t kernel_bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + manifest->kernel_bitmap = kernel_bitmap; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_kernel_bitmap failed (%i)\n", + retval); + } + return retval; +} + +vied_nci_cell_ID_t ia_css_program_manifest_get_cell_ID( + const ia_css_program_manifest_t *manifest) +{ + vied_nci_cell_ID_t cell_id = VIED_NCI_N_CELL_ID; +#if IA_CSS_PROCESS_MAX_CELLS > 1 + int i = 0; +#endif /* IA_CSS_PROCESS_MAX_CELLS > 1 */ + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_cell_ID(): enter:\n"); + + verifexit(manifest != NULL); + +#if IA_CSS_PROCESS_MAX_CELLS == 1 + cell_id = manifest->cell_id; +#else + for (i = 1; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + assert(manifest->cells[i] == VIED_NCI_N_CELL_ID); +#ifdef __HIVECC +#pragma hivecc unroll +#endif + } + cell_id = manifest->cells[0]; +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_cell_ID invalid argument\n"); + } + return cell_id; +} + +int ia_css_program_manifest_set_cell_ID( + ia_css_program_manifest_t *manifest, + const vied_nci_cell_ID_t cell_id) +{ + int retval = -1; +#if IA_CSS_PROCESS_MAX_CELLS > 1 + int i = 0; +#endif /* IA_CSS_PROCESS_MAX_CELLS > 1 */ + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_cell_ID(): enter:\n"); + if (manifest != NULL) { +#if IA_CSS_PROCESS_MAX_CELLS == 1 + manifest->cell_id = cell_id; +#else + manifest->cells[0] = cell_id; + for (i = 1; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + manifest->cells[i] = VIED_NCI_N_CELL_ID; + } +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_cell_ID failed (%i)\n", retval); + } + return retval; +} + +vied_nci_cell_type_ID_t ia_css_program_manifest_get_cell_type_ID( + const ia_css_program_manifest_t *manifest) +{ + vied_nci_cell_type_ID_t cell_type_id = VIED_NCI_N_CELL_TYPE_ID; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_cell_type_ID(): enter:\n"); + + verifexit(manifest != NULL); + + cell_type_id = (vied_nci_cell_type_ID_t)(manifest->cell_type_id); +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_cell_type_ID invalid argument\n"); + } + return cell_type_id; +} + +int ia_css_program_manifest_set_cell_type_ID( + ia_css_program_manifest_t *manifest, + const vied_nci_cell_type_ID_t cell_type_id) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_cell_type_ID(): enter:\n"); + if (manifest != NULL) { + manifest->cell_type_id = cell_type_id; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_cell_type_ID failed (%i)\n", + retval); + } + return retval; +} + +vied_nci_resource_size_t ia_css_program_manifest_get_int_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id) +{ + vied_nci_resource_size_t int_mem_size = 0; + vied_nci_cell_type_ID_t cell_type_id; + int mem_index; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_int_mem_size(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(mem_type_id < VIED_NCI_N_MEM_TYPE_ID); + + if (ia_css_has_program_manifest_fixed_cell(manifest)) { + vied_nci_cell_ID_t cell_id = + ia_css_program_manifest_get_cell_ID(manifest); + + cell_type_id = vied_nci_cell_get_type(cell_id); + } else { + cell_type_id = + ia_css_program_manifest_get_cell_type_ID(manifest); + } + + /* loop over vied_nci_cell_mem_type to verify mem_type_id for a + * specific cell_type_id + */ + for (mem_index = 0; mem_index < VIED_NCI_N_MEM_TYPE_ID; mem_index++) { + if ((int)mem_type_id == + (int)vied_nci_cell_type_get_mem_type( + cell_type_id, mem_index)) { + int_mem_size = manifest->int_mem_size[mem_index]; + } + } + +EXIT: + if (NULL == manifest || mem_type_id >= VIED_NCI_N_MEM_TYPE_ID) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_int_mem_size invalid argument\n"); + } + return int_mem_size; +} + +int ia_css_program_manifest_set_cells_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + int array_index = 0; + int bit_index; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_cells_bitmap(): enter:\n"); + + if (manifest != NULL) { + for (bit_index = 0; bit_index < VIED_NCI_N_CELL_ID; bit_index++) { + if (vied_nci_is_bit_set_in_bitmap(bitmap, bit_index)) { + verifexit(array_index < IA_CSS_PROCESS_MAX_CELLS); +#if IA_CSS_PROCESS_MAX_CELLS == 1 + manifest->cell_id = (vied_nci_cell_ID_t)bit_index; +#else + manifest->cells[array_index] = (vied_nci_cell_ID_t)bit_index; +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ + array_index++; + } + } + for (; array_index < IA_CSS_PROCESS_MAX_CELLS; array_index++) { +#if IA_CSS_PROCESS_MAX_CELLS == 1 + manifest->cell_id = VIED_NCI_N_CELL_ID; +#else + manifest->cells[array_index] = VIED_NCI_N_CELL_ID; +#endif /* IA_CSS_PROCESS_MAX_CELLS */ + } + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_cells_bitmap invalid argument\n"); + } +EXIT: + return retval; +} + +vied_nci_resource_bitmap_t ia_css_program_manifest_get_cells_bitmap( + const ia_css_program_manifest_t *manifest) +{ + vied_nci_resource_bitmap_t bitmap = 0; +#if IA_CSS_PROCESS_MAX_CELLS > 1 + int i = 0; +#endif /* IA_CSS_PROCESS_MAX_CELLS > 1 */ + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_cells_bitmap(): enter:\n"); + + verifexit(manifest != NULL); + +#if IA_CSS_PROCESS_MAX_CELLS == 1 + bitmap = (1 << manifest->cell_id); +#else + for (i = 0; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + if (VIED_NCI_N_CELL_ID != manifest->cells[i]) { + bitmap |= (1 << manifest->cells[i]); + } +#ifdef __HIVECC +#pragma hivecc unroll +#endif + } +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_cells_bitmap invalid argument\n"); + } + return bitmap; +} + +int ia_css_program_manifest_set_dfm_port_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_dfm_port_bitmap(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + manifest->dfm_port_bitmap[dfm_type_id] = bitmap; +#else + (void)bitmap; + (void)dfm_type_id; +#endif + retval = 0; + +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_dfm_port_bitmap invalid argument\n"); + } + return retval; +} + +int ia_css_program_manifest_set_dfm_active_port_bitmap( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const vied_nci_resource_bitmap_t bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_dfm_active_port_bitmap(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + manifest->dfm_active_port_bitmap[dfm_type_id] = bitmap; +#else + (void)bitmap; + (void)dfm_type_id; +#endif + retval = 0; + +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_dfm_active_port_bitmap invalid argument\n"); + } + return retval; +} + +int ia_css_program_manifest_set_is_dfm_relocatable( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id, + const uint8_t is_relocatable) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_is_dfm_relocatable(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + manifest->is_dfm_relocatable[dfm_type_id] = is_relocatable; +#else + (void)is_relocatable; + (void)dfm_type_id; +#endif + retval = 0; + +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_is_dfm_relocatable invalid argument\n"); + } + + return retval; +} + +uint8_t ia_css_program_manifest_get_is_dfm_relocatable( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id) +{ + uint8_t ret = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_is_dfm_relocatable(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + ret = manifest->is_dfm_relocatable[dfm_type_id]; +#else + ret = 0; + (void)dfm_type_id; +#endif +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_is_dfm_relocatable invalid argument\n"); + } + return ret; +} + +vied_nci_resource_bitmap_t ia_css_program_manifest_get_dfm_port_bitmap( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id) +{ + vied_nci_resource_bitmap_t bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_dfm_port_bitmap(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + bitmap = manifest->dfm_port_bitmap[dfm_type_id]; +#else + bitmap = 0; + (void)dfm_type_id; +#endif +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_dfm_port_bitmap invalid argument\n"); + } + return bitmap; +} + +vied_nci_resource_bitmap_t ia_css_program_manifest_get_dfm_active_port_bitmap( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_dfm_id_t dfm_type_id) +{ + vied_nci_resource_bitmap_t bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_dfm_active_port_bitmap(): enter:\n"); + + verifexit(manifest != NULL); +#if (VIED_NCI_N_DEV_DFM_ID > 0) + verifexit(dfm_type_id < VIED_NCI_N_DEV_DFM_ID); + bitmap = manifest->dfm_active_port_bitmap[dfm_type_id]; +#else + bitmap = 0; + (void)dfm_type_id; +#endif +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_dfm_active_port_bitmap invalid argument\n"); + } + return bitmap; +} + +int ia_css_program_manifest_set_int_mem_size( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t int_mem_size) +{ + int retval = -1; + vied_nci_cell_type_ID_t cell_type_id; + int mem_index; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_int_mem_size(): enter:\n"); + + if (ia_css_has_program_manifest_fixed_cell(manifest)) { + vied_nci_cell_ID_t cell_id = + ia_css_program_manifest_get_cell_ID(manifest); + + cell_type_id = vied_nci_cell_get_type(cell_id); + } else { + cell_type_id = + ia_css_program_manifest_get_cell_type_ID(manifest); + } + + if (manifest != NULL && mem_type_id < VIED_NCI_N_MEM_TYPE_ID) { + /* loop over vied_nci_cell_mem_type to verify mem_type_id for + * a specific cell_type_id + */ + for (mem_index = 0; mem_index < VIED_NCI_N_MEM_TYPE_ID; + mem_index++) { + if ((int)mem_type_id == + (int)vied_nci_cell_type_get_mem_type( + cell_type_id, mem_index)) { + manifest->int_mem_size[mem_index] = + int_mem_size; + retval = 0; + } + } + } + if (retval != 0) { + IA_CSS_TRACE_2(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_int_mem_size cell_type_id %d has no mem_type_id %d\n", + (int)cell_type_id, (int)mem_type_id); + } + + return retval; +} + +vied_nci_resource_size_t ia_css_program_manifest_get_ext_mem_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id) +{ + vied_nci_resource_size_t ext_mem_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_ext_mem_size(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID); + + ext_mem_size = manifest->ext_mem_size[mem_type_id]; +EXIT: + if (NULL == manifest || mem_type_id >= VIED_NCI_N_DATA_MEM_TYPE_ID) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_ext_mem_size invalid argument\n"); + } + return ext_mem_size; +} + +vied_nci_resource_size_t ia_css_program_manifest_get_ext_mem_offset( + const ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id) +{ + vied_nci_resource_size_t ext_mem_offset = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_ext_mem_offset(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID); + + ext_mem_offset = manifest->ext_mem_offset[mem_type_id]; +EXIT: + if (NULL == manifest || mem_type_id >= VIED_NCI_N_DATA_MEM_TYPE_ID) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_ext_mem_offset invalid argument\n"); + } + return ext_mem_offset; +} + +int ia_css_program_manifest_set_ext_mem_size( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t ext_mem_size) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_ext_mem_size(): enter:\n"); + + if (manifest != NULL && mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID) { + manifest->ext_mem_size[mem_type_id] = ext_mem_size; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_ext_mem_size invalid argument\n"); + } + + return retval; +} + +int ia_css_program_manifest_set_ext_mem_offset( + ia_css_program_manifest_t *manifest, + const vied_nci_mem_type_ID_t mem_type_id, + const vied_nci_resource_size_t ext_mem_offset) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_ext_mem_offset(): enter:\n"); + + if (manifest != NULL && mem_type_id < VIED_NCI_N_DATA_MEM_TYPE_ID) { + manifest->ext_mem_offset[mem_type_id] = ext_mem_offset; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_ext_mem_offset invalid argument\n"); + } + + return retval; +} + +vied_nci_resource_size_t ia_css_program_manifest_get_dev_chn_size( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id) +{ + vied_nci_resource_size_t dev_chn_size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_dev_chn_size(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(dev_chn_id < VIED_NCI_N_DEV_CHN_ID); + + dev_chn_size = manifest->dev_chn_size[dev_chn_id]; +EXIT: + if (NULL == manifest || dev_chn_id >= VIED_NCI_N_DEV_CHN_ID) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_dev_chn_size invalid argument\n"); + } + return dev_chn_size; +} + +vied_nci_resource_size_t ia_css_program_manifest_get_dev_chn_offset( + const ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id) +{ + vied_nci_resource_size_t dev_chn_offset = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_dev_chn_offset(): enter:\n"); + + verifexit(manifest != NULL); + verifexit(dev_chn_id < VIED_NCI_N_DEV_CHN_ID); + + dev_chn_offset = manifest->dev_chn_offset[dev_chn_id]; +EXIT: + if (NULL == manifest || dev_chn_id >= VIED_NCI_N_DEV_CHN_ID) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_dev_chn_offset invalid argument\n"); + } + return dev_chn_offset; +} + +int ia_css_program_manifest_set_dev_chn_size( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t dev_chn_size) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_dev_chn_size(): enter:\n"); + + if (manifest != NULL && dev_chn_id < VIED_NCI_N_DEV_CHN_ID) { + manifest->dev_chn_size[dev_chn_id] = dev_chn_size; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_dev_chn_size invalid argument\n"); + } + + return retval; +} + +int ia_css_program_manifest_set_dev_chn_offset( + ia_css_program_manifest_t *manifest, + const vied_nci_dev_chn_ID_t dev_chn_id, + const vied_nci_resource_size_t dev_chn_offset) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_dev_chn_offset(): enter:\n"); + + if (manifest != NULL && dev_chn_id < VIED_NCI_N_DEV_CHN_ID) { + manifest->dev_chn_offset[dev_chn_id] = dev_chn_offset; + retval = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_set_dev_chn_offset invalid argument\n"); + } + + return retval; +} + +uint8_t ia_css_program_manifest_get_program_dependency_count( + const ia_css_program_manifest_t *manifest) +{ + uint8_t program_dependency_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_program_dependency_count(): enter:\n"); + + if (manifest != NULL) { + program_dependency_count = manifest->program_dependency_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_program_dependency_count invalid argument\n"); + } + return program_dependency_count; +} + +uint8_t ia_css_program_manifest_get_program_dependency( + const ia_css_program_manifest_t *manifest, + const unsigned int index) +{ + uint8_t program_dependency = IA_CSS_PROGRAM_INVALID_DEPENDENCY; + uint8_t *program_dep_ptr; + uint8_t program_dependency_count; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_program_dependency(): enter:\n"); + + program_dependency_count = + ia_css_program_manifest_get_program_dependency_count(manifest); + + if (index < program_dependency_count) { + program_dep_ptr = + (uint8_t *)((uint8_t *)manifest + + manifest->program_dependency_offset + + index * sizeof(uint8_t)); + program_dependency = *program_dep_ptr; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_program_dependency invalid argument\n"); + } + return program_dependency; +} + +int ia_css_program_manifest_set_program_dependency( + ia_css_program_manifest_t *manifest, + const uint8_t program_dependency, + const unsigned int index) +{ + int retval = -1; + uint8_t *program_dep_ptr; + uint8_t program_dependency_count; + uint8_t program_count; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_program_dependency(): enter:\n"); + + program_dependency_count = + ia_css_program_manifest_get_program_dependency_count(manifest); + program_count = + ia_css_program_group_manifest_get_program_count( + ia_css_program_manifest_get_parent(manifest)); + + if ((index < program_dependency_count) && + (program_dependency < program_count)) { + program_dep_ptr = (uint8_t *)((uint8_t *)manifest + + manifest->program_dependency_offset + + index*sizeof(uint8_t)); + *program_dep_ptr = program_dependency; + retval = 0; + } + + if (retval != 0) { + IA_CSS_TRACE_3(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_program_dependency(m, %d, %d) failed (%i)\n", + program_dependency, index, retval); + } + return retval; +} + +uint8_t ia_css_program_manifest_get_terminal_dependency_count( + const ia_css_program_manifest_t *manifest) +{ + uint8_t terminal_dependency_count = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_terminal_dependency_count(): enter:\n"); + + if (manifest != NULL) { + terminal_dependency_count = manifest->terminal_dependency_count; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_terminal_dependency_count invalid argument\n"); + } + return terminal_dependency_count; +} + +uint8_t ia_css_program_manifest_get_terminal_dependency( + const ia_css_program_manifest_t *manifest, + const unsigned int index) +{ + uint8_t terminal_dependency = IA_CSS_PROGRAM_INVALID_DEPENDENCY; + uint8_t *terminal_dep_ptr; + uint8_t terminal_dependency_count = + ia_css_program_manifest_get_terminal_dependency_count(manifest); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_get_terminal_dependency(): enter:\n"); + + if (index < terminal_dependency_count) { + terminal_dep_ptr = (uint8_t *)((uint8_t *)manifest + + manifest->terminal_dependency_offset + index); + terminal_dependency = *terminal_dep_ptr; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_program_manifest_get_terminal_dependency invalid argument\n"); + } + return terminal_dependency; +} + +int ia_css_program_manifest_set_terminal_dependency( + ia_css_program_manifest_t *manifest, + const uint8_t terminal_dependency, + const unsigned int index) +{ + int retval = -1; + uint8_t *terminal_dep_ptr; + uint8_t terminal_dependency_count = + ia_css_program_manifest_get_terminal_dependency_count(manifest); + uint8_t terminal_count = + ia_css_program_group_manifest_get_terminal_count( + ia_css_program_manifest_get_parent(manifest)); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_program_manifest_set_terminal_dependency(): enter:\n"); + + if ((index < terminal_dependency_count) && + (terminal_dependency < terminal_count)) { + terminal_dep_ptr = (uint8_t *)((uint8_t *)manifest + + manifest->terminal_dependency_offset + index); + *terminal_dep_ptr = terminal_dependency; + retval = 0; + } + + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_set_terminal_dependency failed (%i)\n", + retval); + } + return retval; +} + +bool ia_css_is_program_manifest_subnode_program_type( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_type_t program_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_program_manifest_subnode_program_type(): enter:\n"); + + program_type = ia_css_program_manifest_get_type(manifest); +/* The error return is the limit value, so no need to check on the manifest + * pointer + */ + return (program_type == IA_CSS_PROGRAM_TYPE_PARALLEL_SUB) || + (program_type == IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUB) || + (program_type == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUB); +} + +bool ia_css_is_program_manifest_supernode_program_type( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_type_t program_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_program_manifest_supernode_program_type(): enter:\n"); + + program_type = ia_css_program_manifest_get_type(manifest); + +/* The error return is the limit value, so no need to check on the manifest + * pointer + */ + return (program_type == IA_CSS_PROGRAM_TYPE_PARALLEL_SUPER) || + (program_type == IA_CSS_PROGRAM_TYPE_EXCLUSIVE_SUPER) || + (program_type == IA_CSS_PROGRAM_TYPE_VIRTUAL_SUPER); +} + +bool ia_css_is_program_manifest_singular_program_type( + const ia_css_program_manifest_t *manifest) +{ + ia_css_program_type_t program_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_program_manifest_singular_program_type(): enter:\n"); + + program_type = ia_css_program_manifest_get_type(manifest); + +/* The error return is the limit value, so no need to check on the manifest + * pointer + */ + return (program_type == IA_CSS_PROGRAM_TYPE_SINGULAR); +} + +void ia_css_program_manifest_init( + ia_css_program_manifest_t *blob, + const uint8_t program_dependency_count, + const uint8_t terminal_dependency_count) +{ + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, + "ia_css_program_manifest_init(): enter:\n"); + + /*TODO: add assert*/ + if (!blob) + return; + + blob->ID = 1; + blob->program_dependency_count = program_dependency_count; + blob->terminal_dependency_count = terminal_dependency_count; + blob->program_dependency_offset = sizeof(ia_css_program_manifest_t); + blob->terminal_dependency_offset = blob->program_dependency_offset + + sizeof(uint8_t) * program_dependency_count; + blob->size = + (uint16_t)ia_css_sizeof_program_manifest( + program_dependency_count, + terminal_dependency_count); +} + +/* We need to refactor those files in order to build in the firmware only + what is needed, switches are put current to workaround compilation problems + in the firmware (for example lack of uint64_t support) + supported in the firmware + */ +#if !defined(__HIVECC) + +#if defined(_MSC_VER) +/* WA for a visual studio compiler bug, refer to + developercommunity.visualstudio.com/content/problem/209359/ice-with-fpfast-in-156-and-msvc-daily-1413263051-p.html +*/ +#pragma optimize("", off) +#endif + +int ia_css_program_manifest_print( + const ia_css_program_manifest_t *manifest, + void *fid) +{ + int retval = -1; + int i, mem_index, dev_chn_index; + + vied_nci_cell_type_ID_t cell_type_id; + uint8_t program_dependency_count; + uint8_t terminal_dependency_count; + ia_css_kernel_bitmap_t bitmap; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, + "ia_css_program_manifest_print(): enter:\n"); + + verifexit(manifest != NULL); + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "sizeof(manifest) = %d\n", + (int)ia_css_program_manifest_get_size(manifest)); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "program ID = %d\n", + (int)ia_css_program_manifest_get_program_ID(manifest)); + + bitmap = ia_css_program_manifest_get_kernel_bitmap(manifest); + verifexit(ia_css_kernel_bitmap_print(bitmap, fid) == 0); + + if (ia_css_has_program_manifest_fixed_cell(manifest)) { + vied_nci_cell_ID_t cell_id = + ia_css_program_manifest_get_cell_ID(manifest); + + cell_type_id = vied_nci_cell_get_type(cell_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "cell(program) = %d\n", + (int)cell_id); + } else { + cell_type_id = + ia_css_program_manifest_get_cell_type_ID(manifest); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "cell type(program) = %d\n", + (int)cell_type_id); + + for (mem_index = 0; mem_index < (int)VIED_NCI_N_MEM_TYPE_ID; + mem_index++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(internal mem) type = %d\n", + (int)vied_nci_cell_type_get_mem_type(cell_type_id, mem_index)); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(internal mem) size = %d\n", + manifest->int_mem_size[mem_index]); + } + + for (mem_index = 0; mem_index < (int)VIED_NCI_N_DATA_MEM_TYPE_ID; + mem_index++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(external mem) type = %d\n", + (int)(vied_nci_mem_type_ID_t)mem_index); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(external mem) size = %d\n", + manifest->ext_mem_size[mem_index]); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(external mem) offset = %d\n", + manifest->ext_mem_offset[mem_index]); + } + + for (dev_chn_index = 0; dev_chn_index < (int)VIED_NCI_N_DEV_CHN_ID; + dev_chn_index++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(device channel) type = %d\n", + (int)dev_chn_index); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(device channel) size = %d\n", + manifest->dev_chn_size[dev_chn_index]); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(device channel) offset = %d\n", + manifest->dev_chn_offset[dev_chn_index]); + } +#if HAS_DFM + for (dev_chn_index = 0; dev_chn_index < (int)VIED_NCI_N_DEV_DFM_ID; + dev_chn_index++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(dfm port) type = %d\n", + (int)dev_chn_index); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(dfm port) port_bitmap = %d\n", + manifest->dfm_port_bitmap[dev_chn_index]); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(dfm port) active_port_bitmap = %d\n", + manifest->dfm_active_port_bitmap[dev_chn_index]); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(dfm port) is_dfm_relocatable = %d\n", + manifest->is_dfm_relocatable[dev_chn_index]); + } +#endif + +#if IA_CSS_PROCESS_MAX_CELLS == 1 + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(cells) bitmap = %d\n", + manifest->cell_id); +#else + for (i = 0; i < IA_CSS_PROCESS_MAX_CELLS; i++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\ttype(cells) bitmap = %d\n", + manifest->cells[i]); + } +#endif /* IA_CSS_PROCESS_MAX_CELLS == 1 */ + program_dependency_count = + ia_css_program_manifest_get_program_dependency_count(manifest); + if (program_dependency_count == 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "program_dependencies[%d] {};\n", + program_dependency_count); + } else { + uint8_t prog_dep; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "program_dependencies[%d] {\n", + program_dependency_count); + for (i = 0; i < (int)program_dependency_count - 1; i++) { + prog_dep = + ia_css_program_manifest_get_program_dependency( + manifest, i); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t %4d,\n", prog_dep); + } + prog_dep = + ia_css_program_manifest_get_program_dependency(manifest, i); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\t %4d }\n", prog_dep); + (void)prog_dep; + } + + terminal_dependency_count = + ia_css_program_manifest_get_terminal_dependency_count(manifest); + if (terminal_dependency_count == 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "terminal_dependencies[%d] {};\n", + terminal_dependency_count); + } else { + uint8_t term_dep; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "terminal_dependencies[%d] {\n", + terminal_dependency_count); + for (i = 0; i < (int)terminal_dependency_count - 1; i++) { + term_dep = + ia_css_program_manifest_get_terminal_dependency( + manifest, i); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t %4d,\n", term_dep); + } + term_dep = + ia_css_program_manifest_get_terminal_dependency(manifest, i); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\t %4d }\n", term_dep); + (void)term_dep; + } + (void)cell_type_id; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_program_manifest_print failed (%i)\n", retval); + } + return retval; +} + +#if defined(_MSC_VER) +/* WA for a visual studio compiler bug */ +#pragma optimize("", off) +#endif + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_terminal_manifest.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_terminal_manifest.c new file mode 100644 index 0000000000000..9d8434a13d8d9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/psysapi/static/src/ia_css_psys_terminal_manifest.c @@ -0,0 +1,1137 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + + +#include + +/* Data object types on the terminals */ +#include +/* for ia_css_kernel_bitmap_t, ia_css_kernel_bitmap_clear, ia_css_... */ +#include + +#include "ia_css_psys_program_group_private.h" +#include "ia_css_terminal_manifest.h" +#include "ia_css_terminal_manifest_types.h" + +#include +#include +#include +#include "ia_css_psys_static_trace.h" + +/* We need to refactor those files in order to build in the firmware only + what is needed, switches are put current to workaround compilation problems + in the firmware (for example lack of uint64_t support) + supported in the firmware + */ +#if !defined(__HIVECC) +static const char *terminal_type_strings[IA_CSS_N_TERMINAL_TYPES + 1] = { + "IA_CSS_TERMINAL_TYPE_DATA_IN", + "IA_CSS_TERMINAL_TYPE_DATA_OUT", + "IA_CSS_TERMINAL_TYPE_PARAM_STREAM", + /**< Type 1-5 parameter input */ + "IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN", + /**< Type 1-5 parameter output */ + "IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT", + /**< Represent the new type of terminal for + * the "spatial dependent parameters", when params go in + */ + "IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN", + /**< Represent the new type of terminal for + * the "spatial dependent parameters", when params go out + */ + "IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT", + /**< Represent the new type of terminal for + * the explicit slicing, when params go in + */ + "IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN", + /**< Represent the new type of terminal for + * the explicit slicing, when params go out + */ + "IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT", + /**< State (private data) input */ + "IA_CSS_TERMINAL_TYPE_STATE_IN", + /**< State (private data) output */ + "IA_CSS_TERMINAL_TYPE_STATE_OUT", + "IA_CSS_TERMINAL_TYPE_PROGRAM", + "IA_CSS_TERMINAL_TYPR_PROGRAM_CONTROL_INIT", + "UNDEFINED_TERMINAL_TYPE"}; + +#endif + +bool ia_css_is_terminal_manifest_spatial_parameter_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_parameter_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return ((terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN) || + (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT)); +} + +bool ia_css_is_terminal_manifest_program_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_parameter_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM); +} + +bool ia_css_is_terminal_manifest_program_control_init_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_program_control_init_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT); +} + + +bool ia_css_is_terminal_manifest_parameter_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + /* will return an error value on error */ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_parameter_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT); +} + +bool ia_css_is_terminal_manifest_data_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + /* will return an error value on error */ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_data_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return ((terminal_type == IA_CSS_TERMINAL_TYPE_DATA_IN) || + (terminal_type == IA_CSS_TERMINAL_TYPE_DATA_OUT)); +} + +bool ia_css_is_terminal_manifest_sliced_terminal( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_type_t terminal_type; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_is_terminal_manifest_sliced_terminal(): enter:\n"); + + terminal_type = ia_css_terminal_manifest_get_type(manifest); + + return ((terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN) || + (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT)); +} + +size_t ia_css_terminal_manifest_get_size( + const ia_css_terminal_manifest_t *manifest) +{ + size_t size = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_get_size(): enter:\n"); + + if (manifest != NULL) { + size = manifest->size; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_terminal_manifest_get_size: invalid argument\n"); + } + return size; +} + +ia_css_terminal_type_t ia_css_terminal_manifest_get_type( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_type_t terminal_type = IA_CSS_N_TERMINAL_TYPES; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_get_type(): enter:\n"); + + if (manifest != NULL) { + terminal_type = manifest->terminal_type; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_terminal_manifest_get_type: invalid argument\n"); + } + return terminal_type; +} + +int ia_css_terminal_manifest_set_type( + ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_type_t terminal_type) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_set_type(): enter:\n"); + + if (manifest != NULL) { + manifest->terminal_type = terminal_type; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_terminal_manifest_set_type failed (%i)\n", + retval); + } + return retval; +} + +int ia_css_terminal_manifest_set_ID( + ia_css_terminal_manifest_t *manifest, + const ia_css_terminal_ID_t ID) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_set_ID(): enter:\n"); + + if (manifest != NULL) { + manifest->ID = ID; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_terminal_manifest_set_ID failed (%i)\n", + retval); + } + return retval; +} + +ia_css_terminal_ID_t ia_css_terminal_manifest_get_ID( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_terminal_ID_t retval; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_get_ID(): enter:\n"); + + if (manifest != NULL) { + retval = manifest->ID; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_terminal_manifest_get_ID failed\n"); + retval = IA_CSS_TERMINAL_INVALID_ID; + } + return retval; +} + +ia_css_program_group_manifest_t *ia_css_terminal_manifest_get_parent( + const ia_css_terminal_manifest_t *manifest) +{ + ia_css_program_group_manifest_t *parent = NULL; + char *base; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_get_parent(): enter:\n"); + + verifexit(manifest != NULL); + + base = (char *)((char *)manifest + manifest->parent_offset); + + parent = (ia_css_program_group_manifest_t *)(base); +EXIT: + return parent; +} + +int ia_css_terminal_manifest_set_parent_offset( + ia_css_terminal_manifest_t *manifest, + int32_t terminal_offset) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_terminal_manifest_set_parent_offset(): enter:\n"); + + verifexit(manifest != NULL); + + /* parent is at negative offset away from current terminal offset*/ + manifest->parent_offset = -terminal_offset; + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_terminal_manifest_set_parent_offset failed (%i)\n", + retval); + } + return retval; +} + +ia_css_frame_format_bitmap_t +ia_css_data_terminal_manifest_get_frame_format_bitmap( + const ia_css_data_terminal_manifest_t *manifest) +{ + ia_css_frame_format_bitmap_t bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_frame_format_bitmap(): enter:\n"); + + if (manifest != NULL) { + bitmap = manifest->frame_format_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_data_terminal_manifest_get_frame_format_bitmap invalid argument\n"); + } + return bitmap; +} + +int ia_css_data_terminal_manifest_set_frame_format_bitmap( + ia_css_data_terminal_manifest_t *manifest, + ia_css_frame_format_bitmap_t bitmap) +{ + int ret = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_frame_format_bitmap(): enter:\n"); + + if (manifest != NULL) { + manifest->frame_format_bitmap = bitmap; + ret = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_frame_format_bitmap failed (%i)\n", + ret); + } + + return ret; +} + +bool ia_css_data_terminal_manifest_can_support_compression( + const ia_css_data_terminal_manifest_t *manifest) +{ + bool compression_support = false; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_compression_support(): enter:\n"); + + if (manifest != NULL) { + /* compression_support is used boolean encoded in uint8_t. + * So we only need to check + * if this is non-zero + */ + compression_support = (manifest->compression_support != 0); + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_can_support_compression invalid argument\n"); + } + + return compression_support; +} + +int ia_css_data_terminal_manifest_set_compression_support( + ia_css_data_terminal_manifest_t *manifest, + bool compression_support) +{ + int ret = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_compression_support(): enter:\n"); + + if (manifest != NULL) { + manifest->compression_support = + (compression_support == true) ? 1 : 0; + ret = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_compression_support failed (%i)\n", + ret); + } + + return ret; +} + +ia_css_connection_bitmap_t ia_css_data_terminal_manifest_get_connection_bitmap( + const ia_css_data_terminal_manifest_t *manifest) +{ + ia_css_connection_bitmap_t connection_bitmap = 0; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_connection_bitmap(): enter:\n"); + + if (manifest != NULL) { + connection_bitmap = manifest->connection_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_data_terminal_manifest_get_connection_bitmap invalid argument\n"); + } + return connection_bitmap; +} + +int ia_css_data_terminal_manifest_set_connection_bitmap( + ia_css_data_terminal_manifest_t *manifest, ia_css_connection_bitmap_t bitmap) +{ + int ret = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_connection_bitmap(): enter:\n"); + + if (manifest != NULL) { + assert(bitmap != 0); /* zero means there is no connection, this is invalid. */ + assert((bitmap >> IA_CSS_N_CONNECTION_TYPES) == 0); + + manifest->connection_bitmap = bitmap; + ret = 0; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_data_terminal_manifest_set_connection_bitmap invalid argument\n"); + } + return ret; +} + +/* We need to refactor those files in order to build in the firmware only + what is needed, switches are put current to workaround compilation problems + in the firmware (for example lack of uint64_t support) + supported in the firmware + */ +#if !defined(__HIVECC) +ia_css_kernel_bitmap_t ia_css_data_terminal_manifest_get_kernel_bitmap( + const ia_css_data_terminal_manifest_t *manifest) +{ + ia_css_kernel_bitmap_t kernel_bitmap = ia_css_kernel_bitmap_clear(); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + kernel_bitmap = manifest->kernel_bitmap; + } else { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "ia_css_data_terminal_manifest_get_kernel_bitmap: invalid argument\n"); + } + return kernel_bitmap; +} + +int ia_css_data_terminal_manifest_set_kernel_bitmap( + ia_css_data_terminal_manifest_t *manifest, + const ia_css_kernel_bitmap_t kernel_bitmap) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_kernel_bitmap(): enter:\n"); + + if (manifest != NULL) { + manifest->kernel_bitmap = kernel_bitmap; + retval = 0; + } else { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_kernel_bitmap: failed (%i)\n", + retval); + } + + return retval; +} + +int ia_css_data_terminal_manifest_set_kernel_bitmap_unique( + ia_css_data_terminal_manifest_t *manifest, + const unsigned int index) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_kernel_bitmap_unique(): enter:\n"); + + if (manifest != NULL) { + ia_css_kernel_bitmap_t kernel_bitmap = + ia_css_kernel_bitmap_clear(); + + kernel_bitmap = ia_css_kernel_bitmap_set(kernel_bitmap, index); + verifexit(!ia_css_is_kernel_bitmap_empty(kernel_bitmap)); + verifexit(ia_css_data_terminal_manifest_set_kernel_bitmap( + manifest, kernel_bitmap) == 0); + retval = 0; + } + +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_kernel_bitmap_unique failed (%i)\n", + retval); + } + return retval; +} +#endif + +int ia_css_data_terminal_manifest_set_min_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t min_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_min_size(): enter:\n"); + + verifexit(manifest != NULL); + + manifest->min_size[IA_CSS_COL_DIMENSION] = + min_size[IA_CSS_COL_DIMENSION]; + manifest->min_size[IA_CSS_ROW_DIMENSION] = + min_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_min_size: invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_set_max_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t max_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_max_size(): enter:\n"); + + verifexit(manifest != NULL); + + manifest->max_size[IA_CSS_COL_DIMENSION] = + max_size[IA_CSS_COL_DIMENSION]; + manifest->max_size[IA_CSS_ROW_DIMENSION] = + max_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_max_size: invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_get_min_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t min_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_min_size(): enter:\n"); + + verifexit(manifest != NULL); + + min_size[IA_CSS_COL_DIMENSION] = + manifest->min_size[IA_CSS_COL_DIMENSION]; + min_size[IA_CSS_ROW_DIMENSION] = + manifest->min_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_get_min_size: invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_get_max_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t max_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_max_size(): enter:\n"); + + verifexit(manifest != NULL); + + max_size[IA_CSS_COL_DIMENSION] = + manifest->max_size[IA_CSS_COL_DIMENSION]; + max_size[IA_CSS_ROW_DIMENSION] = + manifest->max_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_get_max_size: invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_set_min_fragment_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t min_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_min_fragment_size(): enter:\n"); + + verifexit(manifest != NULL); + + manifest->min_fragment_size[IA_CSS_COL_DIMENSION] = + min_size[IA_CSS_COL_DIMENSION]; + manifest->min_fragment_size[IA_CSS_ROW_DIMENSION] = + min_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_min_fragment_size invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_set_max_fragment_size( + ia_css_data_terminal_manifest_t *manifest, + const uint16_t max_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_set_max_fragment_size(): enter:\n"); + + verifexit(manifest != NULL); + + manifest->max_fragment_size[IA_CSS_COL_DIMENSION] = + max_size[IA_CSS_COL_DIMENSION]; + manifest->max_fragment_size[IA_CSS_ROW_DIMENSION] = + max_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_set_max_fragment_size invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_get_min_fragment_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t min_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_min_fragment_size(): enter:\n"); + + verifexit(manifest != NULL); + + min_size[IA_CSS_COL_DIMENSION] = + manifest->min_fragment_size[IA_CSS_COL_DIMENSION]; + min_size[IA_CSS_ROW_DIMENSION] = + manifest->min_fragment_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_get_min_fragment_size invalid argument\n"); + } + return retval; +} + +int ia_css_data_terminal_manifest_get_max_fragment_size( + const ia_css_data_terminal_manifest_t *manifest, + uint16_t max_size[IA_CSS_N_DATA_DIMENSION]) +{ + int retval = -1; + + IA_CSS_TRACE_0(PSYSAPI_STATIC, VERBOSE, + "ia_css_data_terminal_manifest_get_max_fragment_size(): enter:\n"); + + verifexit(manifest != NULL); + + max_size[IA_CSS_COL_DIMENSION] = + manifest->max_fragment_size[IA_CSS_COL_DIMENSION]; + max_size[IA_CSS_ROW_DIMENSION] = + manifest->max_fragment_size[IA_CSS_ROW_DIMENSION]; + retval = 0; + +EXIT: + if (manifest == NULL) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, ERROR, + "ia_css_data_terminal_manifest_get_max_fragment_size invalid argument\n"); + } + return retval; +} + +/* We need to refactor those files in order to build in the firmware only + what is needed, switches are put current to workaround compilation problems + in the firmware (for example lack of uint64_t support) + supported in the firmware + */ +#if !defined(__HIVECC) + +#define PRINT_DIMENSION(name, var) IA_CSS_TRACE_3(PSYSAPI_STATIC, \ + INFO, "%s:\t%d %d\n", \ + (name), \ + (var)[IA_CSS_COL_DIMENSION], \ + (var)[IA_CSS_ROW_DIMENSION]) + +int ia_css_terminal_manifest_print( + const ia_css_terminal_manifest_t *manifest, + void *fid) +{ + int retval = -1; + ia_css_terminal_type_t terminal_type = + ia_css_terminal_manifest_get_type(manifest); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, + "ia_css_terminal_manifest_print(): enter:\n"); + + verifexit(manifest != NULL); + NOT_USED(fid); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "sizeof(manifest) = %d\n", + (int)ia_css_terminal_manifest_get_size(manifest)); + + PRINT("typeof(manifest) = %s\n", terminal_type_strings[terminal_type]); + + if (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT) { + ia_css_param_terminal_manifest_t *pterminal_manifest = + (ia_css_param_terminal_manifest_t *)manifest; + uint16_t section_count = + pterminal_manifest->param_manifest_section_desc_count; + int i; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "sections(manifest) = %d\n", (int)section_count); + for (i = 0; i < section_count; i++) { + const ia_css_param_manifest_section_desc_t *manifest = + ia_css_param_terminal_manifest_get_prm_sct_desc( + pterminal_manifest, i); + verifjmpexit(manifest != NULL); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "kernel_id = %d\n", (int)manifest->kernel_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "mem_type_id = %d\n", + (int)manifest->mem_type_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "max_mem_size = %d\n", + (int)manifest->max_mem_size); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "region_id = %d\n", + (int)manifest->region_id); + } + } else if (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT) { + ia_css_sliced_param_terminal_manifest_t + *sliced_terminal_manifest = + (ia_css_sliced_param_terminal_manifest_t *)manifest; + uint32_t kernel_id; + uint16_t section_count; + uint16_t section_idx; + + kernel_id = sliced_terminal_manifest->kernel_id; + section_count = + sliced_terminal_manifest->sliced_param_section_count; + + NOT_USED(kernel_id); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "kernel_id = %d\n", (int)kernel_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "section_count = %d\n", (int)section_count); + + for (section_idx = 0; section_idx < section_count; + section_idx++) { + ia_css_sliced_param_manifest_section_desc_t + *sliced_param_manifest_section_desc; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "section %d\n", (int)section_idx); + sliced_param_manifest_section_desc = + ia_css_sliced_param_terminal_manifest_get_sliced_prm_sct_desc( + sliced_terminal_manifest, section_idx); + verifjmpexit(sliced_param_manifest_section_desc != + NULL); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "mem_type_id = %d\n", + (int)sliced_param_manifest_section_desc->mem_type_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "region_id = %d\n", + (int)sliced_param_manifest_section_desc->region_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "max_mem_size = %d\n", + (int)sliced_param_manifest_section_desc->max_mem_size); + } + } else if (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM) { + ia_css_program_terminal_manifest_t *program_terminal_manifest = + (ia_css_program_terminal_manifest_t *)manifest; + uint32_t sequencer_info_kernel_id; + uint16_t max_kernel_fragment_sequencer_command_desc; + uint16_t kernel_fragment_sequencer_info_manifest_info_count; + uint16_t seq_info_idx; + + sequencer_info_kernel_id = + program_terminal_manifest->sequencer_info_kernel_id; + max_kernel_fragment_sequencer_command_desc = + program_terminal_manifest-> + max_kernel_fragment_sequencer_command_desc; + kernel_fragment_sequencer_info_manifest_info_count = + program_terminal_manifest-> + kernel_fragment_sequencer_info_manifest_info_count; + + NOT_USED(sequencer_info_kernel_id); + NOT_USED(max_kernel_fragment_sequencer_command_desc); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "sequencer_info_kernel_id = %d\n", + (int)sequencer_info_kernel_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "max_kernel_fragment_sequencer_command_desc = %d\n", + (int)max_kernel_fragment_sequencer_command_desc); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "kernel_fragment_sequencer_info_manifest_info_count = %d\n", + (int) + kernel_fragment_sequencer_info_manifest_info_count); + + for (seq_info_idx = 0; seq_info_idx < + kernel_fragment_sequencer_info_manifest_info_count; + seq_info_idx++) { + ia_css_kernel_fragment_sequencer_info_manifest_desc_t + *sequencer_info_manifest_desc; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "sequencer info %d\n", (int)seq_info_idx); + sequencer_info_manifest_desc = + ia_css_program_terminal_manifest_get_kernel_frgmnt_seq_info_desc + (program_terminal_manifest, seq_info_idx); + verifjmpexit(sequencer_info_manifest_desc != NULL); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "min_fragment_grid_slice_dimension[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + min_fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + min_fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "max_fragment_grid_slice_dimension[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + max_fragment_grid_slice_dimension[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + max_fragment_grid_slice_dimension[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "min_fragment_grid_slice_count[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + min_fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + min_fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "max_fragment_grid_slice_count[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + max_fragment_grid_slice_count[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + max_fragment_grid_slice_count[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "min_fragment_grid_point_decimation_factor[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + min_fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + min_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "max_fragment_grid_point_decimation_factor[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + max_fragment_grid_point_decimation_factor[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + max_fragment_grid_point_decimation_factor[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "min_fragment_grid_overlay_on_pixel_topleft_index[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + min_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "max_fragment_grid_overlay_on_pixel_topleft_index[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + max_fragment_grid_overlay_pixel_topleft_index[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "min_fragment_grid_overlay_on_pixel_dimension[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + min_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + IA_CSS_TRACE_2(PSYSAPI_STATIC, INFO, + "max_fragment_grid_overlay_on_pixel_dimension[] = {%d, %d}\n", + (int)sequencer_info_manifest_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_COL_DIMENSION], + (int)sequencer_info_manifest_desc-> + max_fragment_grid_overlay_pixel_dimension[ + IA_CSS_ROW_DIMENSION]); + } + } else if (terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT) { + ia_css_program_control_init_terminal_manifest_t *progctrlinit_man = + (ia_css_program_control_init_terminal_manifest_t *)manifest; + ia_css_program_control_init_terminal_manifest_print(progctrlinit_man); + } else if (terminal_type == IA_CSS_TERMINAL_TYPE_DATA_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_DATA_OUT) { + + ia_css_data_terminal_manifest_t *dterminal_manifest = + (ia_css_data_terminal_manifest_t *)manifest; + int i; + + NOT_USED(dterminal_manifest); + + verifexit(ia_css_kernel_bitmap_print( + ia_css_data_terminal_manifest_get_kernel_bitmap( + dterminal_manifest), fid) == 0); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "formats(manifest) = %04x\n", + (int)ia_css_data_terminal_manifest_get_frame_format_bitmap( + dterminal_manifest)); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "connection(manifest) = %04x\n", + (int)ia_css_data_terminal_manifest_get_connection_bitmap( + dterminal_manifest)); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "dependent(manifest) = %d\n", + (int)dterminal_manifest->terminal_dependency); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\tmin_size[%d] = {\n", + IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d,\n", dterminal_manifest->min_size[i]); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d }\n", dterminal_manifest->min_size[i]); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\tmax_size[%d] = {\n", IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d,\n", dterminal_manifest->max_size[i]); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d }\n", dterminal_manifest->max_size[i]); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\tmin_fragment_size[%d] = {\n", + IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d,\n", + dterminal_manifest->min_fragment_size[i]); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d }\n", + dterminal_manifest->min_fragment_size[i]); + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\tmax_fragment_size[%d] = {\n", + IA_CSS_N_DATA_DIMENSION); + for (i = 0; i < (int)IA_CSS_N_DATA_DIMENSION - 1; i++) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d,\n", + dterminal_manifest->max_fragment_size[i]); + } + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, + "\t\t%4d }\n", + dterminal_manifest->max_fragment_size[i]); + + } else if (terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN || + terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT) { + + ia_css_spatial_param_terminal_manifest_t *stm = + (ia_css_spatial_param_terminal_manifest_t *)manifest; + ia_css_frame_grid_param_manifest_section_desc_t *sec; + int sec_count = + stm->frame_grid_param_manifest_section_desc_count; + ia_css_fragment_grid_manifest_desc_t *fragd = + &stm->common_fragment_grid_desc; + ia_css_frame_grid_manifest_desc_t *framed = + &stm->frame_grid_desc; + int sec_index; + + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "kernel_id:\t\t%d\n", + stm->kernel_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "compute_units_p_elem:\t%d\n", + stm->compute_units_p_elem); + + PRINT_DIMENSION("min_fragment_grid_dimension", + fragd->min_fragment_grid_dimension); + PRINT_DIMENSION("max_fragment_grid_dimension", + fragd->max_fragment_grid_dimension); + PRINT_DIMENSION("min_frame_grid_dimension", + framed->min_frame_grid_dimension); + PRINT_DIMENSION("max_frame_grid_dimension", + framed->max_frame_grid_dimension); + + NOT_USED(framed); + NOT_USED(fragd); + + for (sec_index = 0; sec_index < sec_count; sec_index++) { + sec = ia_css_spatial_param_terminal_manifest_get_frm_grid_prm_sct_desc( + stm, sec_index); + verifjmpexit(sec != NULL); + + IA_CSS_TRACE_0(PSYSAPI_STATIC, INFO, "--------------------------\n"); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\tmem_type_id:\t%d\n", + sec->mem_type_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\tregion_id:\t%d\n", + sec->region_id); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\telem_size:\t%d\n", + sec->elem_size); + IA_CSS_TRACE_1(PSYSAPI_STATIC, INFO, "\tmax_mem_size:\t%d\n", + sec->max_mem_size); + } + } else if (terminal_type < IA_CSS_N_TERMINAL_TYPES) { + IA_CSS_TRACE_0(PSYSAPI_STATIC, WARNING, + "terminal type can not be pretty printed, not supported\n"); + } + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_1(PSYSAPI_STATIC, ERROR, + "ia_css_terminal_manifest_print failed (%i)\n", + retval); + } + return retval; +} + +/* Program control init Terminal */ +unsigned int ia_css_program_control_init_terminal_manifest_get_connect_section_count( + const ia_css_program_control_init_manifest_program_desc_t *prog) +{ + assert(prog); + return prog->connect_section_count; +} + + +unsigned int ia_css_program_control_init_terminal_manifest_get_load_section_count( + const ia_css_program_control_init_manifest_program_desc_t *prog) +{ + assert(prog); + return prog->load_section_count; +} + +unsigned int ia_css_program_control_init_terminal_manifest_get_size( + const uint16_t nof_programs, + const uint16_t *nof_load_sections, + const uint16_t *nof_connect_sections) +{ + (void)nof_load_sections; /* might be needed in future */ + (void)nof_connect_sections; /* might be needed in future */ + + return sizeof(ia_css_program_control_init_terminal_manifest_t) + + nof_programs * + sizeof(ia_css_program_control_init_manifest_program_desc_t); +} + +ia_css_program_control_init_manifest_program_desc_t * +ia_css_program_control_init_terminal_manifest_get_program_desc( + const ia_css_program_control_init_terminal_manifest_t *terminal, + unsigned int program) +{ + ia_css_program_control_init_manifest_program_desc_t *progs; + + assert(terminal != NULL); + assert(program < terminal->program_count); + + progs = (ia_css_program_control_init_manifest_program_desc_t *) + ((const char *)terminal + terminal->program_desc_offset); + + return &progs[program]; +} + +int ia_css_program_control_init_terminal_manifest_init( + ia_css_program_control_init_terminal_manifest_t *terminal, + const uint16_t nof_programs, + const uint16_t *nof_load_sections, + const uint16_t *nof_connect_sections) +{ + unsigned int i; + ia_css_program_control_init_manifest_program_desc_t *progs; + + if (terminal == NULL) { + return -EFAULT; + } + + terminal->program_count = nof_programs; + terminal->program_desc_offset = + sizeof(ia_css_program_control_init_terminal_manifest_t); + + progs = ia_css_program_control_init_terminal_manifest_get_program_desc( + terminal, 0); + + for (i = 0; i < nof_programs; i++) { + progs[i].load_section_count = nof_load_sections[i]; + progs[i].connect_section_count = nof_connect_sections[i]; + } + return 0; +} + +void ia_css_program_control_init_terminal_manifest_print( + ia_css_program_control_init_terminal_manifest_t *terminal) +{ + unsigned int i; + + ia_css_program_control_init_manifest_program_desc_t *progs; + + progs = ia_css_program_control_init_terminal_manifest_get_program_desc( + terminal, 0); + + assert(progs); + (void)progs; + + for (i = 0; i < terminal->program_count; i++) { + IA_CSS_TRACE_3(PSYSAPI_STATIC, INFO, + "program index: %d, load sec: %d, connect sec: %d\n", + i, + progs[i].load_section_count, + progs[i].connect_section_count); + } +} + +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/reg_dump/src/psys/cnlB0_gen_reg_dump/ia_css_debug_dump.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/reg_dump/src/psys/cnlB0_gen_reg_dump/ia_css_debug_dump.c new file mode 100644 index 0000000000000..c51d65c8cb647 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/reg_dump/src/psys/cnlB0_gen_reg_dump/ia_css_debug_dump.c @@ -0,0 +1,15 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#include "ia_css_debug_dump.h" + void ia_css_debug_dump(void) {} \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/reg_dump/src/psys/cnlB0_gen_reg_dump/ia_css_debug_dump.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/reg_dump/src/psys/cnlB0_gen_reg_dump/ia_css_debug_dump.h new file mode 100644 index 0000000000000..5dd23ddbd180b --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/reg_dump/src/psys/cnlB0_gen_reg_dump/ia_css_debug_dump.h @@ -0,0 +1,17 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. +* Copyright (c) 2010 - 2018, Intel Corporation. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +*/ +#ifndef __IA_CSS_DEBUG_DUMP_H_ + #define __IA_CSS_DEBUG_DUMP_H_ + void ia_css_debug_dump(void); + #endif /* __IA_CSS_DEBUG_DUMP_H_ */ \ No newline at end of file diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/reg_dump/src/reg_dump_generic_bridge.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/reg_dump/src/reg_dump_generic_bridge.c new file mode 100644 index 0000000000000..9b9161ae78cf2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/reg_dump/src/reg_dump_generic_bridge.c @@ -0,0 +1,39 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include +#include "ia_css_trace.h" +#ifdef USE_LOGICAL_SSIDS +/* + Logical names can be used to define the SSID + In order to resolve these names the following include file should be provided + and the define above should be enabled +*/ +#include +#endif + +#define REG_DUMP_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#define REG_DUMP_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED + +/* SSID value is defined in test makefiles as either isys0 or psys0 */ +#define REG_DUMP_READ_REGISTER(addr) vied_subsystem_load_32(SSID, addr) + +#define REG_DUMP_PRINT_0(...) \ +EXPAND_VA_ARGS(IA_CSS_TRACE_0(REG_DUMP, VERBOSE, __VA_ARGS__)) +#define REG_DUMP_PRINT_1(...) \ +EXPAND_VA_ARGS(IA_CSS_TRACE_1(REG_DUMP, VERBOSE, __VA_ARGS__)) +#define EXPAND_VA_ARGS(x) x + +/* Including generated source code for reg_dump */ +#include "ia_css_debug_dump.c" diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/interface/regmem_access.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/interface/regmem_access.h new file mode 100644 index 0000000000000..d4576af936f6d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/interface/regmem_access.h @@ -0,0 +1,67 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_ACCESS_H +#define __REGMEM_ACCESS_H + +#include "storage_class.h" + +enum regmem_id { + /* pass pkg_dir address to SPC in non-secure mode */ + PKG_DIR_ADDR_REG = 0, + /* pass syscom configuration to SPC */ + SYSCOM_CONFIG_REG = 1, + /* syscom state - modified by SP */ + SYSCOM_STATE_REG = 2, + /* syscom commands - modified by the host */ + SYSCOM_COMMAND_REG = 3, + /* Store interrupt status - updated by SP */ + SYSCOM_IRQ_REG = 4, + /* Store VTL0_ADDR_MASK in trusted secure regision - provided by host.*/ + SYSCOM_VTL0_ADDR_MASK = 5, +#if HAS_DUAL_CMD_CTX_SUPPORT + /* Initialized if trustlet exists - updated by host */ + TRUSTLET_STATUS = 6, + /* identify if SPC access blocker programming is completed - updated by SP */ + AB_SPC_STATUS = 7, + /* first syscom queue pointer register */ + SYSCOM_QPR_BASE_REG = 8 +#else + /* first syscom queue pointer register */ + SYSCOM_QPR_BASE_REG = 6 +#endif +}; + +#if HAS_DUAL_CMD_CTX_SUPPORT +/* Bit 0: for untrusted non-secure DRV driver on VTL0 + * Bit 1: for trusted secure TEE driver on VTL1 + */ +#define SYSCOM_IRQ_VTL0_MASK 0x1 +#define SYSCOM_IRQ_VTL1_MASK 0x2 +#endif + +STORAGE_CLASS_INLINE unsigned int +regmem_load_32(unsigned int mem_address, unsigned int reg, unsigned int ssid); + +STORAGE_CLASS_INLINE void +regmem_store_32(unsigned int mem_address, unsigned int reg, unsigned int value, + unsigned int ssid); + +#ifdef __VIED_CELL +#include "regmem_access_cell.h" +#else +#include "regmem_access_host.h" +#endif + +#endif /* __REGMEM_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/regmem.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/regmem.mk new file mode 100644 index 0000000000000..24ebc1c325d8e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/regmem.mk @@ -0,0 +1,32 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +ifndef REGMEM_MK +REGMEM_MK=1 + +# MODULE is REGMEM + +REGMEM_DIR=$${MODULES_DIR}/regmem + +REGMEM_INTERFACE=$(REGMEM_DIR)/interface +REGMEM_SOURCES=$(REGMEM_DIR)/src + +REGMEM_HOST_FILES = +REGMEM_FW_FILES = $(REGMEM_SOURCES)/regmem.c + +REGMEM_CPPFLAGS = -I$(REGMEM_INTERFACE) -I$(REGMEM_SOURCES) +REGMEM_HOST_CPPFLAGS = $(REGMEM_CPPFLAGS) +REGMEM_FW_CPPFLAGS = $(REGMEM_CPPFLAGS) + +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/src/regmem_access_host.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/src/regmem_access_host.h new file mode 100644 index 0000000000000..8878d7074fabb --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/src/regmem_access_host.h @@ -0,0 +1,41 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_ACCESS_HOST_H +#define __REGMEM_ACCESS_HOST_H + +#include "regmem_access.h" /* implemented interface */ + +#include "storage_class.h" +#include "regmem_const.h" +#include +#include "ia_css_cmem.h" + +STORAGE_CLASS_INLINE unsigned int +regmem_load_32(unsigned int mem_addr, unsigned int reg, unsigned int ssid) +{ + /* No need to add REGMEM_OFFSET, it is already included in mem_addr. */ + return ia_css_cmem_load_32(ssid, mem_addr + (REGMEM_WORD_BYTES*reg)); +} + +STORAGE_CLASS_INLINE void +regmem_store_32(unsigned int mem_addr, unsigned int reg, + unsigned int value, unsigned int ssid) +{ + /* No need to add REGMEM_OFFSET, it is already included in mem_addr. */ + ia_css_cmem_store_32(ssid, mem_addr + (REGMEM_WORD_BYTES*reg), + value); +} + +#endif /* __REGMEM_ACCESS_HOST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/src/regmem_const.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/src/regmem_const.h new file mode 100644 index 0000000000000..ac7e3a98a434f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/regmem/src/regmem_const.h @@ -0,0 +1,28 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __REGMEM_CONST_H +#define __REGMEM_CONST_H + +#ifndef REGMEM_SIZE +#define REGMEM_SIZE (16) +#endif /* REGMEM_SIZE */ +#ifndef REGMEM_OFFSET +#define REGMEM_OFFSET (0) +#endif /* REGMEM_OFFSET */ +#ifndef REGMEM_WORD_BYTES +#define REGMEM_WORD_BYTES (4) +#endif + +#endif /* __REGMEM_CONST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm.h new file mode 100644 index 0000000000000..4a04a98903264 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm.h @@ -0,0 +1,173 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_H +#define __IA_CSS_RBM_H + +#include "ia_css_rbm_storage_class.h" +#include + +#define IA_CSS_RBM_BITS 64 +/** An element is a 32 bit unsigned integer. 64 bit integers might cause + * problems in the compiler. + */ +#define IA_CSS_RBM_ELEM_TYPE uint32_t +#define IA_CSS_RBM_ELEM_BITS \ + (sizeof(IA_CSS_RBM_ELEM_TYPE)*8) +#define IA_CSS_RBM_NOF_ELEMS \ + ((IA_CSS_RBM_BITS) / (IA_CSS_RBM_ELEM_BITS)) + +/** Users should make no assumption about the actual type of + * ia_css_rbm_t. + */ +typedef struct { + IA_CSS_RBM_ELEM_TYPE data[IA_CSS_RBM_NOF_ELEMS]; +} ia_css_rbm_elems_t; +typedef ia_css_rbm_elems_t ia_css_rbm_t; + +/** Print the bits of a routing bitmap + * @return < 0 on error + */ +IA_CSS_RBM_STORAGE_CLASS_H +int ia_css_rbm_print( + const ia_css_rbm_t bitmap, + void *fid); + +/** Create an empty routing bitmap + * @return bitmap = 0 + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_clear(void); + +/** Creates the complement of a routing bitmap + * @param bitmap[in] routing bitmap + * @return ~bitmap + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_complement( + const ia_css_rbm_t bitmap); + +/** Create the union of two routing bitmaps + * @param bitmap0[in] routing bitmap 0 + * @param bitmap1[in] routing bitmap 1 + * @return bitmap0 | bitmap1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_union( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1); + +/** Create the intersection of two routing bitmaps + * @param bitmap0[in] routing bitmap 0 + * @param bitmap1[in] routing bitmap 1 + * @return bitmap0 & bitmap1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_intersection( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1); + +/** Check if the routing bitmaps is empty + * @param bitmap[in] routing bitmap + * @return bitmap == 0 + */ +IA_CSS_RBM_STORAGE_CLASS_H +bool ia_css_is_rbm_empty( + const ia_css_rbm_t bitmap); + +/** Check if the intersection of two routing bitmaps is empty + * @param bitmap0[in] routing bitmap 0 + * @param bitmap1[in] routing bitmap 1 + * @return (bitmap0 & bitmap1) == 0 + */ +IA_CSS_RBM_STORAGE_CLASS_H +bool ia_css_is_rbm_intersection_empty( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1); + +/** Check if the second routing bitmap is a subset of the first (or equal) + * @param bitmap0[in] routing bitmap 0 + * @param bitmap1[in routing bitmap 1 + * Note: An empty set is always a subset, this function + * returns true if bitmap 1 is empty + * @return (bitmap0 & bitmap1) == bitmap1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +bool ia_css_is_rbm_subset( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1); + +/** Check if the routing bitmaps are equal + * @param bitmap0[in] routing bitmap 0 + * @param bitmap1[in] routing bitmap 1 + * @return bitmap0 == bitmap1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +bool ia_css_is_rbm_equal( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1); + +/** Checks whether a specific kernel bit is set + * @return bitmap[index] == 1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +int ia_css_is_rbm_set( + const ia_css_rbm_t bitmap, + const unsigned int index); + +/** Create the union of a routing bitmap with a onehot bitmap + * with a bit set at index + * @return bitmap[index] |= 1 +*/ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_set( + const ia_css_rbm_t bitmap, + const unsigned int index); + +/** Creates routing bitmap using a uint64 value. + * @return bitmap with the same bits set as in value (provided that width of bitmap is sufficient). + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_create_from_uint64( + const uint64_t value); + +/** Converts an ia_css_rbm_t type to uint64_t. Note that if + * ia_css_rbm_t contains more then 64 bits, only the lowest 64 bits + * are returned. + * @return uint64_t representation of value + */ +IA_CSS_RBM_STORAGE_CLASS_H +uint64_t ia_css_rbm_to_uint64( + const ia_css_rbm_t value); + +/** Creates a routing bitmap with the bit at index 'index' removed. + * @return ~(1 << index) & bitmap + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_unset( + const ia_css_rbm_t bitmap, + const unsigned int index); + +/** Create a onehot routing bitmap with a bit set at index + * @return bitmap[index] = 1 + */ +IA_CSS_RBM_STORAGE_CLASS_H +ia_css_rbm_t ia_css_rbm_bit_mask( + const unsigned int index); + +#ifdef __IA_CSS_RBM_INLINE__ +#include "ia_css_rbm_impl.h" +#endif /* __IA_CSS_RBM_INLINE__ */ + +#endif /* __IA_CSS_RBM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest.h new file mode 100644 index 0000000000000..f497a7de90a93 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest.h @@ -0,0 +1,133 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_MANIFEST_H +#define __IA_CSS_RBM_MANIFEST_H + +#include "type_support.h" +#include "ia_css_rbm_manifest_types.h" + +/** Returns the descriptor size of the RBM manifest. + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +unsigned int +ia_css_rbm_manifest_get_size(void); + +/** Initializes the RBM manifest. + * @param rbm[in] Routing bitmap. + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +void +ia_css_rbm_manifest_init(struct ia_css_rbm_manifest_s *rbm); + +/** Returns a pointer to the array of mux descriptors. + * @param manifest[in] Routing bitmap manifest. + * @return NULL on error + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +ia_css_rbm_mux_desc_t * +ia_css_rbm_manifest_get_muxes(const ia_css_rbm_manifest_t *manifest); + +/** Returns the size of mux descriptors array. + * @param manifest[in] Routing bitmap manifest. + * @return size + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +unsigned int +ia_css_rbm_manifest_get_mux_count(const ia_css_rbm_manifest_t *manifest); + +/** Returns a pointer to the array of validation descriptors. + * @param manifest[in] Routing bitmap manifest. + * @return NULL on error + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +ia_css_rbm_validation_rule_t * +ia_css_rbm_manifest_get_validation_rules(const ia_css_rbm_manifest_t *manifest); + +/** Returns the size of the validation descriptor array. + * @param manifest[in] Routing bitmap manifest. + * @return size + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +unsigned int +ia_css_rbm_manifest_get_validation_rule_count(const ia_css_rbm_manifest_t *manifest); + +/** Returns a pointer to the array of terminal routing descriptors. + * @param manifest[in] Routing bitmap manifest. + * @return NULL on error + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +ia_css_rbm_terminal_routing_desc_t * +ia_css_rbm_manifest_get_terminal_routing_desc(const ia_css_rbm_manifest_t *manifest); + +/** \brief Returns the size of the terminal routing descriptor array. + * Note: pretty printing differs from on host and on IPU. + * @param manifest[in] Routing bitmap manifest. + * @return size + */ +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H +unsigned int +ia_css_rbm_manifest_get_terminal_routing_desc_count(const ia_css_rbm_manifest_t *manifest); + +/** Pretty prints the routing bitmap manifest. + * @param manifest[in] Routing bitmap manifest. + */ +void +ia_css_rbm_manifest_print(const ia_css_rbm_manifest_t *manifest); + +/** \brief Pretty prints a RBM (routing bitmap). + * Note: pretty printing differs from on host and on IPU. + * @param rbm[in] Routing bitmap. + * @param mux[in] List of mux descriptors corresponding to rbm. + * @param mux_desc_count[in] Number of muxes in list mux. + */ +void +ia_css_rbm_pretty_print( + const ia_css_rbm_t *rbm, + const ia_css_rbm_mux_desc_t *mux, + unsigned int mux_desc_count); + +/** \brief check for the validity of a routing bitmap. + * @param manifest[in] Routing bitmap manifest. + * @param rbm[in] Routing bitmap + * @return true on match. + */ +bool +ia_css_rbm_manifest_check_rbm_validity( + const ia_css_rbm_manifest_t *manifest, + const ia_css_rbm_t *rbm); + +/** \brief sets, using manifest info, the value of a mux in the routing bitmap. + * @param rbm[in] Routing bitmap. + * @param mux[in] List of mux descriptors corresponding to rbm. + * @param mux_count[in] Number of muxes in list mux. + * @param gp_dev_id[in] ID of sub system (PSA/ISA) where the mux is located. + * @param mux_id[in] ID of mux to set configuration for. + * @param value[in] Value of the mux. + * @return routing bitmap. + */ +ia_css_rbm_t +ia_css_rbm_set_mux( + ia_css_rbm_t rbm, + ia_css_rbm_mux_desc_t *mux, + unsigned int mux_count, + unsigned int gp_dev_id, + unsigned int mux_id, + unsigned int value); + +#ifdef __IA_CSS_RBM_MANIFEST_INLINE__ +#include "ia_css_rbm_manifest_impl.h" +#endif /* __IA_CSS_RBM_MANIFEST_INLINE__ */ + +#endif /* __IA_CSS_RBM_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest_types.h new file mode 100644 index 0000000000000..ade20446b9f64 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_manifest_types.h @@ -0,0 +1,95 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_MANIFEST_TYPES_H +#define __IA_CSS_RBM_MANIFEST_TYPES_H + +#include "ia_css_rbm.h" +#include "vied_nci_psys_resource_model.h" + +#ifndef VIED_NCI_RBM_MAX_MUX_COUNT +#error Please define VIED_NCI_RBM_MAX_MUX_COUNT +#endif +#ifndef VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT +#error Please define VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT +#endif +#ifndef VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT +#error Please define VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT +#endif +#ifndef N_PADDING_UINT8_IN_RBM_MANIFEST +#error Please define N_PADDING_UINT8_IN_RBM_MANIFEST +#endif + +#define SIZE_OF_RBM_MUX_DESC_S ( \ + (4 * IA_CSS_UINT8_T_BITS)) + +typedef struct ia_css_rbm_mux_desc_s { + uint8_t gp_dev_id; + uint8_t mux_id; + uint8_t offset; + uint8_t size_bits; +} ia_css_rbm_mux_desc_t; + +#define SIZE_OF_RBM_VALIDATION_RULE_DESC_S ( \ + (2 * IA_CSS_RBM_BITS) \ + + (1 * IA_CSS_UINT32_T_BITS)) + +typedef struct ia_css_rbm_validation_rule_s { + ia_css_rbm_t match; /* RBM is an array of 32 bit elements */ + ia_css_rbm_t mask; + uint32_t expected_value; +} ia_css_rbm_validation_rule_t; + +#define SIZE_OF_RBM_TERMINAL_ROUTING_DESC_S ( \ + (4 * IA_CSS_UINT8_T_BITS)) + +typedef struct ia_css_rbm_terminal_routing_desc_s { + uint8_t terminal_id; + uint8_t connection_state; + uint8_t mux_id; + uint8_t state; +} ia_css_rbm_terminal_routing_desc_t; + +#define SIZE_OF_RBM_MANIFEST_S ( \ + (VIED_NCI_RBM_MAX_MUX_COUNT * SIZE_OF_RBM_MUX_DESC_S) \ + + (VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT * SIZE_OF_RBM_VALIDATION_RULE_DESC_S) \ + + (VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT * SIZE_OF_RBM_TERMINAL_ROUTING_DESC_S) \ + + (3 * IA_CSS_UINT16_T_BITS) \ + + (N_PADDING_UINT8_IN_RBM_MANIFEST * IA_CSS_UINT8_T_BITS)) + +typedef struct ia_css_rbm_manifest_s { +#if VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT > 0 + ia_css_rbm_validation_rule_t + validation_rules[VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT]; +#endif + uint16_t mux_desc_count; + uint16_t validation_rule_count; + uint16_t terminal_routing_desc_count; + +#if VIED_NCI_RBM_MAX_MUX_COUNT > 0 + ia_css_rbm_mux_desc_t + mux_desc[VIED_NCI_RBM_MAX_MUX_COUNT]; +#endif + +#if VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT > 0 + ia_css_rbm_terminal_routing_desc_t + terminal_routing_desc[VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT]; +#endif + +#if N_PADDING_UINT8_IN_RBM_MANIFEST > 0 + uint8_t padding[N_PADDING_UINT8_IN_RBM_MANIFEST]; +#endif +} ia_css_rbm_manifest_t; + +#endif /* __IA_CSS_RBM_MANIFEST_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_storage_class.h new file mode 100644 index 0000000000000..9548e9a9fabbc --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_storage_class.h @@ -0,0 +1,36 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_STORAGE_CLASS_H +#define __IA_CSS_RBM_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __IA_CSS_RBM_INLINE__ +#define IA_CSS_RBM_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_RBM_STORAGE_CLASS_C +#else +#define IA_CSS_RBM_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_RBM_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#ifndef __IA_CSS_RBM_MANIFEST_INLINE__ +#define IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +#else +#define IA_CSS_RBM_MANIFEST_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_RBM_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_trace.h new file mode 100644 index 0000000000000..dd060323da5c2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/interface/ia_css_rbm_trace.h @@ -0,0 +1,77 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_TRACE_H +#define __IA_CSS_RBM_TRACE_H + +#include "ia_css_trace.h" + +/* Not using 0 to identify wrong configuration being passed from the .mk file outside. +* Log levels not in the range below will cause a "No RBM_TRACE_CONFIG Tracing level defined" +*/ +#define RBM_TRACE_LOG_LEVEL_OFF 1 +#define RBM_TRACE_LOG_LEVEL_NORMAL 2 +#define RBM_TRACE_LOG_LEVEL_DEBUG 3 + +#define RBM_TRACE_CONFIG_DEFAULT RBM_TRACE_LOG_LEVEL_NORMAL + +#if !defined(RBM_TRACE_CONFIG) +# define RBM_TRACE_CONFIG RBM_TRACE_CONFIG_DEFAULT +#endif + +/* IPU_RESOURCE Module tracing backend is mapped to TUNIT tracing for target platforms */ +#ifdef __HIVECC +# ifndef HRT_CSIM +# define RBM_TRACE_METHOD IA_CSS_TRACE_METHOD_TRACE +# else +# define RBM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +# endif +#else +# define RBM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#endif + +#if (defined(RBM_TRACE_CONFIG)) +/* Module specific trace setting */ +# if RBM_TRACE_CONFIG == RBM_TRACE_LOG_LEVEL_OFF +/* RBM_TRACE_LOG_LEVEL_OFF */ +# define RBM_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED +# elif RBM_TRACE_CONFIG == RBM_TRACE_LOG_LEVEL_NORMAL +/* RBM_TRACE_LOG_LEVEL_NORMAL */ +# define RBM_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_DISABLED +# define RBM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED +# elif RBM_TRACE_CONFIG == RBM_TRACE_LOG_LEVEL_DEBUG +/* RBM_TRACE_LOG_LEVEL_DEBUG */ +# define RBM_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_DEBUG IA_CSS_TRACE_LEVEL_ENABLED +# define RBM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED +# else +# error "No RBM_TRACE_CONFIG Tracing level defined" +# endif +#else +# error "RBM_TRACE_CONFIG not defined" +#endif + +#endif /* __RBM_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/routing_bitmap.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/routing_bitmap.mk new file mode 100644 index 0000000000000..f4251f9740fde --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/routing_bitmap.mk @@ -0,0 +1,39 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# + +ifdef _H_ROUTING_BITMAP_MK +$(error ERROR: routing_bitmap.mk included multiple times, please check makefile) +else +_H_ROUTING_BITMAP_MK=1 +endif + +ROUTING_BITMAP_FILES += $(ROUTING_BITMAP_DIR)/src/ia_css_rbm_manifest.c + +ROUTING_BITMAP_DIR = $(MODULES_DIR)/routing_bitmap +ROUTING_BITMAP_INTERFACE = $(ROUTING_BITMAP_DIR)/interface +ROUTING_BITMAP_SOURCES = $(ROUTING_BITMAP_DIR)/src + +ROUTING_BITMAP_CPPFLAGS = -I$(ROUTING_BITMAP_INTERFACE) +ROUTING_BITMAP_CPPFLAGS += -I$(ROUTING_BITMAP_SOURCES) + +ifeq ($(ROUTING_BITMAP_INLINE),1) +ROUTING_BITMAP_CPPFLAGS += -D__IA_CSS_RBM_INLINE__ +else +ROUTING_BITMAP_FILES += $(ROUTING_BITMAP_DIR)/src/ia_css_rbm.c +endif + +ifeq ($(ROUTING_BITMAP_MANIFEST_INLINE),1) +ROUTING_BITMAP_CPPFLAGS += -D__IA_CSS_RBM_MANIFEST_INLINE__ +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm.c new file mode 100644 index 0000000000000..bc5bf14efbd77 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm.c @@ -0,0 +1,17 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_RBM_INLINE__ +#include "ia_css_rbm_impl.h" +#endif /* __IA_CSS_RBM_INLINE__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_impl.h new file mode 100644 index 0000000000000..c8cd78d416a17 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_impl.h @@ -0,0 +1,338 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_rbm.h" +#include "type_support.h" +#include "misc_support.h" +#include "assert_support.h" +#include "math_support.h" +#include "ia_css_rbm_trace.h" + +STORAGE_CLASS_INLINE int ia_css_rbm_compute_weight( + const ia_css_rbm_t bitmap); + +STORAGE_CLASS_INLINE ia_css_rbm_t ia_css_rbm_shift( + const ia_css_rbm_t bitmap); + +IA_CSS_RBM_STORAGE_CLASS_C +bool ia_css_is_rbm_intersection_empty( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1) +{ + ia_css_rbm_t intersection; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_is_rbm_intersection_empty(): enter:\n"); + + intersection = ia_css_rbm_intersection(bitmap0, bitmap1); + return ia_css_is_rbm_empty(intersection); +} + +IA_CSS_RBM_STORAGE_CLASS_C +bool ia_css_is_rbm_empty( + const ia_css_rbm_t bitmap) +{ + unsigned int i; + bool is_empty = true; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_is_rbm_empty(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + is_empty &= bitmap.data[i] == 0; + } + return is_empty; +} + +IA_CSS_RBM_STORAGE_CLASS_C +bool ia_css_is_rbm_equal( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1) +{ + unsigned int i; + bool is_equal = true; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_is_rbm_equal(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + is_equal = is_equal && (bitmap0.data[i] == bitmap1.data[i]); + } + return is_equal; +} + +IA_CSS_RBM_STORAGE_CLASS_C +bool ia_css_is_rbm_subset( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1) +{ + ia_css_rbm_t intersection; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_is_rbm_subset(): enter:\n"); + + intersection = ia_css_rbm_intersection(bitmap0, bitmap1); + return ia_css_is_rbm_equal(intersection, bitmap1); +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_clear(void) +{ + unsigned int i; + ia_css_rbm_t bitmap; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_clear(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + bitmap.data[i] = 0; + } + return bitmap; +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_complement( + const ia_css_rbm_t bitmap) +{ + unsigned int i; + ia_css_rbm_t result; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_complement(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + result.data[i] = ~bitmap.data[i]; + } + return result; +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_union( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1) +{ + unsigned int i; + ia_css_rbm_t result; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_union(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + result.data[i] = (bitmap0.data[i] | bitmap1.data[i]); + } + return result; +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_intersection( + const ia_css_rbm_t bitmap0, + const ia_css_rbm_t bitmap1) +{ + unsigned int i; + ia_css_rbm_t result; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_intersection(): enter:\n"); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + result.data[i] = (bitmap0.data[i] & bitmap1.data[i]); + } + return result; +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_set( + const ia_css_rbm_t bitmap, + const unsigned int index) +{ + ia_css_rbm_t bit_mask; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_set(): enter:\n"); + + bit_mask = ia_css_rbm_bit_mask(index); + return ia_css_rbm_union(bitmap, bit_mask); +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_create_from_uint64( + const uint64_t value) +{ + unsigned int i; + ia_css_rbm_t result; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_create_from_uint64(): enter:\n"); + + result = ia_css_rbm_clear(); + for (i = 0; i < IA_CSS_RBM_NOF_ELEMS; i++) { + /* masking is done implictly, the MSB bits of casting will be chopped off */ + result.data[i] = (IA_CSS_RBM_ELEM_TYPE) + (value >> (i * IA_CSS_RBM_ELEM_BITS)); + } + return result; +} + +IA_CSS_RBM_STORAGE_CLASS_C +uint64_t ia_css_rbm_to_uint64( + const ia_css_rbm_t value) +{ + const unsigned int bits64 = sizeof(uint64_t) * 8; + const unsigned int nof_elems_bits64 = bits64 / IA_CSS_RBM_ELEM_BITS; + unsigned int i; + uint64_t res = 0; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_to_uint64(): enter:\n"); + + assert((bits64 % IA_CSS_RBM_ELEM_BITS) == 0); + assert(nof_elems_bits64 > 0); + + for (i = 0; i < MIN(IA_CSS_RBM_NOF_ELEMS, nof_elems_bits64); i++) { + res |= ((uint64_t)(value.data[i]) << (i * IA_CSS_RBM_ELEM_BITS)); + } + for (i = nof_elems_bits64; i < IA_CSS_RBM_NOF_ELEMS; i++) { + assert(value.data[i] == 0); + } + return res; +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_unset( + const ia_css_rbm_t bitmap, + const unsigned int index) +{ + ia_css_rbm_t result; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_unset(): enter:\n"); + + result = ia_css_rbm_bit_mask(index); + result = ia_css_rbm_complement(result); + return ia_css_rbm_intersection(bitmap, result); +} + +IA_CSS_RBM_STORAGE_CLASS_C +ia_css_rbm_t ia_css_rbm_bit_mask( + const unsigned int index) +{ + unsigned int elem_index; + unsigned int elem_bit_index; + ia_css_rbm_t bit_mask = ia_css_rbm_clear(); + + assert(index < IA_CSS_RBM_BITS); + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_bit_mask(): enter:\n"); + if (index < IA_CSS_RBM_BITS) { + elem_index = index / IA_CSS_RBM_ELEM_BITS; + elem_bit_index = index % IA_CSS_RBM_ELEM_BITS; + assert(elem_index < IA_CSS_RBM_NOF_ELEMS); + + bit_mask.data[elem_index] = 1 << elem_bit_index; + } + return bit_mask; +} + +STORAGE_CLASS_INLINE +int ia_css_rbm_compute_weight( + const ia_css_rbm_t bitmap) +{ + ia_css_rbm_t loc_bitmap; + int weight = 0; + int i; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_compute_weight(): enter:\n"); + + loc_bitmap = bitmap; + + /* In fact; do not need the iterator "i" */ + for (i = 0; (i < IA_CSS_RBM_BITS) && + !ia_css_is_rbm_empty(loc_bitmap); i++) { + weight += ia_css_is_rbm_set(loc_bitmap, 0); + loc_bitmap = ia_css_rbm_shift(loc_bitmap); + } + + return weight; +} + +IA_CSS_RBM_STORAGE_CLASS_C +int ia_css_is_rbm_set( + const ia_css_rbm_t bitmap, + const unsigned int index) +{ + unsigned int elem_index; + unsigned int elem_bit_index; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_is_rbm_set(): enter:\n"); + + assert(index < IA_CSS_RBM_BITS); + + elem_index = index / IA_CSS_RBM_ELEM_BITS; + elem_bit_index = index % IA_CSS_RBM_ELEM_BITS; + assert(elem_index < IA_CSS_RBM_NOF_ELEMS); + return (((bitmap.data[elem_index] >> elem_bit_index) & 0x1) == 1); +} + +STORAGE_CLASS_INLINE +ia_css_rbm_t ia_css_rbm_shift( + const ia_css_rbm_t bitmap) +{ + int i; + unsigned int lsb_current_elem = 0; + unsigned int lsb_previous_elem = 0; + ia_css_rbm_t loc_bitmap; + + IA_CSS_TRACE_0(RBM, VERBOSE, + "ia_css_rbm_shift(): enter:\n"); + + loc_bitmap = bitmap; + + for (i = IA_CSS_RBM_NOF_ELEMS - 1; i >= 0; i--) { + lsb_current_elem = bitmap.data[i] & 0x01; + loc_bitmap.data[i] >>= 1; + loc_bitmap.data[i] |= (lsb_previous_elem << (IA_CSS_RBM_ELEM_BITS - 1)); + lsb_previous_elem = lsb_current_elem; + } + return loc_bitmap; +} + +IA_CSS_RBM_STORAGE_CLASS_C +int ia_css_rbm_print( + const ia_css_rbm_t bitmap, + void *fid) +{ + int retval = -1; + int bit; + unsigned int bit_index = 0; + ia_css_rbm_t loc_bitmap; + + IA_CSS_TRACE_0(RBM, INFO, + "ia_css_rbm_print(): enter:\n"); + + NOT_USED(fid); + NOT_USED(bit); + + IA_CSS_TRACE_0(RBM, INFO, "kernel bitmap {\n"); + + loc_bitmap = bitmap; + + for (bit_index = 0; (bit_index < IA_CSS_RBM_BITS) && + !ia_css_is_rbm_empty(loc_bitmap); bit_index++) { + + bit = ia_css_is_rbm_set(loc_bitmap, 0); + loc_bitmap = ia_css_rbm_shift(loc_bitmap); + IA_CSS_TRACE_2(RBM, INFO, "\t%d\t = %d\n", bit_index, bit); + } + IA_CSS_TRACE_0(RBM, INFO, "}\n"); + + retval = 0; + return retval; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest.c new file mode 100644 index 0000000000000..ef3beb8760b62 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest.c @@ -0,0 +1,224 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_rbm_manifest.h" +#include "ia_css_rbm.h" +#include "type_support.h" +#include "misc_support.h" +#include "assert_support.h" +#include "math_support.h" +#include "ia_css_rbm_trace.h" + +#ifndef __IA_CSS_RBM_MANIFEST_INLINE__ +#include "ia_css_rbm_manifest_impl.h" +#endif /* __IA_CSS_RBM_MANIFEST_INLINE__ */ + +STORAGE_CLASS_INLINE void +ia_css_rbm_print_with_header( + const ia_css_rbm_t *rbm, + const ia_css_rbm_mux_desc_t *mux, + unsigned int mux_desc_count, + bool print_header) +{ +#ifdef __HIVECC + ia_css_rbm_print(*rbm, NULL); + (void)print_header; + (void)mux_desc_count; + (void)mux; +#else + int i, j; + + assert(mux != NULL); + assert(rbm != NULL); + if (mux == NULL || rbm == NULL) + return; + + if (print_header) { + for (i = mux_desc_count - 1; i >= 0; i--) { + PRINT("%*d|", mux[i].size_bits, mux[i].mux_id); + } + PRINT("\n"); + } + for (i = mux_desc_count - 1; i >= 0; i--) { + for (j = mux[i].size_bits - 1; j >= 0; j--) { + PRINT("%d", ia_css_is_rbm_set(*rbm, j + mux[i].offset)); + } + PRINT("|"); + } +#endif +} + +STORAGE_CLASS_INLINE void +ia_css_rbm_validation_rule_print( + ia_css_rbm_validation_rule_t *rule, + ia_css_rbm_mux_desc_t *mux_desc, + unsigned int mux_desc_count, + bool print_header) +{ + ia_css_rbm_print_with_header(&rule->match, mux_desc, mux_desc_count, print_header); +#ifdef __HIVECC + IA_CSS_TRACE_0(RBM, INFO, "Mask\n"); +#else + PRINT("\t"); +#endif + ia_css_rbm_print_with_header(&rule->mask, mux_desc, mux_desc_count, false); +#ifdef __HIVECC + IA_CSS_TRACE_1(RBM, INFO, "Rule expected_value: %d\n", rule->expected_value); +#else + PRINT("\t%d\n", rule->expected_value); +#endif +} + +void +ia_css_rbm_pretty_print( + const ia_css_rbm_t *rbm, + const ia_css_rbm_mux_desc_t *mux, + unsigned int mux_desc_count) +{ + ia_css_rbm_print_with_header(rbm, mux, mux_desc_count, false); +#ifndef __HIVECC + PRINT("\n"); +#endif +} + +void +ia_css_rbm_manifest_print( + const ia_css_rbm_manifest_t *manifest) +{ + int retval = -1; + unsigned int i; + bool print_header = true; + ia_css_rbm_mux_desc_t *muxes; + ia_css_rbm_validation_rule_t *validation_rule; + ia_css_rbm_terminal_routing_desc_t *terminal_routing_desc; + + verifjmpexit(manifest != NULL); + muxes = ia_css_rbm_manifest_get_muxes(manifest); + verifjmpexit(muxes != NULL || manifest->mux_desc_count == 0); + + for (i = 0; i < manifest->mux_desc_count; i++) { + IA_CSS_TRACE_4(RBM, INFO, "id: %d.%d offstet: %d size_bits: %d\n", + muxes[i].gp_dev_id, + muxes[i].mux_id, + muxes[i].offset, + muxes[i].size_bits); + } +#if VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT != 0 + validation_rule = ia_css_rbm_manifest_get_validation_rules(manifest); + verifjmpexit(validation_rule != NULL || manifest->validation_rule_count == 0); + + for (i = 0; i < manifest->validation_rule_count; i++) { + ia_css_rbm_validation_rule_print(&validation_rule[i], muxes, manifest->mux_desc_count, print_header); + print_header = false; + } +#else + (void) validation_rule; + (void) print_header; +#endif + terminal_routing_desc = ia_css_rbm_manifest_get_terminal_routing_desc(manifest); + verifjmpexit(terminal_routing_desc != NULL || manifest->terminal_routing_desc_count == 0); + for (i = 0; i < manifest->terminal_routing_desc_count; i++) { + IA_CSS_TRACE_4(RBM, INFO, "terminal_id: %d connection_state: %d mux_id: %d state: %d\n", + terminal_routing_desc[i].terminal_id, + terminal_routing_desc[i].connection_state, + terminal_routing_desc[i].mux_id, + terminal_routing_desc[i].state); + } + + retval = 0; +EXIT: + if (retval != 0) { + IA_CSS_TRACE_0(RBM, ERROR, "ia_css_rbm_manifest_print failed\n"); + } +} + +bool +ia_css_rbm_manifest_check_rbm_validity( + const ia_css_rbm_manifest_t *manifest, + const ia_css_rbm_t *rbm) +{ + unsigned int i; + ia_css_rbm_t res; + ia_css_rbm_t final_rbm = ia_css_rbm_clear(); + ia_css_rbm_validation_rule_t *rules; + bool matches_rules; + + verifjmpexit(manifest != NULL); + verifjmpexit(rbm != NULL); + + if (ia_css_is_rbm_empty(*rbm)) { + IA_CSS_TRACE_0(RBM, ERROR, "ia_css_rbm_manifest_check_rbm_validity failes: RBM is empty.\n"); + return false; + } + +#if VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT != 0 + rules = ia_css_rbm_manifest_get_validation_rules(manifest); + verifjmpexit(rules != NULL || manifest->validation_rule_count == 0); + + for (i = 0; i < manifest->validation_rule_count; i++) { + res = ia_css_rbm_intersection(*rbm, rules[i].mask); + matches_rules = ia_css_is_rbm_equal(res, rules[i].match); + + if (!matches_rules) + continue; + + if (rules[i].expected_value == 1) { + final_rbm = ia_css_rbm_union(final_rbm, res); + } else { + IA_CSS_TRACE_1(RBM, INFO, "ia_css_rbm_manifest_check_rbm_validity failes on rule %d\n", 1); + return false; + } + } +#else + (void)matches_rules; + (void)i; + (void)rules; + (void)res; +#endif + return ia_css_is_rbm_equal(final_rbm, *rbm); +EXIT: + return false; +} + +ia_css_rbm_t +ia_css_rbm_set_mux( + ia_css_rbm_t rbm, + ia_css_rbm_mux_desc_t *mux, + unsigned int mux_count, + unsigned int gp_dev_id, + unsigned int mux_id, + unsigned int value) +{ + unsigned int i; + + verifjmpexit(mux != NULL); + + for (i = 0; i < mux_count; i++) { + if (mux[i].gp_dev_id == gp_dev_id && mux[i].mux_id == mux_id) + break; + } + if (i >= mux_count) { + IA_CSS_TRACE_2(RBM, ERROR, + "ia_css_rbm_set_mux mux with mux_id %d.%d not found\n", gp_dev_id, mux_id); + return rbm; + } + if (value >= mux[i].size_bits) { + IA_CSS_TRACE_3(RBM, ERROR, + "ia_css_rbm_set_mux mux mux_id %d.%d, value %d illegal\n", gp_dev_id, mux_id, value); + return rbm; + } + rbm = ia_css_rbm_set(rbm, mux[i].offset + value); +EXIT: + return rbm; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest_impl.h new file mode 100644 index 0000000000000..7059b6bc898e0 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/routing_bitmap/src/ia_css_rbm_manifest_impl.h @@ -0,0 +1,108 @@ + + +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_rbm_manifest.h" +#include "ia_css_rbm_trace.h" + +#include "type_support.h" +#include "math_support.h" +#include "error_support.h" +#include "assert_support.h" +#include "print_support.h" + +STORAGE_CLASS_INLINE +void __ia_css_rbm_manifest_check_struct(void) +{ + COMPILATION_ERROR_IF( + sizeof(ia_css_rbm_manifest_t) != (SIZE_OF_RBM_MANIFEST_S / IA_CSS_UINT8_T_BITS)); + COMPILATION_ERROR_IF( + (sizeof(ia_css_rbm_manifest_t) % 8 /* 64 bit */) != 0); +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +unsigned int +ia_css_rbm_manifest_get_size(void) +{ + unsigned int size = sizeof(struct ia_css_rbm_manifest_s); + + return ceil_mul(size, sizeof(uint64_t)); +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +void +ia_css_rbm_manifest_init(struct ia_css_rbm_manifest_s *rbm) +{ + rbm->mux_desc_count = 0; + rbm->terminal_routing_desc_count = 0; + rbm->validation_rule_count = 0; +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +ia_css_rbm_mux_desc_t * +ia_css_rbm_manifest_get_muxes(const ia_css_rbm_manifest_t *manifest) +{ +#if VIED_NCI_RBM_MAX_MUX_COUNT == 0 + (void)manifest; + return NULL; +#else + return (ia_css_rbm_mux_desc_t *)manifest->mux_desc; +#endif +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +unsigned int +ia_css_rbm_manifest_get_mux_count(const ia_css_rbm_manifest_t *manifest) +{ + return manifest->mux_desc_count; +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +ia_css_rbm_validation_rule_t * +ia_css_rbm_manifest_get_validation_rules(const ia_css_rbm_manifest_t *manifest) +{ +#if VIED_NCI_RBM_MAX_VALIDATION_RULE_COUNT == 0 + (void)manifest; + return NULL; +#else + return (ia_css_rbm_validation_rule_t *)manifest->validation_rules; +#endif +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +unsigned int +ia_css_rbm_manifest_get_validation_rule_count(const ia_css_rbm_manifest_t *manifest) +{ + return manifest->validation_rule_count; +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +ia_css_rbm_terminal_routing_desc_t * +ia_css_rbm_manifest_get_terminal_routing_desc(const ia_css_rbm_manifest_t *manifest) +{ +#if VIED_NCI_RBM_MAX_TERMINAL_DESC_COUNT == 0 + (void)manifest; + return NULL; +#else + return (ia_css_rbm_terminal_routing_desc_t *)manifest->terminal_routing_desc; +#endif +} + +IA_CSS_RBM_MANIFEST_STORAGE_CLASS_C +unsigned int +ia_css_rbm_manifest_get_terminal_routing_desc_count(const ia_css_rbm_manifest_t *manifest) +{ + return manifest->terminal_routing_desc_count; +} diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/assert_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/assert_support.h new file mode 100644 index 0000000000000..f904a494b53c9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/assert_support.h @@ -0,0 +1,197 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __ASSERT_SUPPORT_H +#define __ASSERT_SUPPORT_H + +/* This file provides support for run-time assertions + * and compile-time assertions. + * + * Run-time asstions are provided via the following syntax: + * assert(condition) + * Run-time assertions are disabled using the NDEBUG flag. + * + * Compile time assertions are provided via the following syntax: + * COMPILATION_ERROR_IF(condition); + * A compile-time assertion will fail to compile if the condition is false. + * The condition must be constant, such that it can be evaluated + * at compile time. + * + * OP___assert is deprecated. + */ + +#define IA_CSS_ASSERT(expr) assert(expr) + +#ifdef __KLOCWORK__ +/* Klocwork does not see that assert will lead to abortion + * as there is no good way to tell this to KW and the code + * should not depend on assert to function (actually the assert + * could be disabled in a release build) it was decided to + * disable the assert for KW scans (by defining NDEBUG) + */ +#define NDEBUG +#endif /* __KLOCWORK__ */ + +/** + * The following macro can help to test the size of a struct at compile + * time rather than at run-time. It does not work for all compilers; see + * below. + * + * Depending on the value of 'condition', the following macro is expanded to: + * - condition==true: + * an expression containing an array declaration with negative size, + * usually resulting in a compilation error + * - condition==false: + * (void) 1; // C statement with no effect + * + * example: + * COMPILATION_ERROR_IF( sizeof(struct host_sp_queues) != + * SIZE_OF_HOST_SP_QUEUES_STRUCT); + * + * verify that the macro indeed triggers a compilation error with your compiler: + * COMPILATION_ERROR_IF( sizeof(struct host_sp_queues) != + * (sizeof(struct host_sp_queues)+1) ); + * + * Not all compilers will trigger an error with this macro; + * use a search engine to search for BUILD_BUG_ON to find other methods. + */ +#define COMPILATION_ERROR_IF(condition) \ +((void)sizeof(char[1 - 2*!!(condition)])) + +/* Compile time assertion */ +#ifndef CT_ASSERT +#define CT_ASSERT(cnd) ((void)sizeof(char[(cnd)?1 : -1])) +#endif /* CT_ASSERT */ + +#ifdef NDEBUG + +#define assert(cnd) ((void)0) + +#else + +#include "storage_class.h" + +#if defined(_MSC_VER) +#ifdef _KERNEL_MODE +/* Windows kernel mode compilation */ +#include +#define assert(cnd) ASSERT(cnd) +#else +/* Windows usermode compilation */ +#include +#endif + +#elif defined(__HIVECC) + +/* + * target: assert disabled + * sched: assert enabled only when SCHED_DEBUG is defined + * unsched: assert enabled + */ +#if defined(HRT_HW) +#define assert(cnd) ((void)0) +#elif defined(HRT_SCHED) && !defined(DEBUG_SCHED) +#define assert(cnd) ((void)0) +#elif defined(PIPE_GENERATION) +#define assert(cnd) ((void)0) +#else +#include +#define assert(cnd) OP___csim_assert(cnd) +#endif + +#elif defined(__KERNEL__) +#include + +#ifndef KERNEL_ASSERT_TO_BUG +#ifndef KERNEL_ASSERT_TO_BUG_ON +#ifndef KERNEL_ASSERT_TO_WARN_ON +#ifndef KERNEL_ASSERT_TO_WARN_ON_INF_LOOP +#ifndef KERNEL_ASSERT_UNDEFINED +/* Default */ +#define KERNEL_ASSERT_TO_BUG +#endif /*KERNEL_ASSERT_UNDEFINED*/ +#endif /*KERNEL_ASSERT_TO_WARN_ON_INF_LOOP*/ +#endif /*KERNEL_ASSERT_TO_WARN_ON*/ +#endif /*KERNEL_ASSERT_TO_BUG_ON*/ +#endif /*KERNEL_ASSERT_TO_BUG*/ + +#ifdef KERNEL_ASSERT_TO_BUG +/* TODO: it would be cleaner to use this: + * #define assert(cnd) BUG_ON(cnd) + * but that causes many compiler warnings (==errors) under Android + * because it seems that the BUG_ON() macro is not seen as a check by + * gcc like the BUG() macro is. */ +#define assert(cnd) \ + do { \ + if (!(cnd)) { \ + BUG(); \ + } \ + } while (0) +#endif /*KERNEL_ASSERT_TO_BUG*/ + +#ifdef KERNEL_ASSERT_TO_BUG_ON +#define assert(cnd) BUG_ON(!(cnd)) +#endif /*KERNEL_ASSERT_TO_BUG_ON*/ + +#ifdef KERNEL_ASSERT_TO_WARN_ON +#define assert(cnd) WARN_ON(!(cnd)) +#endif /*KERNEL_ASSERT_TO_WARN_ON*/ + +#ifdef KERNEL_ASSERT_TO_WARN_ON_INF_LOOP +#define assert(cnd) \ + do { \ + int not_cnd = !(cnd); \ + WARN_ON(not_cnd); \ + if (not_cnd) { \ + for (;;) { \ + } \ + } \ + } while (0) +#endif /*KERNEL_ASSERT_TO_WARN_ON_INF_LOOP*/ + +#ifdef KERNEL_ASSERT_UNDEFINED +#include KERNEL_ASSERT_DEFINITION_FILESTRING +#endif /*KERNEL_ASSERT_UNDEFINED*/ + +#elif defined(__FIST__) || defined(__GNUC__) + +#include "assert.h" + +#else /* default is for unknown environments */ +#define assert(cnd) ((void)0) +#endif + +#endif /* NDEBUG */ + +#ifndef PIPE_GENERATION +/* Deprecated OP___assert, this is still used in ~1000 places + * in the code. This will be removed over time. + * The implementation for the pipe generation tool is in see support.isp.h */ +#define OP___assert(cnd) assert(cnd) + +#ifdef C_RUN +#define compile_time_assert(cond) OP___assert(cond) +#else +#include "storage_class.h" +extern void _compile_time_assert(void); +STORAGE_CLASS_INLINE void compile_time_assert(unsigned cond) +{ + /* Call undefined function if cond is false */ + if (!cond) + _compile_time_assert(); +} +#endif +#endif /* PIPE_GENERATION */ + +#endif /* __ASSERT_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/cpu_mem_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/cpu_mem_support.h new file mode 100644 index 0000000000000..defea068429ff --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/cpu_mem_support.h @@ -0,0 +1,233 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __CPU_MEM_SUPPORT_H +#define __CPU_MEM_SUPPORT_H + +#include "storage_class.h" +#include "assert_support.h" +#include "type_support.h" + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_copy(void *dst, const void *src, unsigned int size) +{ + /* memcpy cannot be used in Windows (function is not allowed), + * and the safer function memcpy_s is not available on other platforms. + * Because usage of ia_css_cpu_mem_copy is minimal, we implement it here in an easy, + * but sub-optimal way. + */ + unsigned int i; + + assert(dst != NULL && src != NULL); + + if (!(dst != NULL && src != NULL)) { + return NULL; + } + for (i = 0; i < size; i++) { + ((char *)dst)[i] = ((char *)src)[i]; + } + return dst; +} + +#if defined(__KERNEL__) + +#include +#include +#include +#include + +/* TODO: remove, workaround for issue in hrt file ibuf_ctrl_2600_config.c + * error checking code added to SDK that uses calls to exit function + */ +#define exit(a) return + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return kmalloc(size, GFP_KERNEL); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + return ia_css_cpu_mem_alloc(size); /* todo: align to page size */ +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_protect(void *ptr, unsigned int size, int prot) +{ + /* nothing here yet */ +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); /* available in kernel in linux/string.h */ +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + kfree(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ + /* parameter check here */ + if (ptr == NULL) + return; + + clflush_cache_range(ptr, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ + /* for now same as flush */ + ia_css_cpu_mem_cache_flush(ptr, size); +} + +#elif defined(_MSC_VER) + +#include +#include +#include + +extern void *hrt_malloc(size_t bytes, int zero_mem); +extern void *hrt_free(void *ptr); +extern void hrt_mem_cache_flush(void *ptr, unsigned int size); +extern void hrt_mem_cache_invalidate(void *ptr, unsigned int size); + +#define malloc(a) hrt_malloc(a, 1) +#define free(a) hrt_free(a) + +#define CSS_PAGE_SIZE (1<<12) + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return malloc(size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + unsigned int buffer_size = size; + + /* Currently hrt_malloc calls Windows ExAllocatePoolWithTag() routine + * to request system memory. If the number of bytes is equal or bigger + * than the page size, then the returned address is page aligned, + * but if it's smaller it's not necessarily page-aligned We agreed + * with Windows team that we allocate a full page + * if it's less than page size + */ + if (buffer_size < CSS_PAGE_SIZE) + buffer_size = CSS_PAGE_SIZE; + + return ia_css_cpu_mem_alloc(buffer_size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + free(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ +#ifdef _KERNEL_MODE + hrt_mem_cache_flush(ptr, size); +#else + (void)ptr; + (void)size; +#endif +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ +#ifdef _KERNEL_MODE + hrt_mem_cache_invalidate(ptr, size); +#else + (void)ptr; + (void)size; +#endif +} + +#else + +#include +#include +#include +/* Needed for the MPROTECT */ +#include +#include +#include +#include + + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc(unsigned int size) +{ + return malloc(size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_alloc_page_aligned(unsigned int size) +{ + int pagesize; + + pagesize = sysconf(_SC_PAGE_SIZE); + return memalign(pagesize, size); +} + +STORAGE_CLASS_INLINE void* +ia_css_cpu_mem_set_zero(void *dst, unsigned int size) +{ + return memset(dst, 0, size); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_free(void *ptr) +{ + free(ptr); +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_flush(void *ptr, unsigned int size) +{ + /* not needed in simulation */ + (void)ptr; + (void)size; +} + +STORAGE_CLASS_INLINE void +ia_css_cpu_mem_cache_invalidate(void *ptr, unsigned int size) +{ + /* not needed in simulation */ + (void)ptr; + (void)size; +} + +#endif + +#endif /* __CPU_MEM_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/error_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/error_support.h new file mode 100644 index 0000000000000..9fe1f65125e6c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/error_support.h @@ -0,0 +1,110 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __ERROR_SUPPORT_H +#define __ERROR_SUPPORT_H + +#if defined(__KERNEL__) +#include +#else +#include +#endif +#include + +/* OS-independent definition of IA_CSS errno values */ +/* #define IA_CSS_EINVAL 1 */ +/* #define IA_CSS_EFAULT 2 */ + +#ifdef __HIVECC +#define ERR_EMBEDDED 1 +#else +#define ERR_EMBEDDED 0 +#endif + +#if ERR_EMBEDDED +#define DECLARE_ERRVAL +#else +#define DECLARE_ERRVAL \ + int _errval = 0; +#endif + +/* Use "owl" in while to prevent compiler warnings in Windows */ +#define ALWAYS_FALSE ((void)0, 0) + +#define verifret(cond, error_type) \ +do { \ + if (!(cond)) { \ + return error_type; \ + } \ +} while (ALWAYS_FALSE) + +#define verifjmp(cond, error_tag) \ +do { \ + if (!(cond)) { \ + goto error_tag; \ + } \ +} while (ALWAYS_FALSE) + +#define verifexit(cond) \ +do { \ + if (!(cond)) { \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#if ERR_EMBEDDED +#define verifexitval(cond, error_tag) \ +do { \ + assert(cond); \ +} while (ALWAYS_FALSE) +#else +#define verifexitval(cond, error_tag) \ +do { \ + if (!(cond)) { \ + _errval = (error_tag); \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) +#endif + +#if ERR_EMBEDDED +#define haserror(error_tag) (0) +#else +#define haserror(error_tag) \ + (_errval == (error_tag)) +#endif + +#if ERR_EMBEDDED +#define noerror() (1) +#else +#define noerror() \ + (_errval == 0) +#endif + +#define verifjmpexit(cond) \ +do { \ + if (!(cond)) { \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#define verifjmpexitsetretval(cond, retval) \ +do { \ + if (!(cond)) { \ + retval = -1; \ + goto EXIT; \ + } \ +} while (ALWAYS_FALSE) + +#endif /* __ERROR_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/math_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/math_support.h new file mode 100644 index 0000000000000..9eb344e962600 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/math_support.h @@ -0,0 +1,316 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __MATH_SUPPORT_H +#define __MATH_SUPPORT_H + +#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ +#include "type_support.h" +#include "assert_support.h" + +/* in case we have min/max/MIN/MAX macro's undefine them */ +#ifdef min +#undef min +#endif +#ifdef max +#undef max +#endif +#ifdef MIN /* also defined in include/hrt/numeric.h from SDK */ +#undef MIN +#endif +#ifdef MAX +#undef MAX +#endif + +#ifndef UINT16_MAX +#define UINT16_MAX (0xffffUL) +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX (0xffffffffUL) +#endif + +#define IS_ODD(a) ((a) & 0x1) +#define IS_EVEN(a) (!IS_ODD(a)) +#define IS_POWER2(a) (!((a)&((a)-1))) +#define IS_MASK_BITS_SET(a, b) ((a & b) != 0) + +/*To Find next power of 2 number from x */ +#define bit2(x) ((x) | ((x) >> 1)) +#define bit4(x) (bit2(x) | (bit2(x) >> 2)) +#define bit8(x) (bit4(x) | (bit4(x) >> 4)) +#define bit16(x) (bit8(x) | (bit8(x) >> 8)) +#define bit32(x) (bit16(x) | (bit16(x) >> 16)) +#define NEXT_POWER_OF_2(x) (bit32(x-1) + 1) + +/* force a value to a lower even value */ +#define EVEN_FLOOR(x) ((x) & ~1UL) + +/* A => B */ +#define IMPLIES(a, b) (!(a) || (b)) + +/* The ORIG_BITS th bit is the sign bit */ +/* Sign extends a ORIG_BITS bits long signed number to a 64-bit signed number */ +/* By type casting it can relimited to any valid type-size + * (32-bit signed or 16-bit or 8-bit) + */ +/* By masking it can be transformed to any arbitrary bit size */ +#define SIGN_EXTEND(VAL, ORIG_BITS) \ +((~(((VAL)&(1ULL<<((ORIG_BITS)-1)))-1))|(VAL)) + +#define EXTRACT_BIT(a, b) ((a >> b) & 1) + +/* for preprocessor and array sizing use MIN and MAX + otherwise use min and max */ +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define CLIP(a, b, c) MIN((MAX((a), (b))), (c)) +/* Integer round-down division of a with b */ +#define FLOOR_DIV(a, b) ((b) ? ((a) / (b)) : 0) +/* Align a to the lower multiple of b */ +#define FLOOR_MUL(a, b) (FLOOR_DIV(a, b) * (b)) +/* Integer round-up division of a with b */ +#define CEIL_DIV(a, b) ((b) ? (((a) + (b) - 1) / (b)) : 0) +/* Align a to the upper multiple of b */ +#define CEIL_MUL(a, b) (CEIL_DIV(a, b) * (b)) +/* Align a to the upper multiple of b - fast implementation + * for cases when b=pow(2,n) + */ +#define CEIL_MUL2(a, b) (((a) + (b) - 1) & ~((b) - 1)) +/* integer round-up division of a with pow(2,b) */ +#define CEIL_SHIFT(a, b) (((a) + (1UL << (b)) - 1) >> (b)) +/* Align a to the upper multiple of pow(2,b) */ +#define CEIL_SHIFT_MUL(a, b) (CEIL_SHIFT(a, b) << (b)) +/* Absolute difference of a and b */ +#define ABS_DIF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a))) +#define ABS(a) ABS_DIF(a, 0) +/* Square of x */ +#define SQR(x) ((x)*(x)) +/* Integer round-half-down division of a nad b */ +#define ROUND_HALF_DOWN_DIV(a, b) ((b) ? ((a) + (b / 2) - 1) / (b) : 0) +/* Align a to the round-half-down multiple of b */ +#define ROUND_HALF_DOWN_MUL(a, b) (ROUND_HALF_DOWN_DIV(a, b) * (b)) + +#define MAX3(a, b, c) MAX((a), MAX((b), (c))) +#define MIN3(a, b, c) MIN((a), MIN((b), (c))) +#define MAX4(a, b, c, d) MAX((MAX((a), (b))), (MAX((c), (d)))) +#define MIN4(a, b, c, d) MIN((MIN((a), (b))), (MIN((c), (d)))) + +/* min and max should not be macros as they will evaluate their arguments twice. + if you really need a macro (e.g. for CPP or for initializing an array) + use MIN() and MAX(), otherwise use min() and max() */ + +#ifndef ARRAY_SIZE +#ifndef __KERNEL__ +#define ARRAY_SIZE(a) ((sizeof(a) / sizeof(*(a)))) +#endif +#endif + +#ifndef BYTES +#define BYTES(bit) (((bit)+7)/8) +#endif + +#if !defined(PIPE_GENERATION) +STORAGE_CLASS_INLINE unsigned int max_value_bits(unsigned int bits) +{ + return (bits == 0) ? 0 : ((2 * ((1 << ((bits) - 1)) - 1)) + 1); +} +STORAGE_CLASS_INLINE unsigned int max_value_bytes(unsigned int bytes) +{ + return max_value_bits(IA_CSS_UINT8_T_BITS * bytes); +} +STORAGE_CLASS_INLINE int max(int a, int b) +{ + return MAX(a, b); +} + +STORAGE_CLASS_INLINE int min(int a, int b) +{ + return MIN(a, b); +} + +STORAGE_CLASS_INLINE int clip(int a, int b, int c) +{ + return min(max(a, b), c); +} + +STORAGE_CLASS_INLINE unsigned int ipu4_umax(unsigned int a, unsigned int b) +{ + return MAX(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ipu4_umin(unsigned int a, unsigned int b) +{ + return MIN(a, b); +} + +STORAGE_CLASS_INLINE unsigned int uclip(unsigned int a, unsigned int b, + unsigned int c) +{ + return ipu4_umin(ipu4_umax(a, b), c); +} + +STORAGE_CLASS_INLINE unsigned int ceil_div(unsigned int a, unsigned int b) +{ + return CEIL_DIV(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_mul(unsigned int a, unsigned int b) +{ + return CEIL_MUL(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_mul2(unsigned int a, unsigned int b) +{ + return CEIL_MUL2(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_shift(unsigned int a, unsigned int b) +{ + return CEIL_SHIFT(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_shift_mul(unsigned int a, unsigned int b) +{ + return CEIL_SHIFT_MUL(a, b); +} + +STORAGE_CLASS_INLINE int abs_dif(int a, int b) +{ + return ABS_DIF(a, b); +} + +STORAGE_CLASS_INLINE unsigned int uabs_dif(unsigned int a, unsigned int b) +{ + return ABS_DIF(a, b); +} + +STORAGE_CLASS_INLINE unsigned int round_half_down_div(unsigned int a, + unsigned int b) +{ + return ROUND_HALF_DOWN_DIV(a, b); +} + +STORAGE_CLASS_INLINE unsigned int round_half_down_mul(unsigned int a, + unsigned int b) +{ + return ROUND_HALF_DOWN_MUL(a, b); +} + +STORAGE_CLASS_INLINE unsigned int ceil_pow2(uint32_t a) +{ + unsigned int retval = 0; + + if (IS_POWER2(a)) { + retval = (unsigned int)a; + } else { + unsigned int v = a; + + v |= v>>1; + v |= v>>2; + v |= v>>4; + v |= v>>8; + v |= v>>16; + retval = (unsigned int)(v+1); + } + return retval; +} + +STORAGE_CLASS_INLINE unsigned int floor_log2(uint32_t a) +{ + static const uint8_t de_bruijn[] = { + 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 + }; + uint32_t v = a; + + v |= v>>1; + v |= v>>2; + v |= v>>4; + v |= v>>8; + v |= v>>16; + return (unsigned int)de_bruijn[(v*0x07C4ACDDU)>>27]; +} + +/* Divide by small power of two */ +STORAGE_CLASS_INLINE unsigned int +udiv2_small_i(uint32_t a, uint32_t b) +{ + assert(b <= 2); + return a >> (b-1); +} + +/* optimized divide for small results + * a will be divided by b + * outbits is the number of bits needed for the result + * the smaller the cheaper the function will be. + * if the result doesn't fit in the number of output bits + * the result is incorrect and the function will assert + */ +STORAGE_CLASS_INLINE unsigned int +udiv_medium(uint32_t a, uint32_t b, unsigned int outbits) +{ + int bit; + unsigned int res = 0; + unsigned int mask; + +#ifdef VOLCANO +#pragma ipu unroll +#endif + for (bit = outbits-1 ; bit >= 0; bit--) { + mask = 1<= (b<= c ? a+b-c : a+b); +} + +/* + * For SP and ISP, SDK provides the definition of OP_asp_slor. + * We need it only for host + */ +STORAGE_CLASS_INLINE unsigned int OP_asp_slor(int a, int b, int c) +{ + return ((a << c) | b); +} +#else +#include "hive/customops.h" +#endif /* !defined(__VIED_CELL) */ + +#endif /* !defined(PIPE_GENERATION) */ + +#if !defined(__KERNEL__) +#define clamp(a, min_val, max_val) MIN(MAX((a), (min_val)), (max_val)) +#endif /* !defined(__KERNEL__) */ + +#endif /* __MATH_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/misc_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/misc_support.h new file mode 100644 index 0000000000000..a2c2729e946d2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/misc_support.h @@ -0,0 +1,76 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __MISC_SUPPORT_H +#define __MISC_SUPPORT_H + +/* suppress compiler warnings on unused variables */ +#ifndef NOT_USED +#define NOT_USED(a) ((void)(a)) +#endif + +/* Calculate the total bytes for pow(2) byte alignment */ +#define tot_bytes_for_pow2_align(pow2, cur_bytes) \ + ((cur_bytes + (pow2 - 1)) & ~(pow2 - 1)) + +/* Display the macro value given a string */ +#define _STR(x) #x +#define STR(x) _STR(x) + +/* Concatenate */ +#ifndef CAT /* also defined in */ +#define _CAT(a, b) a ## b +#define CAT(a, b) _CAT(a, b) +#endif + +#define _CAT3(a, b, c) a ## b ## c +#define CAT3(a, b, c) _CAT3(a, b, c) + +/* NO_HOIST, NO_CSE, NO_ALIAS attributes must be ignored for host code */ +#ifndef __HIVECC +#ifndef NO_HOIST +#define NO_HOIST +#endif +#ifndef NO_CSE +#define NO_CSE +#endif +#ifndef NO_ALIAS +#define NO_ALIAS +#endif +#endif + +enum hive_method_id { + HIVE_METHOD_ID_CRUN, + HIVE_METHOD_ID_UNSCHED, + HIVE_METHOD_ID_SCHED, + HIVE_METHOD_ID_TARGET +}; + +/* Derive METHOD */ +#if defined(C_RUN) + #define HIVE_METHOD "crun" + #define HIVE_METHOD_ID HIVE_METHOD_ID_CRUN +#elif defined(HRT_UNSCHED) + #define HIVE_METHOD "unsched" + #define HIVE_METHOD_ID HIVE_METHOD_ID_UNSCHED +#elif defined(HRT_SCHED) + #define HIVE_METHOD "sched" + #define HIVE_METHOD_ID HIVE_METHOD_ID_SCHED +#else + #define HIVE_METHOD "target" + #define HIVE_METHOD_ID HIVE_METHOD_ID_TARGET + #define HRT_TARGET 1 +#endif + +#endif /* __MISC_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/platform_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/platform_support.h new file mode 100644 index 0000000000000..d281d841e1c33 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/platform_support.h @@ -0,0 +1,146 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PLATFORM_SUPPORT_H +#define __PLATFORM_SUPPORT_H + +#include "storage_class.h" + +#define MSEC_IN_SEC 1000 +#define NSEC_IN_MSEC 1000000 + +#if defined(_MSC_VER) +#include + +#define IA_CSS_EXTERN +#define SYNC_WITH(x) +#define CSS_ALIGN(d, a) _declspec(align(a)) d + +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + /* Placeholder for driver team*/ +} + +STORAGE_CLASS_INLINE void ia_css_sleep_msec(unsigned long delay_time_ms) +{ + /* Placeholder for driver team*/ + (void)delay_time_ms; +} + +#elif defined(__HIVECC) +#include +#include + +#define IA_CSS_EXTERN extern +#define CSS_ALIGN(d, a) d __aligned(a) +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + OP___schedule(); +} + +#elif defined(__KERNEL__) +#include +#include + +#define IA_CSS_EXTERN +#define CSS_ALIGN(d, a) d __aligned(a) + +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + usleep_range(1, 50); +} + +#elif defined(__GNUC__) +#include + +#define IA_CSS_EXTERN +#define CSS_ALIGN(d, a) d __aligned(a) + +/* Define some __HIVECC specific macros to nothing to allow host code compilation */ +#ifndef NO_ALIAS +#define NO_ALIAS +#endif + +#ifndef SYNC_WITH +#define SYNC_WITH(x) +#endif + +#if defined(HRT_CSIM) +#include "hrt/host.h" /* Using hrt_sleep from hrt/host.h */ +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + /* For the SDK still using hrt_sleep */ + hrt_sleep(); +} +STORAGE_CLASS_INLINE void ia_css_sleep_msec(long unsigned int delay_time_ms) +{ + /* For the SDK still using hrt_sleep */ + long unsigned int i = 0; + for (i = 0; i < delay_time_ms; i++) { + hrt_sleep(); + } +} +#else +#include +STORAGE_CLASS_INLINE void ia_css_sleep(void) +{ + struct timespec delay_time; + + delay_time.tv_sec = 0; + delay_time.tv_nsec = 10; + nanosleep(&delay_time, NULL); +} +STORAGE_CLASS_INLINE void ia_css_sleep_msec(long unsigned int delay_time_ms) +{ + struct timespec delay_time; + + if (delay_time_ms >= MSEC_IN_SEC) { + delay_time.tv_sec = delay_time_ms / MSEC_IN_SEC; + delay_time.tv_nsec = (delay_time_ms % MSEC_IN_SEC) * NSEC_IN_MSEC; + } else { + delay_time.tv_sec = 0; + delay_time.tv_nsec = delay_time_ms * NSEC_IN_MSEC; + } + nanosleep(&delay_time, NULL); +} +#endif + +#else +#include +#endif + +/*needed for the include in stdint.h for various environments */ +#include "type_support.h" +#include "storage_class.h" + +#define MAX_ALIGNMENT 8 +#define aligned_uint8(type, obj) CSS_ALIGN(uint8_t obj, 1) +#define aligned_int8(type, obj) CSS_ALIGN(int8_t obj, 1) +#define aligned_uint16(type, obj) CSS_ALIGN(uint16_t obj, 2) +#define aligned_int16(type, obj) CSS_ALIGN(int16_t obj, 2) +#define aligned_uint32(type, obj) CSS_ALIGN(uint32_t obj, 4) +#define aligned_int32(type, obj) CSS_ALIGN(int32_t obj, 4) + +/* needed as long as hivecc does not define the type (u)int64_t */ +#if defined(__HIVECC) +#define aligned_uint64(type, obj) CSS_ALIGN(unsigned long long obj, 8) +#define aligned_int64(type, obj) CSS_ALIGN(signed long long obj, 8) +#else +#define aligned_uint64(type, obj) CSS_ALIGN(uint64_t obj, 8) +#define aligned_int64(type, obj) CSS_ALIGN(int64_t obj, 8) +#endif +#define aligned_enum(enum_type, obj) CSS_ALIGN(uint32_t obj, 4) +#define aligned_struct(struct_type, obj) struct_type obj + +#endif /* __PLATFORM_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/print_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/print_support.h new file mode 100644 index 0000000000000..0b614f7ef12d8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/print_support.h @@ -0,0 +1,90 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __PRINT_SUPPORT_H +#define __PRINT_SUPPORT_H + +#if defined(_MSC_VER) +#ifdef _KERNEL_MODE + +/* TODO: Windows driver team to provide tracing mechanism for kernel mode + * e.g. DbgPrint and DbgPrintEx + */ +extern void FwTracePrintPWARN(const char *fmt, ...); +extern void FwTracePrintPRINT(const char *fmt, ...); +extern void FwTracePrintPERROR(const char *fmt, ...); +extern void FwTracePrintPDEBUG(const char *fmt, ...); + +#define PWARN(format, ...) FwTracePrintPWARN(format, __VA_ARGS__) +#define PRINT(format, ...) FwTracePrintPRINT(format, __VA_ARGS__) +#define PERROR(format, ...) FwTracePrintPERROR(format, __VA_ARGS__) +#define PDEBUG(format, ...) FwTracePrintPDEBUG(format, __VA_ARGS__) + +#else +/* Windows usermode compilation */ +#include + +/* To change the defines below, communicate with Windows team first + * to ensure they will not get flooded with prints + */ +/* This is temporary workaround to avoid flooding userspace + * Windows driver with prints + */ + +#define PWARN(format, ...) +#define PRINT(format, ...) +#define PERROR(format, ...) printf("error: " format, __VA_ARGS__) +#define PDEBUG(format, ...) + +#endif /* _KERNEL_MODE */ + +#elif defined(__HIVECC) +#include +/* To be revised + +#define PWARN(format) +#define PRINT(format) OP___printstring(format) +#define PERROR(variable) OP___dump(9999, arguments) +#define PDEBUG(variable) OP___dump(__LINE__, arguments) + +*/ + +#define PRINTSTRING(str) OP___printstring(str) + +#elif defined(__KERNEL__) +#include +#include + + +#define PWARN(format, arguments...) pr_debug(format, ##arguments) +#define PRINT(format, arguments...) pr_debug(format, ##arguments) +#define PERROR(format, arguments...) pr_debug(format, ##arguments) +#define PDEBUG(format, arguments...) pr_debug(format, ##arguments) + +#else +#include + +#define PRINT_HELPER(prefix, format, ...) printf(prefix format "%s", __VA_ARGS__) + +/* The trailing "" allows the edge case of printing single string */ +#define PWARN(...) PRINT_HELPER("warning: ", __VA_ARGS__, "") +#define PRINT(...) PRINT_HELPER("", __VA_ARGS__, "") +#define PERROR(...) PRINT_HELPER("error: ", __VA_ARGS__, "") +#define PDEBUG(...) PRINT_HELPER("debug: ", __VA_ARGS__, "") + +#define PRINTSTRING(str) PRINT(str) + +#endif + +#endif /* __PRINT_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/storage_class.h new file mode 100644 index 0000000000000..58932a6b3ec76 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/storage_class.h @@ -0,0 +1,51 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __STORAGE_CLASS_H +#define __STORAGE_CLASS_H + +#define STORAGE_CLASS_EXTERN \ +extern + +#if defined(_MSC_VER) +#define STORAGE_CLASS_INLINE \ +static inline +#elif defined(__HIVECC) +#define STORAGE_CLASS_INLINE \ +static inline +#else +#define STORAGE_CLASS_INLINE \ +static inline +#endif + +/* Register struct */ +#ifndef __register +#if defined(__HIVECC) && !defined(PIPE_GENERATION) +#define __register register +#else +#define __register +#endif +#endif + +/* Memory attribute */ +#ifndef MEM +#ifdef PIPE_GENERATION +#elif defined(__HIVECC) +#include +#else +#define MEM(any_mem) +#endif +#endif + +#endif /* __STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/type_support.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/type_support.h new file mode 100644 index 0000000000000..7d8e00fdd95e1 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/support/type_support.h @@ -0,0 +1,80 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __TYPE_SUPPORT_H +#define __TYPE_SUPPORT_H + +/* Per the DLI spec, types are in "type_support.h" and + * "platform_support.h" is for unclassified/to be refactored + * platform specific definitions. + */ +#define IA_CSS_UINT8_T_BITS 8 +#define IA_CSS_UINT16_T_BITS 16 +#define IA_CSS_UINT32_T_BITS 32 +#define IA_CSS_INT32_T_BITS 32 +#define IA_CSS_UINT64_T_BITS 64 + + +#if defined(_MSC_VER) +#include +#include +#include +#include +#if defined(_M_X64) +#define HOST_ADDRESS(x) ((unsigned long long)(x)) +#else +#define HOST_ADDRESS(x) ((unsigned long)(x)) +#endif + +#elif defined(PARAM_GENERATION) +/* Nothing */ +#elif defined(__HIVECC) +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#elif defined(__KERNEL__) +#include +#include + +#define CHAR_BIT (8) +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#elif defined(__GNUC__) +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#else /* default is for the FIST environment */ +#include +#include +#include +#include +#define HOST_ADDRESS(x) ((unsigned long)(x)) + +#endif + +#if !defined(PIPE_GENERATION) && !defined(IO_GENERATION) +/* genpipe cannot handle the void* syntax */ +typedef void *HANDLE; +#endif + +#endif /* __TYPE_SUPPORT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/interface/ia_css_syscom.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/interface/ia_css_syscom.h new file mode 100644 index 0000000000000..5426d6d18e0bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/interface/ia_css_syscom.h @@ -0,0 +1,247 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_H +#define __IA_CSS_SYSCOM_H + + +/* + * The CSS Subsystem Communication Interface - Host side + * + * It provides subsystem initialzation, send ports and receive ports + * The PSYS and ISYS interfaces are implemented on top of this interface. + */ + +#include "ia_css_syscom_config.h" + +#define FW_ERROR_INVALID_PARAMETER (-1) +#define FW_ERROR_BAD_ADDRESS (-2) +#define FW_ERROR_BUSY (-3) +#define FW_ERROR_NO_MEMORY (-4) + +struct ia_css_syscom_context; + +/** + * ia_css_syscom_size() - provide syscom external buffer requirements + * @config: pointer to the configuration data (read) + * @size: pointer to the buffer size (write) + * + * Purpose: + * - Provide external buffer requirements + * - To be used for external buffer allocation + * + */ +extern void +ia_css_syscom_size( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size *size +); + +/** + * ia_css_syscom_open() - initialize a subsystem context + * @config: pointer to the configuration data (read) + * @buf: pointer to externally allocated buffers (read) + * @returns: struct ia_css_syscom_context* on success, 0 otherwise. + * + * Purpose: + * - initialize host side data structures + * - boot the subsystem? + * + */ +extern struct ia_css_syscom_context* +ia_css_syscom_open( + struct ia_css_syscom_config *config, + struct ia_css_syscom_buf *buf +); + +/** + * ia_css_syscom_close() - signal close to cell + * @context: pointer to the subsystem context + * @returns: 0 on success, -2 (FW_ERROR_BUSY) if SPC is not ready yet. + * + * Purpose: + * Request from the Cell to terminate + */ +extern int +ia_css_syscom_close( + struct ia_css_syscom_context *context +); + +/** + * ia_css_syscom_release() - free context + * @context: pointer to the subsystem context + * @force: flag which specifies whether cell + * state will be checked before freeing the + * context. + * @returns: 0 on success, -2 (FW_ERROR_BUSY) if cell + * is busy and call was not forced. + * + * Purpose: + * 2 modes, with first (force==true) immediately + * free context, and second (force==false) verifying + * that the cell state is ok and freeing context if so, + * returning error otherwise. + */ +extern int +ia_css_syscom_release( + struct ia_css_syscom_context *context, + unsigned int force +); + +/** + * Open a port for sending tokens to the subsystem + * @context: pointer to the subsystem context + * @port: send port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_open( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Closes a port for sending tokens to the subsystem + * @context: pointer to the subsystem context + * @port: send port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_close( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Get the number of tokens that can be sent to a port without error. + * @context: pointer to the subsystem context + * @port: send port index + * @returns: number of available tokens on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_available( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Send a token to the subsystem port + * The token size is determined during initialization + * @context: pointer to the subsystem context + * @port: send port index + * @token: pointer to the token value that is transferred to the subsystem + * @returns: number of tokens sent on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_send_port_transfer( + struct ia_css_syscom_context *context, + unsigned int port, + const void *token +); + +/** + * Open a port for receiving tokens to the subsystem + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_open( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Closes a port for receiving tokens to the subsystem + * Returns 0 on success, otherwise negative value of error code + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_close( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Get the number of tokens that can be received from a port without errors. + * @context: pointer to the subsystem context + * @port: receive port index + * @returns: number of available tokens on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_available( + struct ia_css_syscom_context *context, + unsigned int port +); + +/** + * Receive a token from the subsystem port + * The token size is determined during initialization + * @context: pointer to the subsystem context + * @port: receive port index + * @token (output): pointer to (space for) the token to be received + * @returns: number of tokens received on success, + * -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_recv_port_transfer( + struct ia_css_syscom_context *context, + unsigned int port, + void *token +); + +#if HAS_DUAL_CMD_CTX_SUPPORT +/** + * ia_css_syscom_store_dmem() - store subsystem context information in DMEM + * @context: pointer to the subsystem context + * @ssid: subsystem id + * @vtl0_addr_mask: VTL0 address mask; only applicable when the passed in context is secure + * @returns: 0 on success, -1 (FW_ERROR_INVALID_PARAMETER) otherwise. + */ +extern int +ia_css_syscom_store_dmem( + struct ia_css_syscom_context *context, + unsigned int ssid, + unsigned int vtl0_addr_mask +); + +/** + * ia_css_syscom_set_trustlet_status() - store truslet configuration setting + * @context: pointer to the subsystem context + * @trustlet_exist: 1 if trustlet exists + */ +extern void +ia_css_syscom_set_trustlet_status( + unsigned int dmem_addr, + unsigned int ssid, + bool trustlet_exist +); + +/** + * ia_css_syscom_is_ab_spc_ready() - check if SPC access blocker programming is completed + * @context: pointer to the subsystem context + * @returns: 1 when status is ready. 0 otherwise + */ +bool +ia_css_syscom_is_ab_spc_ready( + struct ia_css_syscom_context *ctx +); +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ + +#endif /* __IA_CSS_SYSCOM_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/interface/ia_css_syscom_config.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/interface/ia_css_syscom_config.h new file mode 100644 index 0000000000000..2f5eb309df94e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/interface/ia_css_syscom_config.h @@ -0,0 +1,97 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONFIG_H +#define __IA_CSS_SYSCOM_CONFIG_H + +#include +#include + +/* syscom size struct, output of ia_css_syscom_size, + * input for (external) allocation + */ +struct ia_css_syscom_size { + /* Size of host buffer */ + unsigned int cpu; + /* Size of shared config buffer (host to cell) */ + unsigned int shm; + /* Size of shared input queue buffers (host to cell) */ + unsigned int ibuf; + /* Size of shared output queue buffers (cell to host) */ + unsigned int obuf; +}; + +/* syscom buffer struct, output of (external) allocation, + * input for ia_css_syscom_open + */ +struct ia_css_syscom_buf { + char *cpu; /* host buffer */ + + /* shared memory buffer host address */ + host_virtual_address_t shm_host; + /* shared memory buffer cell address */ + vied_virtual_address_t shm_cell; + + /* input queue shared buffer host address */ + host_virtual_address_t ibuf_host; + /* input queue shared buffer cell address */ + vied_virtual_address_t ibuf_cell; + + /* output queue shared buffer host address */ + host_virtual_address_t obuf_host; + /* output queue shared buffer cell address */ + vied_virtual_address_t obuf_cell; +}; + +struct ia_css_syscom_queue_config { + unsigned int queue_size; /* tokens per queue */ + unsigned int token_size; /* bytes per token */ +}; + +/** + * Parameter struct for ia_css_syscom_open + */ +struct ia_css_syscom_config { + /* This member in no longer used in syscom. + It is kept to not break any driver builds, and will be removed when + all assignments have been removed from driver code */ + /* address of firmware in DDR/IMR */ + unsigned long long host_firmware_address; + + /* address of firmware in DDR, seen from SPC */ + unsigned int vied_firmware_address; + + unsigned int ssid; + unsigned int mmid; + + unsigned int num_input_queues; + unsigned int num_output_queues; + struct ia_css_syscom_queue_config *input; + struct ia_css_syscom_queue_config *output; + + unsigned int regs_addr; + unsigned int dmem_addr; + + /* firmware-specific configuration data */ + void *specific_addr; + unsigned int specific_size; + + /* if true; secure syscom in VTIO Case + * if false, non-secure syscom + */ + bool secure; + unsigned int vtl0_addr_mask; /* only applicable in 'secure' case */ +}; + +#endif /* __IA_CSS_SYSCOM_CONFIG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/interface/ia_css_syscom_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/interface/ia_css_syscom_trace.h new file mode 100644 index 0000000000000..2c32693c2a82e --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/interface/ia_css_syscom_trace.h @@ -0,0 +1,51 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __IA_CSS_SYSCOM_TRACE_H +#define __IA_CSS_SYSCOM_TRACE_H + +#include "ia_css_trace.h" + +#define SYSCOM_TRACE_LEVEL_DEFAULT 1 +#define SYSCOM_TRACE_LEVEL_DEBUG 2 + +/* Set to default level if no level is defined */ +#ifndef SYSCOM_TRACE_LEVEL +#define SYSCOM_TRACE_LEVEL SYSCOM_TRACE_LEVEL_DEFAULT +#endif /* SYSCOM_TRACE_LEVEL */ + +/* SYSCOM Module tracing backend is mapped to TUNIT tracing for target platforms */ +#ifdef __HIVECC +# ifndef HRT_CSIM +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_TRACE +# else +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +# endif +#else +# define SYSCOM_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE +#endif + +#define SYSCOM_TRACE_LEVEL_INFO IA_CSS_TRACE_LEVEL_ENABLED +#define SYSCOM_TRACE_LEVEL_WARNING IA_CSS_TRACE_LEVEL_ENABLED +#define SYSCOM_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + +#if (SYSCOM_TRACE_LEVEL == SYSCOM_TRACE_LEVEL_DEFAULT) +# define SYSCOM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_DISABLED +#elif (SYSCOM_TRACE_LEVEL == SYSCOM_TRACE_LEVEL_DEBUG) +# define SYSCOM_TRACE_LEVEL_VERBOSE IA_CSS_TRACE_LEVEL_ENABLED +#else +# error "Connection manager trace level not defined!" +#endif /* SYSCOM_TRACE_LEVEL */ + +#endif /* __IA_CSS_SYSCOM_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/src/ia_css_syscom.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/src/ia_css_syscom.c new file mode 100644 index 0000000000000..dffbf581eb2b3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/src/ia_css_syscom.c @@ -0,0 +1,652 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#include "ia_css_syscom.h" + +#include "ia_css_syscom_context.h" +#include "ia_css_syscom_config_fw.h" +#include "ia_css_syscom_trace.h" + +#include "queue.h" +#include "send_port.h" +#include "recv_port.h" +#include "regmem_access.h" + +#include "error_support.h" +#include "cpu_mem_support.h" + +#include "queue_struct.h" +#include "send_port_struct.h" +#include "recv_port_struct.h" + +#include "type_support.h" +#include +#include +#include "platform_support.h" + +#include "ia_css_cell.h" + +/* struct of internal buffer sizes */ +struct ia_css_syscom_size_intern { + unsigned int context; + unsigned int input_queue; + unsigned int output_queue; + unsigned int input_port; + unsigned int output_port; + + unsigned int fw_config; + unsigned int specific; + + unsigned int input_buffer; + unsigned int output_buffer; +}; + +/* Allocate buffers internally, when no buffers are provided */ +static int +ia_css_syscom_alloc( + unsigned int ssid, + unsigned int mmid, + const struct ia_css_syscom_size *size, + struct ia_css_syscom_buf *buf) +{ + /* zero the buffer to set all pointers to zero */ + memset(buf, 0, sizeof(*buf)); + + /* allocate cpu_mem */ + buf->cpu = (char *)ia_css_cpu_mem_alloc(size->cpu); + if (!buf->cpu) + goto EXIT7; + + /* allocate and map shared config buffer */ + buf->shm_host = shared_memory_alloc(mmid, size->shm); + if (!buf->shm_host) + goto EXIT6; + buf->shm_cell = shared_memory_map(ssid, mmid, buf->shm_host); + if (!buf->shm_cell) + goto EXIT5; + + /* allocate and map input queue buffer */ + buf->ibuf_host = shared_memory_alloc(mmid, size->ibuf); + if (!buf->ibuf_host) + goto EXIT4; + buf->ibuf_cell = shared_memory_map(ssid, mmid, buf->ibuf_host); + if (!buf->ibuf_cell) + goto EXIT3; + + /* allocate and map output queue buffer */ + buf->obuf_host = shared_memory_alloc(mmid, size->obuf); + if (!buf->obuf_host) + goto EXIT2; + buf->obuf_cell = shared_memory_map(ssid, mmid, buf->obuf_host); + if (!buf->obuf_cell) + goto EXIT1; + + return 0; + +EXIT1: shared_memory_free(mmid, buf->obuf_host); +EXIT2: shared_memory_unmap(ssid, mmid, buf->ibuf_cell); +EXIT3: shared_memory_free(mmid, buf->ibuf_host); +EXIT4: shared_memory_unmap(ssid, mmid, buf->shm_cell); +EXIT5: shared_memory_free(mmid, buf->shm_host); +EXIT6: ia_css_cpu_mem_free(buf->cpu); +EXIT7: return FW_ERROR_NO_MEMORY; +} + +static void +ia_css_syscom_size_intern( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size_intern *size) +{ + /* convert syscom config into syscom internal size struct */ + + unsigned int i; + + size->context = sizeof(struct ia_css_syscom_context); + size->input_queue = cfg->num_input_queues * sizeof(struct sys_queue); + size->output_queue = cfg->num_output_queues * sizeof(struct sys_queue); + size->input_port = cfg->num_input_queues * sizeof(struct send_port); + size->output_port = cfg->num_output_queues * sizeof(struct recv_port); + + size->fw_config = sizeof(struct ia_css_syscom_config_fw); + size->specific = cfg->specific_size; + + /* accumulate input queue buffer sizes */ + size->input_buffer = 0; + for (i = 0; i < cfg->num_input_queues; i++) { + size->input_buffer += + sys_queue_buf_size(cfg->input[i].queue_size, + cfg->input[i].token_size); + } + + /* accumulate outut queue buffer sizes */ + size->output_buffer = 0; + for (i = 0; i < cfg->num_output_queues; i++) { + size->output_buffer += + sys_queue_buf_size(cfg->output[i].queue_size, + cfg->output[i].token_size); + } +} + +static void +ia_css_syscom_size_extern( + const struct ia_css_syscom_size_intern *i, + struct ia_css_syscom_size *e) +{ + /* convert syscom internal size struct into external size struct */ + + e->cpu = i->context + i->input_queue + i->output_queue + + i->input_port + i->output_port; + e->shm = i->fw_config + i->input_queue + i->output_queue + i->specific; + e->ibuf = i->input_buffer; + e->obuf = i->output_buffer; +} + +/* Function that provides buffer sizes to be allocated */ +void +ia_css_syscom_size( + const struct ia_css_syscom_config *cfg, + struct ia_css_syscom_size *size) +{ + struct ia_css_syscom_size_intern i; + + ia_css_syscom_size_intern(cfg, &i); + ia_css_syscom_size_extern(&i, size); +} + +static struct ia_css_syscom_context* +ia_css_syscom_assign_buf( + const struct ia_css_syscom_size_intern *i, + const struct ia_css_syscom_buf *buf) +{ + struct ia_css_syscom_context *ctx; + char *cpu_mem_buf; + host_virtual_address_t shm_buf_host; + vied_virtual_address_t shm_buf_cell; + + /* host context */ + cpu_mem_buf = buf->cpu; + + ctx = (struct ia_css_syscom_context *)cpu_mem_buf; + ia_css_cpu_mem_set_zero(ctx, i->context); + cpu_mem_buf += i->context; + + ctx->input_queue = (struct sys_queue *) cpu_mem_buf; + cpu_mem_buf += i->input_queue; + + ctx->output_queue = (struct sys_queue *) cpu_mem_buf; + cpu_mem_buf += i->output_queue; + + ctx->send_port = (struct send_port *) cpu_mem_buf; + cpu_mem_buf += i->input_port; + + ctx->recv_port = (struct recv_port *) cpu_mem_buf; + + + /* cell config */ + shm_buf_host = buf->shm_host; + shm_buf_cell = buf->shm_cell; + + ctx->config_host_addr = shm_buf_host; + shm_buf_host += i->fw_config; + ctx->config_vied_addr = shm_buf_cell; + shm_buf_cell += i->fw_config; + + ctx->input_queue_host_addr = shm_buf_host; + shm_buf_host += i->input_queue; + ctx->input_queue_vied_addr = shm_buf_cell; + shm_buf_cell += i->input_queue; + + ctx->output_queue_host_addr = shm_buf_host; + shm_buf_host += i->output_queue; + ctx->output_queue_vied_addr = shm_buf_cell; + shm_buf_cell += i->output_queue; + + ctx->specific_host_addr = shm_buf_host; + ctx->specific_vied_addr = shm_buf_cell; + + ctx->ibuf_host_addr = buf->ibuf_host; + ctx->ibuf_vied_addr = buf->ibuf_cell; + + ctx->obuf_host_addr = buf->obuf_host; + ctx->obuf_vied_addr = buf->obuf_cell; + + return ctx; +} + +struct ia_css_syscom_context* +ia_css_syscom_open( + struct ia_css_syscom_config *cfg, + struct ia_css_syscom_buf *buf_extern +) +{ + struct ia_css_syscom_size_intern size_intern; + struct ia_css_syscom_size size; + struct ia_css_syscom_buf buf_intern; + struct ia_css_syscom_buf *buf; + struct ia_css_syscom_context *ctx; + struct ia_css_syscom_config_fw fw_cfg; + unsigned int i; + struct sys_queue_res res; + + IA_CSS_TRACE_0(SYSCOM, INFO, "Entered: ia_css_syscom_open\n"); + + /* error handling */ + if (cfg == NULL) + return NULL; + + IA_CSS_TRACE_1(SYSCOM, INFO, "ia_css_syscom_open (secure %d) start\n", cfg->secure); + + /* check members of cfg: TBD */ + + /* + * Check if SP is in valid state, have to wait if not ready. + * In some platform (Such as VP), it will need more time to wait due to system performance; + * If return NULL without wait for SPC0 ready, Driver load FW will failed + */ + ia_css_cell_wait(cfg->ssid, SPC0); + + ia_css_syscom_size_intern(cfg, &size_intern); + ia_css_syscom_size_extern(&size_intern, &size); + + if (buf_extern) { + /* use externally allocated buffers */ + buf = buf_extern; + } else { + /* use internally allocated buffers */ + buf = &buf_intern; + if (ia_css_syscom_alloc(cfg->ssid, cfg->mmid, &size, buf) != 0) + return NULL; + } + + /* assign buffer pointers */ + ctx = ia_css_syscom_assign_buf(&size_intern, buf); + /* only need to free internally allocated buffers */ + ctx->free_buf = !buf_extern; + + ctx->cell_regs_addr = cfg->regs_addr; + /* regmem is at cell_dmem_addr + REGMEM_OFFSET */ + ctx->cell_dmem_addr = cfg->dmem_addr; + + ctx->num_input_queues = cfg->num_input_queues; + ctx->num_output_queues = cfg->num_output_queues; + + ctx->env.mmid = cfg->mmid; + ctx->env.ssid = cfg->ssid; + ctx->env.mem_addr = cfg->dmem_addr; + + ctx->regmem_idx = SYSCOM_QPR_BASE_REG; + + /* initialize input queues */ + res.reg = SYSCOM_QPR_BASE_REG; + res.host_address = ctx->ibuf_host_addr; + res.vied_address = ctx->ibuf_vied_addr; + for (i = 0; i < cfg->num_input_queues; i++) { + sys_queue_init(ctx->input_queue + i, + cfg->input[i].queue_size, + cfg->input[i].token_size, &res); + } + + /* initialize output queues */ + res.host_address = ctx->obuf_host_addr; + res.vied_address = ctx->obuf_vied_addr; + for (i = 0; i < cfg->num_output_queues; i++) { + sys_queue_init(ctx->output_queue + i, + cfg->output[i].queue_size, + cfg->output[i].token_size, &res); + } + + /* fill shared queue structs */ + shared_memory_store(cfg->mmid, ctx->input_queue_host_addr, + ctx->input_queue, + cfg->num_input_queues * sizeof(struct sys_queue)); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->input_queue_host_addr), + cfg->num_input_queues * sizeof(struct sys_queue)); + shared_memory_store(cfg->mmid, ctx->output_queue_host_addr, + ctx->output_queue, + cfg->num_output_queues * sizeof(struct sys_queue)); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->output_queue_host_addr), + cfg->num_output_queues * sizeof(struct sys_queue)); + + /* Zero the queue buffers. Is this really needed? */ + shared_memory_zero(cfg->mmid, buf->ibuf_host, size.ibuf); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(buf->ibuf_host), + size.ibuf); + shared_memory_zero(cfg->mmid, buf->obuf_host, size.obuf); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(buf->obuf_host), + size.obuf); + + /* copy firmware specific data */ + if (cfg->specific_addr && cfg->specific_size) { + shared_memory_store(cfg->mmid, ctx->specific_host_addr, + cfg->specific_addr, cfg->specific_size); + ia_css_cpu_mem_cache_flush( + (void *)HOST_ADDRESS(ctx->specific_host_addr), + cfg->specific_size); + } + + fw_cfg.num_input_queues = cfg->num_input_queues; + fw_cfg.num_output_queues = cfg->num_output_queues; + fw_cfg.input_queue = ctx->input_queue_vied_addr; + fw_cfg.output_queue = ctx->output_queue_vied_addr; + fw_cfg.specific_addr = ctx->specific_vied_addr; + fw_cfg.specific_size = cfg->specific_size; + + shared_memory_store(cfg->mmid, ctx->config_host_addr, + &fw_cfg, sizeof(struct ia_css_syscom_config_fw)); + ia_css_cpu_mem_cache_flush((void *)HOST_ADDRESS(ctx->config_host_addr), + sizeof(struct ia_css_syscom_config_fw)); + +#if !HAS_DUAL_CMD_CTX_SUPPORT + /* store syscom uninitialized state */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store STATE_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_STATE_UNINIT, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + SYSCOM_STATE_UNINIT, cfg->ssid); + /* store syscom uninitialized command */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store COMMAND_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_COMMAND_UNINIT, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_UNINIT, cfg->ssid); + /* store firmware configuration address */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_open store CONFIG_REG (%#x) @ dmem_addr %#x ssid %d\n", + ctx->config_vied_addr, ctx->cell_dmem_addr, cfg->ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_CONFIG_REG, + ctx->config_vied_addr, cfg->ssid); +#endif + + /* Indicate if ctx is created for secure stream purpose */ + ctx->secure = cfg->secure; + + IA_CSS_TRACE_1(SYSCOM, INFO, "ia_css_syscom_open (secure %d) completed\n", cfg->secure); + return ctx; +} + + +int +ia_css_syscom_close( + struct ia_css_syscom_context *ctx +) +{ + int state; + + state = regmem_load_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle close request yet */ + return FW_ERROR_BUSY; + } + + /* set close request flag */ + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_INACTIVE, ctx->env.ssid); + + return 0; +} + +static void +ia_css_syscom_free(struct ia_css_syscom_context *ctx) +{ + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, ctx->ibuf_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->ibuf_host_addr); + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, ctx->obuf_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->obuf_host_addr); + shared_memory_unmap(ctx->env.ssid, ctx->env.mmid, + ctx->config_vied_addr); + shared_memory_free(ctx->env.mmid, ctx->config_host_addr); + ia_css_cpu_mem_free(ctx); +} + +int +ia_css_syscom_release( + struct ia_css_syscom_context *ctx, + unsigned int force +) +{ + /* check if release is forced, an verify cell state if it is not */ + if (!force) { + if (!ia_css_cell_is_ready(ctx->env.ssid, SPC0)) + return FW_ERROR_BUSY; + } + + /* Reset the regmem idx */ + ctx->regmem_idx = 0; + + if (ctx->free_buf) + ia_css_syscom_free(ctx); + + return 0; +} + +int ia_css_syscom_send_port_open( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + int state; + + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + /* check if SP syscom is ready to open the queue */ + state = regmem_load_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle messages yet */ + return FW_ERROR_BUSY; + } + + /* initialize the port */ + send_port_open(ctx->send_port + port, + ctx->input_queue + port, &(ctx->env)); + + return 0; +} + +int ia_css_syscom_send_port_close( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return 0; +} + +int ia_css_syscom_send_port_available( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return send_port_available(ctx->send_port + port); +} + +int ia_css_syscom_send_port_transfer( + struct ia_css_syscom_context *ctx, + unsigned int port, + const void *token +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_input_queues, FW_ERROR_INVALID_PARAMETER); + + return send_port_transfer(ctx->send_port + port, token); +} + +int ia_css_syscom_recv_port_open( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + int state; + + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + /* check if SP syscom is ready to open the queue */ + state = regmem_load_32(ctx->cell_dmem_addr, + SYSCOM_STATE_REG, ctx->env.ssid); + if (state != SYSCOM_STATE_READY) { + /* SPC is not ready to handle messages yet */ + return FW_ERROR_BUSY; + } + + /* initialize the port */ + recv_port_open(ctx->recv_port + port, + ctx->output_queue + port, &(ctx->env)); + + return 0; +} + +int ia_css_syscom_recv_port_close( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check parameters */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return 0; +} + +/* + * Get the number of responses in the response queue + */ +int +ia_css_syscom_recv_port_available( + struct ia_css_syscom_context *ctx, + unsigned int port +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return recv_port_available(ctx->recv_port + port); +} + + +/* + * Dequeue the head of the response queue + * returns an error when the response queue is empty + */ +int +ia_css_syscom_recv_port_transfer( + struct ia_css_syscom_context *ctx, + unsigned int port, + void *token +) +{ + /* check params */ + verifret(ctx != NULL, FW_ERROR_BAD_ADDRESS); + verifret(port < ctx->num_output_queues, FW_ERROR_INVALID_PARAMETER); + + return recv_port_transfer(ctx->recv_port + port, token); +} + +#if HAS_DUAL_CMD_CTX_SUPPORT +/* + * store subsystem context information in DMEM + */ +int +ia_css_syscom_store_dmem( + struct ia_css_syscom_context *ctx, + unsigned int ssid, + unsigned int vtl0_addr_mask +) +{ + unsigned int read_back; + + NOT_USED(vtl0_addr_mask); + NOT_USED(read_back); + + if (ctx->secure) { + /* store VTL0 address mask in 'secure' context */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem VTL0_ADDR_MASK (%#x) @ dmem_addr %#x ssid %d\n", + vtl0_addr_mask, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_VTL0_ADDR_MASK, vtl0_addr_mask, ssid); + } + /* store firmware configuration address */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem CONFIG_REG (%#x) @ dmem_addr %#x ssid %d\n", + ctx->config_vied_addr, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_CONFIG_REG, + ctx->config_vied_addr, ssid); + /* store syscom uninitialized state */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem STATE_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_STATE_UNINIT, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_STATE_REG, + SYSCOM_STATE_UNINIT, ssid); + /* store syscom uninitialized command */ + IA_CSS_TRACE_3(SYSCOM, INFO, "ia_css_syscom_store_dmem COMMAND_REG (%#x) @ dmem_addr %#x ssid %d\n", + SYSCOM_COMMAND_UNINIT, ctx->cell_dmem_addr, ssid); + regmem_store_32(ctx->cell_dmem_addr, SYSCOM_COMMAND_REG, + SYSCOM_COMMAND_UNINIT, ssid); + + return 0; +} + +/* + * store truslet configuration status setting + */ +void +ia_css_syscom_set_trustlet_status( + unsigned int dmem_addr, + unsigned int ssid, + bool trustlet_exist +) +{ + unsigned int value; + + value = trustlet_exist ? TRUSTLET_EXIST : TRUSTLET_NOT_EXIST; + IA_CSS_TRACE_3(SYSCOM, INFO, + "ia_css_syscom_set_trustlet_status TRUSTLET_STATUS (%#x) @ dmem_addr %#x ssid %d\n", + value, dmem_addr, ssid); + regmem_store_32(dmem_addr, TRUSTLET_STATUS, value, ssid); +} + +/* + * check if SPC access blocker programming is completed + */ +bool +ia_css_syscom_is_ab_spc_ready( + struct ia_css_syscom_context *ctx +) +{ + unsigned int value; + + /* We only expect the call from non-secure context only */ + if (ctx->secure) { + IA_CSS_TRACE_0(SYSCOM, ERROR, "ia_css_syscom_is_spc_ab_ready - Please call from non-secure context\n"); + return false; + } + + value = regmem_load_32(ctx->cell_dmem_addr, AB_SPC_STATUS, ctx->env.ssid); + IA_CSS_TRACE_3(SYSCOM, INFO, + "ia_css_syscom_is_spc_ab_ready AB_SPC_STATUS @ dmem_addr %#x ssid %d - value %#x\n", + ctx->cell_dmem_addr, ctx->env.ssid, value); + + return (value == AB_SPC_READY); +} +#endif /* HAS_DUAL_CMD_CTX_SUPPORT */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/src/ia_css_syscom_config_fw.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/src/ia_css_syscom_config_fw.h new file mode 100644 index 0000000000000..0cacd5a34934d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/src/ia_css_syscom_config_fw.h @@ -0,0 +1,69 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONFIG_FW_H +#define __IA_CSS_SYSCOM_CONFIG_FW_H + +#include "type_support.h" + +enum { + /* Program load or explicit host setting should init to this */ + SYSCOM_STATE_UNINIT = 0x57A7E000, + /* SP Syscom sets this when it is ready for use */ + SYSCOM_STATE_READY = 0x57A7E001, + /* SP Syscom sets this when no more syscom accesses will happen */ + SYSCOM_STATE_INACTIVE = 0x57A7E002 +}; + +enum { + /* Program load or explicit host setting should init to this */ + SYSCOM_COMMAND_UNINIT = 0x57A7F000, + /* Host Syscom requests syscom to become inactive */ + SYSCOM_COMMAND_INACTIVE = 0x57A7F001 +}; + +#if HAS_DUAL_CMD_CTX_SUPPORT +enum { + /* Program load or explicit host setting should init to this */ + TRUSTLET_UNINIT = 0x57A8E000, + /* Host Syscom informs SP that Trustlet exists */ + TRUSTLET_EXIST = 0x57A8E001, + /* Host Syscom informs SP that Trustlet does not exist */ + TRUSTLET_NOT_EXIST = 0x57A8E002 +}; + +enum { + /* Program load or explicit setting initialized by SP */ + AB_SPC_NOT_READY = 0x57A8F000, + /* SP informs host that SPC access programming is completed */ + AB_SPC_READY = 0x57A8F001 +}; +#endif + +/* firmware config: data that sent from the host to SP via DDR */ +/* Cell copies data into a context */ + +struct ia_css_syscom_config_fw { + unsigned int firmware_address; + + unsigned int num_input_queues; + unsigned int num_output_queues; + unsigned int input_queue; /* hmm_ptr / struct queue* */ + unsigned int output_queue; /* hmm_ptr / struct queue* */ + + unsigned int specific_addr; /* vied virtual address */ + unsigned int specific_size; +}; + +#endif /* __IA_CSS_SYSCOM_CONFIG_FW_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/src/ia_css_syscom_context.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/src/ia_css_syscom_context.h new file mode 100644 index 0000000000000..ecf22f6b7ac53 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/src/ia_css_syscom_context.h @@ -0,0 +1,65 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_SYSCOM_CONTEXT_H +#define __IA_CSS_SYSCOM_CONTEXT_H + +#include + +#include "port_env_struct.h" +#include + +/* host context */ +struct ia_css_syscom_context { + vied_virtual_address_t cell_firmware_addr; + unsigned int cell_regs_addr; + unsigned int cell_dmem_addr; + + struct port_env env; + + unsigned int num_input_queues; + unsigned int num_output_queues; + + /* array of input queues (from host to SP) */ + struct sys_queue *input_queue; + /* array of output queues (from SP to host) */ + struct sys_queue *output_queue; + + struct send_port *send_port; + struct recv_port *recv_port; + + unsigned int regmem_idx; + unsigned int free_buf; + + host_virtual_address_t config_host_addr; + host_virtual_address_t input_queue_host_addr; + host_virtual_address_t output_queue_host_addr; + host_virtual_address_t specific_host_addr; + host_virtual_address_t ibuf_host_addr; + host_virtual_address_t obuf_host_addr; + + vied_virtual_address_t config_vied_addr; + vied_virtual_address_t input_queue_vied_addr; + vied_virtual_address_t output_queue_vied_addr; + vied_virtual_address_t specific_vied_addr; + vied_virtual_address_t ibuf_vied_addr; + vied_virtual_address_t obuf_vied_addr; + + /* if true; secure syscom object as in VTIO Case + * if false, non-secure syscom + */ + bool secure; +}; + +#endif /* __IA_CSS_SYSCOM_CONTEXT_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/syscom.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/syscom.mk new file mode 100644 index 0000000000000..8d36b8928af55 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/syscom/syscom.mk @@ -0,0 +1,42 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is SYSCOM + +SYSCOM_DIR=$${MODULES_DIR}/syscom + +SYSCOM_INTERFACE=$(SYSCOM_DIR)/interface +SYSCOM_SOURCES1=$(SYSCOM_DIR)/src + +SYSCOM_HOST_FILES += $(SYSCOM_SOURCES1)/ia_css_syscom.c + +SYSCOM_HOST_CPPFLAGS += -I$(SYSCOM_INTERFACE) +SYSCOM_HOST_CPPFLAGS += -I$(SYSCOM_SOURCES1) +SYSCOM_HOST_CPPFLAGS += -I$${MODULES_DIR}/devices +ifdef REGMEM_SECURE_OFFSET +SYSCOM_HOST_CPPFLAGS += -DREGMEM_SECURE_OFFSET=$(REGMEM_SECURE_OFFSET) +else +SYSCOM_HOST_CPPFLAGS += -DREGMEM_SECURE_OFFSET=0 +endif + +SYSCOM_FW_FILES += $(SYSCOM_SOURCES1)/ia_css_syscom_fw.c + +SYSCOM_FW_CPPFLAGS += -I$(SYSCOM_INTERFACE) +SYSCOM_FW_CPPFLAGS += -I$(SYSCOM_SOURCES1) +SYSCOM_FW_CPPFLAGS += -DREGMEM_OFFSET=$(REGMEM_OFFSET) +ifdef REGMEM_SECURE_OFFSET +SYSCOM_FW_CPPFLAGS += -DREGMEM_SECURE_OFFSET=$(REGMEM_SECURE_OFFSET) +else +SYSCOM_FW_CPPFLAGS += -DREGMEM_SECURE_OFFSET=0 +endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/trace/interface/ia_css_trace.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/trace/interface/ia_css_trace.h new file mode 100644 index 0000000000000..b85b1810f1070 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/trace/interface/ia_css_trace.h @@ -0,0 +1,883 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +/*! \file */ + +#ifndef __IA_CSS_TRACE_H +#define __IA_CSS_TRACE_H + +/* +** Configurations +*/ + +/** + * STEP 1: Define {Module Name}_TRACE_METHOD to one of the following. + * Where: + * {Module Name} is the name of the targeted module. + * + * Example: + * #define NCI_DMA_TRACE_METHOD IA_CSS_TRACE_METHOD_NATIVE + */ + +/**< Use whatever method of tracing that best suits the platform + * this code is compiled for. + */ +#define IA_CSS_TRACE_METHOD_NATIVE 1 +/**< Use the Tracing NCI. */ +#define IA_CSS_TRACE_METHOD_TRACE 2 + +/** + * STEP 2: Define {Module Name}_TRACE_LEVEL_{Level} to one of the following. + * Where: + * {Module Name} is the name of the targeted module. + * {Level}, in decreasing order of severity, is one of the + * following values: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * + * Example: + * #define NCI_DMA_TRACE_LEVEL_ASSERT IA_CSS_TRACE_LEVEL_DISABLED + * #define NCI_DMA_TRACE_LEVEL_ERROR IA_CSS_TRACE_LEVEL_ENABLED + */ +/**< Disables the corresponding trace level. */ +#define IA_CSS_TRACE_LEVEL_DISABLED 0 +/**< Enables the corresponding trace level. */ +#define IA_CSS_TRACE_LEVEL_ENABLED 1 + +/* + * Used in macro definition with do-while loop + * for removing checkpatch warnings + */ +#define IA_CSS_TRACE_FILE_DUMMY_DEFINE + +/** + * STEP 3: Define IA_CSS_TRACE_PRINT_FILE_LINE to have file name and + * line printed with every log message. + * + * Example: + * #define IA_CSS_TRACE_PRINT_FILE_LINE + */ + +/* +** Interface +*/ + +/* +** Static +*/ + +/** + * Logs a message with zero arguments if the targeted severity level is enabled + * at compile-time. + * @param module The targeted module. + * @param severity The severity level of the trace message. In decreasing order: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * @param format The message to be traced. + */ +#define IA_CSS_TRACE_0(module, severity, format) \ + IA_CSS_TRACE_IMPL(module, 0, severity, format) + +/** + * Logs a message with one argument if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_1(module, severity, format, a1) \ + IA_CSS_TRACE_IMPL(module, 1, severity, format, a1) + +/** + * Logs a message with two arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_2(module, severity, format, a1, a2) \ + IA_CSS_TRACE_IMPL(module, 2, severity, format, a1, a2) + +/** + * Logs a message with three arguments if the targeted severity level + * is enabled at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_3(module, severity, format, a1, a2, a3) \ + IA_CSS_TRACE_IMPL(module, 3, severity, format, a1, a2, a3) + +/** + * Logs a message with four arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_4(module, severity, format, a1, a2, a3, a4) \ + IA_CSS_TRACE_IMPL(module, 4, severity, format, a1, a2, a3, a4) + +/** + * Logs a message with five arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_5(module, severity, format, a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_IMPL(module, 5, severity, format, a1, a2, a3, a4, a5) + +/** + * Logs a message with six arguments if the targeted severity level is enabled + * at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_6(module, severity, format, a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_IMPL(module, 6, severity, format, a1, a2, a3, a4, a5, a6) + +/** + * Logs a message with seven arguments if the targeted severity level + * is enabled at compile-time. + * @see IA_CSS_TRACE_0 + */ +#define IA_CSS_TRACE_7(module, severity, format, a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_IMPL(module, 7, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) + +/* +** Dynamic +*/ + +/** +* Declares, but does not define, dynamic tracing functions and variables +* for module \p module. For each module, place an instance of this macro +* in the compilation unit in which you want to use dynamic tracing facility +* so as to inform the compiler of the declaration of the available functions. +* An invocation of this function does not enable any of the available tracing +* levels. Do not place a semicolon after a call to this macro. +* @see IA_CSS_TRACE_DYNAMIC_DEFINE +*/ +#define IA_CSS_TRACE_DYNAMIC_DECLARE(module) \ + IA_CSS_TRACE_DYNAMIC_DECLARE_IMPL(module) +/** +* Declares the configuration function for the dynamic api seperatly, if one +* wants to use it. +*/ +#define IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC(module) \ + IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC_IMPL(module) + +/** +* Defines dynamic tracing functions and variables for module \p module. +* For each module, place an instance of this macro in one, and only one, +* of your SOURCE files so as to allow the linker resolve the related symbols. +* An invocation of this macro does not enable any of the available tracing +* levels. Do not place a semicolon after a call to this macro. +* @see IA_CSS_TRACE_DYNAMIC_DECLARE +*/ +#define IA_CSS_TRACE_DYNAMIC_DEFINE(module) \ + IA_CSS_TRACE_DYNAMIC_DEFINE_IMPL(module) +/** +* Defines the configuration function for the dynamic api seperatly, if one +* wants to use it. +*/ +#define IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC(module) \ + IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC_IMPL(module) + +/** + * Logs a message with zero arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @param module The targeted module. + * @param severity The severity level of the trace message. In decreasing order: + * {ASSERT, ERROR, WARNING, INFO, DEBUG, VERBOSE}. + * @param format The message to be traced. + */ +#define IA_CSS_TRACE_DYNAMIC_0(module, severity, format) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 0, severity, format) + +/** + * Logs a message with one argument if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_1(module, severity, format, a1) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 1, severity, format, a1) + +/** + * Logs a message with two arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_2(module, severity, format, a1, a2) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 2, severity, format, a1, a2) + +/** + * Logs a message with three arguments if the targeted severity level + * is enabled both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_3(module, severity, format, a1, a2, a3) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 3, severity, format, a1, a2, a3) + +/** + * Logs a message with four arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_4(module, severity, format, a1, a2, a3, a4) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 4, severity, format, a1, a2, a3, a4) + +/** + * Logs a message with five arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_5(module, severity, format, a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 5, severity, format, \ + a1, a2, a3, a4, a5) + +/** + * Logs a message with six arguments if the targeted severity level is enabled + * both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_6(module, severity, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 6, severity, format, \ + a1, a2, a3, a4, a5, a6) + +/** + * Logs a message with seven arguments if the targeted severity level + * is enabled both at compile-time, and run-time. + * @see IA_CSS_TRACE_DYNAMIC_0 + */ +#define IA_CSS_TRACE_DYNAMIC_7(module, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_DYNAMIC_IMPL(module, 7, severity, format, \ + a1, a2, a3, a4, a5, a6, a7) + +/* +** Implementation +*/ + +/* CAT */ +#define IA_CSS_TRACE_CAT_IMPL(a, b) a ## b +#define IA_CSS_TRACE_CAT(a, b) IA_CSS_TRACE_CAT_IMPL(a, b) + +/* Bridge */ +#if defined(__HIVECC) || defined(__GNUC__) +#define IA_CSS_TRACE_IMPL(module, argument_count, severity, arguments ...) \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_, \ + argument_count \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_LEVEL_ \ + ), \ + severity \ + ) \ + ( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_SEVERITY_, \ + severity \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + #module, \ + ## arguments \ + ) \ + ) + +/* Bridge */ +#define IA_CSS_TRACE_DYNAMIC_IMPL(module, argument_count, severity, \ + arguments ...) \ + do { \ + if (IA_CSS_TRACE_CAT(IA_CSS_TRACE_CAT(module, _trace_level_), \ + severity)) { \ + IA_CSS_TRACE_IMPL(module, argument_count, severity, \ + ## arguments); \ + } \ + } while (0) +#elif defined(_MSC_VER) +#define IA_CSS_TRACE_IMPL(module, argument_count, severity, ...) \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_, \ + argument_count \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_LEVEL_ \ + ), \ + severity \ + ) \ + ( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_CAT( \ + IA_CSS_TRACE_SEVERITY_, \ + severity \ + ), \ + _ \ + ), \ + IA_CSS_TRACE_CAT( \ + module, \ + _TRACE_METHOD \ + ) \ + ), \ + #module, \ + __VA_ARGS__ \ + ) \ + ) + +/* Bridge */ +#define IA_CSS_TRACE_DYNAMIC_IMPL(module, argument_count, severity, ...) \ + do { \ + if (IA_CSS_TRACE_CAT(IA_CSS_TRACE_CAT(module, _trace_level_), \ + severity)) { \ + IA_CSS_TRACE_IMPL(module, argument_count, severity, \ + __VA_ARGS__); \ + } \ + } while (0) +#endif + +/* +** Native Backend +*/ + +#if defined(__HIVECC) + #define IA_CSS_TRACE_PLATFORM_CELL +#elif defined(__GNUC__) + #define IA_CSS_TRACE_PLATFORM_HOST + + #define IA_CSS_TRACE_NATIVE(severity, module, format, arguments ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, module, \ + format), ## arguments); \ + } while (0) + /* TODO: In case Host Side tracing is needed to be mapped to the + * Tunit, the following "IA_CSS_TRACE_TRACE" needs to be modified from + * PRINT to vied_nci_tunit_print function calls + */ + #define IA_CSS_TRACE_TRACE(severity, module, format, arguments ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, module, \ + format), ## arguments); \ + } while (0) + +#elif defined(_MSC_VER) + #define IA_CSS_TRACE_PLATFORM_HOST + + #define IA_CSS_TRACE_NATIVE(severity, module, format, ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, \ + module, format), __VA_ARGS__); \ + } while (0) + /* TODO: In case Host Side tracing is needed to be mapped to the + * Tunit, the following "IA_CSS_TRACE_TRACE" needs to be modified from + * PRINT to vied_nci_tunit_print function calls + */ + #define IA_CSS_TRACE_TRACE(severity, module, format, ...) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + PRINT(IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, \ + module, format), __VA_ARGS__); \ + } while (0) +#else + #error Unsupported platform! +#endif /* Platform */ + +#if defined(IA_CSS_TRACE_PLATFORM_CELL) + #include /* VOLATILE */ + + #ifdef IA_CSS_TRACE_PRINT_FILE_LINE + #define IA_CSS_TRACE_FILE_PRINT_COMMAND \ + do { \ + OP___printstring(__FILE__":") VOLATILE; \ + OP___printdec(__LINE__) VOLATILE; \ + OP___printstring("\n") VOLATILE; \ + } while (0) + #else + #define IA_CSS_TRACE_FILE_PRINT_COMMAND + #endif + + #define IA_CSS_TRACE_MODULE_SEVERITY_PRINT(module, severity) \ + do { \ + IA_CSS_TRACE_FILE_DUMMY_DEFINE; \ + OP___printstring("["module"]:["severity"]:") \ + VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_MSG_NATIVE(severity, module, format) \ + do { \ + IA_CSS_TRACE_FILE_PRINT_COMMAND; \ + OP___printstring("["module"]:["severity"]: "format) \ + VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_ARG_NATIVE(module, severity, i, value) \ + do { \ + IA_CSS_TRACE_MODULE_SEVERITY_PRINT(module, severity); \ + OP___dump(i, value) VOLATILE; \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_0(severity, module, format) \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format) + + #define IA_CSS_TRACE_NATIVE_1(severity, module, format, a1) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_2(severity, module, format, a1, a2) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_3(severity, module, format, a1, a2, a3) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_4(severity, module, format, \ + a1, a2, a3, a4) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 6, a6); \ + } while (0) + + #define IA_CSS_TRACE_NATIVE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + do { \ + IA_CSS_TRACE_MSG_NATIVE(severity, module, format); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 1, a1); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 2, a2); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 3, a3); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 4, a4); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 5, a5); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 6, a6); \ + IA_CSS_TRACE_ARG_NATIVE(module, severity, 7, a7); \ + } while (0) + /* + ** Tracing Backend + */ +#if !defined(HRT_CSIM) && !defined(NO_TUNIT) + #include "vied_nci_tunit.h" +#endif + #define IA_CSS_TRACE_AUG_FORMAT_TRACE(format, module) \ + "[" module "]" format " : PID = %x : Timestamp = %d : PC = %x" + + #define IA_CSS_TRACE_TRACE_0(severity, module, format) \ + vied_nci_tunit_print(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity) + + #define IA_CSS_TRACE_TRACE_1(severity, module, format, a1) \ + vied_nci_tunit_print1i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1) + + #define IA_CSS_TRACE_TRACE_2(severity, module, format, a1, a2) \ + vied_nci_tunit_print2i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2) + + #define IA_CSS_TRACE_TRACE_3(severity, module, format, a1, a2, a3) \ + vied_nci_tunit_print3i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3) + + #define IA_CSS_TRACE_TRACE_4(severity, module, format, a1, a2, a3, a4) \ + vied_nci_tunit_print4i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4) + + #define IA_CSS_TRACE_TRACE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + vied_nci_tunit_print5i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_TRACE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + vied_nci_tunit_print6i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_TRACE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + vied_nci_tunit_print7i(IA_CSS_TRACE_AUG_FORMAT_TRACE(format, \ + module), \ + severity, a1, a2, a3, a4, a5, a6, a7) + +#elif defined(IA_CSS_TRACE_PLATFORM_HOST) + #include "print_support.h" + + #ifdef IA_CSS_TRACE_PRINT_FILE_LINE + #define IA_CSS_TRACE_FILE_PRINT_COMMAND \ + PRINT("%s:%d:\n", __FILE__, __LINE__) + #else + #define IA_CSS_TRACE_FILE_PRINT_COMMAND + #endif + + #define IA_CSS_TRACE_FORMAT_AUG_NATIVE(severity, module, format) \ + "[" module "]:[" severity "]: " format + + #define IA_CSS_TRACE_NATIVE_0(severity, module, format) \ + IA_CSS_TRACE_NATIVE(severity, module, format) + + #define IA_CSS_TRACE_NATIVE_1(severity, module, format, a1) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1) + + #define IA_CSS_TRACE_NATIVE_2(severity, module, format, a1, a2) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2) + + #define IA_CSS_TRACE_NATIVE_3(severity, module, format, a1, a2, a3) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2, a3) + + #define IA_CSS_TRACE_NATIVE_4(severity, module, format, \ + a1, a2, a3, a4) \ + IA_CSS_TRACE_NATIVE(severity, module, format, a1, a2, a3, a4) + + #define IA_CSS_TRACE_NATIVE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_NATIVE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_NATIVE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_NATIVE(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) + + #define IA_CSS_TRACE_FORMAT_AUG_TRACE(severity, module, format) \ + "["module"]:["severity"]: "format + + #define IA_CSS_TRACE_TRACE_0(severity, module, format) \ + IA_CSS_TRACE_TRACE(severity, module, format) + + #define IA_CSS_TRACE_TRACE_1(severity, module, format, a1) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1) + + #define IA_CSS_TRACE_TRACE_2(severity, module, format, a1, a2) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2) + + #define IA_CSS_TRACE_TRACE_3(severity, module, format, a1, a2, a3) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2, a3) + + #define IA_CSS_TRACE_TRACE_4(severity, module, format, \ + a1, a2, a3, a4) \ + IA_CSS_TRACE_TRACE(severity, module, format, a1, a2, a3, a4) + + #define IA_CSS_TRACE_TRACE_5(severity, module, format, \ + a1, a2, a3, a4, a5) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5) + + #define IA_CSS_TRACE_TRACE_6(severity, module, format, \ + a1, a2, a3, a4, a5, a6) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5, a6) + + #define IA_CSS_TRACE_TRACE_7(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) \ + IA_CSS_TRACE_TRACE(severity, module, format, \ + a1, a2, a3, a4, a5, a6, a7) +#endif + +/* Disabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_1_0(severity, module, format) +#define IA_CSS_TRACE_1_1_0(severity, module, format, arg1) +#define IA_CSS_TRACE_2_1_0(severity, module, format, arg1, arg2) +#define IA_CSS_TRACE_3_1_0(severity, module, format, arg1, arg2, arg3) +#define IA_CSS_TRACE_4_1_0(severity, module, format, arg1, arg2, arg3, arg4) +#define IA_CSS_TRACE_5_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5) +#define IA_CSS_TRACE_6_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6) +#define IA_CSS_TRACE_7_1_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7) + +/* Enabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_1_1 IA_CSS_TRACE_NATIVE_0 +#define IA_CSS_TRACE_1_1_1 IA_CSS_TRACE_NATIVE_1 +#define IA_CSS_TRACE_2_1_1 IA_CSS_TRACE_NATIVE_2 +#define IA_CSS_TRACE_3_1_1 IA_CSS_TRACE_NATIVE_3 +#define IA_CSS_TRACE_4_1_1 IA_CSS_TRACE_NATIVE_4 +#define IA_CSS_TRACE_5_1_1 IA_CSS_TRACE_NATIVE_5 +#define IA_CSS_TRACE_6_1_1 IA_CSS_TRACE_NATIVE_6 +#define IA_CSS_TRACE_7_1_1 IA_CSS_TRACE_NATIVE_7 + +/* Enabled */ +/* Legend: IA_CSS_TRACE_SEVERITY_{Severity Level}_{Backend ID} */ +#define IA_CSS_TRACE_SEVERITY_ASSERT_1 "Assert" +#define IA_CSS_TRACE_SEVERITY_ERROR_1 "Error" +#define IA_CSS_TRACE_SEVERITY_WARNING_1 "Warning" +#define IA_CSS_TRACE_SEVERITY_INFO_1 "Info" +#define IA_CSS_TRACE_SEVERITY_DEBUG_1 "Debug" +#define IA_CSS_TRACE_SEVERITY_VERBOSE_1 "Verbose" + +/* Disabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_2_0(severity, module, format) +#define IA_CSS_TRACE_1_2_0(severity, module, format, arg1) +#define IA_CSS_TRACE_2_2_0(severity, module, format, arg1, arg2) +#define IA_CSS_TRACE_3_2_0(severity, module, format, arg1, arg2, arg3) +#define IA_CSS_TRACE_4_2_0(severity, module, format, arg1, arg2, arg3, arg4) +#define IA_CSS_TRACE_5_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5) +#define IA_CSS_TRACE_6_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6) +#define IA_CSS_TRACE_7_2_0(severity, module, format, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7) + +/* Enabled */ +/* Legend: IA_CSS_TRACE_{Argument Count}_{Backend ID}_{Enabled} */ +#define IA_CSS_TRACE_0_2_1 IA_CSS_TRACE_TRACE_0 +#define IA_CSS_TRACE_1_2_1 IA_CSS_TRACE_TRACE_1 +#define IA_CSS_TRACE_2_2_1 IA_CSS_TRACE_TRACE_2 +#define IA_CSS_TRACE_3_2_1 IA_CSS_TRACE_TRACE_3 +#define IA_CSS_TRACE_4_2_1 IA_CSS_TRACE_TRACE_4 +#define IA_CSS_TRACE_5_2_1 IA_CSS_TRACE_TRACE_5 +#define IA_CSS_TRACE_6_2_1 IA_CSS_TRACE_TRACE_6 +#define IA_CSS_TRACE_7_2_1 IA_CSS_TRACE_TRACE_7 + +/* Enabled */ +/* Legend: IA_CSS_TRACE_SEVERITY_{Severity Level}_{Backend ID} */ +#define IA_CSS_TRACE_SEVERITY_ASSERT_2 VIED_NCI_TUNIT_MSG_SEVERITY_FATAL +#define IA_CSS_TRACE_SEVERITY_ERROR_2 VIED_NCI_TUNIT_MSG_SEVERITY_ERROR +#define IA_CSS_TRACE_SEVERITY_WARNING_2 VIED_NCI_TUNIT_MSG_SEVERITY_WARNING +#define IA_CSS_TRACE_SEVERITY_INFO_2 VIED_NCI_TUNIT_MSG_SEVERITY_NORMAL +#define IA_CSS_TRACE_SEVERITY_DEBUG_2 VIED_NCI_TUNIT_MSG_SEVERITY_USER1 +#define IA_CSS_TRACE_SEVERITY_VERBOSE_2 VIED_NCI_TUNIT_MSG_SEVERITY_USER2 + +/* +** Dynamicism +*/ + +#define IA_CSS_TRACE_DYNAMIC_DECLARE_IMPL(module) \ + do { \ + void IA_CSS_TRACE_CAT(module, _trace_assert_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_assert_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_error_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_error_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_warning_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_warning_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_info_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_info_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_debug_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_debug_disable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_enable)(void); \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_disable)(void); \ + } while (0) + +#define IA_CSS_TRACE_DYNAMIC_DECLARE_CONFIG_FUNC_IMPL(module) \ + do { \ + IA_CSS_TRACE_FILE_DUMMY_DEFINE; \ + void IA_CSS_TRACE_CAT(module, _trace_configure)\ + (int argc, const char *const *argv); \ + } while (0) + +#include "platform_support.h" +#include "type_support.h" + +#define IA_CSS_TRACE_DYNAMIC_DEFINE_IMPL(module) \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_assert); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_error); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_warning); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_info); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_debug); \ + static uint8_t IA_CSS_TRACE_CAT(module, _trace_level_verbose); \ + \ + void IA_CSS_TRACE_CAT(module, _trace_assert_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_assert) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_assert_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_assert) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_error_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_error) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_error_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_error) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_warning_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_warning) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_warning_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_warning) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_info_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_info) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_info_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_info) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_debug_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_debug) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_debug_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_debug) = 0; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_enable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_verbose) = 1; \ + } \ + \ + void IA_CSS_TRACE_CAT(module, _trace_verbose_disable)(void) \ + { \ + IA_CSS_TRACE_CAT(module, _trace_level_verbose) = 0; \ + } + +#define IA_CSS_TRACE_DYNAMIC_DEFINE_CONFIG_FUNC_IMPL(module) \ +void IA_CSS_TRACE_CAT(module, _trace_configure)(const int argc, \ + const char *const *const argv) \ +{ \ + int i = 1; \ + const char *levels = 0; \ + \ + while (i < argc) { \ + if (!strcmp(argv[i], "-" #module "_trace")) { \ + ++i; \ + \ + if (i < argc) { \ + levels = argv[i]; \ + \ + while (*levels) { \ + switch (*levels++) { \ + case 'a': \ + IA_CSS_TRACE_CAT \ + (module, _trace_assert_enable)(); \ + break; \ + \ + case 'e': \ + IA_CSS_TRACE_CAT \ + (module, _trace_error_enable)(); \ + break; \ + \ + case 'w': \ + IA_CSS_TRACE_CAT \ + (module, _trace_warning_enable)(); \ + break; \ + \ + case 'i': \ + IA_CSS_TRACE_CAT \ + (module, _trace_info_enable)(); \ + break; \ + \ + case 'd': \ + IA_CSS_TRACE_CAT \ + (module, _trace_debug_enable)(); \ + break; \ + \ + case 'v': \ + IA_CSS_TRACE_CAT \ + (module, _trace_verbose_enable)(); \ + break; \ + \ + default: \ + } \ + } \ + } \ + } \ + \ + ++i; \ + } \ +} + +#endif /* __IA_CSS_TRACE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/trace/trace.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/trace/trace.mk new file mode 100644 index 0000000000000..b232880b882bd --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/trace/trace.mk @@ -0,0 +1,40 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE Trace + +# Dependencies +IA_CSS_TRACE_SUPPORT = $${MODULES_DIR}/support + +# API +IA_CSS_TRACE = $${MODULES_DIR}/trace +IA_CSS_TRACE_INTERFACE = $(IA_CSS_TRACE)/interface + +# +# Host +# + +# Host CPP Flags +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE_SUPPORT) +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE_INTERFACE) +IA_CSS_TRACE_HOST_CPPFLAGS += -I$(IA_CSS_TRACE)/trace_modules + +# +# Firmware +# + +# Firmware CPP Flags +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE_SUPPORT) +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE_INTERFACE) +IA_CSS_TRACE_FW_CPPFLAGS += -I$(IA_CSS_TRACE)/trace_modules diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/shared_memory_access.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/shared_memory_access.h new file mode 100644 index 0000000000000..fd11c12367fec --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/shared_memory_access.h @@ -0,0 +1,138 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _SHARED_MEMORY_ACCESS_H +#define _SHARED_MEMORY_ACCESS_H + +#include +#include +#include + +typedef enum { + sm_esuccess, + sm_enomem, + sm_ezeroalloc, + sm_ebadvaddr, + sm_einternalerror, + sm_ecorruption, + sm_enocontiguousmem, + sm_enolocmem, + sm_emultiplefree, +} shared_memory_error; + +/** + * \brief Virtual address of (DDR) shared memory space as seen from the VIED subsystem + */ +typedef uint32_t vied_virtual_address_t; + +/** + * \brief Virtual address of (DDR) shared memory space as seen from the host + */ +typedef unsigned long long host_virtual_address_t; + +/** + * \brief List of physical addresses of (DDR) shared memory space. This is used to represent a list of physical pages. + */ +typedef struct shared_memory_physical_page_list_s *shared_memory_physical_page_list; +typedef struct shared_memory_physical_page_list_s { + shared_memory_physical_page_list next; + vied_physical_address_t address; +} shared_memory_physical_page_list_s; + + +/** + * \brief Initialize the shared memory interface administration on the host. + * \param idm: id of ddr memory + * \param host_ddr_addr: physical address of memory as seen from host + * \param memory_size: size of ddr memory in bytes + * \param ps: size of page in bytes (for instance 4096) + */ +int shared_memory_allocation_initialize(vied_memory_t idm, vied_physical_address_t host_ddr_addr, size_t memory_size, size_t ps); + +/** + * \brief De-initialize the shared memory interface administration on the host. + * + */ +void shared_memory_allocation_uninitialize(vied_memory_t idm); + +/** + * \brief Allocate (DDR) shared memory space and return a host virtual address. Returns NULL when insufficient memory available + */ +host_virtual_address_t shared_memory_alloc(vied_memory_t idm, size_t bytes); + +/** + * \brief Free (DDR) shared memory space. +*/ +void shared_memory_free(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Translate a virtual host.address to a physical address. +*/ +vied_physical_address_t shared_memory_virtual_host_to_physical_address(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Return the allocated physical pages for a virtual host.address. +*/ +shared_memory_physical_page_list shared_memory_virtual_host_to_physical_pages(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Destroy a shared_memory_physical_page_list. +*/ +void shared_memory_physical_pages_list_destroy(shared_memory_physical_page_list ppl); + +/** + * \brief Store a byte into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_8(vied_memory_t idm, host_virtual_address_t addr, uint8_t data); + +/** + * \brief Store a 16-bit word into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_16(vied_memory_t idm, host_virtual_address_t addr, uint16_t data); + +/** + * \brief Store a 32-bit word into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store_32(vied_memory_t idm, host_virtual_address_t addr, uint32_t data); + +/** + * \brief Store a number of bytes into (DDR) shared memory space using a host virtual address + */ +void shared_memory_store(vied_memory_t idm, host_virtual_address_t addr, const void *data, size_t bytes); + +/** + * \brief Set a number of bytes of (DDR) shared memory space to 0 using a host virtual address + */ +void shared_memory_zero(vied_memory_t idm, host_virtual_address_t addr, size_t bytes); + +/** + * \brief Load a byte from (DDR) shared memory space using a host virtual address + */ +uint8_t shared_memory_load_8(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a 16-bit word from (DDR) shared memory space using a host virtual address + */ +uint16_t shared_memory_load_16(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a 32-bit word from (DDR) shared memory space using a host virtual address + */ +uint32_t shared_memory_load_32(vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Load a number of bytes from (DDR) shared memory space using a host virtual address + */ +void shared_memory_load(vied_memory_t idm, host_virtual_address_t addr, void *data, size_t bytes); + +#endif /* _SHARED_MEMORY_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/shared_memory_map.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/shared_memory_map.h new file mode 100644 index 0000000000000..1bbedcf9e7fd8 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/shared_memory_map.h @@ -0,0 +1,53 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _SHARED_MEMORY_MAP_H +#define _SHARED_MEMORY_MAP_H + +#include +#include +#include + +typedef void (*shared_memory_invalidate_mmu_tlb)(void); +typedef void (*shared_memory_set_page_table_base_address)(vied_physical_address_t); + +typedef void (*shared_memory_invalidate_mmu_tlb_ssid)(vied_subsystem_t id); +typedef void (*shared_memory_set_page_table_base_address_ssid)(vied_subsystem_t id, vied_physical_address_t); + +/** + * \brief Initialize the CSS virtual address system and MMU. The subsystem id will NOT be taken into account. +*/ +int shared_memory_map_initialize(vied_subsystem_t id, vied_memory_t idm, size_t mmu_ps, size_t mmu_pnrs, vied_physical_address_t ddr_addr, shared_memory_invalidate_mmu_tlb inv_tlb, shared_memory_set_page_table_base_address sbt); + +/** + * \brief Initialize the CSS virtual address system and MMU. The subsystem id will be taken into account. +*/ +int shared_memory_map_initialize_ssid(vied_subsystem_t id, vied_memory_t idm, size_t mmu_ps, size_t mmu_pnrs, vied_physical_address_t ddr_addr, shared_memory_invalidate_mmu_tlb_ssid inv_tlb, shared_memory_set_page_table_base_address_ssid sbt); + +/** + * \brief De-initialize the CSS virtual address system and MMU. +*/ +void shared_memory_map_uninitialize(vied_subsystem_t id, vied_memory_t idm); + +/** + * \brief Convert a host virtual address to a CSS virtual address and update the MMU. +*/ +vied_virtual_address_t shared_memory_map(vied_subsystem_t id, vied_memory_t idm, host_virtual_address_t addr); + +/** + * \brief Free a CSS virtual address and update the MMU. +*/ +void shared_memory_unmap(vied_subsystem_t id, vied_memory_t idm, vied_virtual_address_t addr); + + +#endif /* _SHARED_MEMORY_MAP_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_config.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_config.h new file mode 100644 index 0000000000000..33ae98e27605d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_config.h @@ -0,0 +1,33 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_CONFIG_H +#define _HRT_VIED_CONFIG_H + +/* Defines from the compiler: + * HRT_HOST - this is code running on the host + * HRT_CELL - this is code running on a cell + */ +#ifdef HRT_HOST +# define CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL 1 +# undef CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL + +#elif defined(HRT_CELL) +# undef CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL +# define CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL 1 + +#else /* !HRT_CELL */ +/* Allow neither HRT_HOST nor HRT_CELL for testing purposes */ +#endif /* !HRT_CELL */ + +#endif /* _HRT_VIED_CONFIG_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_memory_access_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_memory_access_types.h new file mode 100644 index 0000000000000..0b44492789e37 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_memory_access_types.h @@ -0,0 +1,36 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_MEMORY_ACCESS_TYPES_H +#define _HRT_VIED_MEMORY_ACCESS_TYPES_H + +/** Types for the VIED memory access interface */ + +#include "vied_types.h" + +/** + * \brief An identifier for a system memory. + * + * This identifier must be a compile-time constant. It is used in + * access to system memory. + */ +typedef unsigned int vied_memory_t; + +#ifndef __HIVECC +/** + * \brief The type for a physical address + */ +typedef unsigned long long vied_physical_address_t; +#endif + +#endif /* _HRT_VIED_MEMORY_ACCESS_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_subsystem_access.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_subsystem_access.h new file mode 100644 index 0000000000000..879bcb41253a9 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_subsystem_access.h @@ -0,0 +1,70 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_H + +#include +#include "vied_config.h" +#include "vied_subsystem_access_types.h" + +#if !defined(CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL) && \ + !defined(CFG_VIED_SUBSYSTEM_ACCESS_LIB_IMPL) +#error Implementation selection macro for vied subsystem access not defined +#endif + +#if defined(CFG_VIED_SUBSYSTEM_ACCESS_INLINE_IMPL) +#ifndef __HIVECC +#error "Inline implementation of subsystem access not supported for host" +#endif +#define _VIED_SUBSYSTEM_ACCESS_INLINE static inline +#include "vied_subsystem_access_impl.h" +#else +#define _VIED_SUBSYSTEM_ACCESS_INLINE +#endif + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_8(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint8_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_16(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint16_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store_32(vied_subsystem_t dev, + vied_subsystem_address_t addr, uint32_t data); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_store(vied_subsystem_t dev, + vied_subsystem_address_t addr, + const void *data, unsigned int size); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint8_t vied_subsystem_load_8(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint16_t vied_subsystem_load_16(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +uint32_t vied_subsystem_load_32(vied_subsystem_t dev, + vied_subsystem_address_t addr); + +_VIED_SUBSYSTEM_ACCESS_INLINE +void vied_subsystem_load(vied_subsystem_t dev, + vied_subsystem_address_t addr, + void *data, unsigned int size); + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_subsystem_access_initialization.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_subsystem_access_initialization.h new file mode 100644 index 0000000000000..344f31c4df104 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_subsystem_access_initialization.h @@ -0,0 +1,44 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H + +#include "vied_subsystem_access_types.h" + +/** @brief Initialises the access of a subsystem. + * @param[in] system The subsystem for which the access has to be initialised. + * + * vied_subsystem_access_initialize initilalises the access a subsystem. + * It sets the base address of the subsystem. This base address is extracted from the hsd file. + * + */ +void +vied_subsystem_access_initialize(vied_subsystem_t system); + + +/** @brief Initialises the access of multiple subsystems. + * @param[in] nr _subsystems The number of subsystems for which the access has to be initialised. + * @param[in] dev_base_addresses A pointer to an array of base addresses of subsystems. + * The size of this array must be "nr_subsystems". + * This array must be available during the accesses of the subsystem. + * + * vied_subsystems_access_initialize initilalises the access to multiple subsystems. + * It sets the base addresses of the subsystems that are provided by the array dev_base_addresses. + * + */ +void +vied_subsystems_access_initialize(unsigned int nr_subsystems + , const vied_subsystem_base_address_t *base_addresses); + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_INITIALIZE_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_subsystem_access_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_subsystem_access_types.h new file mode 100644 index 0000000000000..75fef6c4ddba2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_subsystem_access_types.h @@ -0,0 +1,34 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H +#define _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H + +/** Types for the VIED subsystem access interface */ +#include + +/** \brief An identifier for a VIED subsystem. + * + * This identifier must be a compile-time constant. It is used in + * access to a VIED subsystem. + */ +typedef unsigned int vied_subsystem_t; + + +/** \brief An address within a VIED subsystem */ +typedef uint32_t vied_subsystem_address_t; + +/** \brief A base address of a VIED subsystem seen from the host */ +typedef unsigned long long vied_subsystem_base_address_t; + +#endif /* _HRT_VIED_SUBSYSTEM_ACCESS_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_types.h new file mode 100644 index 0000000000000..0acfdbb00cfa3 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied/vied/vied_types.h @@ -0,0 +1,45 @@ +/* +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ +#ifndef _HRT_VIED_TYPES_H +#define _HRT_VIED_TYPES_H + +/** Types shared by VIED interfaces */ + +#include + +/** \brief An address within a VIED subsystem + * + * This will eventually replace teh vied_memory_address_t and vied_subsystem_address_t + */ +typedef uint32_t vied_address_t; + +/** \brief Memory address type + * + * A memory address is an offset within a memory. + */ +typedef uint32_t vied_memory_address_t; + +/** \brief Master port id */ +typedef int vied_master_port_id_t; + +/** + * \brief Require the existence of a certain type + * + * This macro can be used in interface header files to ensure that + * an implementation define type with a specified name exists. + */ +#define _VIED_REQUIRE_TYPE(T) enum { _VIED_SIZEOF_##T = sizeof(T) } + + +#endif /* _HRT_VIED_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_nci_acb/interface/vied_nci_acb_route_type.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_nci_acb/interface/vied_nci_acb_route_type.h new file mode 100644 index 0000000000000..b09d9f4d5d427 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_nci_acb/interface/vied_nci_acb_route_type.h @@ -0,0 +1,39 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef VIED_NCI_ACB_ROUTE_TYPE_H_ +#define VIED_NCI_ACB_ROUTE_TYPE_H_ + +#include "type_support.h" + +typedef enum { + NCI_ACB_PORT_ISP = 0, + NCI_ACB_PORT_ACC = 1, + NCI_ACB_PORT_INVALID = 0xFF +} nci_acb_port_t; + +typedef struct { + /* 0 = ISP, 1 = Acc */ + nci_acb_port_t in_select; + /* 0 = ISP, 1 = Acc */ + nci_acb_port_t out_select; + /* When set, Ack will be sent only when Eof arrives */ + uint32_t ignore_line_num; + /* Fork adapter to enable streaming to both output + * (next acb out and isp out) + */ + uint32_t fork_acb_output; +} nci_acb_route_t; + +#endif /* VIED_NCI_ACB_ROUTE_TYPE_H_ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_param_storage_class.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_param_storage_class.h new file mode 100644 index 0000000000000..1ea7e729078c2 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_param_storage_class.h @@ -0,0 +1,28 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_PARAM_STORAGE_CLASS_H +#define __IA_CSS_PARAM_STORAGE_CLASS_H + +#include "storage_class.h" + +#ifndef __INLINE_PARAMETERS__ +#define IA_CSS_PARAMETERS_STORAGE_CLASS_H STORAGE_CLASS_EXTERN +#define IA_CSS_PARAMETERS_STORAGE_CLASS_C +#else +#define IA_CSS_PARAMETERS_STORAGE_CLASS_H STORAGE_CLASS_INLINE +#define IA_CSS_PARAMETERS_STORAGE_CLASS_C STORAGE_CLASS_INLINE +#endif + +#endif /* __IA_CSS_PARAM_STORAGE_CLASS_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal.h new file mode 100644 index 0000000000000..4cc71be3fc389 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal.h @@ -0,0 +1,188 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_H +#define __IA_CSS_TERMINAL_H + +#include "type_support.h" +#include "ia_css_terminal_types.h" +#include "ia_css_param_storage_class.h" + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_param_in_terminal_get_descriptor_size( + const unsigned int nof_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_param_section_desc_t * +ia_css_param_in_terminal_get_param_section_desc( + const ia_css_param_terminal_t *param_terminal, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_param_out_terminal_get_descriptor_size( + const unsigned int nof_sections, + const unsigned int nof_fragments +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_param_section_desc_t * +ia_css_param_out_terminal_get_param_section_desc( + const ia_css_param_terminal_t *param_terminal, + const unsigned int section_index, + const unsigned int nof_sections, + const unsigned int fragment_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_param_terminal_create( + ia_css_param_terminal_t *param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal +); + + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_spatial_param_terminal_get_descriptor_size( + const unsigned int nof_frame_param_sections, + const unsigned int nof_fragments +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_fragment_grid_desc_t * +ia_css_spatial_param_terminal_get_fragment_grid_desc( + const ia_css_spatial_param_terminal_t *spatial_param_terminal, + const unsigned int fragment_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_frame_grid_param_section_desc_t * +ia_css_spatial_param_terminal_get_frame_grid_param_section_desc( + const ia_css_spatial_param_terminal_t *spatial_param_terminal, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_spatial_param_terminal_create( + ia_css_spatial_param_terminal_t *spatial_param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal, + const unsigned int nof_fragments, + const uint32_t kernel_id +); + + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_sliced_param_terminal_get_descriptor_size( + const unsigned int nof_slice_param_sections, + const unsigned int nof_slices[], + const unsigned int nof_fragments +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_fragment_slice_desc_t * +ia_css_sliced_param_terminal_get_fragment_slice_desc( + const ia_css_sliced_param_terminal_t *sliced_param_terminal, + const unsigned int fragment_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_slice_param_section_desc_t * +ia_css_sliced_param_terminal_get_slice_param_section_desc( + const ia_css_sliced_param_terminal_t *sliced_param_terminal, + const unsigned int fragment_index, + const unsigned int slice_index, + const unsigned int section_index, + const unsigned int nof_slice_param_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_sliced_param_terminal_create( + ia_css_sliced_param_terminal_t *sliced_param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal, + const unsigned int nof_slice_param_sections, + const unsigned int nof_slices[], + const unsigned int nof_fragments, + const uint32_t kernel_id +); + + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_program_terminal_get_descriptor_size( + const unsigned int nof_fragments, + const unsigned int nof_fragment_param_sections, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int nof_command_objs +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_fragment_param_section_desc_t * +ia_css_program_terminal_get_frgmnt_prm_sct_desc( + const ia_css_program_terminal_t *program_terminal, + const unsigned int fragment_index, + const unsigned int section_index, + const unsigned int nof_fragment_param_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_kernel_fragment_sequencer_info_desc_t * +ia_css_program_terminal_get_kernel_frgmnt_seq_info_desc( + const ia_css_program_terminal_t *program_terminal, + const unsigned int fragment_index, + const unsigned int info_index, + const unsigned int nof_kernel_fragment_sequencer_infos +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_program_terminal_create( + ia_css_program_terminal_t *program_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const unsigned int nof_fragments, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int nof_command_objs +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_program_terminal_get_command_base_offset( + const ia_css_program_terminal_t *program_terminal, + const unsigned int nof_fragments, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int commands_slots_used, + uint16_t *command_desc_offset +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +uint16_t *ia_css_program_terminal_get_line_count( + const ia_css_kernel_fragment_sequencer_command_desc_t + *kernel_fragment_sequencer_command_desc_base, + const unsigned int set_count +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_spatial_param_terminal_get_descriptor_size( + const unsigned int nof_frame_param_sections, + const unsigned int nof_fragments +); + +#ifdef __INLINE_PARAMETERS__ +#include "ia_css_terminal_impl.h" +#endif /* __INLINE_PARAMETERS__ */ + +#endif /* __IA_CSS_TERMINAL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest.h new file mode 100644 index 0000000000000..ca0a436082cf6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest.h @@ -0,0 +1,109 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_MANIFEST_H +#define __IA_CSS_TERMINAL_MANIFEST_H + +#include "type_support.h" +#include "ia_css_param_storage_class.h" +#include "ia_css_terminal_manifest_types.h" + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_param_terminal_manifest_get_size( + const unsigned int nof_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_param_terminal_manifest_init( + ia_css_param_terminal_manifest_t *param_terminal, + const uint16_t section_count +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_param_manifest_section_desc_t * +ia_css_param_terminal_manifest_get_prm_sct_desc( + const ia_css_param_terminal_manifest_t *param_terminal_manifest, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_spatial_param_terminal_manifest_get_size( + const unsigned int nof_frame_param_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_spatial_param_terminal_manifest_init( + ia_css_spatial_param_terminal_manifest_t *spatial_param_terminal, + const uint16_t section_count +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_frame_grid_param_manifest_section_desc_t * +ia_css_spatial_param_terminal_manifest_get_frm_grid_prm_sct_desc( + const ia_css_spatial_param_terminal_manifest_t * + spatial_param_terminal_manifest, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_sliced_param_terminal_manifest_get_size( + const unsigned int nof_slice_param_sections +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_sliced_param_terminal_manifest_init( + ia_css_sliced_param_terminal_manifest_t *sliced_param_terminal, + const uint16_t section_count +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_sliced_param_manifest_section_desc_t * +ia_css_sliced_param_terminal_manifest_get_sliced_prm_sct_desc( + const ia_css_sliced_param_terminal_manifest_t * + sliced_param_terminal_manifest, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +unsigned int ia_css_program_terminal_manifest_get_size( + const unsigned int nof_fragment_param_sections, + const unsigned int nof_kernel_fragment_sequencer_infos +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +int ia_css_program_terminal_manifest_init( + ia_css_program_terminal_manifest_t *program_terminal, + const uint16_t fragment_param_section_count, + const uint16_t kernel_fragment_seq_info_section_count +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_fragment_param_manifest_section_desc_t * +ia_css_program_terminal_manifest_get_frgmnt_prm_sct_desc( + const ia_css_program_terminal_manifest_t *program_terminal_manifest, + const unsigned int section_index +); + +IA_CSS_PARAMETERS_STORAGE_CLASS_H +ia_css_kernel_fragment_sequencer_info_manifest_desc_t * +ia_css_program_terminal_manifest_get_kernel_frgmnt_seq_info_desc( + const ia_css_program_terminal_manifest_t *program_terminal_manifest, + const unsigned int info_index +); + +#ifdef __INLINE_PARAMETERS__ +#include "ia_css_terminal_manifest_impl.h" +#endif /* __INLINE_PARAMETERS__ */ + +#endif /* __IA_CSS_TERMINAL_MANIFEST_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest_types.h new file mode 100644 index 0000000000000..fe146395a8f4f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_manifest_types.h @@ -0,0 +1,342 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_MANIFEST_TYPES_H +#define __IA_CSS_TERMINAL_MANIFEST_TYPES_H + + +#include "ia_css_terminal_defs.h" +#include "type_support.h" +#include "ia_css_base_types.h" +#include "ia_css_terminal_manifest_base_types.h" + +#define N_PADDING_UINT8_IN_PARAM_TERMINAL_MANIFEST_SEC_STRUCT 1 +#define SIZE_OF_PARAM_TERMINAL_MANIFEST_SEC_STRUCT_IN_BITS \ + (1 * IA_CSS_UINT32_T_BITS \ + + 3 * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_PARAM_TERMINAL_MANIFEST_SEC_STRUCT * IA_CSS_UINT8_T_BITS) + +/* =============== Cached Param Terminal Manifest - START ============== */ +struct ia_css_param_manifest_section_desc_s { + /* Maximum size of the related parameter region */ + uint32_t max_mem_size; + /* Indication of the kernel this parameter belongs to */ + uint8_t kernel_id; + /* Memory targeted by this section + * (Register MMIO Interface/DMEM/VMEM/GMEM etc) + */ + uint8_t mem_type_id; + /* Region id within the specified memory */ + uint8_t region_id; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PARAM_TERMINAL_MANIFEST_SEC_STRUCT]; +}; + +typedef struct ia_css_param_manifest_section_desc_s + ia_css_param_manifest_section_desc_t; + + +#define N_PADDING_UINT8_IN_PARAM_TERMINAL_MAN_STRUCT 4 +#define SIZE_OF_PARAM_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + (SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + + (2*IA_CSS_UINT16_T_BITS) \ + + (N_PADDING_UINT8_IN_PARAM_TERMINAL_MAN_STRUCT * IA_CSS_UINT8_T_BITS)) + +/* Frame constant parameters terminal manifest */ +struct ia_css_param_terminal_manifest_s { + /* Parameter terminal manifest base */ + ia_css_terminal_manifest_t base; + /* + * Number of cached parameter sections, coming from manifest + * but also shared by the terminal + */ + uint16_t param_manifest_section_desc_count; + /* + * Points to the variable array of + * struct ia_css_param_section_desc_s + */ + uint16_t param_manifest_section_desc_offset; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PARAM_TERMINAL_MAN_STRUCT]; +}; + +typedef struct ia_css_param_terminal_manifest_s + ia_css_param_terminal_manifest_t; +/* ================= Cached Param Terminal Manifest - End ================ */ + + +/* ================= Spatial Param Terminal Manifest - START ============= */ + +#define SIZE_OF_FRAG_GRID_MAN_STRUCT_IN_BITS \ + ((IA_CSS_N_DATA_DIMENSION*IA_CSS_UINT16_T_BITS) \ + + (IA_CSS_N_DATA_DIMENSION*IA_CSS_UINT16_T_BITS)) + +struct ia_css_fragment_grid_manifest_desc_s { + /* Min resolution width/height of the spatial parameters + * for the fragment measured in compute units + */ + uint16_t min_fragment_grid_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Max resolution width/height of the spatial parameters + * for the fragment measured in compute units + */ + uint16_t max_fragment_grid_dimension[IA_CSS_N_DATA_DIMENSION]; +}; + +typedef struct ia_css_fragment_grid_manifest_desc_s + ia_css_fragment_grid_manifest_desc_t; + +#define N_PADDING_UINT8_IN_FRAME_GRID_PARAM_MAN_SEC_STRUCT 1 +#define SIZE_OF_FRAME_GRID_PARAM_MAN_SEC_STRUCT_IN_BITS \ + (1 * IA_CSS_UINT32_T_BITS \ + + 3 * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_FRAME_GRID_PARAM_MAN_SEC_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_frame_grid_param_manifest_section_desc_s { + /* Maximum buffer total size allowed for + * this frame of parameters + */ + uint32_t max_mem_size; + /* Memory space targeted by this section + * (Register MMIO Interface/DMEM/VMEM/GMEM etc) + */ + uint8_t mem_type_id; + /* Region id within the specified memory space */ + uint8_t region_id; + /* size in bytes of each compute unit for + * the specified memory space and region + */ + uint8_t elem_size; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_FRAME_GRID_PARAM_MAN_SEC_STRUCT]; +}; + +typedef struct ia_css_frame_grid_param_manifest_section_desc_s + ia_css_frame_grid_param_manifest_section_desc_t; + +#define SIZE_OF_FRAME_GRID_MAN_STRUCT_IN_BITS \ + ((IA_CSS_N_DATA_DIMENSION*IA_CSS_UINT16_T_BITS) \ + + (IA_CSS_N_DATA_DIMENSION*IA_CSS_UINT16_T_BITS)) + +struct ia_css_frame_grid_manifest_desc_s { + /* Min resolution width/height of the spatial parameters for + * the frame measured in compute units + */ + uint16_t min_frame_grid_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Max resolution width/height of the spatial parameters for + * the frame measured in compute units + */ + uint16_t max_frame_grid_dimension[IA_CSS_N_DATA_DIMENSION]; +}; + +typedef struct ia_css_frame_grid_manifest_desc_s + ia_css_frame_grid_manifest_desc_t; + +#define N_PADDING_UINT8_IN_SPATIAL_PARAM_TERM_MAN_STRUCT 2 +#define SIZE_OF_SPATIAL_PARAM_TERM_MAN_STRUCT_IN_BITS \ + ((SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS) \ + + (SIZE_OF_FRAME_GRID_MAN_STRUCT_IN_BITS) \ + + (SIZE_OF_FRAG_GRID_MAN_STRUCT_IN_BITS) \ + + (2 * IA_CSS_UINT16_T_BITS) \ + + (2 * IA_CSS_UINT8_T_BITS) \ + + (N_PADDING_UINT8_IN_SPATIAL_PARAM_TERM_MAN_STRUCT * \ + IA_CSS_UINT8_T_BITS)) + +struct ia_css_spatial_param_terminal_manifest_s { + /* Spatial Parameter terminal manifest base */ + ia_css_terminal_manifest_t base; + /* Contains limits for the frame spatial parameters */ + ia_css_frame_grid_manifest_desc_t frame_grid_desc; + /* + * Constains limits for the fragment spatial parameters + * - COMMON AMONG FRAGMENTS + */ + ia_css_fragment_grid_manifest_desc_t common_fragment_grid_desc; + /* + * Number of frame spatial parameter sections, they are set + * in slice-steps through frame processing + */ + uint16_t frame_grid_param_manifest_section_desc_count; + /* + * Points to the variable array of + * ia_css_frame_spatial_param_manifest_section_desc_t + */ + uint16_t frame_grid_param_manifest_section_desc_offset; + /* + * Indication of the kernel this spatial parameter terminal belongs to + * SHOULD MATCH TO INDEX AND BE USED ONLY FOR CHECK + */ + uint8_t kernel_id; + /* + * Groups together compute units in order to achieve alignment + * requirements for transfes and to achieve canonical frame + * representation + */ + uint8_t compute_units_p_elem; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_SPATIAL_PARAM_TERM_MAN_STRUCT]; +}; + +typedef struct ia_css_spatial_param_terminal_manifest_s + ia_css_spatial_param_terminal_manifest_t; + +/* ================= Spatial Param Terminal Manifest - END ================ */ + +/* ================= Sliced Param Terminal Manifest - START =============== */ + +#define N_PADDING_UINT8_IN_SLICED_TERMINAL_MAN_SECTION_STRUCT (2) +#define SIZE_OF_SLICED_PARAM_MAN_SEC_STRUCT_IN_BITS \ + (1 * IA_CSS_UINT32_T_BITS \ + + 2 * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_SLICED_TERMINAL_MAN_SECTION_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_sliced_param_manifest_section_desc_s { + /* Maximum size of the related parameter region */ + uint32_t max_mem_size; + /* + * Memory targeted by this section + * (Register MMIO Interface/DMEM/VMEM/GMEM etc) + */ + uint8_t mem_type_id; + /* Region id within the specified memory */ + uint8_t region_id; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_SLICED_TERMINAL_MAN_SECTION_STRUCT]; +}; + +typedef struct ia_css_sliced_param_manifest_section_desc_s + ia_css_sliced_param_manifest_section_desc_t; + +#define N_PADDING_UINT8_IN_SLICED_TERMINAL_MANIFEST_STRUCT 3 +#define SIZE_OF_SLICED_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + (SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS \ + + 2 * IA_CSS_UINT16_T_BITS \ + + 1 * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_SLICED_TERMINAL_MANIFEST_STRUCT * IA_CSS_UINT8_T_BITS) + +/* Frame constant parameters terminal manifest */ +struct ia_css_sliced_param_terminal_manifest_s { + /* Spatial Parameter terminal base */ + ia_css_terminal_manifest_t base; + /* + * Number of the array elements + * sliced_param_section_offset points to + */ + uint16_t sliced_param_section_count; + /* + * Points to array of ia_css_sliced_param_manifest_section_desc_s + * which constain info for the slicing of the parameters + */ + uint16_t sliced_param_section_offset; + /* Kernel identifier */ + uint8_t kernel_id; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_SLICED_TERMINAL_MANIFEST_STRUCT]; +}; + +typedef struct ia_css_sliced_param_terminal_manifest_s + ia_css_sliced_param_terminal_manifest_t; + +/* ================= Slice Param Terminal Manifest - End =============== */ + +/* ================= Program Terminal Manifest - START ================= */ + +#define N_PADDING_UINT8_IN_FRAG_PARAM_MAN_SEC_STRUCT 1 +#define SIZE_OF_FRAG_PARAM_MAN_SEC_STRUCT_IN_BITS \ + (1 * IA_CSS_UINT32_T_BITS \ + + 3 * IA_CSS_UINT8_T_BITS \ + + N_PADDING_UINT8_IN_FRAG_PARAM_MAN_SEC_STRUCT * IA_CSS_UINT8_T_BITS) + +/* Fragment constant parameters manifest */ +struct ia_css_fragment_param_manifest_section_desc_s { + /* Maximum size of the related parameter region */ + uint32_t max_mem_size; + /* Indication of the kernel this parameter belongs to */ + uint8_t kernel_id; + /* Memory targeted by this section + * (Register MMIO Interface/DMEM/VMEM/GMEM etc) + */ + uint8_t mem_type_id; + /* Region id within the specified memory space */ + uint8_t region_id; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_FRAG_PARAM_MAN_SEC_STRUCT]; +}; + +typedef struct ia_css_fragment_param_manifest_section_desc_s + ia_css_fragment_param_manifest_section_desc_t; + +#define SIZE_OF_KERNEL_FRAG_SEQ_INFO_MAN_STRUCT_IN_BITS \ + (10*IA_CSS_N_DATA_DIMENSION*IA_CSS_UINT16_T_BITS) + +struct ia_css_kernel_fragment_sequencer_info_manifest_desc_s { + /* Slice dimensions */ + uint16_t min_fragment_grid_slice_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Slice dimensions */ + uint16_t max_fragment_grid_slice_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Nof slices */ + uint16_t min_fragment_grid_slice_count[IA_CSS_N_DATA_DIMENSION]; + /* Nof slices */ + uint16_t max_fragment_grid_slice_count[IA_CSS_N_DATA_DIMENSION]; + /* Grid point decimation factor */ + uint16_t + min_fragment_grid_point_decimation_factor[IA_CSS_N_DATA_DIMENSION]; + /* Grid point decimation factor */ + uint16_t + max_fragment_grid_point_decimation_factor[IA_CSS_N_DATA_DIMENSION]; + /* Relative position of grid origin to pixel origin */ + int16_t + min_fragment_grid_overlay_pixel_topleft_index[IA_CSS_N_DATA_DIMENSION]; + /* Relative position of grid origin to pixel origin */ + int16_t + max_fragment_grid_overlay_pixel_topleft_index[IA_CSS_N_DATA_DIMENSION]; + /* Dimension of grid */ + int16_t + min_fragment_grid_overlay_pixel_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Dimension of grid */ + int16_t + max_fragment_grid_overlay_pixel_dimension[IA_CSS_N_DATA_DIMENSION]; +}; + +typedef struct ia_css_kernel_fragment_sequencer_info_manifest_desc_s + ia_css_kernel_fragment_sequencer_info_manifest_desc_t; + +#define N_PADDING_UINT8_IN_PROGRAM_TERM_MAN_STRUCT 2 +#define SIZE_OF_PROG_TERM_MAN_STRUCT_IN_BITS \ + ((SIZE_OF_TERMINAL_MANIFEST_STRUCT_IN_BITS) \ + + (IA_CSS_UINT32_T_BITS) \ + + (5*IA_CSS_UINT16_T_BITS) \ + + (N_PADDING_UINT8_IN_PROGRAM_TERM_MAN_STRUCT * IA_CSS_UINT8_T_BITS)) + +struct ia_css_program_terminal_manifest_s { + ia_css_terminal_manifest_t base; + /* Connection manager passes seq info as single blob at the moment */ + uint32_t sequencer_info_kernel_id; + /* Maximum number of command secriptors supported + * by the program group + */ + uint16_t max_kernel_fragment_sequencer_command_desc; + uint16_t fragment_param_manifest_section_desc_count; + uint16_t fragment_param_manifest_section_desc_offset; + uint16_t kernel_fragment_sequencer_info_manifest_info_count; + uint16_t kernel_fragment_sequencer_info_manifest_info_offset; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PROGRAM_TERM_MAN_STRUCT]; +}; + +typedef struct ia_css_program_terminal_manifest_s + ia_css_program_terminal_manifest_t; + +/* ==================== Program Terminal Manifest - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_MANIFEST_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_types.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_types.h new file mode 100644 index 0000000000000..c5c89fb7ec917 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/interface/ia_css_terminal_types.h @@ -0,0 +1,351 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_TYPES_H +#define __IA_CSS_TERMINAL_TYPES_H + +#include "type_support.h" +#include "ia_css_base_types.h" +#include "ia_css_terminal_base_types.h" + + +typedef struct ia_css_program_control_init_load_section_desc_s + ia_css_program_control_init_load_section_desc_t; +typedef struct ia_css_program_control_init_connect_section_desc_s + ia_css_program_control_init_connect_section_desc_t; +typedef struct ia_css_program_control_init_program_desc_s + ia_css_program_control_init_program_desc_t; +typedef struct ia_css_program_control_init_terminal_s + ia_css_program_control_init_terminal_t; + +typedef struct ia_css_program_terminal_s ia_css_program_terminal_t; +typedef struct ia_css_fragment_param_section_desc_s + ia_css_fragment_param_section_desc_t; +typedef struct ia_css_kernel_fragment_sequencer_info_desc_s + ia_css_kernel_fragment_sequencer_info_desc_t; +typedef struct ia_css_kernel_fragment_sequencer_command_desc_s + ia_css_kernel_fragment_sequencer_command_desc_t; + +typedef struct ia_css_sliced_param_terminal_s ia_css_sliced_param_terminal_t; +typedef struct ia_css_fragment_slice_desc_s ia_css_fragment_slice_desc_t; +typedef struct ia_css_slice_param_section_desc_s + ia_css_slice_param_section_desc_t; + +typedef struct ia_css_spatial_param_terminal_s ia_css_spatial_param_terminal_t; +typedef struct ia_css_frame_grid_desc_s ia_css_frame_grid_desc_t; +typedef struct ia_css_frame_grid_param_section_desc_s + ia_css_frame_grid_param_section_desc_t; +typedef struct ia_css_fragment_grid_desc_s ia_css_fragment_grid_desc_t; + +typedef struct ia_css_param_terminal_s ia_css_param_terminal_t; +typedef struct ia_css_param_section_desc_s ia_css_param_section_desc_t; + +typedef struct ia_css_param_payload_s ia_css_param_payload_t; +typedef struct ia_css_terminal_s ia_css_terminal_t; + +/* =================== Generic Parameter Payload - START =================== */ +#define N_UINT64_IN_PARAM_PAYLOAD_STRUCT 1 +#define N_UINT32_IN_PARAM_PAYLOAD_STRUCT 1 + +#define IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + (N_UINT64_IN_PARAM_PAYLOAD_STRUCT * IA_CSS_UINT64_T_BITS \ + + VIED_VADDRESS_BITS \ + + N_UINT32_IN_PARAM_PAYLOAD_STRUCT * IA_CSS_UINT32_T_BITS) + +struct ia_css_param_payload_s { + /* + * Temporary variable holding the host address of the parameter buffer + * as PSYS is handling the parameters on the host side for the moment + */ + uint64_t host_buffer; + /* + * Base virtual addresses to parameters in subsystem virtual + * memory space + * NOTE: Used in legacy pg flow + */ + vied_vaddress_t buffer; + /* + * Offset to buffer address within external buffer set structure + * NOTE: Used in ppg flow + */ + uint32_t terminal_index; +}; +/* =================== Generic Parameter Payload - End ==================== */ + + +/* ==================== Cached Param Terminal - START ==================== */ +#define N_UINT32_IN_PARAM_SEC_STRUCT 2 + +#define SIZE_OF_PARAM_SEC_STRUCT_BITS \ + (N_UINT32_IN_PARAM_SEC_STRUCT * IA_CSS_UINT32_T_BITS) + +/* Frame constant parameters section */ +struct ia_css_param_section_desc_s { + /* Offset of the parameter allocation in memory */ + uint32_t mem_offset; + /* Memory allocation size needs of this parameter */ + uint32_t mem_size; +}; + +#define N_UINT16_IN_PARAM_TERMINAL_STRUCT 1 +#define N_PADDING_UINT8_IN_PARAM_TERMINAL_STRUCT 6 + +#define SIZE_OF_PARAM_TERMINAL_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + + N_UINT16_IN_PARAM_TERMINAL_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_IN_PARAM_TERMINAL_STRUCT * IA_CSS_UINT8_T_BITS) + +/* Frame constant parameters terminal */ +struct ia_css_param_terminal_s { + /* Parameter terminal base */ + ia_css_terminal_t base; + /* Parameter buffer handle attached to the terminal */ + ia_css_param_payload_t param_payload; + /* Points to the variable array of ia_css_param_section_desc_t */ + uint16_t param_section_desc_offset; + uint8_t padding[N_PADDING_UINT8_IN_PARAM_TERMINAL_STRUCT]; +}; +/* ==================== Cached Param Terminal - End ==================== */ + + +/* ==================== Spatial Param Terminal - START ==================== */ +#define N_UINT16_IN_FRAG_GRID_STRUCT (2 * IA_CSS_N_DATA_DIMENSION) + +#define SIZE_OF_FRAG_GRID_STRUCT_BITS \ + (N_UINT16_IN_FRAG_GRID_STRUCT * IA_CSS_UINT16_T_BITS) + +struct ia_css_fragment_grid_desc_s { + /* + * Offset width/height of the top-left compute unit of the + * fragment compared to the frame + */ + uint16_t fragment_grid_index[IA_CSS_N_DATA_DIMENSION]; + /* + * Resolution width/height of the spatial parameters that + * correspond to the fragment measured in compute units + */ + uint16_t fragment_grid_dimension[IA_CSS_N_DATA_DIMENSION]; +}; + +#define N_UINT32_IN_FRAME_GRID_PARAM_SEC_STRUCT 3 +#define N_PADDING_UINT8_IN_FRAME_GRID_PARAM_SEC_STRUCT 4 + +#define SIZE_OF_FRAME_GRID_PARAM_SEC_STRUCT_BITS \ + (N_UINT32_IN_FRAME_GRID_PARAM_SEC_STRUCT * IA_CSS_UINT32_T_BITS \ + + N_PADDING_UINT8_IN_FRAME_GRID_PARAM_SEC_STRUCT * IA_CSS_UINT8_T_BITS) + +/* + * A plane of parameters with spatial aspect + * (compute units correlated to pixel data) + */ +struct ia_css_frame_grid_param_section_desc_s { + /* Offset of the parameter allocation in memory */ + uint32_t mem_offset; + /* Memory allocation size needs of this parameter */ + uint32_t mem_size; + /* + * stride in bytes of each line of compute units for + * the specified memory space and region + */ + uint32_t stride; + uint8_t padding[N_PADDING_UINT8_IN_FRAME_GRID_PARAM_SEC_STRUCT]; +}; + +#define N_UINT16_IN_FRAME_GRID_STRUCT_STRUCT IA_CSS_N_DATA_DIMENSION +#define N_PADDING_UINT8_IN_FRAME_GRID_STRUCT 4 + +#define SIZE_OF_FRAME_GRID_STRUCT_BITS \ + (N_UINT16_IN_FRAME_GRID_STRUCT_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_IN_FRAME_GRID_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_frame_grid_desc_s { + /* Resolution width/height of the frame of + * spatial parameters measured in compute units + */ + uint16_t frame_grid_dimension[IA_CSS_N_DATA_DIMENSION]; + uint8_t padding[N_PADDING_UINT8_IN_FRAME_GRID_STRUCT]; +}; + +#define N_UINT32_IN_SPATIAL_PARAM_TERM_STRUCT 1 +#define N_UINT16_IN_SPATIAL_PARAM_TERM_STRUCT 2 + +#define SIZE_OF_SPATIAL_PARAM_TERM_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + + SIZE_OF_FRAME_GRID_STRUCT_BITS \ + + N_UINT32_IN_SPATIAL_PARAM_TERM_STRUCT * IA_CSS_UINT32_T_BITS \ + + N_UINT16_IN_SPATIAL_PARAM_TERM_STRUCT * IA_CSS_UINT16_T_BITS) + +struct ia_css_spatial_param_terminal_s { + /* Spatial Parameter terminal base */ + ia_css_terminal_t base; + /* Spatial Parameter buffer handle attached to the terminal */ + ia_css_param_payload_t param_payload; + /* Contains info for the frame of spatial parameters */ + ia_css_frame_grid_desc_t frame_grid_desc; + /* Kernel identifier */ + uint32_t kernel_id; + /* + * Points to the variable array of + * ia_css_frame_grid_param_section_desc_t + */ + uint16_t frame_grid_param_section_desc_offset; + /* + * Points to array of ia_css_fragment_spatial_desc_t + * which constain info for the fragments of spatial parameters + */ + uint16_t fragment_grid_desc_offset; +}; +/* ==================== Spatial Param Terminal - END ==================== */ + + +/* ==================== Sliced Param Terminal - START ==================== */ +#define N_UINT32_IN_SLICE_PARAM_SECTION_DESC_STRUCT 2 + +#define SIZE_OF_SLICE_PARAM_SECTION_DESC_STRUCT_BITS \ + (N_UINT32_IN_SLICE_PARAM_SECTION_DESC_STRUCT * IA_CSS_UINT32_T_BITS) + +/* A Slice of parameters ready to be trasferred from/to registers */ +struct ia_css_slice_param_section_desc_s { + /* Offset of the parameter allocation in memory */ + uint32_t mem_offset; + /* Memory allocation size needs of this parameter */ + uint32_t mem_size; +}; + +#define N_UINT16_IN_FRAGMENT_SLICE_DESC_STRUCT 2 +#define N_PADDING_UINT8_FRAGMENT_SLICE_DESC_STRUCT 4 + +#define SIZE_OF_FRAGMENT_SLICE_DESC_STRUCT_BITS \ + (N_UINT16_IN_FRAGMENT_SLICE_DESC_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_FRAGMENT_SLICE_DESC_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_fragment_slice_desc_s { + /* + * Points to array of ia_css_slice_param_section_desc_t + * which constain info for each prameter slice + */ + uint16_t slice_section_desc_offset; + /* Number of slices for the parameters for this fragment */ + uint16_t slice_count; + uint8_t padding[N_PADDING_UINT8_FRAGMENT_SLICE_DESC_STRUCT]; +}; + +#define N_UINT32_IN_SLICED_PARAM_TERMINAL_STRUCT 1 +#define N_UINT16_IN_SLICED_PARAM_TERMINAL_STRUCT 1 +#define N_PADDING_UINT8_SLICED_PARAM_TERMINAL_STRUCT 2 + +#define SIZE_OF_SLICED_PARAM_TERM_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + + N_UINT32_IN_SLICED_PARAM_TERMINAL_STRUCT * IA_CSS_UINT32_T_BITS \ + + N_UINT16_IN_SLICED_PARAM_TERMINAL_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_SLICED_PARAM_TERMINAL_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_sliced_param_terminal_s { + /* Spatial Parameter terminal base */ + ia_css_terminal_t base; + /* Spatial Parameter buffer handle attached to the terminal */ + ia_css_param_payload_t param_payload; + /* Kernel identifier */ + uint32_t kernel_id; + /* + * Points to array of ia_css_fragment_slice_desc_t + * which constain info for the slicing of the parameters + */ + uint16_t fragment_slice_desc_offset; + uint8_t padding[N_PADDING_UINT8_SLICED_PARAM_TERMINAL_STRUCT]; +}; +/* ==================== Sliced Param Terminal - END ==================== */ + + +/* ==================== Program Terminal - START ==================== */ + +#define N_UINT32_IN_FRAG_PARAM_SEC_STRUCT 2 + +#define SIZE_OF_FRAG_PARAM_SEC_STRUCT_BITS \ + (N_UINT32_IN_FRAG_PARAM_SEC_STRUCT * IA_CSS_UINT32_T_BITS) + +/* Fragment constant parameters section */ +struct ia_css_fragment_param_section_desc_s { + /* Offset of the parameter allocation in memory */ + uint32_t mem_offset; + /* Memory allocation size needs of this parameter */ + uint32_t mem_size; +}; + +#define N_UINT16_IN_FRAG_SEQ_COMMAND_STRUCT IA_CSS_N_COMMAND_COUNT + +#define SIZE_OF_FRAG_SEQ_COMMANDS_STRUCT_BITS \ + (N_UINT16_IN_FRAG_SEQ_COMMAND_STRUCT * IA_CSS_UINT16_T_BITS) + +/* 4 commands packe together to save memory space */ +struct ia_css_kernel_fragment_sequencer_command_desc_s { + /* Contains the "(command_index%4) == index" command desc */ + uint16_t line_count[IA_CSS_N_COMMAND_COUNT]; +}; + +#define N_UINT16_IN_FRAG_SEQ_INFO_STRUCT (5 * IA_CSS_N_DATA_DIMENSION + 2) + +#define SIZE_OF_FRAG_SEQ_INFO_STRUCT_BITS \ + (N_UINT16_IN_FRAG_SEQ_INFO_STRUCT * IA_CSS_UINT16_T_BITS) + +struct ia_css_kernel_fragment_sequencer_info_desc_s { + /* Slice dimensions */ + uint16_t fragment_grid_slice_dimension[IA_CSS_N_DATA_DIMENSION]; + /* Nof slices */ + uint16_t fragment_grid_slice_count[IA_CSS_N_DATA_DIMENSION]; + /* Grid point decimation factor */ + uint16_t + fragment_grid_point_decimation_factor[IA_CSS_N_DATA_DIMENSION]; + /* Relative position of grid origin to pixel origin */ + int16_t + fragment_grid_overlay_pixel_topleft_index[IA_CSS_N_DATA_DIMENSION]; + /* Size of active fragment region */ + int16_t + fragment_grid_overlay_pixel_dimension[IA_CSS_N_DATA_DIMENSION]; + /* If >0 it overrides the standard fragment sequencer info */ + uint16_t command_count; + /* + * To be used only if command_count>0, points to the descriptors + * for the commands (ia_css_kernel_fragment_sequencer_command_desc_s) + */ + uint16_t command_desc_offset; +}; + +#define N_UINT16_IN_PROG_TERM_STRUCT 2 +#define N_PADDING_UINT8_IN_PROG_TERM_STRUCT 4 + +#define SIZE_OF_PROG_TERM_STRUCT_BITS \ + (SIZE_OF_TERMINAL_STRUCT_BITS \ + + IA_CSS_PARAM_PAYLOAD_STRUCT_BITS \ + + N_UINT16_IN_PROG_TERM_STRUCT * IA_CSS_UINT16_T_BITS \ + + N_PADDING_UINT8_IN_PROG_TERM_STRUCT * IA_CSS_UINT8_T_BITS) + +struct ia_css_program_terminal_s { + /* Program terminal base */ + ia_css_terminal_t base; + /* Program terminal buffer handle attached to the terminal */ + ia_css_param_payload_t param_payload; + /* Points to array of ia_css_fragment_param_desc_s */ + uint16_t fragment_param_section_desc_offset; + /* Points to array of ia_css_kernel_fragment_sequencer_info_s */ + uint16_t kernel_fragment_sequencer_info_desc_offset; + /* align to 64 */ + uint8_t padding[N_PADDING_UINT8_IN_PROG_TERM_STRUCT]; +}; +/* ==================== Program Terminal - END ==================== */ + +#endif /* __IA_CSS_TERMINAL_TYPES_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal.c new file mode 100644 index 0000000000000..683fb3a88cd87 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal.c @@ -0,0 +1,20 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifdef __INLINE_PARAMETERS__ +#include "storage_class.h" +STORAGE_CLASS_INLINE int __ia_css_param_avoid_warning_on_empty_file(void) { return 0; } +#else /* __INLINE_PARAMETERS__ */ +#include "ia_css_terminal_impl.h" +#endif /* __INLINE_PARAMETERS__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_impl.h new file mode 100644 index 0000000000000..9ccf3931e8e3d --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_impl.h @@ -0,0 +1,495 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_IMPL_H +#define __IA_CSS_TERMINAL_IMPL_H + +#include "ia_css_terminal.h" +#include "ia_css_terminal_types.h" +#include "error_support.h" +#include "assert_support.h" +#include "storage_class.h" + +/* Param Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_param_in_terminal_get_descriptor_size( + const unsigned int nof_sections) +{ + return sizeof(ia_css_param_terminal_t) + + nof_sections*sizeof(ia_css_param_section_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_param_section_desc_t *ia_css_param_in_terminal_get_param_section_desc( + const ia_css_param_terminal_t *param_terminal, + const unsigned int section_index) +{ + ia_css_param_section_desc_t *param_section_base; + ia_css_param_section_desc_t *param_section_desc = NULL; + + verifjmpexit(param_terminal != NULL); + + param_section_base = + (ia_css_param_section_desc_t *) + (((const char *)param_terminal) + + param_terminal->param_section_desc_offset); + param_section_desc = &(param_section_base[section_index]); + +EXIT: + return param_section_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_param_out_terminal_get_descriptor_size( + const unsigned int nof_sections, + const unsigned int nof_fragments) +{ + return sizeof(ia_css_param_terminal_t) + + nof_fragments*nof_sections*sizeof(ia_css_param_section_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_param_section_desc_t *ia_css_param_out_terminal_get_param_section_desc( + const ia_css_param_terminal_t *param_terminal, + const unsigned int section_index, + const unsigned int nof_sections, + const unsigned int fragment_index) +{ + ia_css_param_section_desc_t *param_section_base; + ia_css_param_section_desc_t *param_section_desc = NULL; + + verifjmpexit(param_terminal != NULL); + + param_section_base = + (ia_css_param_section_desc_t *) + (((const char *)param_terminal) + + param_terminal->param_section_desc_offset); + param_section_desc = + &(param_section_base[(nof_sections * fragment_index) + + section_index]); + +EXIT: + return param_section_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_param_terminal_create( + ia_css_param_terminal_t *param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal) +{ + if (param_terminal == NULL) { + return -EFAULT; + } + + if (terminal_offset > (1<<15)) { + return -EINVAL; + } + + param_terminal->base.terminal_type = + is_input_terminal ? + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN : + IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT; + param_terminal->base.parent_offset = + 0 - ((int16_t)terminal_offset); + param_terminal->base.size = terminal_size; + param_terminal->param_section_desc_offset = + sizeof(ia_css_param_terminal_t); + + return 0; +} + +/* Spatial Param Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_spatial_param_terminal_get_descriptor_size( + const unsigned int nof_frame_param_sections, + const unsigned int nof_fragments) +{ + return sizeof(ia_css_spatial_param_terminal_t) + + nof_frame_param_sections * sizeof( + ia_css_frame_grid_param_section_desc_t) + + nof_fragments * sizeof(ia_css_fragment_grid_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_fragment_grid_desc_t * +ia_css_spatial_param_terminal_get_fragment_grid_desc( + const ia_css_spatial_param_terminal_t *spatial_param_terminal, + const unsigned int fragment_index) +{ + ia_css_fragment_grid_desc_t *fragment_grid_desc_base; + ia_css_fragment_grid_desc_t *fragment_grid_desc = NULL; + + verifjmpexit(spatial_param_terminal != NULL); + + fragment_grid_desc_base = + (ia_css_fragment_grid_desc_t *) + (((const char *)spatial_param_terminal) + + spatial_param_terminal->fragment_grid_desc_offset); + fragment_grid_desc = &(fragment_grid_desc_base[fragment_index]); + +EXIT: + return fragment_grid_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_frame_grid_param_section_desc_t * +ia_css_spatial_param_terminal_get_frame_grid_param_section_desc( + const ia_css_spatial_param_terminal_t *spatial_param_terminal, + const unsigned int section_index) +{ + ia_css_frame_grid_param_section_desc_t * + frame_grid_param_section_base; + ia_css_frame_grid_param_section_desc_t * + frame_grid_param_section_desc = NULL; + + verifjmpexit(spatial_param_terminal != NULL); + + frame_grid_param_section_base = + (ia_css_frame_grid_param_section_desc_t *) + (((const char *)spatial_param_terminal) + + spatial_param_terminal->frame_grid_param_section_desc_offset); + frame_grid_param_section_desc = + &(frame_grid_param_section_base[section_index]); + +EXIT: + return frame_grid_param_section_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_spatial_param_terminal_create( + ia_css_spatial_param_terminal_t *spatial_param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal, + const unsigned int nof_fragments, + const uint32_t kernel_id) +{ + if (spatial_param_terminal == NULL) { + return -EFAULT; + } + + if (terminal_offset > (1<<15)) { + return -EINVAL; + } + + spatial_param_terminal->base.terminal_type = + is_input_terminal ? + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN : + IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT; + spatial_param_terminal->base.parent_offset = + 0 - ((int16_t)terminal_offset); + spatial_param_terminal->base.size = terminal_size; + spatial_param_terminal->kernel_id = kernel_id; + spatial_param_terminal->fragment_grid_desc_offset = + sizeof(ia_css_spatial_param_terminal_t); + spatial_param_terminal->frame_grid_param_section_desc_offset = + spatial_param_terminal->fragment_grid_desc_offset + + (nof_fragments * sizeof(ia_css_fragment_grid_desc_t)); + + return 0; +} + +/* Sliced terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_sliced_param_terminal_get_descriptor_size( + const unsigned int nof_slice_param_sections, + const unsigned int nof_slices[], + const unsigned int nof_fragments) +{ + unsigned int descriptor_size = 0; + unsigned int fragment_index; + unsigned int nof_slices_total = 0; + + verifjmpexit(nof_slices != NULL); + + for (fragment_index = 0; + fragment_index < nof_fragments; fragment_index++) { + nof_slices_total += nof_slices[fragment_index]; + } + + descriptor_size = + sizeof(ia_css_sliced_param_terminal_t) + + nof_fragments*sizeof(ia_css_fragment_slice_desc_t) + + nof_slices_total*nof_slice_param_sections*sizeof( + ia_css_fragment_param_section_desc_t); + +EXIT: + return descriptor_size; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_fragment_slice_desc_t * +ia_css_sliced_param_terminal_get_fragment_slice_desc( + const ia_css_sliced_param_terminal_t *sliced_param_terminal, + const unsigned int fragment_index +) +{ + ia_css_fragment_slice_desc_t *fragment_slice_desc_base; + ia_css_fragment_slice_desc_t *fragment_slice_desc = NULL; + + verifjmpexit(sliced_param_terminal != NULL); + + fragment_slice_desc_base = + (ia_css_fragment_slice_desc_t *) + (((const char *)sliced_param_terminal) + + sliced_param_terminal->fragment_slice_desc_offset); + fragment_slice_desc = &(fragment_slice_desc_base[fragment_index]); + +EXIT: + return fragment_slice_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_slice_param_section_desc_t * +ia_css_sliced_param_terminal_get_slice_param_section_desc( + const ia_css_sliced_param_terminal_t *sliced_param_terminal, + const unsigned int fragment_index, + const unsigned int slice_index, + const unsigned int section_index, + const unsigned int nof_slice_param_sections) +{ + ia_css_fragment_slice_desc_t *fragment_slice_desc; + ia_css_slice_param_section_desc_t *slice_param_section_desc_base; + ia_css_slice_param_section_desc_t *slice_param_section_desc = NULL; + + fragment_slice_desc = + ia_css_sliced_param_terminal_get_fragment_slice_desc( + sliced_param_terminal, + fragment_index + ); + verifjmpexit(fragment_slice_desc != NULL); + + slice_param_section_desc_base = + (ia_css_slice_param_section_desc_t *) + (((const char *)sliced_param_terminal) + + fragment_slice_desc->slice_section_desc_offset); + slice_param_section_desc = + &(slice_param_section_desc_base[( + slice_index * nof_slice_param_sections) + + section_index]); + +EXIT: + return slice_param_section_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_sliced_param_terminal_create( + ia_css_sliced_param_terminal_t *sliced_param_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const uint16_t is_input_terminal, + const unsigned int nof_slice_param_sections, + const unsigned int nof_slices[], + const unsigned int nof_fragments, + const uint32_t kernel_id) +{ + unsigned int fragment_index; + unsigned int nof_slices_total = 0; + + if (sliced_param_terminal == NULL) { + return -EFAULT; + } + + if (terminal_offset > (1<<15)) { + return -EINVAL; + } + + sliced_param_terminal->base.terminal_type = + is_input_terminal ? + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN : + IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT; + sliced_param_terminal->base.parent_offset = + 0 - ((int16_t)terminal_offset); + sliced_param_terminal->base.size = terminal_size; + sliced_param_terminal->kernel_id = kernel_id; + /* set here to use below to find the pointer */ + sliced_param_terminal->fragment_slice_desc_offset = + sizeof(ia_css_sliced_param_terminal_t); + for (fragment_index = 0; + fragment_index < nof_fragments; fragment_index++) { + ia_css_fragment_slice_desc_t *fragment_slice_desc = + ia_css_sliced_param_terminal_get_fragment_slice_desc( + sliced_param_terminal, + fragment_index); + /* + * Error handling not required at this point + * since everything has been constructed/validated just above + */ + fragment_slice_desc->slice_count = nof_slices[fragment_index]; + fragment_slice_desc->slice_section_desc_offset = + sliced_param_terminal->fragment_slice_desc_offset + + (nof_fragments * sizeof( + ia_css_fragment_slice_desc_t)) + + (nof_slices_total * nof_slice_param_sections * sizeof( + ia_css_slice_param_section_desc_t)); + nof_slices_total += nof_slices[fragment_index]; + } + + return 0; +} + +/* Program terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_program_terminal_get_descriptor_size( + const unsigned int nof_fragments, + const unsigned int nof_fragment_param_sections, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int nof_command_objs) +{ + return sizeof(ia_css_program_terminal_t) + + nof_fragments * nof_fragment_param_sections * + sizeof(ia_css_fragment_param_section_desc_t) + + nof_fragments * nof_kernel_fragment_sequencer_infos * + sizeof(ia_css_kernel_fragment_sequencer_info_desc_t) + + nof_command_objs * sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_fragment_param_section_desc_t * +ia_css_program_terminal_get_frgmnt_prm_sct_desc( + const ia_css_program_terminal_t *program_terminal, + const unsigned int fragment_index, + const unsigned int section_index, + const unsigned int nof_fragment_param_sections) +{ + ia_css_fragment_param_section_desc_t * + fragment_param_section_desc_base; + ia_css_fragment_param_section_desc_t * + fragment_param_section_desc = NULL; + + verifjmpexit(program_terminal != NULL); + verifjmpexit(section_index < nof_fragment_param_sections); + + fragment_param_section_desc_base = + (ia_css_fragment_param_section_desc_t *) + (((const char *)program_terminal) + + program_terminal->fragment_param_section_desc_offset); + fragment_param_section_desc = + &(fragment_param_section_desc_base[(fragment_index * + nof_fragment_param_sections) + section_index]); + +EXIT: + return fragment_param_section_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_kernel_fragment_sequencer_info_desc_t * +ia_css_program_terminal_get_kernel_frgmnt_seq_info_desc( + const ia_css_program_terminal_t *program_terminal, + const unsigned int fragment_index, + const unsigned int info_index, + const unsigned int nof_kernel_fragment_sequencer_infos) +{ + ia_css_kernel_fragment_sequencer_info_desc_t * + kernel_fragment_sequencer_info_desc_base; + ia_css_kernel_fragment_sequencer_info_desc_t * + kernel_fragment_sequencer_info_desc = NULL; + + verifjmpexit(program_terminal != NULL); + if (nof_kernel_fragment_sequencer_infos > 0) { + verifjmpexit(info_index < nof_kernel_fragment_sequencer_infos); + } + + kernel_fragment_sequencer_info_desc_base = + (ia_css_kernel_fragment_sequencer_info_desc_t *) + (((const char *)program_terminal) + + program_terminal->kernel_fragment_sequencer_info_desc_offset); + kernel_fragment_sequencer_info_desc = + &(kernel_fragment_sequencer_info_desc_base[(fragment_index * + nof_kernel_fragment_sequencer_infos) + info_index]); + +EXIT: + return kernel_fragment_sequencer_info_desc; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_program_terminal_create( + ia_css_program_terminal_t *program_terminal, + const uint16_t terminal_offset, + const uint16_t terminal_size, + const unsigned int nof_fragments, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int nof_command_objs) +{ + if (program_terminal == NULL) { + return -EFAULT; + } + + if (terminal_offset > (1<<15)) { + return -EINVAL; + } + + program_terminal->base.terminal_type = IA_CSS_TERMINAL_TYPE_PROGRAM; + program_terminal->base.parent_offset = 0-((int16_t)terminal_offset); + program_terminal->base.size = terminal_size; + program_terminal->kernel_fragment_sequencer_info_desc_offset = + sizeof(ia_css_program_terminal_t); + program_terminal->fragment_param_section_desc_offset = + program_terminal->kernel_fragment_sequencer_info_desc_offset + + (nof_fragments * nof_kernel_fragment_sequencer_infos * + sizeof(ia_css_kernel_fragment_sequencer_info_desc_t)) + + (nof_command_objs * sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t)); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_program_terminal_get_command_base_offset( + const ia_css_program_terminal_t *program_terminal, + const unsigned int nof_fragments, + const unsigned int nof_kernel_fragment_sequencer_infos, + const unsigned int commands_slots_used, + uint16_t *command_desc_offset) +{ + if (command_desc_offset == NULL) { + return -EFAULT; + } + + *command_desc_offset = 0; + + if (program_terminal == NULL) { + return -EFAULT; + } + + *command_desc_offset = + program_terminal->kernel_fragment_sequencer_info_desc_offset + + (nof_fragments * nof_kernel_fragment_sequencer_infos * + sizeof(ia_css_kernel_fragment_sequencer_info_desc_t)) + + (commands_slots_used * sizeof( + ia_css_kernel_fragment_sequencer_command_desc_t)); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +uint16_t *ia_css_program_terminal_get_line_count( + const ia_css_kernel_fragment_sequencer_command_desc_t + *kernel_fragment_sequencer_command_desc_base, + const unsigned int set_count) +{ + uint16_t *line_count = NULL; + + verifjmpexit(kernel_fragment_sequencer_command_desc_base != NULL); + line_count = + (uint16_t *)&(kernel_fragment_sequencer_command_desc_base[ + set_count >> 2].line_count[set_count & 0x00000003]); +EXIT: + return line_count; +} + +#endif /* __IA_CSS_TERMINAL_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest.c new file mode 100644 index 0000000000000..53c4708c7fc90 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest.c @@ -0,0 +1,20 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifdef __INLINE_PARAMETERS__ +#include "storage_class.h" +STORAGE_CLASS_INLINE int __ia_css_param_avoid_warning_on_empty_file(void) { return 0; } +#else /* __INLINE_PARAMETERS__ */ +#include "ia_css_terminal_manifest_impl.h" +#endif /* __INLINE_PARAMETERS__ */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest_impl.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest_impl.h new file mode 100644 index 0000000000000..288b5c9a1164c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/src/ia_css_terminal_manifest_impl.h @@ -0,0 +1,348 @@ +/** +* Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. +*/ + +#ifndef __IA_CSS_TERMINAL_MANIFEST_IMPL_H +#define __IA_CSS_TERMINAL_MANIFEST_IMPL_H + +#include "ia_css_terminal_manifest.h" +#include "error_support.h" +#include "assert_support.h" +#include "storage_class.h" + +STORAGE_CLASS_INLINE void __terminal_manifest_dummy_check_alignment(void) +{ + COMPILATION_ERROR_IF( + SIZE_OF_PARAM_TERMINAL_MANIFEST_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_param_terminal_manifest_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_param_terminal_manifest_t) % sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PARAM_TERMINAL_MANIFEST_SEC_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_param_manifest_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_param_manifest_section_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_SPATIAL_PARAM_TERM_MAN_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_spatial_param_terminal_manifest_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_spatial_param_terminal_manifest_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAME_GRID_PARAM_MAN_SEC_STRUCT_IN_BITS != + (CHAR_BIT * sizeof( + ia_css_frame_grid_param_manifest_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_frame_grid_param_manifest_section_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PROG_TERM_MAN_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_program_terminal_manifest_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_program_terminal_manifest_t)%sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_FRAG_PARAM_MAN_SEC_STRUCT_IN_BITS != + (CHAR_BIT * sizeof( + ia_css_fragment_param_manifest_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_fragment_param_manifest_section_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_KERNEL_FRAG_SEQ_INFO_MAN_STRUCT_IN_BITS != + (CHAR_BIT * sizeof( + ia_css_kernel_fragment_sequencer_info_manifest_desc_t)) + ); + + COMPILATION_ERROR_IF(0 != sizeof( + ia_css_kernel_fragment_sequencer_info_manifest_desc_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_PARAM_TERMINAL_MANIFEST_STRUCT_IN_BITS != + (CHAR_BIT * sizeof(ia_css_sliced_param_terminal_manifest_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_sliced_param_terminal_manifest_t) % + sizeof(uint64_t)); + + COMPILATION_ERROR_IF( + SIZE_OF_SLICED_PARAM_MAN_SEC_STRUCT_IN_BITS != + (CHAR_BIT * sizeof + (ia_css_sliced_param_manifest_section_desc_t))); + + COMPILATION_ERROR_IF(0 != + sizeof(ia_css_sliced_param_manifest_section_desc_t) % + sizeof(uint64_t)); +} + +/* Parameter Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_param_terminal_manifest_get_size( + const unsigned int nof_sections) +{ + + return sizeof(ia_css_param_terminal_manifest_t) + + nof_sections*sizeof(ia_css_param_manifest_section_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_param_terminal_manifest_init( + ia_css_param_terminal_manifest_t *param_terminal, + const uint16_t section_count) +{ + if (param_terminal == NULL) { + return -EFAULT; + } + + param_terminal->param_manifest_section_desc_count = section_count; + param_terminal->param_manifest_section_desc_offset = sizeof( + ia_css_param_terminal_manifest_t); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_param_manifest_section_desc_t * +ia_css_param_terminal_manifest_get_prm_sct_desc( + const ia_css_param_terminal_manifest_t *param_terminal_manifest, + const unsigned int section_index) +{ + ia_css_param_manifest_section_desc_t *param_manifest_section_base; + + ia_css_param_manifest_section_desc_t * + param_manifest_section_desc = NULL; + + verifjmpexit(param_terminal_manifest != NULL); + + param_manifest_section_base = + (ia_css_param_manifest_section_desc_t *) + (((const char *)param_terminal_manifest) + + param_terminal_manifest->param_manifest_section_desc_offset); + + param_manifest_section_desc = + &(param_manifest_section_base[section_index]); + +EXIT: + return param_manifest_section_desc; +} + +/* Spatial Parameter Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_spatial_param_terminal_manifest_get_size( + const unsigned int nof_frame_param_sections) +{ + return sizeof(ia_css_spatial_param_terminal_manifest_t) + + nof_frame_param_sections * sizeof( + ia_css_frame_grid_param_manifest_section_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_spatial_param_terminal_manifest_init( + ia_css_spatial_param_terminal_manifest_t *spatial_param_terminal, + const uint16_t section_count) +{ + if (spatial_param_terminal == NULL) { + return -EFAULT; + } + + spatial_param_terminal-> + frame_grid_param_manifest_section_desc_count = section_count; + spatial_param_terminal-> + frame_grid_param_manifest_section_desc_offset = + sizeof(ia_css_spatial_param_terminal_manifest_t); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_frame_grid_param_manifest_section_desc_t * +ia_css_spatial_param_terminal_manifest_get_frm_grid_prm_sct_desc( + const ia_css_spatial_param_terminal_manifest_t * + spatial_param_terminal_manifest, + const unsigned int section_index) +{ + ia_css_frame_grid_param_manifest_section_desc_t * + frame_param_manifest_section_base; + ia_css_frame_grid_param_manifest_section_desc_t * + frame_param_manifest_section_desc = NULL; + + verifjmpexit(spatial_param_terminal_manifest != NULL); + + frame_param_manifest_section_base = + (ia_css_frame_grid_param_manifest_section_desc_t *) + (((const char *)spatial_param_terminal_manifest) + + spatial_param_terminal_manifest-> + frame_grid_param_manifest_section_desc_offset); + frame_param_manifest_section_desc = + &(frame_param_manifest_section_base[section_index]); + +EXIT: + return frame_param_manifest_section_desc; +} + +/* Sliced Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_sliced_param_terminal_manifest_get_size( + const unsigned int nof_slice_param_sections) +{ + return sizeof(ia_css_spatial_param_terminal_manifest_t) + + nof_slice_param_sections * + sizeof(ia_css_sliced_param_manifest_section_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_sliced_param_terminal_manifest_init( + ia_css_sliced_param_terminal_manifest_t *sliced_param_terminal, + const uint16_t section_count) +{ + if (sliced_param_terminal == NULL) { + return -EFAULT; + } + + sliced_param_terminal->sliced_param_section_count = section_count; + sliced_param_terminal->sliced_param_section_offset = + sizeof(ia_css_sliced_param_terminal_manifest_t); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_sliced_param_manifest_section_desc_t * +ia_css_sliced_param_terminal_manifest_get_sliced_prm_sct_desc( + const ia_css_sliced_param_terminal_manifest_t * + sliced_param_terminal_manifest, + const unsigned int section_index) +{ + ia_css_sliced_param_manifest_section_desc_t * + sliced_param_manifest_section_base; + ia_css_sliced_param_manifest_section_desc_t * + sliced_param_manifest_section_desc = NULL; + + verifjmpexit(sliced_param_terminal_manifest != NULL); + + sliced_param_manifest_section_base = + (ia_css_sliced_param_manifest_section_desc_t *) + (((const char *)sliced_param_terminal_manifest) + + sliced_param_terminal_manifest-> + sliced_param_section_offset); + sliced_param_manifest_section_desc = + &(sliced_param_manifest_section_base[section_index]); + +EXIT: + return sliced_param_manifest_section_desc; +} + +/* Program Terminal */ +IA_CSS_PARAMETERS_STORAGE_CLASS_C +unsigned int ia_css_program_terminal_manifest_get_size( + const unsigned int nof_fragment_param_sections, + const unsigned int nof_kernel_fragment_sequencer_infos) +{ + return sizeof(ia_css_program_terminal_manifest_t) + + nof_fragment_param_sections * + sizeof(ia_css_fragment_param_manifest_section_desc_t) + + nof_kernel_fragment_sequencer_infos * + sizeof(ia_css_kernel_fragment_sequencer_info_manifest_desc_t); +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +int ia_css_program_terminal_manifest_init( + ia_css_program_terminal_manifest_t *program_terminal, + const uint16_t fragment_param_section_count, + const uint16_t kernel_fragment_seq_info_section_count) +{ + if (program_terminal == NULL) { + return -EFAULT; + } + + program_terminal->fragment_param_manifest_section_desc_count = + fragment_param_section_count; + program_terminal->fragment_param_manifest_section_desc_offset = + sizeof(ia_css_program_terminal_manifest_t); + + program_terminal->kernel_fragment_sequencer_info_manifest_info_count = + kernel_fragment_seq_info_section_count; + program_terminal->kernel_fragment_sequencer_info_manifest_info_offset = + sizeof(ia_css_program_terminal_manifest_t) + + fragment_param_section_count*sizeof( + ia_css_fragment_param_manifest_section_desc_t); + + return 0; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_fragment_param_manifest_section_desc_t * +ia_css_program_terminal_manifest_get_frgmnt_prm_sct_desc( + const ia_css_program_terminal_manifest_t *program_terminal_manifest, + const unsigned int section_index) +{ + ia_css_fragment_param_manifest_section_desc_t * + fragment_param_manifest_section_base; + ia_css_fragment_param_manifest_section_desc_t * + fragment_param_manifest_section = NULL; + + verifjmpexit(program_terminal_manifest != NULL); + + fragment_param_manifest_section_base = + (ia_css_fragment_param_manifest_section_desc_t *) + (((const char *)program_terminal_manifest) + + program_terminal_manifest-> + fragment_param_manifest_section_desc_offset); + fragment_param_manifest_section = + &(fragment_param_manifest_section_base[section_index]); + +EXIT: + return fragment_param_manifest_section; +} + +IA_CSS_PARAMETERS_STORAGE_CLASS_C +ia_css_kernel_fragment_sequencer_info_manifest_desc_t * +ia_css_program_terminal_manifest_get_kernel_frgmnt_seq_info_desc( + const ia_css_program_terminal_manifest_t *program_terminal_manifest, + const unsigned int info_index) +{ + ia_css_kernel_fragment_sequencer_info_manifest_desc_t * + kernel_manifest_fragment_sequencer_info_manifest_desc_base; + ia_css_kernel_fragment_sequencer_info_manifest_desc_t * + kernel_manifest_fragment_sequencer_info_manifest_desc = NULL; + + verifjmpexit(program_terminal_manifest != NULL); + + kernel_manifest_fragment_sequencer_info_manifest_desc_base = + (ia_css_kernel_fragment_sequencer_info_manifest_desc_t *) + (((const char *)program_terminal_manifest) + + program_terminal_manifest-> + kernel_fragment_sequencer_info_manifest_info_offset); + + kernel_manifest_fragment_sequencer_info_manifest_desc = + &(kernel_manifest_fragment_sequencer_info_manifest_desc_base[ + info_index]); + +EXIT: + return kernel_manifest_fragment_sequencer_info_manifest_desc; +} + +#endif /* __IA_CSS_TERMINAL_MANIFEST_IMPL_H */ diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/vied_parameters.mk b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/vied_parameters.mk new file mode 100644 index 0000000000000..834a1a4b2bab6 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/lib/vied_parameters/vied_parameters.mk @@ -0,0 +1,76 @@ +# # # +# Support for Intel Camera Imaging ISP subsystem. +# Copyright (c) 2010 - 2018, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details +# +# +# MODULE is VIED_PARAMETERS + +VIED_PARAMETERS_DIR=$${MODULES_DIR}/vied_parameters + +VIED_PARAMETERS_INTERFACE=$(VIED_PARAMETERS_DIR)/interface +VIED_PARAMETERS_SOURCES=$(VIED_PARAMETERS_DIR)/src +VIED_PARAMETERS_EXTINCLUDE = $${MODULES_DIR}/support + +VIED_PARAMETERS_DYNAMIC_HOST_FILES += $(VIED_PARAMETERS_SOURCES)/ia_css_terminal.c +VIED_PARAMETERS_STATIC_HOST_FILES += $(VIED_PARAMETERS_SOURCES)/ia_css_terminal_manifest.c + +VIED_PARAMETERS_HOST_FILES = $(VIED_PARAMETERS_DYNAMIC_HOST_FILES) +VIED_PARAMETERS_HOST_FILES += $(VIED_PARAMETERS_STATIC_HOST_FILES) + +VIED_PARAMETERS_ISA_CLIENT_HOST_FILES = $(VIED_PARAMETERS_SOURCES)/ia_css_isys_process_group.c +VIED_PARAMETERS_ISA_CLIENT_HOST_FILES += $(VIED_PARAMETERS_DIR)/client/ia_css_isys_parameter_client.c + +VIED_PARAMETERS_DYNAMIC_FW_FILES += $(VIED_PARAMETERS_SOURCES)/ia_css_terminal.c +VIED_PARAMETERS_STATIC_FW_FILES += $(VIED_PARAMETERS_SOURCES)/ia_css_terminal_manifest.c + +VIED_PARAMETERS_FW_FILES = $(VIED_PARAMETERS_DYNAMIC_HOST_FILES) +VIED_PARAMETERS_FW_FILES += $(VIED_PARAMETERS_STATIC_HOST_FILES) +VIED_PARAMETERS_SUPPORT_CPPFLAGS = -I$(VIED_PARAMETERS_DIR)/support +VIED_PARAMETERS_SUPPORT_CPPFLAGS += -I$(VIED_PARAMETERS_DIR)/support/$(IPU_SYSVER) +VIED_PARAMETERS_ISA_CLIENT_HOST_CPPFLAGS = -I$(VIED_PARAMETERS_DIR)/client +VIED_PARAMETERS_PSA_UTILS_HOST_FILES = $(MODULES_DIR)/vied_parameters/support/ia_css_psys_parameter_utils.c +VIED_PARAMETERS_PSA_UTILS_HOST_FILES += $(MODULES_DIR)/vied_parameters/support/$(IPU_SYSVER)/ia_css_psys_parameter_utils_dep.c + +VIED_PARAMETERS_UTILS_HOST_CPPFLAGS = $(VIED_PARAMETERS_SUPPORT_CPPFLAGS) + +VIED_PARAMETERS_ISA_UTILS_HOST_FILES = $(MODULES_DIR)/vied_parameters/support/ia_css_isys_parameter_utils.c +VIED_PARAMETERS_ISA_UTILS_HOST_FILES += $(MODULES_DIR)/vied_parameters/support/$(IPU_SYSVER)/ia_css_isys_parameter_utils_dep.c + +VIED_PARAMETERS_PRINT_CPPFLAGS += -I$(VIED_PARAMETERS_DIR)/print/interface +VIED_PARAMETERS_PRINT_FILES += $(VIED_PARAMETERS_DIR)/print/src/ia_css_terminal_print.c + +# VIED_PARAMETERS Trace Log Level = VIED_PARAMETERS_TRACE_LOG_LEVEL_NORMAL +# Other options are [VIED_PARAMETERS_TRACE_LOG_LEVEL_OFF, VIED_PARAMETERS_TRACE_LOG_LEVEL_DEBUG] +ifndef VIED_PARAMETERS_TRACE_CONFIG_HOST + VIED_PARAMETERS_TRACE_CONFIG_HOST=VIED_PARAMETERS_TRACE_LOG_LEVEL_NORMAL +endif +ifndef VIED_PARAMETERS_TRACE_CONFIG_FW + VIED_PARAMETERS_TRACE_CONFIG_FW=VIED_PARAMETERS_TRACE_LOG_LEVEL_NORMAL +endif + +VIED_PARAMETERS_HOST_CPPFLAGS += -DVIED_PARAMETERS_TRACE_CONFIG=$(VIED_PARAMETERS_TRACE_CONFIG_HOST) +VIED_PARAMETERS_FW_CPPFLAGS += -DVIED_PARAMETERS_TRACE_CONFIG=$(VIED_PARAMETERS_TRACE_CONFIG_FW) + +VIED_PARAMETERS_HOST_CPPFLAGS += -I$(VIED_PARAMETERS_INTERFACE) +VIED_PARAMETERS_HOST_CPPFLAGS += -I$(VIED_PARAMETERS_SOURCES) +VIED_PARAMETERS_HOST_CPPFLAGS += -I$(VIED_PARAMETERS_EXTINCLUDE) +VIED_PARAMETERS_HOST_CPPFLAGS += $(VIED_PARAMETERS_SUPPORT_CPPFLAGS) +VIED_PARAMETERS_FW_CPPFLAGS += -I$(VIED_PARAMETERS_INTERFACE) +VIED_PARAMETERS_FW_CPPFLAGS += -I$(VIED_PARAMETERS_SOURCES) +VIED_PARAMETERS_FW_CPPFLAGS += -I$(VIED_PARAMETERS_EXTINCLUDE) +VIED_PARAMETERS_FW_CPPFLAGS += $(VIED_PARAMETERS_SUPPORT_CPPFLAGS) + +#For IPU interface +include $(MODULES_DIR)/fw_abi_common_types/cpu/fw_abi_cpu_types.mk +VIED_PARAMETERS_HOST_CPPFLAGS += $(FW_ABI_COMMON_TYPES_HOST_CPPFLAGS) + +VIED_PARAMETERS_FW_CPPFLAGS += $(FW_ABI_COMMON_TYPES_FW_CPPFLAGS) diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/libcsspsys2600.c b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/libcsspsys2600.c new file mode 100644 index 0000000000000..55950b0022624 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/libcsspsys2600.c @@ -0,0 +1,489 @@ +/* + * Copyright (c) 2015--2018 Intel Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include + +#include "ipu.h" +#include "ipu-mmu.h" +#include "ipu-psys.h" +#include "ipu-wrapper.h" +#include "ipu-fw-psys.h" +#include "libcsspsys2600.h" + +#include +#include +#include +#include +#include + +int ipu_fw_psys_pg_start(struct ipu_psys_kcmd *kcmd) +{ + return -ia_css_process_group_start((ia_css_process_group_t *) + kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_start); + +int ipu_fw_psys_pg_disown(struct ipu_psys_kcmd *kcmd) +{ + return -ia_css_process_group_disown((ia_css_process_group_t *) + kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_disown); + +int ipu_fw_psys_pg_abort(struct ipu_psys_kcmd *kcmd) +{ + int rval; + + rval = ia_css_process_group_stop((ia_css_process_group_t *) + kcmd->kpg->pg); + if (rval) { + dev_err(&kcmd->fh->psys->adev->dev, + "failed to abort kcmd!\n"); + kcmd->pg_user = NULL; + rval = -EIO; + /* TODO: need to reset PSYS by power cycling it */ + } + return rval; +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_abort); + +int ipu_fw_psys_pg_submit(struct ipu_psys_kcmd *kcmd) +{ + return -ia_css_process_group_submit((ia_css_process_group_t *) + kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_submit); + +static void *syscom_buffer; +static struct ia_css_syscom_config *syscom_config; +static struct ia_css_psys_server_init *server_init; + +int ipu_fw_psys_rcv_event(struct ipu_psys *psys, + struct ipu_fw_psys_event *event) +{ + return ia_css_psys_event_queue_receive(psys_syscom, + IA_CSS_PSYS_EVENT_QUEUE_MAIN_ID, + (struct ia_css_psys_event_s *)event); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_rcv_event); + +int ipu_fw_psys_terminal_set(struct ipu_fw_psys_terminal *terminal, + int terminal_idx, + struct ipu_psys_kcmd *kcmd, + u32 buffer, + unsigned int size) +{ + ia_css_terminal_type_t type; + u32 buffer_state; + + type = ia_css_terminal_get_type((ia_css_terminal_t *)terminal); + + switch (type) { + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT: + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN: + case IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT: + case IA_CSS_TERMINAL_TYPE_PROGRAM: + buffer_state = IA_CSS_BUFFER_UNDEFINED; + break; + case IA_CSS_TERMINAL_TYPE_PARAM_STREAM: + case IA_CSS_TERMINAL_TYPE_DATA_IN: + case IA_CSS_TERMINAL_TYPE_STATE_IN: + buffer_state = IA_CSS_BUFFER_FULL; + break; + case IA_CSS_TERMINAL_TYPE_DATA_OUT: + case IA_CSS_TERMINAL_TYPE_STATE_OUT: + buffer_state = IA_CSS_BUFFER_EMPTY; + break; + default: + dev_err(&kcmd->fh->psys->adev->dev, + "unknown terminal type: 0x%x\n", type); + return -EAGAIN; + } + + if (type == IA_CSS_TERMINAL_TYPE_DATA_IN || + type == IA_CSS_TERMINAL_TYPE_DATA_OUT) { + ia_css_frame_t *frame; + + if (ia_css_data_terminal_set_connection_type( + (ia_css_data_terminal_t *)terminal, + IA_CSS_CONNECTION_MEMORY)) + return -EIO; + frame = ia_css_data_terminal_get_frame( + (ia_css_data_terminal_t *)terminal); + if (!frame) + return -EIO; + + if (ia_css_frame_set_data_bytes(frame, size)) + return -EIO; + } + + return -ia_css_process_group_attach_buffer( + (ia_css_process_group_t *)kcmd->kpg->pg, buffer, + buffer_state, terminal_idx); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_terminal_set); + +void ipu_fw_psys_pg_dump(struct ipu_psys *psys, + struct ipu_psys_kcmd *kcmd, + const char *note) +{ + ia_css_process_group_t *pg = (ia_css_process_group_t *)kcmd->kpg->pg; + ia_css_program_group_ID_t pgid = + ia_css_process_group_get_program_group_ID(pg); + uint8_t processes = ia_css_process_group_get_process_count( + (ia_css_process_group_t *)kcmd->kpg->pg); + unsigned int p, chn, mem; + + dev_dbg(&psys->adev->dev, "%s %s pgid %i has %i processes\n", + __func__, note, pgid, processes); + for (p = 0; p < processes; p++) { + ia_css_process_t *process = + ia_css_process_group_get_process(pg, p); + int cell = ia_css_process_get_cell(process); + + dev_dbg(&psys->adev->dev, + "%s pgid %i process %i cell %i cell_bitmap = 0x%x size = %zu\n", + __func__, pgid, p, + cell, + ia_css_process_get_cells_bitmap(process), + ia_css_process_get_size(process)); + dev_dbg(&psys->adev->dev, + "%s pgid %i process %i kernel bitmap 0x%llx\n", + __func__, pgid, p, + ia_css_process_get_kernel_bitmap(process)); + for (mem = 0; mem < VIED_NCI_N_DATA_MEM_TYPE_ID; mem++) { + unsigned int mem_id = process->ext_mem_id[mem]; + dev_dbg(&psys->adev->dev, + "%s pgid %i process %i index %u type %d id %d offset 0x%x\n", + __func__, pgid, p, mem, + vied_nci_cell_get_mem_type(cell, mem), + mem_id, process->ext_mem_offset[mem]); + } + for (chn = 0; chn < VIED_NCI_N_DEV_CHN_ID; chn++) { + dev_dbg(&psys->adev->dev, + "%s pgid %i process %i dev_chn[%u] = %i\n", + __func__, pgid, p, chn, + ia_css_process_get_dev_chn(process, chn)); + } + } +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_dump); + +int ipu_fw_psys_pg_get_id(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_program_group_ID( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_id); + +int ipu_fw_psys_pg_get_terminal_count(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_terminal_count( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_terminal_count); + +int ipu_fw_psys_pg_get_size(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_size((ia_css_process_group_t *) + kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_size); + +int ipu_fw_psys_pg_set_ipu_vaddress(struct ipu_psys_kcmd *kcmd, + dma_addr_t vaddress) +{ + return ia_css_process_group_set_ipu_vaddress((ia_css_process_group_t *) + kcmd->kpg->pg, vaddress); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_set_ipu_vaddress); + +int ipu_fw_psys_pg_load_cycles(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_pg_load_cycles( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_load_cycles); + +int ipu_fw_psys_pg_init_cycles(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_pg_init_cycles( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_init_cycles); + +int ipu_fw_psys_pg_processing_cycles(struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_pg_processing_cycles( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_processing_cycles); + +struct ipu_fw_psys_terminal * +ipu_fw_psys_pg_get_terminal(struct ipu_psys_kcmd *kcmd, int index) +{ + return (struct ipu_fw_psys_terminal *)ia_css_process_group_get_terminal( + (ia_css_process_group_t *)kcmd->kpg->pg, index); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_terminal); + +void ipu_fw_psys_pg_set_token(struct ipu_psys_kcmd *kcmd, u64 token) +{ + ia_css_process_group_set_token((ia_css_process_group_t *)kcmd->kpg->pg, + token); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_set_token); + +int ipu_fw_psys_pg_get_protocol( + struct ipu_psys_kcmd *kcmd) +{ + return ia_css_process_group_get_protocol_version( + (ia_css_process_group_t *)kcmd->kpg->pg); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_protocol); + +static int libcsspsys2600_init(void); +int ipu_fw_psys_open(struct ipu_psys *psys) +{ + bool opened; + int retry = IPU_PSYS_OPEN_RETRY; + + ipu_wrapper_init(PSYS_MMID, &psys->adev->dev, + psys->pdata->base); + /* When fw psys open, make sure csslib init first */ + libcsspsys2600_init(); + + server_init->icache_prefetch_sp = psys->icache_prefetch_sp; + server_init->icache_prefetch_isp = psys->icache_prefetch_isp; + + psys_syscom = ia_css_psys_open(syscom_buffer, syscom_config); + if (!psys_syscom) { + dev_err(&psys->adev->dev, + "psys library open failed\n"); + return -ENODEV; + } + do { + opened = ia_css_psys_open_is_ready(psys_syscom); + if (opened) + break; + usleep_range(IPU_PSYS_OPEN_TIMEOUT_US, + IPU_PSYS_OPEN_TIMEOUT_US + 10); + retry--; + } while (retry > 0); + + if (!retry && !opened) { + dev_err(&psys->adev->dev, + "psys library open ready failed\n"); + ia_css_psys_close(psys_syscom); + ia_css_psys_release(psys_syscom, 1); + psys_syscom = NULL; + return -ENODEV; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_open); + +int ipu_fw_psys_close(struct ipu_psys *psys) +{ + int rval; + unsigned int retry = IPU_PSYS_CLOSE_TIMEOUT; + + if (!psys_syscom) + return 0; + + if (ia_css_psys_close(psys_syscom)) { + dev_err(&psys->adev->dev, + "psys library close ready failed\n"); + return 0; + } + + do { + rval = ia_css_psys_release(psys_syscom, 0); + if (rval && rval != -EBUSY) { + dev_dbg(&psys->adev->dev, "psys library release failed\n"); + break; + } + usleep_range(IPU_PSYS_CLOSE_TIMEOUT_US, + IPU_PSYS_CLOSE_TIMEOUT_US + 10); + } while (rval && --retry); + + psys_syscom = NULL; + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_close); + +u64 ipu_fw_psys_pg_get_token(struct ipu_psys_kcmd *kcmd) +{ + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_pg_get_token); + +static const struct ipu_fw_resource_definitions default_defs = { + .cells = vied_nci_cell_type, + .num_cells = VIED_NCI_N_CELL_ID, + .num_cells_type = VIED_NCI_N_CELL_TYPE_ID, + .dev_channels = vied_nci_dev_chn_size, + .num_dev_channels = VIED_NCI_N_DEV_CHN_ID, + + .num_ext_mem_types = VIED_NCI_N_DATA_MEM_TYPE_ID, + .num_ext_mem_ids = VIED_NCI_N_MEM_ID, + .ext_mem_ids = vied_nci_mem_size, + + .cell_mem_row = VIED_NCI_N_MEM_TYPE_ID, + .cell_mem = (enum ipu_mem_id *)vied_nci_cell_mem, +}; + +const struct ipu_fw_resource_definitions *res_defs = &default_defs; +EXPORT_SYMBOL_GPL(res_defs); + +int ipu_fw_psys_set_process_cell_id(struct ipu_fw_psys_process *ptr, u8 index, + u8 value) +{ + return ia_css_process_set_cell((ia_css_process_t *)ptr, + (vied_nci_cell_ID_t)value); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_set_process_cell_id); + +u8 ipu_fw_psys_get_process_cell_id(struct ipu_fw_psys_process *ptr, u8 index) +{ + return ia_css_process_get_cell((ia_css_process_t *)ptr); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_get_process_cell_id); + +int ipu_fw_psys_clear_process_cell(struct ipu_fw_psys_process *ptr) +{ + return ia_css_process_clear_cell((ia_css_process_t *)ptr); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_clear_process_cell); + +int ipu_fw_psys_set_process_dev_chn_offset(struct ipu_fw_psys_process *ptr, + u16 offset, u16 value) +{ + return ia_css_process_set_dev_chn((ia_css_process_t *)ptr, + (vied_nci_dev_chn_ID_t)offset, + (vied_nci_resource_size_t)value); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_set_process_dev_chn_offset); + +int ipu_fw_psys_set_process_ext_mem(struct ipu_fw_psys_process *ptr, + u16 type_id, u16 mem_id, u16 offset) +{ + return ia_css_process_set_ext_mem((ia_css_process_t *)ptr, mem_id, offset); +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_set_process_ext_mem); + +int ipu_fw_psys_get_program_manifest_by_process( + struct ipu_fw_generic_program_manifest *gen_pm, + const struct ipu_fw_psys_program_group_manifest *pg_manifest, + struct ipu_fw_psys_process *process) +{ + ia_css_program_ID_t process_id = + ia_css_process_get_program_ID( + (const ia_css_process_t *)process); + int programs = + ia_css_program_group_manifest_get_program_count( + (const ia_css_program_group_manifest_t *)pg_manifest); + int i; + + for (i = 0; i < programs; i++) { + ia_css_program_ID_t program_id; + ia_css_program_manifest_t *pm = + ia_css_program_group_manifest_get_prgrm_mnfst( + (const ia_css_program_group_manifest_t *) + pg_manifest, i); + if (!pm) + continue; + program_id = ia_css_program_manifest_get_program_ID(pm); + if (program_id == process_id) { + gen_pm->dev_chn_size = (u16 *)pm->dev_chn_size; + gen_pm->ext_mem_size = (u16 *)pm->ext_mem_size; + gen_pm->cell_id = pm->cell_id; + gen_pm->cell_type_id = pm->cell_type_id; + return 0; + } + } + return -ENOENT; +} +EXPORT_SYMBOL_GPL(ipu_fw_psys_get_program_manifest_by_process); + +static int libcsspsys2600_init(void) +{ + int rval; + static bool csslib_init; + + if (csslib_init) + return 0; + + syscom_buffer = kzalloc(ia_css_sizeof_psys(NULL), GFP_KERNEL); + if (!syscom_buffer) + return -ENOMEM; + + syscom_config = kzalloc(sizeof(struct ia_css_syscom_config), + GFP_KERNEL); + if (!syscom_config) { + rval = -ENOMEM; + goto out_syscom_buffer_free; + } + + server_init = kzalloc(sizeof(struct ia_css_psys_server_init), + GFP_KERNEL); + if (!server_init) { + rval = -ENOMEM; + goto out_syscom_config_free; + } + + server_init->ddr_pkg_dir_address = 0; + server_init->host_ddr_pkg_dir = 0; + server_init->pkg_dir_size = 0; + + *syscom_config = *ia_css_psys_specify(); + syscom_config->specific_addr = server_init; + syscom_config->specific_size = sizeof(struct ia_css_psys_server_init); + syscom_config->ssid = PSYS_SSID; + syscom_config->mmid = PSYS_MMID; + syscom_config->regs_addr = ipu_device_cell_memory_address(SPC0, + IPU_DEVICE_SP2600_CONTROL_REGS); + syscom_config->dmem_addr = ipu_device_cell_memory_address(SPC0, + IPU_DEVICE_SP2600_CONTROL_DMEM); + csslib_init = true; + + return 0; + +out_syscom_config_free: + kfree(syscom_config); +out_syscom_buffer_free: + kfree(syscom_buffer); + + return rval; +} + +static void __exit libcsspsys2600_exit(void) +{ + kfree(syscom_buffer); + kfree(syscom_config); + kfree(server_init); +} + +module_init(libcsspsys2600_init); +module_exit(libcsspsys2600_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu psys css library"); diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/libcsspsys2600.h b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/libcsspsys2600.h new file mode 100644 index 0000000000000..b8d790f561805 --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/lib2600psys/libcsspsys2600.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015--2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef LIBCSSPSYS2600_H +#define LIBCSSPSYS2600_H + +#include +#include +#include +#include +#include +#include +#include + +extern struct ia_css_syscom_context *psys_syscom; +#endif diff --git a/drivers/media/pci/intel/ipu4/ipu4p-css/libintel-ipu4p.c b/drivers/media/pci/intel/ipu4/ipu4p-css/libintel-ipu4p.c new file mode 100644 index 0000000000000..be872777d319f --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-css/libintel-ipu4p.c @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2014 - 2018 Intel Corporation + +#include +#include +#include +#include "ipu-isys.h" +#include "ipu-wrapper.h" +#include + +#include "ipu-platform.h" + +#define ipu_lib_call_notrace_unlocked(func, isys, ...) \ + ({ \ + int rval; \ + \ + rval = -ia_css_isys_##func((isys)->fwcom, ##__VA_ARGS__); \ + \ + rval; \ + }) + +#define ipu_lib_call_notrace(func, isys, ...) \ + ({ \ + int rval; \ + \ + mutex_lock(&(isys)->lib_mutex); \ + \ + rval = ipu_lib_call_notrace_unlocked( \ + func, isys, ##__VA_ARGS__); \ + \ + mutex_unlock(&(isys)->lib_mutex); \ + \ + rval; \ + }) + +#define ipu_lib_call(func, isys, ...) \ + ({ \ + int rval; \ + dev_dbg(&(isys)->adev->dev, "hostlib: libcall %s\n", #func); \ + rval = ipu_lib_call_notrace(func, isys, ##__VA_ARGS__); \ + \ + rval; \ + }) + +static int wrapper_init_done; + +int ipu_fw_isys_close(struct ipu_isys *isys) +{ + struct device *dev = &isys->adev->dev; + int timeout = IPU_ISYS_TURNOFF_TIMEOUT; + int rval; + unsigned long flags; + + /* + * Ask library to stop the isys fw. Actual close takes + * some time as the FW must stop its actions including code fetch + * to SP icache. + */ + mutex_lock(&isys->lib_mutex); + spin_lock_irqsave(&isys->power_lock, flags); + rval = ipu_lib_call_notrace_unlocked(device_close, isys); + spin_unlock_irqrestore(&isys->power_lock, flags); + mutex_unlock(&isys->lib_mutex); + if (rval) + dev_err(dev, "Device close failure: %d\n", rval); + + /* release probably fails if the close failed. Let's try still */ + do { + usleep_range(IPU_ISYS_TURNOFF_DELAY_US, + 2 * IPU_ISYS_TURNOFF_DELAY_US); + rval = ipu_lib_call_notrace(device_release, isys, 0); + timeout--; + } while (rval != 0 && timeout); + + /* Spin lock to wait the interrupt handler to be finished */ + spin_lock_irqsave(&isys->power_lock, flags); + if (!rval) + isys->fwcom = NULL; /* No further actions needed */ + else + dev_err(dev, "Device release time out %d\n", rval); + spin_unlock_irqrestore(&isys->power_lock, flags); + return rval; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_close); + +int ipu_fw_isys_init(struct ipu_isys *isys, + unsigned int num_streams) +{ + int retry = IPU_ISYS_OPEN_RETRY; + unsigned int i; + + struct ia_css_isys_device_cfg_data isys_cfg = { + .driver_sys = { + .ssid = ISYS_SSID, + .mmid = ISYS_MMID, + .num_send_queues = clamp_t( + unsigned int, num_streams, 1, + IPU_ISYS_NUM_STREAMS), + .num_recv_queues = IPU_ISYS_NUM_RECV_QUEUE, + .send_queue_size = IPU_ISYS_SIZE_SEND_QUEUE, + .recv_queue_size = IPU_ISYS_SIZE_RECV_QUEUE, + .icache_prefetch = isys->icache_prefetch, + }, + }; + struct device *dev = &isys->adev->dev; + int rval; + + if (!wrapper_init_done) { + wrapper_init_done = true; + ipu_wrapper_init(ISYS_MMID, &isys->adev->dev, + isys->pdata->base); + } + + /* + * SRAM partitioning. Initially equal partitioning is set + * TODO: Fine tune the partitining based on the stream pixel load + */ + for (i = 0; i < min(IPU_NOF_SRAM_BLOCKS_MAX, + NOF_SRAM_BLOCKS_MAX); i++) { + if (i < isys_cfg.driver_sys.num_send_queues) + isys_cfg.buffer_partition.num_gda_pages[i] = + (IPU_DEVICE_GDA_NR_PAGES * + IPU_DEVICE_GDA_VIRT_FACTOR) / + isys_cfg.driver_sys.num_send_queues; + else + isys_cfg.buffer_partition.num_gda_pages[i] = 0; + } + + rval = -ia_css_isys_device_open(&isys->fwcom, &isys_cfg); + if (rval < 0) { + dev_err(dev, "isys device open failed %d\n", rval); + return rval; + } + + do { + usleep_range(IPU_ISYS_OPEN_TIMEOUT_US, + IPU_ISYS_OPEN_TIMEOUT_US + 10); + rval = ipu_lib_call(device_open_ready, isys); + if (!rval) + break; + retry--; + } while (retry > 0); + + if (!retry && rval) { + dev_err(dev, "isys device open ready failed %d\n", rval); + ipu_fw_isys_close(isys); + } + + return rval; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_init); + +void ipu_fw_isys_cleanup(struct ipu_isys *isys) +{ + ipu_lib_call(device_release, isys, 1); + isys->fwcom = NULL; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_cleanup); + +struct ipu_fw_isys_resp_info_abi *ipu_fw_isys_get_resp( + void *context, unsigned int queue, + struct ipu_fw_isys_resp_info_abi *response) +{ + struct ia_css_isys_resp_info apiresp; + int rval; + + rval = -ia_css_isys_stream_handle_response(context, &apiresp); + if (rval < 0) + return NULL; + + response->buf_id = 0; + response->type = apiresp.type; + response->timestamp[0] = apiresp.timestamp[0]; + response->timestamp[1] = apiresp.timestamp[1]; + response->stream_handle = apiresp.stream_handle; + response->error_info.error = apiresp.error; + response->error_info.error_details = apiresp.error_details; + response->pin.out_buf_id = apiresp.pin.out_buf_id; + response->pin.addr = apiresp.pin.addr; + response->pin_id = apiresp.pin_id; + response->process_group_light.param_buf_id = + apiresp.process_group_light.param_buf_id; + response->process_group_light.addr = + apiresp.process_group_light.addr; + response->acc_id = apiresp.acc_id; +#ifdef IPU_OTF_SUPPORT + response->frame_counter = apiresp.frame_counter; + response->written_direct = apiresp.written_direct; +#endif + + return response; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_get_resp); + +void ipu_fw_isys_put_resp(void *context, unsigned int queue) +{ + /* Nothing to do here really */ +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_put_resp); + +int ipu_fw_isys_simple_cmd(struct ipu_isys *isys, + const unsigned int stream_handle, + enum ipu_fw_isys_send_type send_type) +{ + int rval = -1; + + switch (send_type) { + case IPU_FW_ISYS_SEND_TYPE_STREAM_START: + rval = ipu_lib_call(stream_start, isys, stream_handle, NULL); + break; + case IPU_FW_ISYS_SEND_TYPE_STREAM_FLUSH: + rval = ipu_lib_call(stream_flush, isys, stream_handle); + break; + case IPU_FW_ISYS_SEND_TYPE_STREAM_STOP: + rval = ipu_lib_call(stream_stop, isys, stream_handle); + break; + case IPU_FW_ISYS_SEND_TYPE_STREAM_CLOSE: + rval = ipu_lib_call(stream_close, isys, stream_handle); + break; + default: + WARN_ON(1); + } + return rval; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_simple_cmd); + +static void resolution_abi_to_api(const struct ipu_fw_isys_resolution_abi *abi, + struct ia_css_isys_resolution *api) +{ + api->width = abi->width; + api->height = abi->height; +} + +static void output_pin_payload_abi_to_api( + struct ipu_fw_isys_output_pin_payload_abi *abi, + struct ia_css_isys_output_pin_payload *api) +{ + api->out_buf_id = abi->out_buf_id; + api->addr = abi->addr; +} + +static void output_pin_info_abi_to_api( + struct ipu_fw_isys_output_pin_info_abi *abi, + struct ia_css_isys_output_pin_info *api) +{ + api->input_pin_id = abi->input_pin_id; + resolution_abi_to_api(&abi->output_res, &api->output_res); + api->stride = abi->stride; + api->pt = abi->pt; + api->watermark_in_lines = abi->watermark_in_lines; + api->payload_buf_size = abi->payload_buf_size; + api->send_irq = abi->send_irq; + api->ft = abi->ft; +#ifdef IPU_OTF_SUPPORT + api->link_id = abi->link_id; +#endif + api->reserve_compression = abi->reserve_compression; +} + +static void param_pin_abi_to_api(struct ipu_fw_isys_param_pin_abi *abi, + struct ia_css_isys_param_pin *api) +{ + api->param_buf_id = abi->param_buf_id; + api->addr = abi->addr; +} + +static void input_pin_info_abi_to_api( + struct ipu_fw_isys_input_pin_info_abi *abi, + struct ia_css_isys_input_pin_info *api) +{ + resolution_abi_to_api(&abi->input_res, &api->input_res); + api->dt = abi->dt; + api->mipi_store_mode = abi->mipi_store_mode; + api->mapped_dt = abi->mapped_dt; +} + +static void isa_cfg_abi_to_api(const struct ipu_fw_isys_isa_cfg_abi *abi, + struct ia_css_isys_isa_cfg *api) +{ + unsigned int i; + + for (i = 0; i < min((int)N_IPU_FW_ISYS_RESOLUTION_INFO, + (int)N_IA_CSS_ISYS_RESOLUTION_INFO); i++) + resolution_abi_to_api(&abi->isa_res[i], &api->isa_res[i]); + + api->blc_enabled = abi->cfg.blc; + api->lsc_enabled = abi->cfg.lsc; + api->dpc_enabled = abi->cfg.dpc; + api->downscaler_enabled = abi->cfg.downscaler; + api->awb_enabled = abi->cfg.awb; + api->af_enabled = abi->cfg.af; + api->ae_enabled = abi->cfg.ae; + api->paf_type = abi->cfg.paf; + api->send_irq_stats_ready = abi->cfg.send_irq_stats_ready; + api->send_resp_stats_ready = abi->cfg.send_irq_stats_ready; +} + +static void cropping_abi_to_api(struct ipu_fw_isys_cropping_abi *abi, + struct ia_css_isys_cropping *api) +{ + api->top_offset = abi->top_offset; + api->left_offset = abi->left_offset; + api->bottom_offset = abi->bottom_offset; + api->right_offset = abi->right_offset; +} + +static void stream_cfg_abi_to_api(struct ipu_fw_isys_stream_cfg_data_abi *abi, + struct ia_css_isys_stream_cfg_data *api) +{ + unsigned int i; + + api->src = abi->src; + api->vc = abi->vc; + api->isl_use = abi->isl_use; + api->compfmt = abi->compfmt; + isa_cfg_abi_to_api(&abi->isa_cfg, &api->isa_cfg); + for (i = 0; i < min((int)N_IPU_FW_ISYS_CROPPING_LOCATION, + (int)N_IA_CSS_ISYS_CROPPING_LOCATION); i++) + cropping_abi_to_api(&abi->crop[i], &api->crop[i]); + + api->send_irq_sof_discarded = abi->send_irq_sof_discarded; + api->send_irq_eof_discarded = abi->send_irq_eof_discarded; + api->send_resp_sof_discarded = abi->send_irq_sof_discarded; + api->send_resp_eof_discarded = abi->send_irq_eof_discarded; + api->nof_input_pins = abi->nof_input_pins; + api->nof_output_pins = abi->nof_output_pins; + for (i = 0; i < abi->nof_input_pins; i++) + input_pin_info_abi_to_api(&abi->input_pins[i], + &api->input_pins[i]); + + for (i = 0; i < abi->nof_output_pins; i++) + output_pin_info_abi_to_api(&abi->output_pins[i], + &api->output_pins[i]); +} + +static void frame_buff_set_abi_to_api( + struct ipu_fw_isys_frame_buff_set_abi *abi, + struct ia_css_isys_frame_buff_set *api) +{ + int i; + + for (i = 0; i < min(IPU_MAX_OPINS, MAX_OPINS); i++) + output_pin_payload_abi_to_api(&abi->output_pins[i], + &api->output_pins[i]); + + param_pin_abi_to_api(&abi->process_group_light, + &api->process_group_light); + + api->send_irq_sof = abi->send_irq_sof; + api->send_irq_eof = abi->send_irq_eof; + api->send_irq_capture_ack = abi->send_irq_capture_ack; + api->send_irq_capture_done = abi->send_irq_capture_done; +} + +int ipu_fw_isys_complex_cmd(struct ipu_isys *isys, + const unsigned int stream_handle, + void *cpu_mapped_buf, + dma_addr_t dma_mapped_buf, + size_t size, + enum ipu_fw_isys_send_type send_type) +{ + union { + struct ia_css_isys_stream_cfg_data stream_cfg; + struct ia_css_isys_frame_buff_set buf; + } param; + int rval = -1; + + memset(¶m, 0, sizeof(param)); + + switch (send_type) { + case IPU_FW_ISYS_SEND_TYPE_STREAM_CAPTURE: + frame_buff_set_abi_to_api(cpu_mapped_buf, ¶m.buf); + rval = ipu_lib_call(stream_capture_indication, + isys, stream_handle, ¶m.buf); + break; + case IPU_FW_ISYS_SEND_TYPE_STREAM_OPEN: + stream_cfg_abi_to_api(cpu_mapped_buf, ¶m.stream_cfg); + rval = ipu_lib_call(stream_open, isys, stream_handle, + ¶m.stream_cfg); + break; + case IPU_FW_ISYS_SEND_TYPE_STREAM_START_AND_CAPTURE: + frame_buff_set_abi_to_api(cpu_mapped_buf, ¶m.buf); + rval = ipu_lib_call(stream_start, isys, stream_handle, + ¶m.buf); + break; + default: + WARN_ON(1); + } + + return rval; +} +EXPORT_SYMBOL_GPL(ipu_fw_isys_complex_cmd); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel ipu library"); diff --git a/drivers/media/pci/intel/ipu4/ipu4p-isys-csi2.c b/drivers/media/pci/intel/ipu4/ipu4p-isys-csi2.c new file mode 100644 index 0000000000000..b7923dbef5d5c --- /dev/null +++ b/drivers/media/pci/intel/ipu4/ipu4p-isys-csi2.c @@ -0,0 +1,449 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Intel Corporation + +#include "ipu.h" +#include "ipu-buttress.h" +#include "ipu-isys.h" +#include "ipu-isys-csi2.h" +#include "ipu-platform-isys-csi2-reg.h" +#include "ipu-platform-regs.h" +#include "ipu-trace.h" +#include "ipu-isys-csi2.h" + +#define CSI2_UPDATE_TIME_TRY_NUM 3 +#define CSI2_UPDATE_TIME_MAX_DIFF 20 + +static int ipu4p_csi2_ev_correction_params(struct ipu_isys_csi2 + *csi2, unsigned int lanes) +{ + /* + * TBD: add implementation for ipu4p + * probably re-use ipu4 implementation + */ + return 0; +} + + +static void ipu4p_csi2_log_rx_state(struct ipu_isys_csi2 *csi2, const char *tag) +{ + u32 enable = readl(csi2->base + CSI2_REG_CSI_RX_ENABLE); + u32 lanes = readl(csi2->base + CSI2_REG_CSI_RX_NOF_ENABLED_LANES); + u32 config = readl(csi2->base + CSI2_REG_CSI_RX_CONFIG); + u32 status = readl(csi2->base + CSI2_REG_CSI_RX_STATUS); + u32 hs = readl(csi2->base + CSI2_REG_CSI_RX_STATUS_DLANE_HS); + u32 lp = readl(csi2->base + CSI2_REG_CSI_RX_STATUS_DLANE_LP); + u32 ctermen = readl(csi2->base + CSI2_REG_CSI_RX_DLY_CNT_TERMEN_CLANE); + u32 csettle = readl(csi2->base + CSI2_REG_CSI_RX_DLY_CNT_SETTLE_CLANE); + + dev_dbg(&csi2->isys->adev->dev, + "csi %u %s: rx enable=0x%x lanes=%u config=0x%x status=0x%x hs=0x%x lp=0x%x ctermen=%u csettle=%u receiver_errors=0x%x\n", + csi2->index, tag, enable, lanes, config, status, hs, lp, + ctermen, csettle, csi2->receiver_errors); +} + +static void ipu4p_isys_register_errors(struct ipu_isys_csi2 *csi2) +{ + u32 status; + unsigned int index; + struct ipu_isys *isys = csi2->isys; + void __iomem *isys_base = isys->pdata->base; + + index = csi2->index; + status = readl(isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(index) + 0x8); + writel(status, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(index) + 0xc); + + status &= 0xffff; + dev_dbg(&isys->adev->dev, "csi %d rxsync status 0x%x", index, status); + csi2->receiver_errors |= status; +} + +void ipu_isys_csi2_error(struct ipu_isys_csi2 *csi2) +{ + /* + * Strings corresponding to CSI-2 receiver errors are here. + * Corresponding macros are defined in the header file. + */ + static const struct ipu_isys_csi2_error { + const char *error_string; + bool is_info_only; + } errors[] = { + {"Single packet header error corrected", true}, + {"Multiple packet header errors detected", true}, + {"Payload checksum (CRC) error", true}, + {"FIFO overflow", false}, + {"Reserved short packet data type detected", true}, + {"Reserved long packet data type detected", true}, + {"Incomplete long packet detected", false}, + {"Frame sync error", false}, + {"Line sync error", false}, + {"DPHY recoverable synchronization error", true}, + {"DPHY non-recoverable synchronization error", false}, + {"Escape mode error", true}, + {"Escape mode trigger event", true}, + {"Escape mode ultra-low power state for data lane(s)", true}, + {"Escape mode ultra-low power state exit for clock lane", true}, + {"Inter-frame short packet discarded", true}, + {"Inter-frame long packet discarded", true}, + }; + u32 status; + unsigned int i; + + /* Register errors once more in case of error interrupts are disabled */ + ipu4p_isys_register_errors(csi2); + ipu4p_csi2_log_rx_state(csi2, "error snapshot"); + status = csi2->receiver_errors; + csi2->receiver_errors = 0; + + for (i = 0; i < ARRAY_SIZE(errors); i++) { + if (status & BIT(i)) { + if (errors[i].is_info_only) + dev_dbg(&csi2->isys->adev->dev, + "csi2-%i info: %s\n", + csi2->index, errors[i].error_string); + else + dev_err_ratelimited(&csi2->isys->adev->dev, + "csi2-%i error: %s\n", + csi2->index, + errors[i].error_string); + } + } +} + +int ipu_isys_csi2_set_stream(struct v4l2_subdev *sd, + struct ipu_isys_csi2_timing timing, + unsigned int nlanes, int enable) +{ + struct ipu_isys_csi2 *csi2 = to_ipu_isys_csi2(sd); + struct ipu_isys *isys = csi2->isys; + void __iomem *isys_base = isys->pdata->base; + unsigned int i; + u32 val, csi2part = 0; + + dev_dbg(&csi2->isys->adev->dev, "csi2 s_stream %d\n", enable); + ipu4p_csi2_log_rx_state(csi2, "set_stream entry"); + if (!enable) { + ipu4p_csi2_log_rx_state(csi2, "set_stream disable pre-error"); + ipu_isys_csi2_error(csi2); + + val = readl(csi2->base + CSI2_REG_CSI_RX_CONFIG); + val &= ~(CSI2_CSI_RX_CONFIG_DISABLE_BYTE_CLK_GATING | + CSI2_CSI_RX_CONFIG_RELEASE_LP11); + writel(val, csi2->base + CSI2_REG_CSI_RX_CONFIG); + + writel(0, csi2->base + CSI2_REG_CSI_RX_ENABLE); + + writel(0, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL_BASE(csi2->index) + 0x4); + writel(0, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL_BASE(csi2->index) + + 0x10); + writel + (0, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(csi2->index) + 0x4); + writel + (0, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(csi2->index) + 0x10); + ipu4p_csi2_log_rx_state(csi2, "set_stream disable done"); + return 0; + } + + ipu4p_csi2_ev_correction_params(csi2, nlanes); + + writel(timing.ctermen, + csi2->base + CSI2_REG_CSI_RX_DLY_CNT_TERMEN_CLANE); + writel(timing.csettle, + csi2->base + CSI2_REG_CSI_RX_DLY_CNT_SETTLE_CLANE); + + for (i = 0; i < nlanes; i++) { + writel + (timing.dtermen, + csi2->base + CSI2_REG_CSI_RX_DLY_CNT_TERMEN_DLANE(i)); + writel + (timing.dsettle, + csi2->base + CSI2_REG_CSI_RX_DLY_CNT_SETTLE_DLANE(i)); + } + + val = readl(csi2->base + CSI2_REG_CSI_RX_CONFIG); + val |= CSI2_CSI_RX_CONFIG_DISABLE_BYTE_CLK_GATING | + CSI2_CSI_RX_CONFIG_RELEASE_LP11; + writel(val, csi2->base + CSI2_REG_CSI_RX_CONFIG); + + writel(nlanes, csi2->base + CSI2_REG_CSI_RX_NOF_ENABLED_LANES); + writel(CSI2_CSI_RX_ENABLE_ENABLE, + csi2->base + CSI2_REG_CSI_RX_ENABLE); + +#ifdef IPU_VC_SUPPORT + /* SOF of VC0-VC3 enabled from CSI2PART register in B0 */ + for (i = 0; i < NR_OF_CSI2_VC; i++) + csi2part |= CSI2_IRQ_FS_VC(i) | CSI2_IRQ_FE_VC(i); +#else + csi2part |= CSI2_IRQ_FS_VC | CSI2_IRQ_FE_VC; +#endif + + /* Enable csi2 receiver error interrupts */ + writel(1, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL_BASE(csi2->index)); + writel(0, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL_BASE(csi2->index) + 0x14); + writel(0xffffffff, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL_BASE(csi2->index) + 0xc); + writel(1, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL_BASE(csi2->index) + 0x4); + writel(1, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL_BASE(csi2->index) + 0x10); + + csi2part |= 0xffff; + writel(csi2part, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(csi2->index)); + writel(0, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(csi2->index) + 0x14); + writel(0xffffffff, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(csi2->index) + 0xc); + writel(csi2part, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(csi2->index) + 0x4); + writel(csi2part, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(csi2->index) + 0x10); + + ipu4p_csi2_log_rx_state(csi2, "set_stream enable done"); + return 0; +} + +void ipu_isys_csi2_isr(struct ipu_isys_csi2 *csi2) +{ + u32 status = 0; +#ifdef IPU_VC_SUPPORT + unsigned int i, bus; +#else + unsigned int bus; +#endif + struct ipu_isys *isys = csi2->isys; + void __iomem *isys_base = isys->pdata->base; + + bus = csi2->index; + /* handle ctrl and ctrl0 irq */ + status = readl(isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL_BASE(bus) + 0x8); + writel(status, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL_BASE(bus) + 0xc); + dev_dbg(&isys->adev->dev, "csi %d irq_ctrl status 0x%x", bus, status); + + if (!(status & BIT(0))) + return; + + status = readl(isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(bus) + 0x8); + writel(status, isys_base + + IPU_REG_ISYS_CSI_IRQ_CTRL0_BASE(bus) + 0xc); + dev_dbg(&isys->adev->dev, "csi %d irq_ctrl0 status 0x%x", bus, status); + /* register the csi sync error */ + csi2->receiver_errors |= status & 0xffff; + /* handle sof and eof event */ +#ifdef IPU_VC_SUPPORT + for (i = 0; i < NR_OF_CSI2_VC; i++) { + if (status & CSI2_IRQ_FS_VC(i)) + ipu_isys_csi2_sof_event(csi2, i); + + if (status & CSI2_IRQ_FE_VC(i)) + ipu_isys_csi2_eof_event(csi2, i); + } +#else + if (status & CSI2_IRQ_FS_VC) + ipu_isys_csi2_sof_event(csi2); + if (status & CSI2_IRQ_FE_VC) + ipu_isys_csi2_eof_event(csi2); +#endif +} + +static u64 tunit_time_to_us(struct ipu_isys *isys, u64 time) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(isys->adev->iommu); + u64 isys_clk = IS_FREQ_SOURCE / adev->ctrl->divisor / 1000000; + + do_div(time, isys_clk); + + return time; +} + +static u64 tsc_time_to_tunit_time(struct ipu_isys *isys, + u64 tsc_base, u64 tunit_base, u64 tsc_time) +{ + struct ipu_bus_device *adev = to_ipu_bus_device(isys->adev->iommu); + u64 isys_clk = IS_FREQ_SOURCE / adev->ctrl->divisor / 100000; + u64 tsc_clk = IPU_BUTTRESS_TSC_CLK / 100000; + + tsc_time *= isys_clk; + tsc_base *= isys_clk; + do_div(tsc_time, tsc_clk); + do_div(tsc_base, tsc_clk); + + return tunit_base + tsc_time - tsc_base; +} + +static int update_timer_base(struct ipu_isys *isys) +{ + int rval, i; + u64 time; + + for (i = 0; i < CSI2_UPDATE_TIME_TRY_NUM; i++) { + rval = ipu_trace_get_timer(&isys->adev->dev, &time); + if (rval) { + dev_err(&isys->adev->dev, + "Failed to read Tunit timer.\n"); + return rval; + } + rval = ipu4_buttress_tsc_read(isys->adev->isp, + &isys->tsc_timer_base); + if (rval) { + dev_err(&isys->adev->dev, + "Failed to read TSC timer.\n"); + return rval; + } + rval = ipu_trace_get_timer(&isys->adev->dev, + &isys->tunit_timer_base); + if (rval) { + dev_err(&isys->adev->dev, + "Failed to read Tunit timer.\n"); + return rval; + } + if (tunit_time_to_us(isys, isys->tunit_timer_base - time) < + CSI2_UPDATE_TIME_MAX_DIFF) + return 0; + } + dev_dbg(&isys->adev->dev, "Timer base values may not be accurate.\n"); + return 0; +} + +/* Extract the timestamp from trace message. + * The timestamp in the traces message contains two parts. + * The lower part contains bit0 ~ 15 of the total 64bit timestamp. + * The higher part contains bit14 ~ 63 of the 64bit timestamp. + * These two parts are sampled at different time. + * Two overlaped bits are used to identify if there's roll overs + * in the lower part during the two samples. + * If the two overlapped bits do not match, a fix is needed to + * handle the roll over. + */ +static u64 extract_time_from_short_packet_msg(struct + ipu_isys_csi2_monitor_message + *msg) +{ + u64 time_h = msg->timestamp_h << 14; + u64 time_l = msg->timestamp_l; + u64 time_h_ovl = time_h & 0xc000; + u64 time_h_h = time_h & (~0xffff); + + /* Fix possible roll overs. */ + if (time_h_ovl >= (time_l & 0xc000)) + return time_h_h | time_l; + else + return (time_h_h - 0x10000) | time_l; +} + +unsigned int ipu_isys_csi2_get_current_field(struct ipu_isys_pipeline *ip, + unsigned int *timestamp) +{ + struct ipu_isys_video *av = container_of(ip, struct ipu_isys_video, ip); + struct ipu_isys *isys = av->isys; + unsigned int field = V4L2_FIELD_TOP; + + /* + * Find the nearest message that has matched msg type, + * port id, virtual channel and packet type. + */ + unsigned int i = ip->short_packet_trace_index; + bool msg_matched = false; + unsigned int monitor_id; + + update_timer_base(isys); + + if (ip->csi2->index >= IPU_ISYS_MAX_CSI2_LEGACY_PORTS) + monitor_id = TRACE_REG_CSI2_3PH_TM_MONITOR_ID; + else + monitor_id = TRACE_REG_CSI2_TM_MONITOR_ID; + + dma_sync_single_for_cpu(&isys->adev->dev, + isys->short_packet_trace_buffer_dma_addr, + IPU_ISYS_SHORT_PACKET_TRACE_BUFFER_SIZE, + DMA_BIDIRECTIONAL); + + do { + struct ipu_isys_csi2_monitor_message msg = + isys->short_packet_trace_buffer[i]; + u64 sof_time = tsc_time_to_tunit_time(isys, + isys->tsc_timer_base, + isys->tunit_timer_base, + (((u64) timestamp[1]) << + 32) | timestamp[0]); + u64 trace_time = extract_time_from_short_packet_msg(&msg); + u64 delta_time_us = tunit_time_to_us(isys, + (sof_time > trace_time) ? + sof_time - trace_time : + trace_time - sof_time); + + i = (i + 1) % IPU_ISYS_SHORT_PACKET_TRACE_MSG_NUMBER; + + if (msg.cmd == TRACE_REG_CMD_TYPE_D64MTS && + msg.monitor_id == monitor_id && + msg.fs == 1 && + msg.port == ip->csi2->index && +#ifdef IPU_VC_SUPPORT + msg.vc == ip->vc && +#endif + delta_time_us < IPU_ISYS_SHORT_PACKET_TRACE_MAX_TIMESHIFT) { + field = (msg.sequence % 2) ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; + ip->short_packet_trace_index = i; + msg_matched = true; + dev_dbg(&isys->adev->dev, + "Interlaced field ready. field = %d\n", field); + break; + } + } while (i != ip->short_packet_trace_index); + if (!msg_matched) + /* We have walked through the whole buffer. */ + dev_dbg(&isys->adev->dev, "No matched trace message found.\n"); + + return field; +} + +bool ipu_isys_csi2_skew_cal_required(struct ipu_isys_csi2 *csi2) +{ + __s64 link_freq; + int rval; + + if (!csi2) + return false; + +#ifdef IPU_VC_SUPPORT + /* Not yet ? */ + if (csi2->remote_streams != csi2->stream_count) + return false; + +#endif + rval = ipu_isys_csi2_get_link_freq(csi2, &link_freq); + if (rval) + return false; + + if (link_freq <= IPU_SKEW_CAL_LIMIT_HZ) + return false; + + return true; +} + +int ipu_isys_csi2_set_skew_cal(struct ipu_isys_csi2 *csi2, int enable) +{ + u32 val; + + val = readl(csi2->base + CSI2_REG_CSI_RX_CONFIG); + + if (enable) + val |= CSI2_CSI_RX_CONFIG_SKEWCAL_ENABLE; + else + val &= ~CSI2_CSI_RX_CONFIG_SKEWCAL_ENABLE; + + writel(val, csi2->base + CSI2_REG_CSI_RX_CONFIG); + + return 0; +} diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 01cf52c3ea33e..f0e64319d1688 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1336,9 +1336,11 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break; case V4L2_PIX_FMT_YVU420: descr = "Planar YVU 4:2:0"; break; case V4L2_PIX_FMT_YUYV: descr = "YUYV 4:2:2"; break; + case V4L2_PIX_FMT_YUYV420_V32: descr = "YUYV 4:2:2 Vector"; break; case V4L2_PIX_FMT_YYUV: descr = "YYUV 4:2:2"; break; case V4L2_PIX_FMT_YVYU: descr = "YVYU 4:2:2"; break; case V4L2_PIX_FMT_UYVY: descr = "UYVY 4:2:2"; break; + case V4L2_PIX_FMT_UYVY_V32: descr = "UYVY 4:2:2 Vector"; break; case V4L2_PIX_FMT_VYUY: descr = "VYUY 4:2:2"; break; case V4L2_PIX_FMT_YUV422P: descr = "Planar YUV 4:2:2"; break; case V4L2_PIX_FMT_YUV411P: descr = "Planar YUV 4:1:1"; break; @@ -1391,6 +1393,14 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_SGBRG8: descr = "8-bit Bayer GBGB/RGRG"; break; case V4L2_PIX_FMT_SGRBG8: descr = "8-bit Bayer GRGR/BGBG"; break; case V4L2_PIX_FMT_SRGGB8: descr = "8-bit Bayer RGRG/GBGB"; break; + case V4L2_PIX_FMT_SBGGR8V32: descr = "8-bit Bayer BGBG/GRGR Vector"; break; + case V4L2_PIX_FMT_SGBRG8V32: descr = "8-bit Bayer GBGB/RGRG Vector"; break; + case V4L2_PIX_FMT_SGRBG8V32: descr = "8-bit Bayer GRGR/BGBG Vector"; break; + case V4L2_PIX_FMT_SRGGB8V32: descr = "8-bit Bayer RGRG/GBGB Vector"; break; + // case V4L2_PIX_FMT_SBGGR8_16V32: descr = "8-bit Bayer BGBG/GRGR Vector"; break; + // case V4L2_PIX_FMT_SGBRG8_16V32: descr = "8-bit Bayer GBGB/RGRG Vector"; break; + // case V4L2_PIX_FMT_SGRBG8_16V32: descr = "8-bit Bayer GRGR/BGBG Vector"; break; + // case V4L2_PIX_FMT_SRGGB8_16V32: descr = "8-bit Bayer RGRG/GBGB Vector"; break; case V4L2_PIX_FMT_SBGGR10: descr = "10-bit Bayer BGBG/GRGR"; break; case V4L2_PIX_FMT_SGBRG10: descr = "10-bit Bayer GBGB/RGRG"; break; case V4L2_PIX_FMT_SGRBG10: descr = "10-bit Bayer GRGR/BGBG"; break; @@ -1399,6 +1409,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_SGBRG10P: descr = "10-bit Bayer GBGB/RGRG Packed"; break; case V4L2_PIX_FMT_SGRBG10P: descr = "10-bit Bayer GRGR/BGBG Packed"; break; case V4L2_PIX_FMT_SRGGB10P: descr = "10-bit Bayer RGRG/GBGB Packed"; break; + case V4L2_PIX_FMT_SBGGR10V32: descr = "10-bit Bayer BGBG/GRGR Vector"; break; + case V4L2_PIX_FMT_SGBRG10V32: descr = "10-bit Bayer GBGB/RGRG Vector"; break; + case V4L2_PIX_FMT_SGRBG10V32: descr = "10-bit Bayer GRGR/BGBG Vector"; break; + case V4L2_PIX_FMT_SRGGB10V32: descr = "10-bit Bayer RGRG/GBGB Vector"; break; case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break; case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break; case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break; @@ -1421,6 +1435,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break; case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break; case V4L2_PIX_FMT_RAW_CRU12: descr = "12-bit Raw CRU Packed"; break; + case V4L2_PIX_FMT_SBGGR12V32: descr = "12-bit Bayer BGBG/GRGR Vector"; break; + case V4L2_PIX_FMT_SGBRG12V32: descr = "12-bit Bayer GBGB/RGRG Vector"; break; + case V4L2_PIX_FMT_SGRBG12V32: descr = "12-bit Bayer GRGR/BGBG Vector"; break; + case V4L2_PIX_FMT_SRGGB12V32: descr = "12-bit Bayer RGRG/GBGB Vector"; break; case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break; case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break; case V4L2_PIX_FMT_SGRBG14: descr = "14-bit Bayer GRGR/BGBG"; break; @@ -1430,6 +1448,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break; case V4L2_PIX_FMT_SRGGB14P: descr = "14-bit Bayer RGRG/GBGB Packed"; break; case V4L2_PIX_FMT_RAW_CRU14: descr = "14-bit Raw CRU Packed"; break; + case V4L2_PIX_FMT_SBGGR14V32: descr = "14-bit Bayer RGRG/GBGB Vector"; break; + case V4L2_PIX_FMT_SGBRG14V32: descr = "14-bit Bayer RGRG/GBGB Vector"; break; + case V4L2_PIX_FMT_SGRBG14V32: descr = "14-bit Bayer RGRG/GBGB Vector"; break; + case V4L2_PIX_FMT_SRGGB14V32: descr = "14-bit Bayer RGRG/GBGB Vector"; break; case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break; case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break; case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break; @@ -1486,6 +1508,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_META_FMT_GENERIC_CSI2_16: descr = "8-bit Generic Meta, 16b CSI-2"; break; case V4L2_META_FMT_GENERIC_CSI2_20: descr = "8-bit Generic Meta, 20b CSI-2"; break; case V4L2_META_FMT_GENERIC_CSI2_24: descr = "8-bit Generic Meta, 24b CSI-2"; break; + case V4L2_FMT_IPU_ISA_CFG: descr = "IPU4 fourcc = ip4c)"; break; + case V4L2_FMT_IPU_ISYS_META: descr = "IPU4 fourcc = ip4m)"; break; default: /* Compressed formats */ diff --git a/include/media/ipu-isys.h b/include/media/ipu-isys.h new file mode 100644 index 0000000000000..13a6960c6a9b5 --- /dev/null +++ b/include/media/ipu-isys.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2014 - 2018 Intel Corporation */ + +#ifndef MEDIA_IPU_H +#define MEDIA_IPU_H + +#include +#include + +#define IPU_ISYS_MAX_CSI2_LANES 4 + +struct ipu_isys_subdev_i2c_info { + struct i2c_board_info board_info; + int i2c_adapter_id; +}; + +struct ipu_isys_subdev_info { + struct ipu_isys_csi2_config *csi2; + struct ipu_isys_subdev_i2c_info i2c; + char *acpiname; +}; + +struct ipu_isys_clk_mapping { + struct clk_lookup clkdev_data; + char *platform_clock_name; +}; + +struct ipu_isys_subdev_pdata { + struct ipu_isys_subdev_info **subdevs; + struct ipu_isys_clk_mapping *clk_map; +}; + +#endif /* MEDIA_IPU_H */ diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index e0bb58cb6d042..c5565ce2fbdce 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -347,19 +347,33 @@ enum v4l2_mbus_frame_desc_flags { * struct v4l2_mbus_frame_desc_entry - media bus frame description structure * * @flags: bitmask flags, as defined by &enum v4l2_mbus_frame_desc_flags. + * @bpp: bits per pixel * @stream: stream in routing configuration * @pixelcode: media bus pixel code, valid if @flags * %FRAME_DESC_FL_BLOB is not set. * @length: number of octets per frame, valid if @flags * %V4L2_MBUS_FRAME_DESC_FL_LEN_MAX is set. + * @start_line: start line of the data for 2D DMA + * @start_pixel: start pixel of the data for 2D DMA + * @width: image width for 2D DMA + * @height: image height for 2D DMA * @bus: Bus-specific frame descriptor parameters * @bus.csi2: CSI-2-specific bus configuration */ struct v4l2_mbus_frame_desc_entry { enum v4l2_mbus_frame_desc_flags flags; + u8 bpp; u32 stream; u32 pixelcode; u32 length; + union { + struct { + u16 start_line; + u16 start_pixel; + u16 width; + u16 height; + } two_dim; + }; union { struct v4l2_mbus_frame_desc_entry_csi2 csi2; } bus; @@ -875,6 +889,8 @@ struct v4l2_subdev_pad_ops { struct v4l2_mbus_frame_desc *fd); int (*get_mbus_config)(struct v4l2_subdev *sd, unsigned int pad, struct v4l2_mbus_config *config); + int (*get_routing)(struct v4l2_subdev *sd, + struct v4l2_subdev_routing *route); int (*set_routing)(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, enum v4l2_subdev_format_whence which, @@ -961,6 +977,8 @@ struct v4l2_subdev_internal_ops { * should set this flag. */ #define V4L2_SUBDEV_FL_HAS_EVENTS (1U << 3) +/* Set this flag if this sub-device supports substreams. */ +#define V4L2_SUBDEV_FL_HAS_SUBSTREAMS (1U << 4) /* * Set this flag if this subdev supports multiplexed streams. This means * that the driver supports routing and handles the stream parameter in its diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index 77ce8238ab303..ddad2e2544535 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -51,6 +51,7 @@ struct vb2_v4l2_buffer { __s32 request_fd; bool is_held; struct vb2_plane planes[VB2_MAX_PLANES]; + __u32 reserved; }; /* VB2 V4L2 flags as set in vb2_queue.subsystem_flags */ diff --git a/include/uapi/linux/ipu-isys-isa-fw.h b/include/uapi/linux/ipu-isys-isa-fw.h new file mode 100644 index 0000000000000..927ffa68dcffc --- /dev/null +++ b/include/uapi/linux/ipu-isys-isa-fw.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* Copyright (C) 2014 - 2018 Intel Corporation */ + +#ifndef IPU_ISYS_ISA_FW_H +#define IPU_ISYS_ISA_FW_H + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +#define ia_css_terminal_offsets(pg) \ + ((uint16_t *)((void *)(pg) + \ + (pg)->terminals_offset_offset)) + +#define to_ia_css_terminal(pg, i) \ + ((struct ia_css_terminal *)( \ + (void *)(pg) + ia_css_terminal_offsets(pg)[i])) + +#define ia_css_terminal_offset(pg, i) \ + (!(i) ? sizeof *(pg) + ((((pg)->terminal_count - 1) | 3) + 1) \ + * sizeof(uint16_t) : \ + ia_css_terminal_offsets(pg)[(i) - 1] \ + + to_ia_css_terminal(pg, (i) - 1)->size) + +/* BEGIN DEFINITIONS IMPORTED FROM FIRMWARE */ + +#define N_IPU_FW_ISYS_KERNEL_ID 20 + +struct ia_css_process_group_light { + uint32_t size; + uint16_t terminals_offset_offset; + uint16_t terminal_count; +}; + +enum ia_css_terminal_type { + IPU_FW_TERMINAL_TYPE_DATA_IN = 0, + IPU_FW_TERMINAL_TYPE_DATA_OUT, + IPU_FW_TERMINAL_TYPE_PARAM_STREAM, + IPU_FW_TERMINAL_TYPE_PARAM_CACHED_IN, + IPU_FW_TERMINAL_TYPE_PARAM_CACHED_OUT, + IPU_FW_TERMINAL_TYPE_PARAM_SPATIAL_IN, + IPU_FW_TERMINAL_TYPE_PARAM_SPATIAL_OUT, + IPU_FW_TERMINAL_TYPE_PARAM_SLICED_IN, + IPU_FW_TERMINAL_TYPE_PARAM_SLICED_OUT, + IPU_FW_TERMINAL_TYPE_STATE_IN, + IPU_FW_TERMINAL_TYPE_STATE_OUT, + IPU_FW_TERMINAL_TYPE_PROGRAM, + IPU_FW_N_TERMINAL_TYPES +}; + +struct ia_css_terminal { + enum ia_css_terminal_type terminal_type; + int16_t parent_offset; + uint16_t size; + uint16_t tm_index; + uint8_t id; + uint8_t padding[5]; +}; + +struct ia_css_param_payload { + uint64_t host_buffer; + uint32_t buffer; + uint8_t padding[4]; +}; + +struct ia_css_param_section_desc { + uint32_t mem_offset; + uint32_t mem_size; +}; + +struct ia_css_param_terminal { + struct ia_css_terminal base; + struct ia_css_param_payload param_payload; + uint16_t param_section_desc_offset; + uint8_t padding[6]; +}; + +struct ia_css_program_terminal { + struct ia_css_terminal base; + struct ia_css_param_payload param_payload; + uint16_t fragment_param_section_desc_offset; + uint16_t kernel_fragment_sequencer_info_desc_offset; + uint8_t padding[4]; +}; + +struct ia_css_sliced_param_terminal { + struct ia_css_terminal base; + struct ia_css_param_payload param_payload; + uint32_t kernel_id; + uint16_t fragment_slice_desc_offset; + uint8_t padding[2]; +}; + +enum ia_css_dimension { + IPU_FW_COL_DIMENSION = 0, + IPU_FW_ROW_DIMENSION = 1, + IPU_FW_N_DATA_DIMENSION = 2 +}; + +struct ia_css_frame_grid_desc { + uint16_t frame_grid_dimension[IPU_FW_N_DATA_DIMENSION]; + uint8_t padding[4]; +}; + +struct ia_css_spatial_param_terminal { + struct ia_css_terminal base; + struct ia_css_param_payload param_payload; + struct ia_css_frame_grid_desc frame_grid_desc; + uint32_t kernel_id; + uint16_t frame_grid_param_section_desc_offset; + uint16_t fragment_grid_desc_offset; +}; + +/* END DEFINITIONS IMPORTED FROM FIRMWARE */ + +#endif /* IPU_ISYS_ISA_FW_H */ diff --git a/include/uapi/linux/ipu-isys.h b/include/uapi/linux/ipu-isys.h new file mode 100644 index 0000000000000..f580aee1cd2f8 --- /dev/null +++ b/include/uapi/linux/ipu-isys.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* Copyright (C) 2016 - 2018 Intel Corporation */ + +#ifndef UAPI_LINUX_IPU_ISYS_H +#define UAPI_LINUX_IPU_ISYS_H + +#define V4L2_CID_IPU_BASE (V4L2_CID_USER_BASE + 0x1080) + +#define V4L2_CID_IPU_ISA_EN (V4L2_CID_IPU_BASE + 1) +#define V4L2_CID_IPU_STORE_CSI2_HEADER (V4L2_CID_IPU_BASE + 2) +#define V4L2_CID_IPU_ISYS_COMPRESSION (V4L2_CID_IPU_BASE + 3) +#define V4L2_CID_IPU_QUERY_SUB_STREAM (V4L2_CID_IPU_BASE + 4) +#define V4L2_CID_IPU_SET_SUB_STREAM (V4L2_CID_IPU_BASE + 5) + +#define V4L2_IPU_ISA_EN_BLC (1 << 0) +#define V4L2_IPU_ISA_EN_LSC (1 << 1) +#define V4L2_IPU_ISA_EN_DPC (1 << 2) +#define V4L2_IPU_ISA_EN_SCALER (1 << 3) +#define V4L2_IPU_ISA_EN_AWB (1 << 4) +#define V4L2_IPU_ISA_EN_AF (1 << 5) +#define V4L2_IPU_ISA_EN_AE (1 << 6) +#define NR_OF_IPU_ISA_CFG 7 + +#define V4L2_FMT_IPU_ISA_CFG v4l2_fourcc('i', 'p', '4', 'c') +#define V4L2_FMT_IPU_ISYS_META v4l2_fourcc('i', 'p', '4', 'm') + + +#define VIDIOC_IPU_GET_DRIVER_VERSION \ + _IOWR('v', BASE_VIDIOC_PRIVATE + 3, uint32_t) + +#endif /* UAPI_LINUX_IPU_ISYS_H */ diff --git a/include/uapi/linux/ipu-psys.h b/include/uapi/linux/ipu-psys.h new file mode 100644 index 0000000000000..7fe795443d4b8 --- /dev/null +++ b/include/uapi/linux/ipu-psys.h @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* Copyright (C) 2013 - 2018 Intel Corporation */ + +#ifndef _UAPI_IPU_PSYS_H +#define _UAPI_IPU_PSYS_H + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +struct ipu_psys_capability { + uint32_t version; + uint8_t driver[20]; + uint32_t pg_count; + uint8_t dev_model[32]; + uint32_t reserved[17]; +} __attribute__ ((packed)); + +struct ipu_psys_event { + uint32_t type; /* IPU_PSYS_EVENT_TYPE_ */ + uint64_t user_token; + uint64_t issue_id; + uint32_t buffer_idx; + uint32_t error; + int32_t reserved[2]; +} __attribute__ ((packed)); + +#define IPU_PSYS_EVENT_TYPE_CMD_COMPLETE 1 +#define IPU_PSYS_EVENT_TYPE_BUFFER_COMPLETE 2 + +/** + * struct ipu_psys_buffer - for input/output terminals + * @len: total allocated size @ base address + * @userptr: user pointer + * @fd: DMA-BUF handle + * @data_offset:offset to valid data + * @bytes_used: amount of valid data including offset + * @flags: flags + */ +struct ipu_psys_buffer { + uint64_t len; + union { + int fd; + void __user *userptr; + uint64_t reserved; + } base; + uint32_t data_offset; + uint32_t bytes_used; + uint32_t flags; + uint32_t reserved[2]; +} __attribute__ ((packed)); + +#define IPU_BUFFER_FLAG_INPUT (1 << 0) +#define IPU_BUFFER_FLAG_OUTPUT (1 << 1) +#define IPU_BUFFER_FLAG_MAPPED (1 << 2) +#define IPU_BUFFER_FLAG_NO_FLUSH (1 << 3) +#define IPU_BUFFER_FLAG_DMA_HANDLE (1 << 4) +#define IPU_BUFFER_FLAG_USERPTR (1 << 5) + +#define IPU_PSYS_CMD_PRIORITY_HIGH 0 +#define IPU_PSYS_CMD_PRIORITY_MED 1 +#define IPU_PSYS_CMD_PRIORITY_LOW 2 +#define IPU_PSYS_CMD_PRIORITY_NUM 3 + +/** + * struct ipu_psys_command - processing command + * @issue_id: unique id for the command set by user + * @user_token: token of the command + * @priority: priority of the command + * @pg_manifest: userspace pointer to program group manifest + * @buffers: userspace pointers to array of psys dma buf structs + * @pg: process group DMA-BUF handle + * @pg_manifest_size: size of program group manifest + * @bufcount: number of buffers in buffers array + * @min_psys_freq: minimum psys frequency in MHz used for this cmd + * + * Specifies a processing command with input and output buffers. + */ +struct ipu_psys_command { + uint64_t issue_id; + uint64_t user_token; + uint32_t priority; + void __user *pg_manifest; + struct ipu_psys_buffer __user *buffers; + int pg; + uint32_t pg_manifest_size; + uint32_t bufcount; + uint32_t min_psys_freq; + uint32_t frame_counter; + uint32_t reserved[2]; +} __attribute__ ((packed)); + +struct ipu_psys_manifest { + uint32_t index; + uint32_t size; + void __user *manifest; + uint32_t reserved[5]; +} __attribute__ ((packed)); + +#define IPU_IOC_QUERYCAP _IOR('A', 1, struct ipu_psys_capability) +#define IPU_IOC_MAPBUF _IOWR('A', 2, int) +#define IPU_IOC_UNMAPBUF _IOWR('A', 3, int) +#define IPU_IOC_GETBUF _IOWR('A', 4, struct ipu_psys_buffer) +#define IPU_IOC_PUTBUF _IOWR('A', 5, struct ipu_psys_buffer) +#define IPU_IOC_QCMD _IOWR('A', 6, struct ipu_psys_command) +#define IPU_IOC_DQEVENT _IOWR('A', 7, struct ipu_psys_event) +#define IPU_IOC_CMD_CANCEL _IOWR('A', 8, struct ipu_psys_command) +#define IPU_IOC_GET_MANIFEST _IOWR('A', 9, struct ipu_psys_manifest) + +#endif /* _UAPI_IPU_PSYS_H */ diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 1c80b1d6bbaf3..feb1d91018741 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -208,6 +208,7 @@ struct media_entity_desc { #define MEDIA_PAD_FL_SINK (1U << 0) #define MEDIA_PAD_FL_SOURCE (1U << 1) #define MEDIA_PAD_FL_MUST_CONNECT (1U << 2) +#define MEDIA_PAD_FL_MULTIPLEX (1U << 3) struct media_pad_desc { __u32 entity; /* entity ID */ diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 2d30107e047ee..91a9da4346da5 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -1227,6 +1227,7 @@ enum v4l2_jpeg_chroma_subsampling { #define V4L2_CID_UNIT_CELL_SIZE (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 8) #define V4L2_CID_NOTIFY_GAINS (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 9) +#define V4L2_CID_MIPI_LANES (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 64) /* Image processing controls */ diff --git a/include/uapi/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h index 2347e266cf751..ac0f4ce59e38d 100644 --- a/include/uapi/linux/v4l2-subdev.h +++ b/include/uapi/linux/v4l2-subdev.h @@ -69,6 +69,8 @@ struct v4l2_subdev_crop { #define V4L2_SUBDEV_MBUS_CODE_CSC_HSV_ENC V4L2_SUBDEV_MBUS_CODE_CSC_YCBCR_ENC #define V4L2_SUBDEV_MBUS_CODE_CSC_QUANTIZATION 0x00000008 +#define V4L2_SUBDEV_FLAG_NEXT_STREAM 0x80000000 + /** * struct v4l2_subdev_mbus_code_enum - Media bus format enumeration * @pad: pad number, as reported by the media API @@ -205,6 +207,9 @@ struct v4l2_subdev_capability { */ #define V4L2_SUBDEV_ROUTE_FL_ACTIVE (1U << 0) +#define V4L2_SUBDEV_ROUTE_FL_IMMUTABLE (1U << 1) +#define V4L2_SUBDEV_ROUTE_FL_SOURCE (1U << 2) + /** * struct v4l2_subdev_route - A route inside a subdev * diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index becd08fdbddb8..82691ab6f117a 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -745,6 +745,44 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6') /* 16 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB16 v4l2_fourcc('R', 'G', '1', '6') /* 16 RGRG.. GBGB.. */ +/* Raw bayer vector formats. */ +#define V4L2_PIX_FMT_SBGGR8_16V32 v4l2_fourcc('b', 'V', '0', 'A') +#define V4L2_PIX_FMT_SGBRG8_16V32 v4l2_fourcc('b', 'V', '0', 'B') +#define V4L2_PIX_FMT_SGRBG8_16V32 v4l2_fourcc('b', 'V', '0', 'C') +#define V4L2_PIX_FMT_SRGGB8_16V32 v4l2_fourcc('b', 'V', '0', 'D') +#define V4L2_PIX_FMT_SBGGR8V32 v4l2_fourcc('b', 'V', '0', 'A') +#define V4L2_PIX_FMT_SGBRG8V32 v4l2_fourcc('b', 'V', '0', 'B') +#define V4L2_PIX_FMT_SGRBG8V32 v4l2_fourcc('b', 'V', '0', 'C') +#define V4L2_PIX_FMT_SRGGB8V32 v4l2_fourcc('b', 'V', '0', 'D') +#define V4L2_PIX_FMT_SBGGR10V32 v4l2_fourcc('b', 'V', '0', 'E') +#define V4L2_PIX_FMT_SGBRG10V32 v4l2_fourcc('b', 'V', '0', 'F') +#define V4L2_PIX_FMT_SGRBG10V32 v4l2_fourcc('b', 'V', '0', 'G') +#define V4L2_PIX_FMT_SRGGB10V32 v4l2_fourcc('b', 'V', '0', 'H') +#define V4L2_PIX_FMT_SBGGR12V32 v4l2_fourcc('b', 'V', '0', 'I') +#define V4L2_PIX_FMT_SGBRG12V32 v4l2_fourcc('b', 'V', '0', 'J') +#define V4L2_PIX_FMT_SGRBG12V32 v4l2_fourcc('b', 'V', '0', 'K') +#define V4L2_PIX_FMT_SRGGB12V32 v4l2_fourcc('b', 'V', '0', 'L') + +#ifndef V4L2_PIX_FMT_SBGGR14V32 +/* + * Non-vectorized 14bit definitions have been upstreamed. + * To keep various versions of the ipu4 builds compileable use local + * definitions when global one's doesn't exists. + */ +#define V4L2_PIX_FMT_SBGGR14V32 v4l2_fourcc('b', 'V', '0', 'M') +#define V4L2_PIX_FMT_SGBRG14V32 v4l2_fourcc('b', 'V', '0', 'N') +#define V4L2_PIX_FMT_SGRBG14V32 v4l2_fourcc('b', 'V', '0', 'O') +#define V4L2_PIX_FMT_SRGGB14V32 v4l2_fourcc('b', 'V', '0', 'P') +#endif + +/* IPU4 */ +#define V4L2_FMT_IPU_ISA_CFG v4l2_fourcc('i', 'p', '4', 'c') +#define V4L2_FMT_IPU_ISYS_META v4l2_fourcc('i', 'p', '4', 'm') + +/* YUV vector formats. */ +#define V4L2_PIX_FMT_UYVY_V32 v4l2_fourcc('y', 'V', '3', '2') +#define V4L2_PIX_FMT_YUYV420_V32 v4l2_fourcc('y', '0', '3', '2') + /* HSV formats */ #define V4L2_PIX_FMT_HSV24 v4l2_fourcc('H', 'S', 'V', '3') #define V4L2_PIX_FMT_HSV32 v4l2_fourcc('H', 'S', 'V', '4')