mirror of https://gitee.com/openkylin/linux.git
media fixes for v5.8-rc7
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+QmuaPwR3wnBdVwACF8+vY7k4RUFAl8VlckACgkQCF8+vY7k 4RWg9RAAhmGk/mYYAIAy6o2G8CPgcNnLrUuhXD+SyYrM25QlkinMjHXVhWiPo0F8 DKq21vXg0qlOe7kwn0vSEQ7tClAuJhK/ERnLnDFWe36lO6QF5ydllzEg9XS+xVq2 4Ur+jdkllaS8j7sjQrEdQF17HW52Sr0WB8KegoeUXfeKcGaIBmB+kfNstK2fWMa+ yuVITK/YNpr53zwwsHlMvmIndui0DJHKGGWuTknZsoQfWJtO62YW50FmkizjqXIt +4DCRiq9Juc/MPYotP2pArwBFiqSl/uP0MeWqn4YzPXvhhhoGPTAhskBWDmZD8jT XI9Q9Uj5x5kCtTLx4CI3mG2X2XrZ+GqFKZhVD0WKnZN2skdHRn/3qn6tHm7O/Rtr s27MVKae5zSQs1XrCXwlEz03T5wZ1y1FCX3dlXGkQqbOQLQGbZTsE8wybPElzkLR 18e8xTA1Ss7tUYf7qcrEmMk242byXP8F43cStaWCwsbJgddBpV2jFFfxan3/j6q9 Kl6Y/ssRn6OrIy1UNpdCClRweLi0U53sFQqM/ZmyUbBXMbT/y+rL6h8Wel8EvFlR PzisYBI/G0AWHahbdHhS9mzQFAZb9etlAboMvI31bo4Bjpbv9UVkX5dMLxabcbEr B70EZ7nigg5EMqeBkemz0kD4W68qvQRKHK0d+TYcYSnq0VMmErI= =/5rQ -----END PGP SIGNATURE----- Merge tag 'media/v5.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media into master Pull media fixes from Mauro Carvalho Chehab: "A series of fixes for the upcoming atomisp driver. They solve issues when probing atomisp on devices with multiple cameras and get rid of warnings when built with W=1. The diffstat is a bit long, as this driver has several abstractions. The patches that solved the issues with W=1 had to get rid of some duplicated code (there used to have 2 versions of the same code, one for ISP2401 and another one for ISP2400). As this driver is not in 5.7, such changes won't cause regressions" * tag 'media/v5.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (38 commits) Revert "media: atomisp: keep the ISP powered on when setting it" media: atomisp: fix mask and shift operation on ISPSSPM0 media: atomisp: move system_local consts into a C file media: atomisp: get rid of version-specific system_local.h media: atomisp: move global stuff into a common header media: atomisp: remove non-used 32-bits consts at system_local media: atomisp: get rid of some unused static vars media: atomisp: Fix error code in ov5693_probe() media: atomisp: Replace trace_printk by pr_info media: atomisp: Fix __func__ style warnings media: atomisp: fix help message for ISP2401 selection media: atomisp: i2c: atomisp-ov2680.c: fixed a brace coding style issue. media: atomisp: make const arrays static, makes object smaller media: atomisp: Clean up non-existing folders from Makefile media: atomisp: Get rid of ACPI specifics in gmin_subdev_add() media: atomisp: Provide Gmin subdev as parameter to gmin_subdev_add() media: atomisp: Use temporary variable for device in gmin_subdev_add() media: atomisp: Refactor PMIC detection to a separate function media: atomisp: Deduplicate return ret in gmin_i2c_write() media: atomisp: Make pointer to PMIC client global ...
This commit is contained in:
commit
d15be54603
|
@ -39,6 +39,7 @@
|
|||
#define BT_MBI_UNIT_PMC 0x04
|
||||
#define BT_MBI_UNIT_GFX 0x06
|
||||
#define BT_MBI_UNIT_SMI 0x0C
|
||||
#define BT_MBI_UNIT_CCK 0x14
|
||||
#define BT_MBI_UNIT_USB 0x43
|
||||
#define BT_MBI_UNIT_SATA 0xA3
|
||||
#define BT_MBI_UNIT_PCIE 0xA6
|
||||
|
|
|
@ -22,7 +22,7 @@ config VIDEO_ATOMISP
|
|||
module will be called atomisp
|
||||
|
||||
config VIDEO_ATOMISP_ISP2401
|
||||
bool "VIDEO_ATOMISP_ISP2401"
|
||||
bool "Use Intel Atom ISP on Cherrytail/Anniedale (ISP2401)"
|
||||
depends on VIDEO_ATOMISP
|
||||
help
|
||||
Enable support for Atom ISP2401-based boards.
|
||||
|
|
|
@ -156,6 +156,7 @@ atomisp-objs += \
|
|||
pci/hive_isp_css_common/host/timed_ctrl.o \
|
||||
pci/hive_isp_css_common/host/vmem.o \
|
||||
pci/hive_isp_css_shared/host/tag.o \
|
||||
pci/system_local.o \
|
||||
|
||||
obj-byt = \
|
||||
pci/css_2400_system/hive/ia_css_isp_configs.o \
|
||||
|
@ -182,7 +183,6 @@ INCLUDES += \
|
|||
-I$(atomisp)/include/hmm/ \
|
||||
-I$(atomisp)/include/mmu/ \
|
||||
-I$(atomisp)/pci/ \
|
||||
-I$(atomisp)/pci/hrt/ \
|
||||
-I$(atomisp)/pci/base/circbuf/interface/ \
|
||||
-I$(atomisp)/pci/base/refcount/interface/ \
|
||||
-I$(atomisp)/pci/camera/pipe/interface/ \
|
||||
|
@ -192,7 +192,6 @@ INCLUDES += \
|
|||
-I$(atomisp)/pci/hive_isp_css_include/ \
|
||||
-I$(atomisp)/pci/hive_isp_css_include/device_access/ \
|
||||
-I$(atomisp)/pci/hive_isp_css_include/host/ \
|
||||
-I$(atomisp)/pci/hive_isp_css_include/memory_access/ \
|
||||
-I$(atomisp)/pci/hive_isp_css_shared/ \
|
||||
-I$(atomisp)/pci/hive_isp_css_shared/host/ \
|
||||
-I$(atomisp)/pci/isp/kernels/ \
|
||||
|
@ -311,9 +310,7 @@ INCLUDES += \
|
|||
-I$(atomisp)/pci/runtime/tagger/interface/
|
||||
|
||||
INCLUDES_byt += \
|
||||
-I$(atomisp)/pci/css_2400_system/ \
|
||||
-I$(atomisp)/pci/css_2400_system/hive/ \
|
||||
-I$(atomisp)/pci/css_2400_system/hrt/ \
|
||||
|
||||
INCLUDES_cht += \
|
||||
-I$(atomisp)/pci/css_2401_system/ \
|
||||
|
@ -321,7 +318,6 @@ INCLUDES_cht += \
|
|||
-I$(atomisp)/pci/css_2401_system/hive/ \
|
||||
-I$(atomisp)/pci/css_2401_system/hrt/ \
|
||||
|
||||
# -I$(atomisp)/pci/css_2401_system/hrt/ \
|
||||
# -I$(atomisp)/pci/css_2401_system/hive_isp_css_2401_system_generated/ \
|
||||
|
||||
DEFINES := -DHRT_HW -DHRT_ISP_CSS_CUSTOM_HOST -DHRT_USE_VIR_ADDRS -D__HOST__
|
||||
|
|
|
@ -495,11 +495,11 @@ static int ov2680_h_flip(struct v4l2_subdev *sd, s32 value)
|
|||
ret = ov2680_read_reg(client, 1, OV2680_MIRROR_REG, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (value) {
|
||||
if (value)
|
||||
val |= OV2680_FLIP_MIRROR_BIT_ENABLE;
|
||||
} else {
|
||||
else
|
||||
val &= ~OV2680_FLIP_MIRROR_BIT_ENABLE;
|
||||
}
|
||||
|
||||
ret = ov2680_write_reg(client, 1,
|
||||
OV2680_MIRROR_REG, val);
|
||||
if (ret)
|
||||
|
|
|
@ -1899,7 +1899,7 @@ static int ov5693_probe(struct i2c_client *client)
|
|||
{
|
||||
struct ov5693_device *dev;
|
||||
int i2c;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
void *pdata;
|
||||
unsigned int i;
|
||||
|
||||
|
@ -1929,8 +1929,10 @@ static int ov5693_probe(struct i2c_client *client)
|
|||
pdata = gmin_camera_platform_data(&dev->sd,
|
||||
ATOMISP_INPUT_FORMAT_RAW_10,
|
||||
atomisp_bayer_order_bggr);
|
||||
if (!pdata)
|
||||
if (!pdata) {
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = ov5693_s_config(&dev->sd, client->irq, pdata);
|
||||
if (ret)
|
||||
|
|
|
@ -250,6 +250,7 @@ const struct atomisp_camera_caps *atomisp_get_default_camera_caps(void);
|
|||
#define IS_MFLD __IS_SOC(INTEL_FAM6_ATOM_SALTWELL_MID)
|
||||
#define IS_BYT __IS_SOC(INTEL_FAM6_ATOM_SILVERMONT)
|
||||
#define IS_CHT __IS_SOC(INTEL_FAM6_ATOM_AIRMONT)
|
||||
#define IS_MRFD __IS_SOC(INTEL_FAM6_ATOM_SILVERMONT_MID)
|
||||
#define IS_MOFD __IS_SOC(INTEL_FAM6_ATOM_AIRMONT_MID)
|
||||
|
||||
/* Both CHT and MOFD come with ISP2401 */
|
||||
|
|
|
@ -20,9 +20,6 @@
|
|||
#define ATOMISP_REGS_H
|
||||
|
||||
/* common register definitions */
|
||||
#define PUNIT_PORT 0x04
|
||||
#define CCK_PORT 0x14
|
||||
|
||||
#define PCICMDSTS 0x01
|
||||
#define INTR 0x0f
|
||||
#define MSI_CAPID 0x24
|
||||
|
|
|
@ -355,11 +355,11 @@ int atomisp_acc_map(struct atomisp_sub_device *asd, struct atomisp_acc_map *map)
|
|||
|
||||
pgnr = DIV_ROUND_UP(map->length, PAGE_SIZE);
|
||||
if (pgnr < ((PAGE_ALIGN(map->length)) >> PAGE_SHIFT)) {
|
||||
dev_err(atomisp_dev,
|
||||
dev_err(asd->isp->dev,
|
||||
"user space memory size is less than the expected size..\n");
|
||||
return -ENOMEM;
|
||||
} else if (pgnr > ((PAGE_ALIGN(map->length)) >> PAGE_SHIFT)) {
|
||||
dev_err(atomisp_dev,
|
||||
dev_err(asd->isp->dev,
|
||||
"user space memory size is large than the expected size..\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/firmware.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kfifo.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
@ -109,7 +110,7 @@ struct atomisp_acc_pipe *atomisp_to_acc_pipe(struct video_device *dev)
|
|||
|
||||
static unsigned short atomisp_get_sensor_fps(struct atomisp_sub_device *asd)
|
||||
{
|
||||
struct v4l2_subdev_frame_interval fi;
|
||||
struct v4l2_subdev_frame_interval fi = { 0 };
|
||||
struct atomisp_device *isp = asd->isp;
|
||||
|
||||
unsigned short fps = 0;
|
||||
|
@ -206,6 +207,7 @@ int atomisp_freq_scaling(struct atomisp_device *isp,
|
|||
enum atomisp_dfs_mode mode,
|
||||
bool force)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
/* FIXME! Only use subdev[0] status yet */
|
||||
struct atomisp_sub_device *asd = &isp->asd[0];
|
||||
const struct atomisp_dfs_config *dfs;
|
||||
|
@ -219,7 +221,7 @@ int atomisp_freq_scaling(struct atomisp_device *isp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((isp->pdev->device & ATOMISP_PCI_DEVICE_SOC_MASK) ==
|
||||
if ((pdev->device & ATOMISP_PCI_DEVICE_SOC_MASK) ==
|
||||
ATOMISP_PCI_DEVICE_SOC_CHT && ATOMISP_USE_YUVPP(asd))
|
||||
isp->dfs = &dfs_config_cht_soc;
|
||||
|
||||
|
@ -357,39 +359,41 @@ static void clear_isp_irq(enum hrt_isp_css_irq irq)
|
|||
irq_clear_all(IRQ0_ID);
|
||||
}
|
||||
|
||||
void atomisp_msi_irq_init(struct atomisp_device *isp, struct pci_dev *dev)
|
||||
void atomisp_msi_irq_init(struct atomisp_device *isp)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
u32 msg32;
|
||||
u16 msg16;
|
||||
|
||||
pci_read_config_dword(dev, PCI_MSI_CAPID, &msg32);
|
||||
pci_read_config_dword(pdev, PCI_MSI_CAPID, &msg32);
|
||||
msg32 |= 1 << MSI_ENABLE_BIT;
|
||||
pci_write_config_dword(dev, PCI_MSI_CAPID, msg32);
|
||||
pci_write_config_dword(pdev, PCI_MSI_CAPID, msg32);
|
||||
|
||||
msg32 = (1 << INTR_IER) | (1 << INTR_IIR);
|
||||
pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, msg32);
|
||||
pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, msg32);
|
||||
|
||||
pci_read_config_word(dev, PCI_COMMAND, &msg16);
|
||||
pci_read_config_word(pdev, PCI_COMMAND, &msg16);
|
||||
msg16 |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
|
||||
PCI_COMMAND_INTX_DISABLE);
|
||||
pci_write_config_word(dev, PCI_COMMAND, msg16);
|
||||
pci_write_config_word(pdev, PCI_COMMAND, msg16);
|
||||
}
|
||||
|
||||
void atomisp_msi_irq_uninit(struct atomisp_device *isp, struct pci_dev *dev)
|
||||
void atomisp_msi_irq_uninit(struct atomisp_device *isp)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
u32 msg32;
|
||||
u16 msg16;
|
||||
|
||||
pci_read_config_dword(dev, PCI_MSI_CAPID, &msg32);
|
||||
pci_read_config_dword(pdev, PCI_MSI_CAPID, &msg32);
|
||||
msg32 &= ~(1 << MSI_ENABLE_BIT);
|
||||
pci_write_config_dword(dev, PCI_MSI_CAPID, msg32);
|
||||
pci_write_config_dword(pdev, PCI_MSI_CAPID, msg32);
|
||||
|
||||
msg32 = 0x0;
|
||||
pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, msg32);
|
||||
pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, msg32);
|
||||
|
||||
pci_read_config_word(dev, PCI_COMMAND, &msg16);
|
||||
pci_read_config_word(pdev, PCI_COMMAND, &msg16);
|
||||
msg16 &= ~(PCI_COMMAND_MASTER);
|
||||
pci_write_config_word(dev, PCI_COMMAND, msg16);
|
||||
pci_write_config_word(pdev, PCI_COMMAND, msg16);
|
||||
}
|
||||
|
||||
static void atomisp_sof_event(struct atomisp_sub_device *asd)
|
||||
|
@ -480,11 +484,12 @@ static void print_csi_rx_errors(enum mipi_port_id port,
|
|||
/* Clear irq reg */
|
||||
static void clear_irq_reg(struct atomisp_device *isp)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
u32 msg_ret;
|
||||
|
||||
pci_read_config_dword(isp->pdev, PCI_INTERRUPT_CTRL, &msg_ret);
|
||||
pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &msg_ret);
|
||||
msg_ret |= 1 << INTR_IIR;
|
||||
pci_write_config_dword(isp->pdev, PCI_INTERRUPT_CTRL, msg_ret);
|
||||
pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, msg_ret);
|
||||
}
|
||||
|
||||
static struct atomisp_sub_device *
|
||||
|
@ -665,11 +670,10 @@ bool atomisp_buffers_queued_pipe(struct atomisp_video_pipe *pipe)
|
|||
void dump_sp_dmem(struct atomisp_device *isp, unsigned int addr,
|
||||
unsigned int size)
|
||||
{
|
||||
u32 __iomem *io_virt_addr;
|
||||
unsigned int data = 0;
|
||||
unsigned int size32 = DIV_ROUND_UP(size, sizeof(u32));
|
||||
|
||||
dev_dbg(isp->dev, "atomisp_io_base:%p\n", atomisp_io_base);
|
||||
dev_dbg(isp->dev, "atomisp mmio base: %p\n", isp->base);
|
||||
dev_dbg(isp->dev, "%s, addr:0x%x, size: %d, size32: %d\n", __func__,
|
||||
addr, size, size32);
|
||||
if (size32 * 4 + addr > 0x4000) {
|
||||
|
@ -678,13 +682,12 @@ void dump_sp_dmem(struct atomisp_device *isp, unsigned int addr,
|
|||
return;
|
||||
}
|
||||
addr += SP_DMEM_BASE;
|
||||
io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
|
||||
addr &= 0x003FFFFF;
|
||||
do {
|
||||
data = *io_virt_addr;
|
||||
data = readl(isp->base + addr);
|
||||
dev_dbg(isp->dev, "%s, \t [0x%x]:0x%x\n", __func__, addr, data);
|
||||
io_virt_addr += sizeof(u32);
|
||||
size32 -= 1;
|
||||
} while (size32 > 0);
|
||||
addr += sizeof(u32);
|
||||
} while (--size32);
|
||||
}
|
||||
|
||||
static struct videobuf_buffer *atomisp_css_frame_to_vbuf(
|
||||
|
@ -1289,6 +1292,7 @@ void atomisp_delayed_init_work(struct work_struct *work)
|
|||
|
||||
static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
enum ia_css_pipe_id css_pipe_id;
|
||||
bool stream_restart[MAX_STREAM_NUM] = {0};
|
||||
bool depth_mode = false;
|
||||
|
@ -1372,8 +1376,8 @@ static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout)
|
|||
clear_isp_irq(hrt_isp_css_irq_sp);
|
||||
|
||||
/* Set the SRSE to 3 before resetting */
|
||||
pci_write_config_dword(isp->pdev, PCI_I_CONTROL, isp->saved_regs.i_control |
|
||||
MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK);
|
||||
pci_write_config_dword(pdev, PCI_I_CONTROL,
|
||||
isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK);
|
||||
|
||||
/* reset ISP and restore its state */
|
||||
isp->isp_timeout = true;
|
||||
|
@ -6158,6 +6162,7 @@ int atomisp_set_shading_table(struct atomisp_sub_device *asd,
|
|||
/*Turn off ISP dphy */
|
||||
int atomisp_ospm_dphy_down(struct atomisp_device *isp)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
|
@ -6179,9 +6184,9 @@ int atomisp_ospm_dphy_down(struct atomisp_device *isp)
|
|||
* MRFLD HW design need all CSI ports are disabled before
|
||||
* powering down the IUNIT.
|
||||
*/
|
||||
pci_read_config_dword(isp->pdev, MRFLD_PCI_CSI_CONTROL, ®);
|
||||
pci_read_config_dword(pdev, MRFLD_PCI_CSI_CONTROL, ®);
|
||||
reg |= MRFLD_ALL_CSI_PORTS_OFF_MASK;
|
||||
pci_write_config_dword(isp->pdev, MRFLD_PCI_CSI_CONTROL, reg);
|
||||
pci_write_config_dword(pdev, MRFLD_PCI_CSI_CONTROL, reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,8 +68,8 @@ bool atomisp_buffers_queued_pipe(struct atomisp_video_pipe *pipe);
|
|||
/*
|
||||
* Interrupt functions
|
||||
*/
|
||||
void atomisp_msi_irq_init(struct atomisp_device *isp, struct pci_dev *dev);
|
||||
void atomisp_msi_irq_uninit(struct atomisp_device *isp, struct pci_dev *dev);
|
||||
void atomisp_msi_irq_init(struct atomisp_device *isp);
|
||||
void atomisp_msi_irq_uninit(struct atomisp_device *isp);
|
||||
void atomisp_wdt_work(struct work_struct *work);
|
||||
void atomisp_wdt(struct timer_list *t);
|
||||
void atomisp_setup_flash(struct atomisp_sub_device *asd);
|
||||
|
|
|
@ -29,8 +29,6 @@ struct atomisp_sub_device;
|
|||
struct video_device;
|
||||
enum atomisp_input_stream_id;
|
||||
|
||||
extern void __iomem *atomisp_io_base;
|
||||
|
||||
struct atomisp_metadata_buf {
|
||||
struct ia_css_metadata *metadata;
|
||||
void *md_vptr;
|
||||
|
|
|
@ -33,13 +33,12 @@
|
|||
#include "atomisp_ioctl.h"
|
||||
#include "atomisp_acc.h"
|
||||
|
||||
#include <asm/intel-mid.h>
|
||||
|
||||
#include "ia_css_debug.h"
|
||||
#include "ia_css_isp_param.h"
|
||||
#include "sh_css_hrt.h"
|
||||
#include "ia_css_isys.h"
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
/* Assume max number of ACC stages */
|
||||
|
@ -69,92 +68,94 @@ struct bayer_ds_factor {
|
|||
|
||||
static void atomisp_css2_hw_store_8(hrt_address addr, uint8_t data)
|
||||
{
|
||||
s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
|
||||
struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mmio_lock, flags);
|
||||
*io_virt_addr = data;
|
||||
writeb(data, isp->base + (addr & 0x003FFFFF));
|
||||
spin_unlock_irqrestore(&mmio_lock, flags);
|
||||
}
|
||||
|
||||
static void atomisp_css2_hw_store_16(hrt_address addr, uint16_t data)
|
||||
{
|
||||
s16 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
|
||||
struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mmio_lock, flags);
|
||||
*io_virt_addr = data;
|
||||
writew(data, isp->base + (addr & 0x003FFFFF));
|
||||
spin_unlock_irqrestore(&mmio_lock, flags);
|
||||
}
|
||||
|
||||
void atomisp_css2_hw_store_32(hrt_address addr, uint32_t data)
|
||||
{
|
||||
s32 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
|
||||
struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mmio_lock, flags);
|
||||
*io_virt_addr = data;
|
||||
writel(data, isp->base + (addr & 0x003FFFFF));
|
||||
spin_unlock_irqrestore(&mmio_lock, flags);
|
||||
}
|
||||
|
||||
static uint8_t atomisp_css2_hw_load_8(hrt_address addr)
|
||||
{
|
||||
s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
|
||||
struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
|
||||
unsigned long flags;
|
||||
u8 ret;
|
||||
|
||||
spin_lock_irqsave(&mmio_lock, flags);
|
||||
ret = *io_virt_addr;
|
||||
ret = readb(isp->base + (addr & 0x003FFFFF));
|
||||
spin_unlock_irqrestore(&mmio_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t atomisp_css2_hw_load_16(hrt_address addr)
|
||||
{
|
||||
s16 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
|
||||
struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
|
||||
unsigned long flags;
|
||||
u16 ret;
|
||||
|
||||
spin_lock_irqsave(&mmio_lock, flags);
|
||||
ret = *io_virt_addr;
|
||||
ret = readw(isp->base + (addr & 0x003FFFFF));
|
||||
spin_unlock_irqrestore(&mmio_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t atomisp_css2_hw_load_32(hrt_address addr)
|
||||
{
|
||||
s32 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
|
||||
struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
|
||||
unsigned long flags;
|
||||
u32 ret;
|
||||
|
||||
spin_lock_irqsave(&mmio_lock, flags);
|
||||
ret = *io_virt_addr;
|
||||
ret = readl(isp->base + (addr & 0x003FFFFF));
|
||||
spin_unlock_irqrestore(&mmio_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void atomisp_css2_hw_store(hrt_address addr,
|
||||
const void *from, uint32_t n)
|
||||
static void atomisp_css2_hw_store(hrt_address addr, const void *from, uint32_t n)
|
||||
{
|
||||
s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
|
||||
struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
|
||||
addr &= 0x003FFFFF;
|
||||
spin_lock_irqsave(&mmio_lock, flags);
|
||||
for (i = 0; i < n; i++, io_virt_addr++, from++)
|
||||
*io_virt_addr = *(s8 *)from;
|
||||
for (i = 0; i < n; i++, from++)
|
||||
writeb(*(s8 *)from, isp->base + addr + i);
|
||||
|
||||
spin_unlock_irqrestore(&mmio_lock, flags);
|
||||
}
|
||||
|
||||
static void atomisp_css2_hw_load(hrt_address addr, void *to, uint32_t n)
|
||||
{
|
||||
s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
|
||||
struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
|
||||
addr &= 0x003FFFFF;
|
||||
spin_lock_irqsave(&mmio_lock, flags);
|
||||
for (i = 0; i < n; i++, to++, io_virt_addr++)
|
||||
*(s8 *)to = *io_virt_addr;
|
||||
for (i = 0; i < n; i++, to++)
|
||||
*(s8 *)to = readb(isp->base + addr + i);
|
||||
spin_unlock_irqrestore(&mmio_lock, flags);
|
||||
}
|
||||
|
||||
|
@ -181,10 +182,10 @@ void atomisp_load_uint32(hrt_address addr, uint32_t *data)
|
|||
*data = atomisp_css2_hw_load_32(addr);
|
||||
}
|
||||
|
||||
static int hmm_get_mmu_base_addr(unsigned int *mmu_base_addr)
|
||||
static int hmm_get_mmu_base_addr(struct device *dev, unsigned int *mmu_base_addr)
|
||||
{
|
||||
if (!sh_mmu_mrfld.get_pd_base) {
|
||||
dev_err(atomisp_dev, "get mmu base address failed.\n");
|
||||
dev_err(dev, "get mmu base address failed.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -839,7 +840,7 @@ int atomisp_css_init(struct atomisp_device *isp)
|
|||
int ret;
|
||||
int err;
|
||||
|
||||
ret = hmm_get_mmu_base_addr(&mmu_base_addr);
|
||||
ret = hmm_get_mmu_base_addr(isp->dev, &mmu_base_addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -941,7 +942,7 @@ int atomisp_css_resume(struct atomisp_device *isp)
|
|||
unsigned int mmu_base_addr;
|
||||
int ret;
|
||||
|
||||
ret = hmm_get_mmu_base_addr(&mmu_base_addr);
|
||||
ret = hmm_get_mmu_base_addr(isp->dev, &mmu_base_addr);
|
||||
if (ret) {
|
||||
dev_err(isp->dev, "get base address error.\n");
|
||||
return -EINVAL;
|
||||
|
@ -1966,8 +1967,7 @@ void atomisp_css_input_set_mode(struct atomisp_sub_device *asd,
|
|||
true,
|
||||
0x13000,
|
||||
&size_mem_words) != 0) {
|
||||
if (intel_mid_identify_cpu() ==
|
||||
INTEL_MID_CPU_CHIP_TANGIER)
|
||||
if (IS_MRFD)
|
||||
size_mem_words = CSS_MIPI_FRAME_BUFFER_SIZE_2;
|
||||
else
|
||||
size_mem_words = CSS_MIPI_FRAME_BUFFER_SIZE_1;
|
||||
|
@ -2414,13 +2414,13 @@ static void __configure_preview_pp_input(struct atomisp_sub_device *asd,
|
|||
struct ia_css_resolution *effective_res =
|
||||
&stream_config->input_config.effective_res;
|
||||
|
||||
const struct bayer_ds_factor bds_fct[] = {{2, 1}, {3, 2}, {5, 4} };
|
||||
static const struct bayer_ds_factor bds_fct[] = {{2, 1}, {3, 2}, {5, 4} };
|
||||
/*
|
||||
* BZ201033: YUV decimation factor of 4 causes couple of rightmost
|
||||
* columns to be shaded. Remove this factor to work around the CSS bug.
|
||||
* const unsigned int yuv_dec_fct[] = {4, 2};
|
||||
*/
|
||||
const unsigned int yuv_dec_fct[] = { 2 };
|
||||
static const unsigned int yuv_dec_fct[] = { 2 };
|
||||
unsigned int i;
|
||||
|
||||
if (width == 0 && height == 0)
|
||||
|
@ -2540,7 +2540,7 @@ static void __configure_video_pp_input(struct atomisp_sub_device *asd,
|
|||
struct ia_css_resolution *effective_res =
|
||||
&stream_config->input_config.effective_res;
|
||||
|
||||
const struct bayer_ds_factor bds_factors[] = {
|
||||
static const struct bayer_ds_factor bds_factors[] = {
|
||||
{8, 1}, {6, 1}, {4, 1}, {3, 1}, {2, 1}, {3, 2}
|
||||
};
|
||||
unsigned int i;
|
||||
|
@ -4337,7 +4337,7 @@ static const char * const fw_acc_type_name[] = {
|
|||
[IA_CSS_ACC_STANDALONE] = "Stand-alone acceleration",
|
||||
};
|
||||
|
||||
int atomisp_css_dump_blob_infor(void)
|
||||
int atomisp_css_dump_blob_infor(struct atomisp_device *isp)
|
||||
{
|
||||
struct ia_css_blob_descr *bd = sh_css_blob_info;
|
||||
unsigned int i, nm = sh_css_num_binaries;
|
||||
|
@ -4354,8 +4354,7 @@ int atomisp_css_dump_blob_infor(void)
|
|||
for (i = 0; i < sh_css_num_binaries - NUM_OF_SPS; i++) {
|
||||
switch (bd[i].header.type) {
|
||||
case ia_css_isp_firmware:
|
||||
dev_dbg(atomisp_dev,
|
||||
"Num%2d type %s (%s), binary id is %2d, name is %s\n",
|
||||
dev_dbg(isp->dev, "Num%2d type %s (%s), binary id is %2d, name is %s\n",
|
||||
i + NUM_OF_SPS,
|
||||
fw_type_name[bd[i].header.type],
|
||||
fw_acc_type_name[bd[i].header.info.isp.type],
|
||||
|
@ -4363,8 +4362,7 @@ int atomisp_css_dump_blob_infor(void)
|
|||
bd[i].name);
|
||||
break;
|
||||
default:
|
||||
dev_dbg(atomisp_dev,
|
||||
"Num%2d type %s, name is %s\n",
|
||||
dev_dbg(isp->dev, "Num%2d type %s, name is %s\n",
|
||||
i + NUM_OF_SPS, fw_type_name[bd[i].header.type],
|
||||
bd[i].name);
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ int atomisp_css_debug_dump_isp_binary(void);
|
|||
|
||||
int atomisp_css_dump_sp_raw_copy_linecount(bool reduced);
|
||||
|
||||
int atomisp_css_dump_blob_infor(void);
|
||||
int atomisp_css_dump_blob_infor(struct atomisp_device *isp);
|
||||
|
||||
void atomisp_css_set_isp_config_id(struct atomisp_sub_device *asd,
|
||||
uint32_t isp_config_id);
|
||||
|
|
|
@ -62,9 +62,9 @@ static inline int iunit_dump_dbgopt(struct atomisp_device *isp,
|
|||
|
||||
if (opt & OPTION_VALID) {
|
||||
if (opt & OPTION_BIN_LIST) {
|
||||
ret = atomisp_css_dump_blob_infor();
|
||||
ret = atomisp_css_dump_blob_infor(isp);
|
||||
if (ret) {
|
||||
dev_err(atomisp_dev, "%s dump blob infor err[ret:%d]\n",
|
||||
dev_err(isp->dev, "%s dump blob infor err[ret:%d]\n",
|
||||
__func__, ret);
|
||||
goto opt_err;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ static inline int iunit_dump_dbgopt(struct atomisp_device *isp,
|
|||
atomisp_css_debug_dump_isp_binary();
|
||||
} else {
|
||||
ret = -EPERM;
|
||||
dev_err(atomisp_dev, "%s dump running bin err[ret:%d]\n",
|
||||
dev_err(isp->dev, "%s dump running bin err[ret:%d]\n",
|
||||
__func__, ret);
|
||||
goto opt_err;
|
||||
}
|
||||
|
@ -86,8 +86,7 @@ static inline int iunit_dump_dbgopt(struct atomisp_device *isp,
|
|||
hmm_show_mem_stat(__func__, __LINE__);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
dev_err(atomisp_dev, "%s dump nothing[ret=%d]\n", __func__,
|
||||
ret);
|
||||
dev_err(isp->dev, "%s dump nothing[ret=%d]\n", __func__, ret);
|
||||
}
|
||||
|
||||
opt_err:
|
||||
|
@ -185,8 +184,9 @@ static void iunit_drvfs_remove_files(struct device_driver *drv)
|
|||
driver_remove_file(drv, &iunit_drvfs_attrs[i]);
|
||||
}
|
||||
|
||||
int atomisp_drvfs_init(struct device_driver *drv, struct atomisp_device *isp)
|
||||
int atomisp_drvfs_init(struct atomisp_device *isp)
|
||||
{
|
||||
struct device_driver *drv = isp->dev->driver;
|
||||
int ret;
|
||||
|
||||
iunit_debug.isp = isp;
|
||||
|
@ -194,7 +194,7 @@ int atomisp_drvfs_init(struct device_driver *drv, struct atomisp_device *isp)
|
|||
|
||||
ret = iunit_drvfs_create_files(iunit_debug.drv);
|
||||
if (ret) {
|
||||
dev_err(atomisp_dev, "drvfs_create_files error: %d\n", ret);
|
||||
dev_err(isp->dev, "drvfs_create_files error: %d\n", ret);
|
||||
iunit_drvfs_remove_files(iunit_debug.drv);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#ifndef __ATOMISP_DRVFS_H__
|
||||
#define __ATOMISP_DRVFS_H__
|
||||
|
||||
int atomisp_drvfs_init(struct device_driver *drv, struct atomisp_device *isp);
|
||||
int atomisp_drvfs_init(struct atomisp_device *isp);
|
||||
void atomisp_drvfs_exit(void);
|
||||
|
||||
#endif /* __ATOMISP_DRVFS_H__ */
|
||||
|
|
|
@ -26,6 +26,9 @@ enum clock_rate {
|
|||
#define CLK_RATE_19_2MHZ 19200000
|
||||
#define CLK_RATE_25_0MHZ 25000000
|
||||
|
||||
/* Valid clock number range from 0 to 5 */
|
||||
#define MAX_CLK_COUNT 5
|
||||
|
||||
/* X-Powers AXP288 register set */
|
||||
#define ALDO1_SEL_REG 0x28
|
||||
#define ALDO1_CTRL3_REG 0x13
|
||||
|
@ -61,9 +64,7 @@ enum clock_rate {
|
|||
|
||||
struct gmin_subdev {
|
||||
struct v4l2_subdev *subdev;
|
||||
int clock_num;
|
||||
enum clock_rate clock_src;
|
||||
bool clock_on;
|
||||
struct clk *pmc_clk;
|
||||
struct gpio_desc *gpio0;
|
||||
struct gpio_desc *gpio1;
|
||||
|
@ -75,11 +76,16 @@ struct gmin_subdev {
|
|||
unsigned int csi_lanes;
|
||||
enum atomisp_input_format csi_fmt;
|
||||
enum atomisp_bayer_order csi_bayer;
|
||||
|
||||
bool clock_on;
|
||||
bool v1p8_on;
|
||||
bool v2p8_on;
|
||||
bool v1p2_on;
|
||||
bool v2p8_vcm_on;
|
||||
|
||||
int v1p8_gpio;
|
||||
int v2p8_gpio;
|
||||
|
||||
u8 pwm_i2c_addr;
|
||||
|
||||
/* For PMIC AXP */
|
||||
|
@ -90,9 +96,9 @@ struct gmin_subdev {
|
|||
static struct gmin_subdev gmin_subdevs[MAX_SUBDEVS];
|
||||
|
||||
/* ACPI HIDs for the PMICs that could be used by this driver */
|
||||
#define PMIC_ACPI_AXP "INT33F4:00" /* XPower AXP288 PMIC */
|
||||
#define PMIC_ACPI_TI "INT33F5:00" /* Dollar Cove TI PMIC */
|
||||
#define PMIC_ACPI_CRYSTALCOVE "INT33FD:00" /* Crystal Cove PMIC */
|
||||
#define PMIC_ACPI_AXP "INT33F4" /* XPower AXP288 PMIC */
|
||||
#define PMIC_ACPI_TI "INT33F5" /* Dollar Cove TI PMIC */
|
||||
#define PMIC_ACPI_CRYSTALCOVE "INT33FD" /* Crystal Cove PMIC */
|
||||
|
||||
#define PMIC_PLATFORM_TI "intel_soc_pmic_chtdc_ti"
|
||||
|
||||
|
@ -105,7 +111,7 @@ static enum {
|
|||
} pmic_id;
|
||||
|
||||
static const char *pmic_name[] = {
|
||||
[PMIC_UNSET] = "unset",
|
||||
[PMIC_UNSET] = "ACPI device PM",
|
||||
[PMIC_REGULATOR] = "regulator driver",
|
||||
[PMIC_AXP] = "XPower AXP288 PMIC",
|
||||
[PMIC_TI] = "Dollar Cove TI PMIC",
|
||||
|
@ -119,24 +125,6 @@ static const struct atomisp_platform_data pdata = {
|
|||
.subdevs = pdata_subdevs,
|
||||
};
|
||||
|
||||
/*
|
||||
* Something of a hack. The ECS E7 board drives camera 2.8v from an
|
||||
* external regulator instead of the PMIC. There's a gmin_CamV2P8
|
||||
* config variable that specifies the GPIO to handle this particular
|
||||
* case, but this needs a broader architecture for handling camera
|
||||
* power.
|
||||
*/
|
||||
enum { V2P8_GPIO_UNSET = -2, V2P8_GPIO_NONE = -1 };
|
||||
static int v2p8_gpio = V2P8_GPIO_UNSET;
|
||||
|
||||
/*
|
||||
* Something of a hack. The CHT RVP board drives camera 1.8v from an
|
||||
* external regulator instead of the PMIC just like ECS E7 board, see the
|
||||
* comments above.
|
||||
*/
|
||||
enum { V1P8_GPIO_UNSET = -2, V1P8_GPIO_NONE = -1 };
|
||||
static int v1p8_gpio = V1P8_GPIO_UNSET;
|
||||
|
||||
static LIST_HEAD(vcm_devices);
|
||||
static DEFINE_MUTEX(vcm_lock);
|
||||
|
||||
|
@ -199,6 +187,8 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
|
|||
* gmin_subdev struct is already initialized for us.
|
||||
*/
|
||||
gs = find_gmin_subdev(subdev);
|
||||
if (!gs)
|
||||
return -ENODEV;
|
||||
|
||||
pdata.subdevs[i].type = type;
|
||||
pdata.subdevs[i].port = gs->csi_port;
|
||||
|
@ -294,6 +284,7 @@ static struct gmin_cfg_var mrd7_vars[] = {
|
|||
{"INT33F8:00_CsiFmt", "13"},
|
||||
{"INT33F8:00_CsiBayer", "0"},
|
||||
{"INT33F8:00_CamClk", "0"},
|
||||
|
||||
{"INT33F9:00_CamType", "1"},
|
||||
{"INT33F9:00_CsiPort", "0"},
|
||||
{"INT33F9:00_CsiLanes", "1"},
|
||||
|
@ -309,6 +300,7 @@ static struct gmin_cfg_var ecs7_vars[] = {
|
|||
{"INT33BE:00_CsiFmt", "13"},
|
||||
{"INT33BE:00_CsiBayer", "2"},
|
||||
{"INT33BE:00_CamClk", "0"},
|
||||
|
||||
{"INT33F0:00_CsiPort", "0"},
|
||||
{"INT33F0:00_CsiLanes", "1"},
|
||||
{"INT33F0:00_CsiFmt", "13"},
|
||||
|
@ -322,6 +314,7 @@ static struct gmin_cfg_var i8880_vars[] = {
|
|||
{"XXOV2680:00_CsiPort", "1"},
|
||||
{"XXOV2680:00_CsiLanes", "1"},
|
||||
{"XXOV2680:00_CamClk", "0"},
|
||||
|
||||
{"XXGC0310:00_CsiPort", "0"},
|
||||
{"XXGC0310:00_CsiLanes", "1"},
|
||||
{"XXGC0310:00_CamClk", "1"},
|
||||
|
@ -381,34 +374,27 @@ static const guid_t atomisp_dsm_guid = GUID_INIT(0xdc2f6c4f, 0x045b, 0x4f1d,
|
|||
#define GMIN_PMC_CLK_NAME 14 /* "pmc_plt_clk_[0..5]" */
|
||||
static char gmin_pmc_clk_name[GMIN_PMC_CLK_NAME];
|
||||
|
||||
static int gmin_i2c_match_one(struct device *dev, const void *data)
|
||||
{
|
||||
const char *name = data;
|
||||
struct i2c_client *client;
|
||||
|
||||
if (dev->type != &i2c_client_type)
|
||||
return 0;
|
||||
|
||||
client = to_i2c_client(dev);
|
||||
|
||||
return (!strcmp(name, client->name));
|
||||
}
|
||||
|
||||
static struct i2c_client *gmin_i2c_dev_exists(struct device *dev, char *name,
|
||||
struct i2c_client **client)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
struct device *d;
|
||||
|
||||
while ((d = bus_find_device(&i2c_bus_type, NULL, name,
|
||||
gmin_i2c_match_one))) {
|
||||
*client = to_i2c_client(d);
|
||||
dev_dbg(dev, "found '%s' at address 0x%02x, adapter %d\n",
|
||||
(*client)->name, (*client)->addr,
|
||||
(*client)->adapter->nr);
|
||||
return *client;
|
||||
}
|
||||
adev = acpi_dev_get_first_match_dev(name, NULL, -1);
|
||||
if (!adev)
|
||||
return NULL;
|
||||
|
||||
return NULL;
|
||||
d = bus_find_device_by_acpi_dev(&i2c_bus_type, adev);
|
||||
acpi_dev_put(adev);
|
||||
if (!d)
|
||||
return NULL;
|
||||
|
||||
*client = i2c_verify_client(d);
|
||||
put_device(d);
|
||||
|
||||
dev_dbg(dev, "found '%s' at address 0x%02x, adapter %d\n",
|
||||
(*client)->name, (*client)->addr, (*client)->adapter->nr);
|
||||
return *client;
|
||||
}
|
||||
|
||||
static int gmin_i2c_write(struct device *dev, u16 i2c_addr, u8 reg,
|
||||
|
@ -427,95 +413,223 @@ static int gmin_i2c_write(struct device *dev, u16 i2c_addr, u8 reg,
|
|||
"I2C write, addr: 0x%02x, reg: 0x%02x, value: 0x%02x, mask: 0x%02x\n",
|
||||
i2c_addr, reg, value, mask);
|
||||
|
||||
ret = intel_soc_pmic_exec_mipi_pmic_seq_element(i2c_addr, reg,
|
||||
value, mask);
|
||||
|
||||
if (ret == -EOPNOTSUPP) {
|
||||
ret = intel_soc_pmic_exec_mipi_pmic_seq_element(i2c_addr, reg, value, mask);
|
||||
if (ret == -EOPNOTSUPP)
|
||||
dev_err(dev,
|
||||
"ACPI didn't mapped the OpRegion needed to access I2C address 0x%02x.\n"
|
||||
"Need to compile the Kernel using CONFIG_*_PMIC_OPREGION settings\n",
|
||||
"Need to compile the kernel using CONFIG_*_PMIC_OPREGION settings\n",
|
||||
i2c_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
|
||||
static int atomisp_get_acpi_power(struct device *dev)
|
||||
{
|
||||
struct i2c_client *power = NULL, *client = v4l2_get_subdevdata(subdev);
|
||||
struct acpi_device *adev;
|
||||
acpi_handle handle;
|
||||
struct device *dev;
|
||||
int i, ret;
|
||||
char name[5];
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
struct acpi_buffer b_name = { sizeof(name), name };
|
||||
union acpi_object *package, *element;
|
||||
acpi_handle handle = ACPI_HANDLE(dev);
|
||||
acpi_handle rhandle;
|
||||
acpi_status status;
|
||||
int clock_num = -1;
|
||||
int i;
|
||||
|
||||
if (!client)
|
||||
return NULL;
|
||||
status = acpi_evaluate_object(handle, "_PR0", NULL, &buffer);
|
||||
if (!ACPI_SUCCESS(status))
|
||||
return -1;
|
||||
|
||||
dev = &client->dev;
|
||||
package = buffer.pointer;
|
||||
|
||||
handle = ACPI_HANDLE(dev);
|
||||
if (!buffer.length || !package
|
||||
|| package->type != ACPI_TYPE_PACKAGE
|
||||
|| !package->package.count)
|
||||
goto fail;
|
||||
|
||||
// FIXME: may need to release resources allocated by acpi_bus_get_device()
|
||||
if (!handle || acpi_bus_get_device(handle, &adev)) {
|
||||
dev_err(dev, "Error could not get ACPI device\n");
|
||||
return NULL;
|
||||
for (i = 0; i < package->package.count; i++) {
|
||||
element = &package->package.elements[i];
|
||||
|
||||
if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
|
||||
continue;
|
||||
|
||||
rhandle = element->reference.handle;
|
||||
if (!rhandle)
|
||||
goto fail;
|
||||
|
||||
acpi_get_name(rhandle, ACPI_SINGLE_NAME, &b_name);
|
||||
|
||||
dev_dbg(dev, "Found PM resource '%s'\n", name);
|
||||
if (strlen(name) == 4 && !strncmp(name, "CLK", 3)) {
|
||||
if (name[3] >= '0' && name[3] <= '4')
|
||||
clock_num = name[3] - '0';
|
||||
#if 0
|
||||
/*
|
||||
* We could abort here, but let's parse all resources,
|
||||
* as this is helpful for debugging purposes
|
||||
*/
|
||||
if (clock_num >= 0)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "%s: ACPI detected it on bus ID=%s, HID=%s\n",
|
||||
__func__, acpi_device_bid(adev), acpi_device_hid(adev));
|
||||
fail:
|
||||
ACPI_FREE(buffer.pointer);
|
||||
|
||||
if (!pmic_id) {
|
||||
if (gmin_i2c_dev_exists(dev, PMIC_ACPI_TI, &power))
|
||||
pmic_id = PMIC_TI;
|
||||
else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_AXP, &power))
|
||||
pmic_id = PMIC_AXP;
|
||||
else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_CRYSTALCOVE, &power))
|
||||
pmic_id = PMIC_CRYSTALCOVE;
|
||||
else
|
||||
pmic_id = PMIC_REGULATOR;
|
||||
}
|
||||
return clock_num;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_SUBDEVS && gmin_subdevs[i].subdev; i++)
|
||||
;
|
||||
if (i >= MAX_SUBDEVS)
|
||||
return NULL;
|
||||
static u8 gmin_get_pmic_id_and_addr(struct device *dev)
|
||||
{
|
||||
struct i2c_client *power;
|
||||
static u8 pmic_i2c_addr;
|
||||
|
||||
if (power) {
|
||||
gmin_subdevs[i].pwm_i2c_addr = power->addr;
|
||||
dev_info(dev,
|
||||
"gmin: power management provided via %s (i2c addr 0x%02x)\n",
|
||||
pmic_name[pmic_id], power->addr);
|
||||
} else {
|
||||
dev_info(dev, "gmin: power management provided via %s\n",
|
||||
pmic_name[pmic_id]);
|
||||
}
|
||||
if (pmic_id)
|
||||
return pmic_i2c_addr;
|
||||
|
||||
if (gmin_i2c_dev_exists(dev, PMIC_ACPI_TI, &power))
|
||||
pmic_id = PMIC_TI;
|
||||
else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_AXP, &power))
|
||||
pmic_id = PMIC_AXP;
|
||||
else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_CRYSTALCOVE, &power))
|
||||
pmic_id = PMIC_CRYSTALCOVE;
|
||||
else
|
||||
pmic_id = PMIC_REGULATOR;
|
||||
|
||||
pmic_i2c_addr = power ? power->addr : 0;
|
||||
return pmic_i2c_addr;
|
||||
}
|
||||
|
||||
static int gmin_detect_pmic(struct v4l2_subdev *subdev)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(subdev);
|
||||
struct device *dev = &client->dev;
|
||||
u8 pmic_i2c_addr;
|
||||
|
||||
pmic_i2c_addr = gmin_get_pmic_id_and_addr(dev);
|
||||
dev_info(dev, "gmin: power management provided via %s (i2c addr 0x%02x)\n",
|
||||
pmic_name[pmic_id], pmic_i2c_addr);
|
||||
return pmic_i2c_addr;
|
||||
}
|
||||
|
||||
static int gmin_subdev_add(struct gmin_subdev *gs)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(gs->subdev);
|
||||
struct device *dev = &client->dev;
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
int ret, clock_num = -1;
|
||||
|
||||
dev_info(dev, "%s: ACPI path is %pfw\n", __func__, dev_fwnode(dev));
|
||||
|
||||
gmin_subdevs[i].subdev = subdev;
|
||||
gmin_subdevs[i].clock_num = gmin_get_var_int(dev, false, "CamClk", 0);
|
||||
/*WA:CHT requires XTAL clock as PLL is not stable.*/
|
||||
gmin_subdevs[i].clock_src = gmin_get_var_int(dev, false, "ClkSrc",
|
||||
VLV2_CLK_PLL_19P2MHZ);
|
||||
gmin_subdevs[i].csi_port = gmin_get_var_int(dev, false, "CsiPort", 0);
|
||||
gmin_subdevs[i].csi_lanes = gmin_get_var_int(dev, false, "CsiLanes", 1);
|
||||
gs->clock_src = gmin_get_var_int(dev, false, "ClkSrc",
|
||||
VLV2_CLK_PLL_19P2MHZ);
|
||||
|
||||
/* get PMC clock with clock framework */
|
||||
snprintf(gmin_pmc_clk_name,
|
||||
sizeof(gmin_pmc_clk_name),
|
||||
"%s_%d", "pmc_plt_clk", gmin_subdevs[i].clock_num);
|
||||
gs->csi_port = gmin_get_var_int(dev, false, "CsiPort", 0);
|
||||
gs->csi_lanes = gmin_get_var_int(dev, false, "CsiLanes", 1);
|
||||
|
||||
gmin_subdevs[i].pmc_clk = devm_clk_get(dev, gmin_pmc_clk_name);
|
||||
if (IS_ERR(gmin_subdevs[i].pmc_clk)) {
|
||||
ret = PTR_ERR(gmin_subdevs[i].pmc_clk);
|
||||
gs->gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gs->gpio0))
|
||||
gs->gpio0 = NULL;
|
||||
else
|
||||
dev_info(dev, "will handle gpio0 via ACPI\n");
|
||||
|
||||
dev_err(dev,
|
||||
"Failed to get clk from %s : %d\n",
|
||||
gmin_pmc_clk_name,
|
||||
ret);
|
||||
gs->gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gs->gpio1))
|
||||
gs->gpio1 = NULL;
|
||||
else
|
||||
dev_info(dev, "will handle gpio1 via ACPI\n");
|
||||
|
||||
return NULL;
|
||||
/*
|
||||
* Those are used only when there is an external regulator apart
|
||||
* from the PMIC that would be providing power supply, like on the
|
||||
* two cases below:
|
||||
*
|
||||
* The ECS E7 board drives camera 2.8v from an external regulator
|
||||
* instead of the PMIC. There's a gmin_CamV2P8 config variable
|
||||
* that specifies the GPIO to handle this particular case,
|
||||
* but this needs a broader architecture for handling camera power.
|
||||
*
|
||||
* The CHT RVP board drives camera 1.8v from an* external regulator
|
||||
* instead of the PMIC just like ECS E7 board.
|
||||
*/
|
||||
|
||||
gs->v1p8_gpio = gmin_get_var_int(dev, true, "V1P8GPIO", -1);
|
||||
gs->v2p8_gpio = gmin_get_var_int(dev, true, "V2P8GPIO", -1);
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
*
|
||||
* The ACPI handling code checks for the _PR? tables in order to
|
||||
* know what is required to switch the device from power state
|
||||
* D0 (_PR0) up to D3COLD (_PR3).
|
||||
*
|
||||
* The adev->flags.power_manageable is set to true if the device
|
||||
* has a _PR0 table, which can be checked by calling
|
||||
* acpi_device_power_manageable(adev).
|
||||
*
|
||||
* However, this only says that the device can be set to power off
|
||||
* mode.
|
||||
*
|
||||
* At least on the DSDT tables we've seen so far, there's no _PR3,
|
||||
* nor _PS3 (which would have a somewhat similar effect).
|
||||
* So, using ACPI for power management won't work, except if adding
|
||||
* an ACPI override logic somewhere.
|
||||
*
|
||||
* So, at least for the existing devices we know, the check below
|
||||
* will always be false.
|
||||
*/
|
||||
if (acpi_device_can_wakeup(adev) &&
|
||||
acpi_device_can_poweroff(adev)) {
|
||||
dev_info(dev,
|
||||
"gmin: power management provided via device PM\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The code below is here due to backward compatibility with devices
|
||||
* whose ACPI BIOS may not contain everything that would be needed
|
||||
* in order to set clocks and do power management.
|
||||
*/
|
||||
|
||||
/*
|
||||
* According with :
|
||||
* https://github.com/projectceladon/hardware-intel-kernelflinger/blob/master/doc/fastboot.md
|
||||
*
|
||||
* The "CamClk" EFI var is set via fastboot on some Android devices,
|
||||
* and seems to contain the number of the clock used to feed the
|
||||
* sensor.
|
||||
*
|
||||
* On systems with a proper ACPI table, this is given via the _PR0
|
||||
* power resource table. The logic below should first check if there
|
||||
* is a power resource already, falling back to the EFI vars detection
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
/* Try first to use ACPI to get the clock resource */
|
||||
if (acpi_device_power_manageable(adev))
|
||||
clock_num = atomisp_get_acpi_power(dev);
|
||||
|
||||
/* Fall-back use EFI and/or DMI match */
|
||||
if (clock_num < 0)
|
||||
clock_num = gmin_get_var_int(dev, false, "CamClk", 0);
|
||||
|
||||
if (clock_num < 0 || clock_num > MAX_CLK_COUNT) {
|
||||
dev_err(dev, "Invalid clock number\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snprintf(gmin_pmc_clk_name, sizeof(gmin_pmc_clk_name),
|
||||
"%s_%d", "pmc_plt_clk", clock_num);
|
||||
|
||||
gs->pmc_clk = devm_clk_get(dev, gmin_pmc_clk_name);
|
||||
if (IS_ERR(gs->pmc_clk)) {
|
||||
ret = PTR_ERR(gs->pmc_clk);
|
||||
dev_err(dev, "Failed to get clk from %s: %d\n", gmin_pmc_clk_name, ret);
|
||||
return ret;
|
||||
}
|
||||
dev_info(dev, "Will use CLK%d (%s)\n", clock_num, gmin_pmc_clk_name);
|
||||
|
||||
/*
|
||||
* The firmware might enable the clock at
|
||||
* boot (this information may or may not
|
||||
|
@ -526,25 +640,17 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
|
|||
* to disable a clock that has not been enabled,
|
||||
* we need to enable the clock first.
|
||||
*/
|
||||
ret = clk_prepare_enable(gmin_subdevs[i].pmc_clk);
|
||||
ret = clk_prepare_enable(gs->pmc_clk);
|
||||
if (!ret)
|
||||
clk_disable_unprepare(gmin_subdevs[i].pmc_clk);
|
||||
|
||||
gmin_subdevs[i].gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gmin_subdevs[i].gpio0))
|
||||
gmin_subdevs[i].gpio0 = NULL;
|
||||
|
||||
gmin_subdevs[i].gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gmin_subdevs[i].gpio1))
|
||||
gmin_subdevs[i].gpio1 = NULL;
|
||||
clk_disable_unprepare(gs->pmc_clk);
|
||||
|
||||
switch (pmic_id) {
|
||||
case PMIC_REGULATOR:
|
||||
gmin_subdevs[i].v1p8_reg = regulator_get(dev, "V1P8SX");
|
||||
gmin_subdevs[i].v2p8_reg = regulator_get(dev, "V2P8SX");
|
||||
gs->v1p8_reg = regulator_get(dev, "V1P8SX");
|
||||
gs->v2p8_reg = regulator_get(dev, "V2P8SX");
|
||||
|
||||
gmin_subdevs[i].v1p2_reg = regulator_get(dev, "V1P2A");
|
||||
gmin_subdevs[i].v2p8_vcm_reg = regulator_get(dev, "VPROG4B");
|
||||
gs->v1p2_reg = regulator_get(dev, "V1P2A");
|
||||
gs->v2p8_vcm_reg = regulator_get(dev, "VPROG4B");
|
||||
|
||||
/* Note: ideally we would initialize v[12]p8_on to the
|
||||
* output of regulator_is_enabled(), but sadly that
|
||||
|
@ -556,32 +662,31 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
|
|||
break;
|
||||
|
||||
case PMIC_AXP:
|
||||
gmin_subdevs[i].eldo1_1p8v = gmin_get_var_int(dev, false,
|
||||
"eldo1_1p8v",
|
||||
ELDO1_1P8V);
|
||||
gmin_subdevs[i].eldo1_sel_reg = gmin_get_var_int(dev, false,
|
||||
"eldo1_sel_reg",
|
||||
ELDO1_SEL_REG);
|
||||
gmin_subdevs[i].eldo1_ctrl_shift = gmin_get_var_int(dev, false,
|
||||
"eldo1_ctrl_shift",
|
||||
ELDO1_CTRL_SHIFT);
|
||||
gmin_subdevs[i].eldo2_1p8v = gmin_get_var_int(dev, false,
|
||||
"eldo2_1p8v",
|
||||
ELDO2_1P8V);
|
||||
gmin_subdevs[i].eldo2_sel_reg = gmin_get_var_int(dev, false,
|
||||
"eldo2_sel_reg",
|
||||
ELDO2_SEL_REG);
|
||||
gmin_subdevs[i].eldo2_ctrl_shift = gmin_get_var_int(dev, false,
|
||||
"eldo2_ctrl_shift",
|
||||
ELDO2_CTRL_SHIFT);
|
||||
gmin_subdevs[i].pwm_i2c_addr = power->addr;
|
||||
gs->eldo1_1p8v = gmin_get_var_int(dev, false,
|
||||
"eldo1_1p8v",
|
||||
ELDO1_1P8V);
|
||||
gs->eldo1_sel_reg = gmin_get_var_int(dev, false,
|
||||
"eldo1_sel_reg",
|
||||
ELDO1_SEL_REG);
|
||||
gs->eldo1_ctrl_shift = gmin_get_var_int(dev, false,
|
||||
"eldo1_ctrl_shift",
|
||||
ELDO1_CTRL_SHIFT);
|
||||
gs->eldo2_1p8v = gmin_get_var_int(dev, false,
|
||||
"eldo2_1p8v",
|
||||
ELDO2_1P8V);
|
||||
gs->eldo2_sel_reg = gmin_get_var_int(dev, false,
|
||||
"eldo2_sel_reg",
|
||||
ELDO2_SEL_REG);
|
||||
gs->eldo2_ctrl_shift = gmin_get_var_int(dev, false,
|
||||
"eldo2_ctrl_shift",
|
||||
ELDO2_CTRL_SHIFT);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return &gmin_subdevs[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct gmin_subdev *find_gmin_subdev(struct v4l2_subdev *subdev)
|
||||
|
@ -591,7 +696,17 @@ static struct gmin_subdev *find_gmin_subdev(struct v4l2_subdev *subdev)
|
|||
for (i = 0; i < MAX_SUBDEVS; i++)
|
||||
if (gmin_subdevs[i].subdev == subdev)
|
||||
return &gmin_subdevs[i];
|
||||
return gmin_subdev_add(subdev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct gmin_subdev *find_free_gmin_subdev_slot(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < MAX_SUBDEVS; i++)
|
||||
if (gmin_subdevs[i].subdev == NULL)
|
||||
return &gmin_subdevs[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int axp_regulator_set(struct device *dev, struct gmin_subdev *gs,
|
||||
|
@ -700,32 +815,24 @@ static int gmin_v1p8_ctrl(struct v4l2_subdev *subdev, int on)
|
|||
{
|
||||
struct gmin_subdev *gs = find_gmin_subdev(subdev);
|
||||
int ret;
|
||||
struct device *dev;
|
||||
struct i2c_client *client = v4l2_get_subdevdata(subdev);
|
||||
int value;
|
||||
|
||||
dev = &client->dev;
|
||||
|
||||
if (v1p8_gpio == V1P8_GPIO_UNSET) {
|
||||
v1p8_gpio = gmin_get_var_int(dev, true,
|
||||
"V1P8GPIO", V1P8_GPIO_NONE);
|
||||
if (v1p8_gpio != V1P8_GPIO_NONE) {
|
||||
pr_info("atomisp_gmin_platform: 1.8v power on GPIO %d\n",
|
||||
v1p8_gpio);
|
||||
ret = gpio_request(v1p8_gpio, "camera_v1p8_en");
|
||||
if (!ret)
|
||||
ret = gpio_direction_output(v1p8_gpio, 0);
|
||||
if (ret)
|
||||
pr_err("V1P8 GPIO initialization failed\n");
|
||||
}
|
||||
if (gs->v1p8_gpio >= 0) {
|
||||
pr_info("atomisp_gmin_platform: 1.8v power on GPIO %d\n",
|
||||
gs->v1p8_gpio);
|
||||
ret = gpio_request(gs->v1p8_gpio, "camera_v1p8_en");
|
||||
if (!ret)
|
||||
ret = gpio_direction_output(gs->v1p8_gpio, 0);
|
||||
if (ret)
|
||||
pr_err("V1P8 GPIO initialization failed\n");
|
||||
}
|
||||
|
||||
if (!gs || gs->v1p8_on == on)
|
||||
return 0;
|
||||
gs->v1p8_on = on;
|
||||
|
||||
if (v1p8_gpio >= 0)
|
||||
gpio_set_value(v1p8_gpio, on);
|
||||
if (gs->v1p8_gpio >= 0)
|
||||
gpio_set_value(gs->v1p8_gpio, on);
|
||||
|
||||
if (gs->v1p8_reg) {
|
||||
regulator_set_voltage(gs->v1p8_reg, 1800000, 1800000);
|
||||
|
@ -762,32 +869,24 @@ static int gmin_v2p8_ctrl(struct v4l2_subdev *subdev, int on)
|
|||
{
|
||||
struct gmin_subdev *gs = find_gmin_subdev(subdev);
|
||||
int ret;
|
||||
struct device *dev;
|
||||
struct i2c_client *client = v4l2_get_subdevdata(subdev);
|
||||
int value;
|
||||
|
||||
dev = &client->dev;
|
||||
|
||||
if (v2p8_gpio == V2P8_GPIO_UNSET) {
|
||||
v2p8_gpio = gmin_get_var_int(dev, true,
|
||||
"V2P8GPIO", V2P8_GPIO_NONE);
|
||||
if (v2p8_gpio != V2P8_GPIO_NONE) {
|
||||
pr_info("atomisp_gmin_platform: 2.8v power on GPIO %d\n",
|
||||
v2p8_gpio);
|
||||
ret = gpio_request(v2p8_gpio, "camera_v2p8");
|
||||
if (!ret)
|
||||
ret = gpio_direction_output(v2p8_gpio, 0);
|
||||
if (ret)
|
||||
pr_err("V2P8 GPIO initialization failed\n");
|
||||
}
|
||||
if (gs->v2p8_gpio >= 0) {
|
||||
pr_info("atomisp_gmin_platform: 2.8v power on GPIO %d\n",
|
||||
gs->v2p8_gpio);
|
||||
ret = gpio_request(gs->v2p8_gpio, "camera_v2p8");
|
||||
if (!ret)
|
||||
ret = gpio_direction_output(gs->v2p8_gpio, 0);
|
||||
if (ret)
|
||||
pr_err("V2P8 GPIO initialization failed\n");
|
||||
}
|
||||
|
||||
if (!gs || gs->v2p8_on == on)
|
||||
return 0;
|
||||
gs->v2p8_on = on;
|
||||
|
||||
if (v2p8_gpio >= 0)
|
||||
gpio_set_value(v2p8_gpio, on);
|
||||
if (gs->v2p8_gpio >= 0)
|
||||
gpio_set_value(gs->v2p8_gpio, on);
|
||||
|
||||
if (gs->v2p8_reg) {
|
||||
regulator_set_voltage(gs->v2p8_reg, 2900000, 2900000);
|
||||
|
@ -819,6 +918,37 @@ static int gmin_v2p8_ctrl(struct v4l2_subdev *subdev, int on)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int gmin_acpi_pm_ctrl(struct v4l2_subdev *subdev, int on)
|
||||
{
|
||||
int ret = 0;
|
||||
struct gmin_subdev *gs = find_gmin_subdev(subdev);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(subdev);
|
||||
struct acpi_device *adev = ACPI_COMPANION(&client->dev);
|
||||
|
||||
/* Use the ACPI power management to control it */
|
||||
on = !!on;
|
||||
if (gs->clock_on == on)
|
||||
return 0;
|
||||
|
||||
dev_dbg(subdev->dev, "Setting power state to %s\n",
|
||||
on ? "on" : "off");
|
||||
|
||||
if (on)
|
||||
ret = acpi_device_set_power(adev,
|
||||
ACPI_STATE_D0);
|
||||
else
|
||||
ret = acpi_device_set_power(adev,
|
||||
ACPI_STATE_D3_COLD);
|
||||
|
||||
if (!ret)
|
||||
gs->clock_on = on;
|
||||
else
|
||||
dev_err(subdev->dev, "Couldn't set power state to %s\n",
|
||||
on ? "on" : "off");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gmin_flisclk_ctrl(struct v4l2_subdev *subdev, int on)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -884,7 +1014,7 @@ static struct camera_vcm_control *gmin_get_vcm_ctrl(struct v4l2_subdev *subdev,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct camera_sensor_platform_data gmin_plat = {
|
||||
static struct camera_sensor_platform_data pmic_gmin_plat = {
|
||||
.gpio0_ctrl = gmin_gpio0_ctrl,
|
||||
.gpio1_ctrl = gmin_gpio1_ctrl,
|
||||
.v1p8_ctrl = gmin_v1p8_ctrl,
|
||||
|
@ -895,17 +1025,36 @@ static struct camera_sensor_platform_data gmin_plat = {
|
|||
.get_vcm_ctrl = gmin_get_vcm_ctrl,
|
||||
};
|
||||
|
||||
static struct camera_sensor_platform_data acpi_gmin_plat = {
|
||||
.gpio0_ctrl = gmin_gpio0_ctrl,
|
||||
.gpio1_ctrl = gmin_gpio1_ctrl,
|
||||
.v1p8_ctrl = gmin_acpi_pm_ctrl,
|
||||
.v2p8_ctrl = gmin_acpi_pm_ctrl,
|
||||
.v1p2_ctrl = gmin_acpi_pm_ctrl,
|
||||
.flisclk_ctrl = gmin_acpi_pm_ctrl,
|
||||
.csi_cfg = gmin_csi_cfg,
|
||||
.get_vcm_ctrl = gmin_get_vcm_ctrl,
|
||||
};
|
||||
|
||||
struct camera_sensor_platform_data *gmin_camera_platform_data(
|
||||
struct v4l2_subdev *subdev,
|
||||
enum atomisp_input_format csi_format,
|
||||
enum atomisp_bayer_order csi_bayer)
|
||||
{
|
||||
struct gmin_subdev *gs = find_gmin_subdev(subdev);
|
||||
u8 pmic_i2c_addr = gmin_detect_pmic(subdev);
|
||||
struct gmin_subdev *gs;
|
||||
|
||||
gs = find_free_gmin_subdev_slot();
|
||||
gs->subdev = subdev;
|
||||
gs->csi_fmt = csi_format;
|
||||
gs->csi_bayer = csi_bayer;
|
||||
gs->pwm_i2c_addr = pmic_i2c_addr;
|
||||
|
||||
return &gmin_plat;
|
||||
gmin_subdev_add(gs);
|
||||
if (gs->pmc_clk)
|
||||
return &pmic_gmin_plat;
|
||||
else
|
||||
return &acpi_gmin_plat;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gmin_camera_platform_data);
|
||||
|
||||
|
@ -957,12 +1106,28 @@ static int gmin_get_config_dsm_var(struct device *dev,
|
|||
union acpi_object *obj, *cur = NULL;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* The data reported by "CamClk" seems to be either 0 or 1 at the
|
||||
* _DSM table.
|
||||
*
|
||||
* At the ACPI tables we looked so far, this is not related to the
|
||||
* actual clock source for the sensor, which is given by the
|
||||
* _PR0 ACPI table. So, ignore it, as otherwise this will be
|
||||
* set to a wrong value.
|
||||
*/
|
||||
if (!strcmp(var, "CamClk"))
|
||||
return -EINVAL;
|
||||
|
||||
obj = acpi_evaluate_dsm(handle, &atomisp_dsm_guid, 0, 0, NULL);
|
||||
if (!obj) {
|
||||
dev_info_once(dev, "Didn't find ACPI _DSM table.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Return on unexpected object type */
|
||||
if (obj->type != ACPI_TYPE_PACKAGE)
|
||||
return -EINVAL;
|
||||
|
||||
#if 0 /* Just for debugging purposes */
|
||||
for (i = 0; i < obj->package.count; i++) {
|
||||
union acpi_object *cur = &obj->package.elements[i];
|
||||
|
@ -1155,10 +1320,10 @@ EXPORT_SYMBOL_GPL(camera_sensor_csi);
|
|||
* trying. The driver itself does direct calls to the PUNIT to manage
|
||||
* ISP power.
|
||||
*/
|
||||
static void isp_pm_cap_fixup(struct pci_dev *dev)
|
||||
static void isp_pm_cap_fixup(struct pci_dev *pdev)
|
||||
{
|
||||
dev_info(&dev->dev, "Disabling PCI power management on camera ISP\n");
|
||||
dev->pm_cap = 0;
|
||||
dev_info(&pdev->dev, "Disabling PCI power management on camera ISP\n");
|
||||
pdev->pm_cap = 0;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0f38, isp_pm_cap_fixup);
|
||||
|
||||
|
|
|
@ -216,12 +216,12 @@ struct atomisp_sw_contex {
|
|||
* ci device struct
|
||||
*/
|
||||
struct atomisp_device {
|
||||
struct pci_dev *pdev;
|
||||
struct device *dev;
|
||||
struct v4l2_device v4l2_dev;
|
||||
struct media_device media_dev;
|
||||
struct atomisp_platform_data *pdata;
|
||||
void *mmu_l1_base;
|
||||
void __iomem *base;
|
||||
const struct firmware *firmware;
|
||||
|
||||
struct pm_qos_request pm_qos;
|
||||
|
|
|
@ -549,8 +549,7 @@ static int atomisp_querycap(struct file *file, void *fh,
|
|||
|
||||
strscpy(cap->driver, DRIVER, sizeof(cap->driver));
|
||||
strscpy(cap->card, CARD, sizeof(cap->card));
|
||||
snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
|
||||
pci_name(isp->pdev));
|
||||
snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", dev_name(isp->dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1635,6 +1634,7 @@ static int atomisp_streamon(struct file *file, void *fh,
|
|||
struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
|
||||
struct atomisp_sub_device *asd = pipe->asd;
|
||||
struct atomisp_device *isp = video_get_drvdata(vdev);
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
enum ia_css_pipe_id css_pipe_id;
|
||||
unsigned int sensor_start_stream;
|
||||
unsigned int wdt_duration = ATOMISP_ISP_TIMEOUT_DURATION;
|
||||
|
@ -1844,9 +1844,8 @@ static int atomisp_streamon(struct file *file, void *fh,
|
|||
/* Enable the CSI interface on ANN B0/K0 */
|
||||
if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
|
||||
ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
|
||||
pci_write_config_word(isp->pdev, MRFLD_PCI_CSI_CONTROL,
|
||||
isp->saved_regs.csi_control |
|
||||
MRFLD_PCI_CSI_CONTROL_CSI_READY);
|
||||
pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL,
|
||||
isp->saved_regs.csi_control | MRFLD_PCI_CSI_CONTROL_CSI_READY);
|
||||
}
|
||||
|
||||
/* stream on the sensor */
|
||||
|
@ -1891,6 +1890,7 @@ int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
|
|||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct atomisp_device *isp = video_get_drvdata(vdev);
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
|
||||
struct atomisp_sub_device *asd = pipe->asd;
|
||||
struct atomisp_video_pipe *capture_pipe = NULL;
|
||||
|
@ -2076,9 +2076,8 @@ int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
|
|||
/* Disable the CSI interface on ANN B0/K0 */
|
||||
if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
|
||||
ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
|
||||
pci_write_config_word(isp->pdev, MRFLD_PCI_CSI_CONTROL,
|
||||
isp->saved_regs.csi_control &
|
||||
~MRFLD_PCI_CSI_CONTROL_CSI_READY);
|
||||
pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL,
|
||||
isp->saved_regs.csi_control & ~MRFLD_PCI_CSI_CONTROL_CSI_READY);
|
||||
}
|
||||
|
||||
if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false))
|
||||
|
@ -2111,8 +2110,8 @@ int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
|
|||
}
|
||||
|
||||
/* disable PUNIT/ISP acknowlede/handshake - SRSE=3 */
|
||||
pci_write_config_dword(isp->pdev, PCI_I_CONTROL, isp->saved_regs.i_control |
|
||||
MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK);
|
||||
pci_write_config_dword(pdev, PCI_I_CONTROL,
|
||||
isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK);
|
||||
dev_err(isp->dev, "atomisp_reset");
|
||||
atomisp_reset(isp);
|
||||
for (i = 0; i < isp->num_of_streams; i++) {
|
||||
|
|
|
@ -127,8 +127,6 @@ MODULE_PARM_DESC(pad_h, "extra data for ISP processing");
|
|||
|
||||
struct device *atomisp_dev;
|
||||
|
||||
void __iomem *atomisp_io_base;
|
||||
|
||||
static const struct atomisp_freq_scaling_rule dfs_rules_merr[] = {
|
||||
{
|
||||
.width = ISP_FREQ_RULE_ANY,
|
||||
|
@ -512,30 +510,27 @@ void atomisp_acc_unregister(struct atomisp_acc_pipe *video)
|
|||
|
||||
static int atomisp_save_iunit_reg(struct atomisp_device *isp)
|
||||
{
|
||||
struct pci_dev *dev = isp->pdev;
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
|
||||
dev_dbg(isp->dev, "%s\n", __func__);
|
||||
|
||||
pci_read_config_word(dev, PCI_COMMAND, &isp->saved_regs.pcicmdsts);
|
||||
pci_read_config_word(pdev, PCI_COMMAND, &isp->saved_regs.pcicmdsts);
|
||||
/* isp->saved_regs.ispmmadr is set from the atomisp_pci_probe() */
|
||||
pci_read_config_dword(dev, PCI_MSI_CAPID, &isp->saved_regs.msicap);
|
||||
pci_read_config_dword(dev, PCI_MSI_ADDR, &isp->saved_regs.msi_addr);
|
||||
pci_read_config_word(dev, PCI_MSI_DATA, &isp->saved_regs.msi_data);
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &isp->saved_regs.intr);
|
||||
pci_read_config_dword(dev, PCI_INTERRUPT_CTRL,
|
||||
&isp->saved_regs.interrupt_control);
|
||||
pci_read_config_dword(pdev, PCI_MSI_CAPID, &isp->saved_regs.msicap);
|
||||
pci_read_config_dword(pdev, PCI_MSI_ADDR, &isp->saved_regs.msi_addr);
|
||||
pci_read_config_word(pdev, PCI_MSI_DATA, &isp->saved_regs.msi_data);
|
||||
pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &isp->saved_regs.intr);
|
||||
pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &isp->saved_regs.interrupt_control);
|
||||
|
||||
pci_read_config_dword(dev, MRFLD_PCI_PMCS,
|
||||
&isp->saved_regs.pmcs);
|
||||
pci_read_config_dword(pdev, MRFLD_PCI_PMCS, &isp->saved_regs.pmcs);
|
||||
/* Ensure read/write combining is enabled. */
|
||||
pci_read_config_dword(dev, PCI_I_CONTROL,
|
||||
&isp->saved_regs.i_control);
|
||||
pci_read_config_dword(pdev, PCI_I_CONTROL, &isp->saved_regs.i_control);
|
||||
isp->saved_regs.i_control |=
|
||||
MRFLD_PCI_I_CONTROL_ENABLE_READ_COMBINING |
|
||||
MRFLD_PCI_I_CONTROL_ENABLE_WRITE_COMBINING;
|
||||
pci_read_config_dword(dev, MRFLD_PCI_CSI_ACCESS_CTRL_VIOL,
|
||||
pci_read_config_dword(pdev, MRFLD_PCI_CSI_ACCESS_CTRL_VIOL,
|
||||
&isp->saved_regs.csi_access_viol);
|
||||
pci_read_config_dword(dev, MRFLD_PCI_CSI_RCOMP_CONTROL,
|
||||
pci_read_config_dword(pdev, MRFLD_PCI_CSI_RCOMP_CONTROL,
|
||||
&isp->saved_regs.csi_rcomp_config);
|
||||
/*
|
||||
* Hardware bugs require setting CSI_HS_OVR_CLK_GATE_ON_UPDATE.
|
||||
|
@ -545,65 +540,58 @@ static int atomisp_save_iunit_reg(struct atomisp_device *isp)
|
|||
* is missed, and IUNIT can hang.
|
||||
* For both issues, setting this bit is a workaround.
|
||||
*/
|
||||
isp->saved_regs.csi_rcomp_config |=
|
||||
MRFLD_PCI_CSI_HS_OVR_CLK_GATE_ON_UPDATE;
|
||||
pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL,
|
||||
isp->saved_regs.csi_rcomp_config |= MRFLD_PCI_CSI_HS_OVR_CLK_GATE_ON_UPDATE;
|
||||
pci_read_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL,
|
||||
&isp->saved_regs.csi_afe_dly);
|
||||
pci_read_config_dword(dev, MRFLD_PCI_CSI_CONTROL,
|
||||
pci_read_config_dword(pdev, MRFLD_PCI_CSI_CONTROL,
|
||||
&isp->saved_regs.csi_control);
|
||||
if (isp->media_dev.hw_revision >=
|
||||
(ATOMISP_HW_REVISION_ISP2401 << ATOMISP_HW_REVISION_SHIFT))
|
||||
isp->saved_regs.csi_control |=
|
||||
MRFLD_PCI_CSI_CONTROL_PARPATHEN;
|
||||
isp->saved_regs.csi_control |= MRFLD_PCI_CSI_CONTROL_PARPATHEN;
|
||||
/*
|
||||
* On CHT CSI_READY bit should be enabled before stream on
|
||||
*/
|
||||
if (IS_CHT && (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
|
||||
ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)))
|
||||
isp->saved_regs.csi_control |=
|
||||
MRFLD_PCI_CSI_CONTROL_CSI_READY;
|
||||
pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_RCOMP_CONTROL,
|
||||
isp->saved_regs.csi_control |= MRFLD_PCI_CSI_CONTROL_CSI_READY;
|
||||
pci_read_config_dword(pdev, MRFLD_PCI_CSI_AFE_RCOMP_CONTROL,
|
||||
&isp->saved_regs.csi_afe_rcomp_config);
|
||||
pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_HS_CONTROL,
|
||||
pci_read_config_dword(pdev, MRFLD_PCI_CSI_AFE_HS_CONTROL,
|
||||
&isp->saved_regs.csi_afe_hs_control);
|
||||
pci_read_config_dword(dev, MRFLD_PCI_CSI_DEADLINE_CONTROL,
|
||||
pci_read_config_dword(pdev, MRFLD_PCI_CSI_DEADLINE_CONTROL,
|
||||
&isp->saved_regs.csi_deadline_control);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused atomisp_restore_iunit_reg(struct atomisp_device *isp)
|
||||
{
|
||||
struct pci_dev *dev = isp->pdev;
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
|
||||
dev_dbg(isp->dev, "%s\n", __func__);
|
||||
|
||||
pci_write_config_word(dev, PCI_COMMAND, isp->saved_regs.pcicmdsts);
|
||||
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
|
||||
isp->saved_regs.ispmmadr);
|
||||
pci_write_config_dword(dev, PCI_MSI_CAPID, isp->saved_regs.msicap);
|
||||
pci_write_config_dword(dev, PCI_MSI_ADDR, isp->saved_regs.msi_addr);
|
||||
pci_write_config_word(dev, PCI_MSI_DATA, isp->saved_regs.msi_data);
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, isp->saved_regs.intr);
|
||||
pci_write_config_dword(dev, PCI_INTERRUPT_CTRL,
|
||||
isp->saved_regs.interrupt_control);
|
||||
pci_write_config_dword(dev, PCI_I_CONTROL,
|
||||
isp->saved_regs.i_control);
|
||||
pci_write_config_word(pdev, PCI_COMMAND, isp->saved_regs.pcicmdsts);
|
||||
pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, isp->saved_regs.ispmmadr);
|
||||
pci_write_config_dword(pdev, PCI_MSI_CAPID, isp->saved_regs.msicap);
|
||||
pci_write_config_dword(pdev, PCI_MSI_ADDR, isp->saved_regs.msi_addr);
|
||||
pci_write_config_word(pdev, PCI_MSI_DATA, isp->saved_regs.msi_data);
|
||||
pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, isp->saved_regs.intr);
|
||||
pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, isp->saved_regs.interrupt_control);
|
||||
pci_write_config_dword(pdev, PCI_I_CONTROL, isp->saved_regs.i_control);
|
||||
|
||||
pci_write_config_dword(dev, MRFLD_PCI_PMCS,
|
||||
isp->saved_regs.pmcs);
|
||||
pci_write_config_dword(dev, MRFLD_PCI_CSI_ACCESS_CTRL_VIOL,
|
||||
pci_write_config_dword(pdev, MRFLD_PCI_PMCS, isp->saved_regs.pmcs);
|
||||
pci_write_config_dword(pdev, MRFLD_PCI_CSI_ACCESS_CTRL_VIOL,
|
||||
isp->saved_regs.csi_access_viol);
|
||||
pci_write_config_dword(dev, MRFLD_PCI_CSI_RCOMP_CONTROL,
|
||||
pci_write_config_dword(pdev, MRFLD_PCI_CSI_RCOMP_CONTROL,
|
||||
isp->saved_regs.csi_rcomp_config);
|
||||
pci_write_config_dword(dev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL,
|
||||
pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL,
|
||||
isp->saved_regs.csi_afe_dly);
|
||||
pci_write_config_dword(dev, MRFLD_PCI_CSI_CONTROL,
|
||||
pci_write_config_dword(pdev, MRFLD_PCI_CSI_CONTROL,
|
||||
isp->saved_regs.csi_control);
|
||||
pci_write_config_dword(dev, MRFLD_PCI_CSI_AFE_RCOMP_CONTROL,
|
||||
pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_RCOMP_CONTROL,
|
||||
isp->saved_regs.csi_afe_rcomp_config);
|
||||
pci_write_config_dword(dev, MRFLD_PCI_CSI_AFE_HS_CONTROL,
|
||||
pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_HS_CONTROL,
|
||||
isp->saved_regs.csi_afe_hs_control);
|
||||
pci_write_config_dword(dev, MRFLD_PCI_CSI_DEADLINE_CONTROL,
|
||||
pci_write_config_dword(pdev, MRFLD_PCI_CSI_DEADLINE_CONTROL,
|
||||
isp->saved_regs.csi_deadline_control);
|
||||
|
||||
/*
|
||||
|
@ -619,7 +607,7 @@ static int __maybe_unused atomisp_restore_iunit_reg(struct atomisp_device *isp)
|
|||
|
||||
static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp)
|
||||
{
|
||||
struct pci_dev *dev = isp->pdev;
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
u32 irq;
|
||||
unsigned long flags;
|
||||
|
||||
|
@ -635,11 +623,11 @@ static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp)
|
|||
* So, here we need to check if there is any pending
|
||||
* IRQ, if so, waiting for it to be served
|
||||
*/
|
||||
pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq);
|
||||
pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq);
|
||||
irq = irq & 1 << INTR_IIR;
|
||||
pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, irq);
|
||||
pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq);
|
||||
|
||||
pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq);
|
||||
pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq);
|
||||
if (!(irq & (1 << INTR_IIR)))
|
||||
goto done;
|
||||
|
||||
|
@ -652,11 +640,11 @@ static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp)
|
|||
spin_unlock_irqrestore(&isp->lock, flags);
|
||||
return -EAGAIN;
|
||||
} else {
|
||||
pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq);
|
||||
pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq);
|
||||
irq = irq & 1 << INTR_IIR;
|
||||
pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, irq);
|
||||
pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq);
|
||||
|
||||
pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq);
|
||||
pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq);
|
||||
if (!(irq & (1 << INTR_IIR))) {
|
||||
atomisp_css2_hw_store_32(MRFLD_INTR_ENABLE_REG, 0x0);
|
||||
goto done;
|
||||
|
@ -675,11 +663,11 @@ static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp)
|
|||
* to IIR. It could block subsequent interrupt messages.
|
||||
* HW sighting:4568410.
|
||||
*/
|
||||
pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq);
|
||||
pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq);
|
||||
irq &= ~(1 << INTR_IER);
|
||||
pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, irq);
|
||||
pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq);
|
||||
|
||||
atomisp_msi_irq_uninit(isp, dev);
|
||||
atomisp_msi_irq_uninit(isp);
|
||||
atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, true);
|
||||
spin_unlock_irqrestore(&isp->lock, flags);
|
||||
|
||||
|
@ -755,7 +743,7 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
|
|||
|
||||
/* Wait until ISPSSPM0 bit[25:24] shows the right value */
|
||||
iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0, &tmp);
|
||||
tmp = (tmp & MRFLD_ISPSSPM0_ISPSSC_MASK) >> MRFLD_ISPSSPM0_ISPSSS_OFFSET;
|
||||
tmp = (tmp >> MRFLD_ISPSSPM0_ISPSSS_OFFSET) & MRFLD_ISPSSPM0_ISPSSC_MASK;
|
||||
if (tmp == val) {
|
||||
trace_ipu_cstate(enable);
|
||||
return 0;
|
||||
|
@ -778,15 +766,13 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
|
|||
/* Workaround for pmu_nc_set_power_state not ready in MRFLD */
|
||||
int atomisp_mrfld_power_down(struct atomisp_device *isp)
|
||||
{
|
||||
// FIXME: at least with ISP2401, enabling this code causes the driver to break
|
||||
return 0 && atomisp_mrfld_power(isp, false);
|
||||
return atomisp_mrfld_power(isp, false);
|
||||
}
|
||||
|
||||
/* Workaround for pmu_nc_set_power_state not ready in MRFLD */
|
||||
int atomisp_mrfld_power_up(struct atomisp_device *isp)
|
||||
{
|
||||
// FIXME: at least with ISP2401, enabling this code causes the driver to break
|
||||
return 0 && atomisp_mrfld_power(isp, true);
|
||||
return atomisp_mrfld_power(isp, true);
|
||||
}
|
||||
|
||||
int atomisp_runtime_suspend(struct device *dev)
|
||||
|
@ -902,6 +888,7 @@ static int __maybe_unused atomisp_resume(struct device *dev)
|
|||
|
||||
int atomisp_csi_lane_config(struct atomisp_device *isp)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(isp->dev);
|
||||
static const struct {
|
||||
u8 code;
|
||||
u8 lanes[MRFLD_PORT_NUM];
|
||||
|
@ -1003,7 +990,7 @@ int atomisp_csi_lane_config(struct atomisp_device *isp)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
pci_read_config_dword(isp->pdev, MRFLD_PCI_CSI_CONTROL, &csi_control);
|
||||
pci_read_config_dword(pdev, MRFLD_PCI_CSI_CONTROL, &csi_control);
|
||||
csi_control &= ~port_config_mask;
|
||||
csi_control |= (portconfigs[i].code << MRFLD_PORT_CONFIGCODE_SHIFT)
|
||||
| (portconfigs[i].lanes[0] ? 0 : (1 << MRFLD_PORT1_ENABLE_SHIFT))
|
||||
|
@ -1013,7 +1000,7 @@ int atomisp_csi_lane_config(struct atomisp_device *isp)
|
|||
| (((1 << portconfigs[i].lanes[1]) - 1) << MRFLD_PORT2_LANES_SHIFT)
|
||||
| (((1 << portconfigs[i].lanes[2]) - 1) << port3_lanes_shift);
|
||||
|
||||
pci_write_config_dword(isp->pdev, MRFLD_PCI_CSI_CONTROL, csi_control);
|
||||
pci_write_config_dword(pdev, MRFLD_PCI_CSI_CONTROL, csi_control);
|
||||
|
||||
dev_dbg(isp->dev,
|
||||
"%s: the portconfig is %d-%d-%d, CSI_CONTROL is 0x%08X\n",
|
||||
|
@ -1440,8 +1427,7 @@ atomisp_load_firmware(struct atomisp_device *isp)
|
|||
* Check for flags the driver was compiled with against the PCI
|
||||
* device. Always returns true on other than ISP 2400.
|
||||
*/
|
||||
static bool is_valid_device(struct pci_dev *dev,
|
||||
const struct pci_device_id *id)
|
||||
static bool is_valid_device(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
unsigned int a0_max_id = 0;
|
||||
const char *name;
|
||||
|
@ -1465,14 +1451,14 @@ static bool is_valid_device(struct pci_dev *dev,
|
|||
name = "Cherrytrail";
|
||||
break;
|
||||
default:
|
||||
dev_err(&dev->dev, "%s: unknown device ID %x04:%x04\n",
|
||||
dev_err(&pdev->dev, "%s: unknown device ID %x04:%x04\n",
|
||||
product, id->vendor, id->device);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dev->revision <= ATOMISP_PCI_REV_BYT_A0_MAX) {
|
||||
dev_err(&dev->dev, "%s revision %d is not unsupported\n",
|
||||
name, dev->revision);
|
||||
if (pdev->revision <= ATOMISP_PCI_REV_BYT_A0_MAX) {
|
||||
dev_err(&pdev->dev, "%s revision %d is not unsupported\n",
|
||||
name, pdev->revision);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1483,22 +1469,20 @@ static bool is_valid_device(struct pci_dev *dev,
|
|||
|
||||
#if defined(ISP2400)
|
||||
if (IS_ISP2401) {
|
||||
dev_err(&dev->dev, "Support for %s (ISP2401) was disabled at compile time\n",
|
||||
dev_err(&pdev->dev, "Support for %s (ISP2401) was disabled at compile time\n",
|
||||
name);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (!IS_ISP2401) {
|
||||
dev_err(&dev->dev, "Support for %s (ISP2400) was disabled at compile time\n",
|
||||
dev_err(&pdev->dev, "Support for %s (ISP2400) was disabled at compile time\n",
|
||||
name);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
dev_info(&dev->dev, "Detected %s version %d (ISP240%c) on %s\n",
|
||||
name, dev->revision,
|
||||
IS_ISP2401 ? '1' : '0',
|
||||
product);
|
||||
dev_info(&pdev->dev, "Detected %s version %d (ISP240%c) on %s\n",
|
||||
name, pdev->revision, IS_ISP2401 ? '1' : '0', product);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1538,66 +1522,60 @@ static int init_atomisp_wdts(struct atomisp_device *isp)
|
|||
|
||||
#define ATOM_ISP_PCI_BAR 0
|
||||
|
||||
static int atomisp_pci_probe(struct pci_dev *dev,
|
||||
const struct pci_device_id *id)
|
||||
static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
const struct atomisp_platform_data *pdata;
|
||||
struct atomisp_device *isp;
|
||||
unsigned int start;
|
||||
void __iomem *base;
|
||||
int err, val;
|
||||
u32 irq;
|
||||
|
||||
if (!is_valid_device(dev, id))
|
||||
if (!is_valid_device(pdev, id))
|
||||
return -ENODEV;
|
||||
|
||||
/* Pointer to struct device. */
|
||||
atomisp_dev = &dev->dev;
|
||||
atomisp_dev = &pdev->dev;
|
||||
|
||||
pdata = atomisp_get_platform_data();
|
||||
if (!pdata)
|
||||
dev_warn(&dev->dev, "no platform data available\n");
|
||||
dev_warn(&pdev->dev, "no platform data available\n");
|
||||
|
||||
err = pcim_enable_device(dev);
|
||||
err = pcim_enable_device(pdev);
|
||||
if (err) {
|
||||
dev_err(&dev->dev, "Failed to enable CI ISP device (%d)\n",
|
||||
err);
|
||||
dev_err(&pdev->dev, "Failed to enable CI ISP device (%d)\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
start = pci_resource_start(dev, ATOM_ISP_PCI_BAR);
|
||||
dev_dbg(&dev->dev, "start: 0x%x\n", start);
|
||||
start = pci_resource_start(pdev, ATOM_ISP_PCI_BAR);
|
||||
dev_dbg(&pdev->dev, "start: 0x%x\n", start);
|
||||
|
||||
err = pcim_iomap_regions(dev, 1 << ATOM_ISP_PCI_BAR, pci_name(dev));
|
||||
err = pcim_iomap_regions(pdev, 1 << ATOM_ISP_PCI_BAR, pci_name(pdev));
|
||||
if (err) {
|
||||
dev_err(&dev->dev, "Failed to I/O memory remapping (%d)\n",
|
||||
err);
|
||||
dev_err(&pdev->dev, "Failed to I/O memory remapping (%d)\n", err);
|
||||
goto ioremap_fail;
|
||||
}
|
||||
|
||||
base = pcim_iomap_table(dev)[ATOM_ISP_PCI_BAR];
|
||||
dev_dbg(&dev->dev, "base: %p\n", base);
|
||||
|
||||
atomisp_io_base = base;
|
||||
|
||||
dev_dbg(&dev->dev, "atomisp_io_base: %p\n", atomisp_io_base);
|
||||
|
||||
isp = devm_kzalloc(&dev->dev, sizeof(struct atomisp_device), GFP_KERNEL);
|
||||
isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL);
|
||||
if (!isp) {
|
||||
err = -ENOMEM;
|
||||
goto atomisp_dev_alloc_fail;
|
||||
}
|
||||
isp->pdev = dev;
|
||||
isp->dev = &dev->dev;
|
||||
|
||||
isp->dev = &pdev->dev;
|
||||
isp->base = pcim_iomap_table(pdev)[ATOM_ISP_PCI_BAR];
|
||||
isp->sw_contex.power_state = ATOM_ISP_POWER_UP;
|
||||
isp->saved_regs.ispmmadr = start;
|
||||
|
||||
dev_dbg(&pdev->dev, "atomisp mmio base: %p\n", isp->base);
|
||||
|
||||
rt_mutex_init(&isp->mutex);
|
||||
mutex_init(&isp->streamoff_mutex);
|
||||
spin_lock_init(&isp->lock);
|
||||
|
||||
/* This is not a true PCI device on SoC, so the delay is not needed. */
|
||||
isp->pdev->d3_delay = 0;
|
||||
pdev->d3_delay = 0;
|
||||
|
||||
pci_set_drvdata(pdev, isp);
|
||||
|
||||
switch (id->device & ATOMISP_PCI_DEVICE_SOC_MASK) {
|
||||
case ATOMISP_PCI_DEVICE_SOC_MRFLD:
|
||||
|
@ -1648,15 +1626,14 @@ static int atomisp_pci_probe(struct pci_dev *dev,
|
|||
* have specs yet for exactly how it varies. Default to
|
||||
* BYT-CR but let provisioning set it via EFI variable
|
||||
*/
|
||||
isp->hpll_freq = gmin_get_var_int(&dev->dev, false, "HpllFreq",
|
||||
HPLL_FREQ_2000MHZ);
|
||||
isp->hpll_freq = gmin_get_var_int(&pdev->dev, false, "HpllFreq", HPLL_FREQ_2000MHZ);
|
||||
|
||||
/*
|
||||
* for BYT/CHT we are put isp into D3cold to avoid pci registers access
|
||||
* in power off. Set d3cold_delay to 0 since default 100ms is not
|
||||
* necessary.
|
||||
*/
|
||||
isp->pdev->d3cold_delay = 0;
|
||||
pdev->d3cold_delay = 0;
|
||||
break;
|
||||
case ATOMISP_PCI_DEVICE_SOC_ANN:
|
||||
isp->media_dev.hw_revision = (
|
||||
|
@ -1666,7 +1643,7 @@ static int atomisp_pci_probe(struct pci_dev *dev,
|
|||
ATOMISP_HW_REVISION_ISP2401_LEGACY
|
||||
#endif
|
||||
<< ATOMISP_HW_REVISION_SHIFT);
|
||||
isp->media_dev.hw_revision |= isp->pdev->revision < 2 ?
|
||||
isp->media_dev.hw_revision |= pdev->revision < 2 ?
|
||||
ATOMISP_HW_STEPPING_A0 : ATOMISP_HW_STEPPING_B0;
|
||||
isp->dfs = &dfs_config_merr;
|
||||
isp->hpll_freq = HPLL_FREQ_1600MHZ;
|
||||
|
@ -1679,13 +1656,13 @@ static int atomisp_pci_probe(struct pci_dev *dev,
|
|||
ATOMISP_HW_REVISION_ISP2401_LEGACY
|
||||
#endif
|
||||
<< ATOMISP_HW_REVISION_SHIFT);
|
||||
isp->media_dev.hw_revision |= isp->pdev->revision < 2 ?
|
||||
isp->media_dev.hw_revision |= pdev->revision < 2 ?
|
||||
ATOMISP_HW_STEPPING_A0 : ATOMISP_HW_STEPPING_B0;
|
||||
|
||||
isp->dfs = &dfs_config_cht;
|
||||
isp->pdev->d3cold_delay = 0;
|
||||
pdev->d3cold_delay = 0;
|
||||
|
||||
iosf_mbi_read(CCK_PORT, MBI_REG_READ, CCK_FUSE_REG_0, &val);
|
||||
iosf_mbi_read(BT_MBI_UNIT_CCK, MBI_REG_READ, CCK_FUSE_REG_0, &val);
|
||||
switch (val & CCK_FUSE_HPLL_FREQ_MASK) {
|
||||
case 0x00:
|
||||
isp->hpll_freq = HPLL_FREQ_800MHZ;
|
||||
|
@ -1698,18 +1675,16 @@ static int atomisp_pci_probe(struct pci_dev *dev,
|
|||
break;
|
||||
default:
|
||||
isp->hpll_freq = HPLL_FREQ_1600MHZ;
|
||||
dev_warn(isp->dev,
|
||||
"read HPLL from cck failed. Default to 1600 MHz.\n");
|
||||
dev_warn(&pdev->dev, "read HPLL from cck failed. Default to 1600 MHz.\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_err(&dev->dev, "un-supported IUNIT device\n");
|
||||
dev_err(&pdev->dev, "un-supported IUNIT device\n");
|
||||
err = -ENODEV;
|
||||
goto atomisp_dev_alloc_fail;
|
||||
}
|
||||
|
||||
dev_info(&dev->dev, "ISP HPLL frequency base = %d MHz\n",
|
||||
isp->hpll_freq);
|
||||
dev_info(&pdev->dev, "ISP HPLL frequency base = %d MHz\n", isp->hpll_freq);
|
||||
|
||||
isp->max_isr_latency = ATOMISP_MAX_ISR_LATENCY;
|
||||
|
||||
|
@ -1718,30 +1693,28 @@ static int atomisp_pci_probe(struct pci_dev *dev,
|
|||
isp->firmware = atomisp_load_firmware(isp);
|
||||
if (!isp->firmware) {
|
||||
err = -ENOENT;
|
||||
dev_dbg(&dev->dev, "Firmware load failed\n");
|
||||
dev_dbg(&pdev->dev, "Firmware load failed\n");
|
||||
goto load_fw_fail;
|
||||
}
|
||||
|
||||
err = sh_css_check_firmware_version(isp->dev,
|
||||
isp->firmware->data);
|
||||
err = sh_css_check_firmware_version(isp->dev, isp->firmware->data);
|
||||
if (err) {
|
||||
dev_dbg(&dev->dev, "Firmware version check failed\n");
|
||||
dev_dbg(&pdev->dev, "Firmware version check failed\n");
|
||||
goto fw_validation_fail;
|
||||
}
|
||||
} else {
|
||||
dev_info(&dev->dev, "Firmware load will be deferred\n");
|
||||
dev_info(&pdev->dev, "Firmware load will be deferred\n");
|
||||
}
|
||||
|
||||
pci_set_master(dev);
|
||||
pci_set_drvdata(dev, isp);
|
||||
pci_set_master(pdev);
|
||||
|
||||
err = pci_enable_msi(dev);
|
||||
err = pci_enable_msi(pdev);
|
||||
if (err) {
|
||||
dev_err(&dev->dev, "Failed to enable msi (%d)\n", err);
|
||||
dev_err(&pdev->dev, "Failed to enable msi (%d)\n", err);
|
||||
goto enable_msi_fail;
|
||||
}
|
||||
|
||||
atomisp_msi_irq_init(isp, dev);
|
||||
atomisp_msi_irq_init(isp);
|
||||
|
||||
cpu_latency_qos_add_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE);
|
||||
|
||||
|
@ -1762,8 +1735,7 @@ static int atomisp_pci_probe(struct pci_dev *dev,
|
|||
* Workaround for imbalance data eye issue which is observed
|
||||
* on TNG B0.
|
||||
*/
|
||||
pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL,
|
||||
&csi_afe_trim);
|
||||
pci_read_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, &csi_afe_trim);
|
||||
csi_afe_trim &= ~((MRFLD_PCI_CSI_HSRXCLKTRIM_MASK <<
|
||||
MRFLD_PCI_CSI1_HSRXCLKTRIM_SHIFT) |
|
||||
(MRFLD_PCI_CSI_HSRXCLKTRIM_MASK <<
|
||||
|
@ -1776,20 +1748,18 @@ static int atomisp_pci_probe(struct pci_dev *dev,
|
|||
MRFLD_PCI_CSI2_HSRXCLKTRIM_SHIFT) |
|
||||
(MRFLD_PCI_CSI3_HSRXCLKTRIM <<
|
||||
MRFLD_PCI_CSI3_HSRXCLKTRIM_SHIFT);
|
||||
pci_write_config_dword(dev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL,
|
||||
csi_afe_trim);
|
||||
pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, csi_afe_trim);
|
||||
}
|
||||
|
||||
err = atomisp_initialize_modules(isp);
|
||||
if (err < 0) {
|
||||
dev_err(&dev->dev, "atomisp_initialize_modules (%d)\n", err);
|
||||
dev_err(&pdev->dev, "atomisp_initialize_modules (%d)\n", err);
|
||||
goto initialize_modules_fail;
|
||||
}
|
||||
|
||||
err = atomisp_register_entities(isp);
|
||||
if (err < 0) {
|
||||
dev_err(&dev->dev, "atomisp_register_entities failed (%d)\n",
|
||||
err);
|
||||
dev_err(&pdev->dev, "atomisp_register_entities failed (%d)\n", err);
|
||||
goto register_entities_fail;
|
||||
}
|
||||
err = atomisp_create_pads_links(isp);
|
||||
|
@ -1802,24 +1772,24 @@ static int atomisp_pci_probe(struct pci_dev *dev,
|
|||
/* save the iunit context only once after all the values are init'ed. */
|
||||
atomisp_save_iunit_reg(isp);
|
||||
|
||||
pm_runtime_put_noidle(&dev->dev);
|
||||
pm_runtime_allow(&dev->dev);
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
pm_runtime_allow(&pdev->dev);
|
||||
|
||||
hmm_init_mem_stat(repool_pgnr, dypool_enable, dypool_pgnr);
|
||||
err = hmm_pool_register(repool_pgnr, HMM_POOL_TYPE_RESERVED);
|
||||
if (err) {
|
||||
dev_err(&dev->dev, "Failed to register reserved memory pool.\n");
|
||||
dev_err(&pdev->dev, "Failed to register reserved memory pool.\n");
|
||||
goto hmm_pool_fail;
|
||||
}
|
||||
|
||||
/* Init ISP memory management */
|
||||
hmm_init();
|
||||
|
||||
err = devm_request_threaded_irq(&dev->dev, dev->irq,
|
||||
err = devm_request_threaded_irq(&pdev->dev, pdev->irq,
|
||||
atomisp_isr, atomisp_isr_thread,
|
||||
IRQF_SHARED, "isp_irq", isp);
|
||||
if (err) {
|
||||
dev_err(&dev->dev, "Failed to request irq (%d)\n", err);
|
||||
dev_err(&pdev->dev, "Failed to request irq (%d)\n", err);
|
||||
goto request_irq_fail;
|
||||
}
|
||||
|
||||
|
@ -1827,23 +1797,23 @@ static int atomisp_pci_probe(struct pci_dev *dev,
|
|||
if (!defer_fw_load) {
|
||||
err = atomisp_css_load_firmware(isp);
|
||||
if (err) {
|
||||
dev_err(&dev->dev, "Failed to init css.\n");
|
||||
dev_err(&pdev->dev, "Failed to init css.\n");
|
||||
goto css_init_fail;
|
||||
}
|
||||
} else {
|
||||
dev_dbg(&dev->dev, "Skip css init.\n");
|
||||
dev_dbg(&pdev->dev, "Skip css init.\n");
|
||||
}
|
||||
/* Clear FW image from memory */
|
||||
release_firmware(isp->firmware);
|
||||
isp->firmware = NULL;
|
||||
isp->css_env.isp_css_fw.data = NULL;
|
||||
|
||||
atomisp_drvfs_init(&dev->driver->driver, isp);
|
||||
atomisp_drvfs_init(isp);
|
||||
|
||||
return 0;
|
||||
|
||||
css_init_fail:
|
||||
devm_free_irq(&dev->dev, dev->irq, isp);
|
||||
devm_free_irq(&pdev->dev, pdev->irq, isp);
|
||||
request_irq_fail:
|
||||
hmm_cleanup();
|
||||
hmm_pool_unregister(HMM_POOL_TYPE_RESERVED);
|
||||
|
@ -1856,8 +1826,8 @@ static int atomisp_pci_probe(struct pci_dev *dev,
|
|||
atomisp_uninitialize_modules(isp);
|
||||
initialize_modules_fail:
|
||||
cpu_latency_qos_remove_request(&isp->pm_qos);
|
||||
atomisp_msi_irq_uninit(isp, dev);
|
||||
pci_disable_msi(dev);
|
||||
atomisp_msi_irq_uninit(isp);
|
||||
pci_disable_msi(pdev);
|
||||
enable_msi_fail:
|
||||
fw_validation_fail:
|
||||
release_firmware(isp->firmware);
|
||||
|
@ -1869,35 +1839,34 @@ static int atomisp_pci_probe(struct pci_dev *dev,
|
|||
* The following lines have been copied from atomisp suspend path
|
||||
*/
|
||||
|
||||
pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq);
|
||||
pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq);
|
||||
irq = irq & 1 << INTR_IIR;
|
||||
pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, irq);
|
||||
pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq);
|
||||
|
||||
pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq);
|
||||
pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq);
|
||||
irq &= ~(1 << INTR_IER);
|
||||
pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, irq);
|
||||
pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq);
|
||||
|
||||
atomisp_msi_irq_uninit(isp, dev);
|
||||
atomisp_msi_irq_uninit(isp);
|
||||
|
||||
atomisp_ospm_dphy_down(isp);
|
||||
|
||||
/* Address later when we worry about the ...field chips */
|
||||
if (IS_ENABLED(CONFIG_PM) && atomisp_mrfld_power_down(isp))
|
||||
dev_err(&dev->dev, "Failed to switch off ISP\n");
|
||||
dev_err(&pdev->dev, "Failed to switch off ISP\n");
|
||||
|
||||
atomisp_dev_alloc_fail:
|
||||
pcim_iounmap_regions(dev, 1 << ATOM_ISP_PCI_BAR);
|
||||
pcim_iounmap_regions(pdev, 1 << ATOM_ISP_PCI_BAR);
|
||||
|
||||
ioremap_fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void atomisp_pci_remove(struct pci_dev *dev)
|
||||
static void atomisp_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct atomisp_device *isp = (struct atomisp_device *)
|
||||
pci_get_drvdata(dev);
|
||||
struct atomisp_device *isp = pci_get_drvdata(pdev);
|
||||
|
||||
dev_info(&dev->dev, "Removing atomisp driver\n");
|
||||
dev_info(&pdev->dev, "Removing atomisp driver\n");
|
||||
|
||||
atomisp_drvfs_exit();
|
||||
|
||||
|
@ -1906,11 +1875,11 @@ static void atomisp_pci_remove(struct pci_dev *dev)
|
|||
ia_css_unload_firmware();
|
||||
hmm_cleanup();
|
||||
|
||||
pm_runtime_forbid(&dev->dev);
|
||||
pm_runtime_get_noresume(&dev->dev);
|
||||
pm_runtime_forbid(&pdev->dev);
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
cpu_latency_qos_remove_request(&isp->pm_qos);
|
||||
|
||||
atomisp_msi_irq_uninit(isp, dev);
|
||||
atomisp_msi_irq_uninit(isp);
|
||||
atomisp_unregister_entities(isp);
|
||||
|
||||
destroy_workqueue(isp->wdt_work_queue);
|
||||
|
|
|
@ -48,7 +48,7 @@ static struct ia_css_refcount_entry *refcount_find_entry(ia_css_ptr ptr,
|
|||
return NULL;
|
||||
if (!myrefcount.items) {
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
|
||||
"refcount_find_entry(): Ref count not initialized!\n");
|
||||
"%s(): Ref count not initialized!\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -73,12 +73,12 @@ int ia_css_refcount_init(uint32_t size)
|
|||
|
||||
if (size == 0) {
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
|
||||
"ia_css_refcount_init(): Size of 0 for Ref count init!\n");
|
||||
"%s(): Size of 0 for Ref count init!\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (myrefcount.items) {
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
|
||||
"ia_css_refcount_init(): Ref count is already initialized\n");
|
||||
"%s(): Ref count is already initialized\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
myrefcount.items =
|
||||
|
@ -99,7 +99,7 @@ void ia_css_refcount_uninit(void)
|
|||
u32 i;
|
||||
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
|
||||
"ia_css_refcount_uninit() entry\n");
|
||||
"%s() entry\n", __func__);
|
||||
for (i = 0; i < myrefcount.size; i++) {
|
||||
/* driver verifier tool has issues with &arr[i]
|
||||
and prefers arr + i; as these are actually equivalent
|
||||
|
@ -120,7 +120,7 @@ void ia_css_refcount_uninit(void)
|
|||
myrefcount.items = NULL;
|
||||
myrefcount.size = 0;
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
|
||||
"ia_css_refcount_uninit() leave\n");
|
||||
"%s() leave\n", __func__);
|
||||
}
|
||||
|
||||
ia_css_ptr ia_css_refcount_increment(s32 id, ia_css_ptr ptr)
|
||||
|
@ -133,7 +133,7 @@ ia_css_ptr ia_css_refcount_increment(s32 id, ia_css_ptr ptr)
|
|||
entry = refcount_find_entry(ptr, false);
|
||||
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
|
||||
"ia_css_refcount_increment(%x) 0x%x\n", id, ptr);
|
||||
"%s(%x) 0x%x\n", __func__, id, ptr);
|
||||
|
||||
if (!entry) {
|
||||
entry = refcount_find_entry(ptr, true);
|
||||
|
@ -145,7 +145,7 @@ ia_css_ptr ia_css_refcount_increment(s32 id, ia_css_ptr ptr)
|
|||
|
||||
if (entry->id != id) {
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
|
||||
"ia_css_refcount_increment(): Ref count IDS do not match!\n");
|
||||
"%s(): Ref count IDS do not match!\n", __func__);
|
||||
return mmgr_NULL;
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ bool ia_css_refcount_decrement(s32 id, ia_css_ptr ptr)
|
|||
struct ia_css_refcount_entry *entry;
|
||||
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
|
||||
"ia_css_refcount_decrement(%x) 0x%x\n", id, ptr);
|
||||
"%s(%x) 0x%x\n", __func__, id, ptr);
|
||||
|
||||
if (ptr == mmgr_NULL)
|
||||
return false;
|
||||
|
@ -175,7 +175,7 @@ bool ia_css_refcount_decrement(s32 id, ia_css_ptr ptr)
|
|||
if (entry) {
|
||||
if (entry->id != id) {
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
|
||||
"ia_css_refcount_decrement(): Ref count IDS do not match!\n");
|
||||
"%s(): Ref count IDS do not match!\n", __func__);
|
||||
return false;
|
||||
}
|
||||
if (entry->count > 0) {
|
||||
|
@ -225,8 +225,8 @@ void ia_css_refcount_clear(s32 id, clear_func clear_func_ptr)
|
|||
u32 count = 0;
|
||||
|
||||
assert(clear_func_ptr);
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_refcount_clear(%x)\n",
|
||||
id);
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%s(%x)\n",
|
||||
__func__, id);
|
||||
|
||||
for (i = 0; i < myrefcount.size; i++) {
|
||||
/* driver verifier tool has issues with &arr[i]
|
||||
|
@ -236,14 +236,14 @@ void ia_css_refcount_clear(s32 id, clear_func clear_func_ptr)
|
|||
entry = myrefcount.items + i;
|
||||
if ((entry->data != mmgr_NULL) && (entry->id == id)) {
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
|
||||
"ia_css_refcount_clear: %x: 0x%x\n",
|
||||
"%s: %x: 0x%x\n", __func__,
|
||||
id, entry->data);
|
||||
if (clear_func_ptr) {
|
||||
/* clear using provided function */
|
||||
clear_func_ptr(entry->data);
|
||||
} else {
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
|
||||
"ia_css_refcount_clear: using hmm_free: no clear_func\n");
|
||||
"%s: using hmm_free: no clear_func\n", __func__);
|
||||
hmm_free(entry->data);
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ void ia_css_refcount_clear(s32 id, clear_func clear_func_ptr)
|
|||
}
|
||||
}
|
||||
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
|
||||
"ia_css_refcount_clear(%x): cleared %d\n", id,
|
||||
"%s(%x): cleared %d\n", __func__, id,
|
||||
count);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,32 +52,14 @@ typedef unsigned short hive_uint16;
|
|||
typedef unsigned int hive_uint32;
|
||||
typedef unsigned long long hive_uint64;
|
||||
|
||||
/* by default assume 32 bit master port (both data and address) */
|
||||
#ifndef HRT_DATA_WIDTH
|
||||
#define HRT_DATA_WIDTH 32
|
||||
#endif
|
||||
#ifndef HRT_ADDRESS_WIDTH
|
||||
#define HRT_ADDRESS_WIDTH 32
|
||||
#endif
|
||||
|
||||
#define HRT_DATA_WIDTH 32
|
||||
#define HRT_ADDRESS_WIDTH 64
|
||||
#define HRT_DATA_BYTES (HRT_DATA_WIDTH / 8)
|
||||
#define HRT_ADDRESS_BYTES (HRT_ADDRESS_WIDTH / 8)
|
||||
#define SIZEOF_HRT_REG (HRT_DATA_WIDTH >> 3)
|
||||
|
||||
#if HRT_DATA_WIDTH == 64
|
||||
typedef hive_uint64 hrt_data;
|
||||
#elif HRT_DATA_WIDTH == 32
|
||||
typedef hive_uint32 hrt_data;
|
||||
#else
|
||||
#error data width not supported
|
||||
#endif
|
||||
|
||||
#if HRT_ADDRESS_WIDTH == 64
|
||||
typedef hive_uint64 hrt_address;
|
||||
#elif HRT_ADDRESS_WIDTH == 32
|
||||
typedef hive_uint32 hrt_address;
|
||||
#else
|
||||
#error adddres width not supported
|
||||
#endif
|
||||
|
||||
/* use 64 bit addresses in simulation, where possible */
|
||||
typedef hive_uint64 hive_sim_address;
|
||||
|
|
|
@ -735,11 +735,11 @@ ia_css_ptr hmm_host_vaddr_to_hrt_vaddr(const void *ptr)
|
|||
|
||||
void hmm_show_mem_stat(const char *func, const int line)
|
||||
{
|
||||
trace_printk("tol_cnt=%d usr_size=%d res_size=%d res_cnt=%d sys_size=%d dyc_thr=%d dyc_size=%d.\n",
|
||||
hmm_mem_stat.tol_cnt,
|
||||
hmm_mem_stat.usr_size, hmm_mem_stat.res_size,
|
||||
hmm_mem_stat.res_cnt, hmm_mem_stat.sys_size,
|
||||
hmm_mem_stat.dyc_thr, hmm_mem_stat.dyc_size);
|
||||
pr_info("tol_cnt=%d usr_size=%d res_size=%d res_cnt=%d sys_size=%d dyc_thr=%d dyc_size=%d.\n",
|
||||
hmm_mem_stat.tol_cnt,
|
||||
hmm_mem_stat.usr_size, hmm_mem_stat.res_size,
|
||||
hmm_mem_stat.res_cnt, hmm_mem_stat.sys_size,
|
||||
hmm_mem_stat.dyc_thr, hmm_mem_stat.dyc_size);
|
||||
}
|
||||
|
||||
void hmm_init_mem_stat(int res_pgnr, int dyc_en, int dyc_pgnr)
|
||||
|
|
|
@ -13,306 +13,4 @@
|
|||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef __SYSTEM_GLOBAL_H_INCLUDED__
|
||||
#define __SYSTEM_GLOBAL_H_INCLUDED__
|
||||
|
||||
#include <hive_isp_css_defs.h>
|
||||
#include <type_support.h>
|
||||
|
||||
/*
|
||||
* The longest allowed (uninteruptible) bus transfer, does not
|
||||
* take stalling into account
|
||||
*/
|
||||
#define HIVE_ISP_MAX_BURST_LENGTH 1024
|
||||
|
||||
/*
|
||||
* Maximum allowed burst length in words for the ISP DMA
|
||||
*/
|
||||
#define ISP_DMA_MAX_BURST_LENGTH 128
|
||||
|
||||
/*
|
||||
* Create a list of HAS and IS properties that defines the system
|
||||
*
|
||||
* The configuration assumes the following
|
||||
* - The system is hetereogeneous; Multiple cells and devices classes
|
||||
* - The cell and device instances are homogeneous, each device type
|
||||
* belongs to the same class
|
||||
* - Device instances supporting a subset of the class capabilities are
|
||||
* allowed
|
||||
*
|
||||
* We could manage different device classes through the enumerated
|
||||
* lists (C) or the use of classes (C++), but that is presently not
|
||||
* fully supported
|
||||
*
|
||||
* N.B. the 3 input formatters are of 2 different classess
|
||||
*/
|
||||
|
||||
#define USE_INPUT_SYSTEM_VERSION_2
|
||||
|
||||
#define HAS_MMU_VERSION_2
|
||||
#define HAS_DMA_VERSION_2
|
||||
#define HAS_GDC_VERSION_2
|
||||
#define HAS_VAMEM_VERSION_2
|
||||
#define HAS_HMEM_VERSION_1
|
||||
#define HAS_BAMEM_VERSION_2
|
||||
#define HAS_IRQ_VERSION_2
|
||||
#define HAS_IRQ_MAP_VERSION_2
|
||||
#define HAS_INPUT_FORMATTER_VERSION_2
|
||||
/* 2401: HAS_INPUT_SYSTEM_VERSION_2401 */
|
||||
#define HAS_INPUT_SYSTEM_VERSION_2
|
||||
#define HAS_BUFFERED_SENSOR
|
||||
#define HAS_FIFO_MONITORS_VERSION_2
|
||||
/* #define HAS_GP_REGS_VERSION_2 */
|
||||
#define HAS_GP_DEVICE_VERSION_2
|
||||
#define HAS_GPIO_VERSION_1
|
||||
#define HAS_TIMED_CTRL_VERSION_1
|
||||
#define HAS_RX_VERSION_2
|
||||
|
||||
#define DMA_DDR_TO_VAMEM_WORKAROUND
|
||||
#define DMA_DDR_TO_HMEM_WORKAROUND
|
||||
|
||||
/*
|
||||
* Semi global. "HRT" is accessible from SP, but the HRT types do not fully apply
|
||||
*/
|
||||
#define HRT_VADDRESS_WIDTH 32
|
||||
//#define HRT_ADDRESS_WIDTH 64 /* Surprise, this is a local property*/
|
||||
#define HRT_DATA_WIDTH 32
|
||||
|
||||
#define SIZEOF_HRT_REG (HRT_DATA_WIDTH >> 3)
|
||||
#define HIVE_ISP_CTRL_DATA_BYTES (HIVE_ISP_CTRL_DATA_WIDTH / 8)
|
||||
|
||||
/* The main bus connecting all devices */
|
||||
#define HRT_BUS_WIDTH HIVE_ISP_CTRL_DATA_WIDTH
|
||||
#define HRT_BUS_BYTES HIVE_ISP_CTRL_DATA_BYTES
|
||||
|
||||
/* per-frame parameter handling support */
|
||||
#define SH_CSS_ENABLE_PER_FRAME_PARAMS
|
||||
|
||||
typedef u32 hrt_bus_align_t;
|
||||
|
||||
/*
|
||||
* Enumerate the devices, device access through the API is by ID, through the DLI by address
|
||||
* The enumerator terminators are used to size the wiring arrays and as an exception value.
|
||||
*/
|
||||
typedef enum {
|
||||
DDR0_ID = 0,
|
||||
N_DDR_ID
|
||||
} ddr_ID_t;
|
||||
|
||||
typedef enum {
|
||||
ISP0_ID = 0,
|
||||
N_ISP_ID
|
||||
} isp_ID_t;
|
||||
|
||||
typedef enum {
|
||||
SP0_ID = 0,
|
||||
N_SP_ID
|
||||
} sp_ID_t;
|
||||
|
||||
typedef enum {
|
||||
MMU0_ID = 0,
|
||||
MMU1_ID,
|
||||
N_MMU_ID
|
||||
} mmu_ID_t;
|
||||
|
||||
typedef enum {
|
||||
DMA0_ID = 0,
|
||||
N_DMA_ID
|
||||
} dma_ID_t;
|
||||
|
||||
typedef enum {
|
||||
GDC0_ID = 0,
|
||||
GDC1_ID,
|
||||
N_GDC_ID
|
||||
} gdc_ID_t;
|
||||
|
||||
#define N_GDC_ID_CPP 2 // this extra define is needed because we want to use it also in the preprocessor, and that doesn't work with enums.
|
||||
|
||||
typedef enum {
|
||||
VAMEM0_ID = 0,
|
||||
VAMEM1_ID,
|
||||
VAMEM2_ID,
|
||||
N_VAMEM_ID
|
||||
} vamem_ID_t;
|
||||
|
||||
typedef enum {
|
||||
BAMEM0_ID = 0,
|
||||
N_BAMEM_ID
|
||||
} bamem_ID_t;
|
||||
|
||||
typedef enum {
|
||||
HMEM0_ID = 0,
|
||||
N_HMEM_ID
|
||||
} hmem_ID_t;
|
||||
|
||||
/*
|
||||
typedef enum {
|
||||
IRQ0_ID = 0,
|
||||
N_IRQ_ID
|
||||
} irq_ID_t;
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
IRQ0_ID = 0, // GP IRQ block
|
||||
IRQ1_ID, // Input formatter
|
||||
IRQ2_ID, // input system
|
||||
IRQ3_ID, // input selector
|
||||
N_IRQ_ID
|
||||
} irq_ID_t;
|
||||
|
||||
typedef enum {
|
||||
FIFO_MONITOR0_ID = 0,
|
||||
N_FIFO_MONITOR_ID
|
||||
} fifo_monitor_ID_t;
|
||||
|
||||
/*
|
||||
* Deprecated: Since all gp_reg instances are different
|
||||
* and put in the address maps of other devices we cannot
|
||||
* enumerate them as that assumes the instrances are the
|
||||
* same.
|
||||
*
|
||||
* We define a single GP_DEVICE containing all gp_regs
|
||||
* w.r.t. a single base address
|
||||
*
|
||||
typedef enum {
|
||||
GP_REGS0_ID = 0,
|
||||
N_GP_REGS_ID
|
||||
} gp_regs_ID_t;
|
||||
*/
|
||||
typedef enum {
|
||||
GP_DEVICE0_ID = 0,
|
||||
N_GP_DEVICE_ID
|
||||
} gp_device_ID_t;
|
||||
|
||||
typedef enum {
|
||||
GP_TIMER0_ID = 0,
|
||||
GP_TIMER1_ID,
|
||||
GP_TIMER2_ID,
|
||||
GP_TIMER3_ID,
|
||||
GP_TIMER4_ID,
|
||||
GP_TIMER5_ID,
|
||||
GP_TIMER6_ID,
|
||||
GP_TIMER7_ID,
|
||||
N_GP_TIMER_ID
|
||||
} gp_timer_ID_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO0_ID = 0,
|
||||
N_GPIO_ID
|
||||
} gpio_ID_t;
|
||||
|
||||
typedef enum {
|
||||
TIMED_CTRL0_ID = 0,
|
||||
N_TIMED_CTRL_ID
|
||||
} timed_ctrl_ID_t;
|
||||
|
||||
typedef enum {
|
||||
INPUT_FORMATTER0_ID = 0,
|
||||
INPUT_FORMATTER1_ID,
|
||||
INPUT_FORMATTER2_ID,
|
||||
INPUT_FORMATTER3_ID,
|
||||
N_INPUT_FORMATTER_ID
|
||||
} input_formatter_ID_t;
|
||||
|
||||
/* The IF RST is outside the IF */
|
||||
#define INPUT_FORMATTER0_SRST_OFFSET 0x0824
|
||||
#define INPUT_FORMATTER1_SRST_OFFSET 0x0624
|
||||
#define INPUT_FORMATTER2_SRST_OFFSET 0x0424
|
||||
#define INPUT_FORMATTER3_SRST_OFFSET 0x0224
|
||||
|
||||
#define INPUT_FORMATTER0_SRST_MASK 0x0001
|
||||
#define INPUT_FORMATTER1_SRST_MASK 0x0002
|
||||
#define INPUT_FORMATTER2_SRST_MASK 0x0004
|
||||
#define INPUT_FORMATTER3_SRST_MASK 0x0008
|
||||
|
||||
typedef enum {
|
||||
INPUT_SYSTEM0_ID = 0,
|
||||
N_INPUT_SYSTEM_ID
|
||||
} input_system_ID_t;
|
||||
|
||||
typedef enum {
|
||||
RX0_ID = 0,
|
||||
N_RX_ID
|
||||
} rx_ID_t;
|
||||
|
||||
enum mipi_port_id {
|
||||
MIPI_PORT0_ID = 0,
|
||||
MIPI_PORT1_ID,
|
||||
MIPI_PORT2_ID,
|
||||
N_MIPI_PORT_ID
|
||||
};
|
||||
|
||||
#define N_RX_CHANNEL_ID 4
|
||||
|
||||
/* Generic port enumeration with an internal port type ID */
|
||||
typedef enum {
|
||||
CSI_PORT0_ID = 0,
|
||||
CSI_PORT1_ID,
|
||||
CSI_PORT2_ID,
|
||||
TPG_PORT0_ID,
|
||||
PRBS_PORT0_ID,
|
||||
FIFO_PORT0_ID,
|
||||
MEMORY_PORT0_ID,
|
||||
N_INPUT_PORT_ID
|
||||
} input_port_ID_t;
|
||||
|
||||
typedef enum {
|
||||
CAPTURE_UNIT0_ID = 0,
|
||||
CAPTURE_UNIT1_ID,
|
||||
CAPTURE_UNIT2_ID,
|
||||
ACQUISITION_UNIT0_ID,
|
||||
DMA_UNIT0_ID,
|
||||
CTRL_UNIT0_ID,
|
||||
GPREGS_UNIT0_ID,
|
||||
FIFO_UNIT0_ID,
|
||||
IRQ_UNIT0_ID,
|
||||
N_SUB_SYSTEM_ID
|
||||
} sub_system_ID_t;
|
||||
|
||||
#define N_CAPTURE_UNIT_ID 3
|
||||
#define N_ACQUISITION_UNIT_ID 1
|
||||
#define N_CTRL_UNIT_ID 1
|
||||
|
||||
enum ia_css_isp_memories {
|
||||
IA_CSS_ISP_PMEM0 = 0,
|
||||
IA_CSS_ISP_DMEM0,
|
||||
IA_CSS_ISP_VMEM0,
|
||||
IA_CSS_ISP_VAMEM0,
|
||||
IA_CSS_ISP_VAMEM1,
|
||||
IA_CSS_ISP_VAMEM2,
|
||||
IA_CSS_ISP_HMEM0,
|
||||
IA_CSS_SP_DMEM0,
|
||||
IA_CSS_DDR,
|
||||
N_IA_CSS_MEMORIES
|
||||
};
|
||||
|
||||
#define IA_CSS_NUM_MEMORIES 9
|
||||
/* For driver compatibility */
|
||||
#define N_IA_CSS_ISP_MEMORIES IA_CSS_NUM_MEMORIES
|
||||
#define IA_CSS_NUM_ISP_MEMORIES IA_CSS_NUM_MEMORIES
|
||||
|
||||
#if 0
|
||||
typedef enum {
|
||||
dev_chn, /* device channels, external resource */
|
||||
ext_mem, /* external memories */
|
||||
int_mem, /* internal memories */
|
||||
int_chn /* internal channels, user defined */
|
||||
} resource_type_t;
|
||||
|
||||
/* if this enum is extended with other memory resources, pls also extend the function resource_to_memptr() */
|
||||
typedef enum {
|
||||
vied_nci_dev_chn_dma_ext0,
|
||||
int_mem_vmem0,
|
||||
int_mem_dmem0
|
||||
} resource_id_t;
|
||||
|
||||
/* enum listing the different memories within a program group.
|
||||
This enum is used in the mem_ptr_t type */
|
||||
typedef enum {
|
||||
buf_mem_invalid = 0,
|
||||
buf_mem_vmem_prog0,
|
||||
buf_mem_dmem_prog0
|
||||
} buf_mem_t;
|
||||
|
||||
#endif
|
||||
#endif /* __SYSTEM_GLOBAL_H_INCLUDED__ */
|
||||
|
|
|
@ -1,321 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Support for Intel Camera Imaging ISP subsystem.
|
||||
* Copyright (c) 2010-2015, Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY 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_LOCAL_H_INCLUDED__
|
||||
#define __SYSTEM_LOCAL_H_INCLUDED__
|
||||
|
||||
#ifdef HRT_ISP_CSS_CUSTOM_HOST
|
||||
#ifndef HRT_USE_VIR_ADDRS
|
||||
#define HRT_USE_VIR_ADDRS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "system_global.h"
|
||||
|
||||
/* HRT assumes 32 by default (see Linux/include/hive_types.h), overrule it in case it is different */
|
||||
#undef HRT_ADDRESS_WIDTH
|
||||
#define HRT_ADDRESS_WIDTH 64 /* Surprise, this is a local property */
|
||||
|
||||
/* This interface is deprecated */
|
||||
#include "hive_types.h"
|
||||
|
||||
/*
|
||||
* Cell specific address maps
|
||||
*/
|
||||
#if HRT_ADDRESS_WIDTH == 64
|
||||
|
||||
#define GP_FIFO_BASE ((hrt_address)0x0000000000090104) /* This is NOT a base address */
|
||||
|
||||
/* DDR */
|
||||
static const hrt_address DDR_BASE[N_DDR_ID] = {
|
||||
(hrt_address)0x0000000120000000ULL
|
||||
};
|
||||
|
||||
/* ISP */
|
||||
static const hrt_address ISP_CTRL_BASE[N_ISP_ID] = {
|
||||
(hrt_address)0x0000000000020000ULL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_DMEM_BASE[N_ISP_ID] = {
|
||||
(hrt_address)0x0000000000200000ULL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID] = {
|
||||
(hrt_address)0x0000000000100000ULL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_VAMEM_BASE[N_VAMEM_ID] = {
|
||||
(hrt_address)0x00000000001C0000ULL,
|
||||
(hrt_address)0x00000000001D0000ULL,
|
||||
(hrt_address)0x00000000001E0000ULL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_HMEM_BASE[N_HMEM_ID] = {
|
||||
(hrt_address)0x00000000001F0000ULL
|
||||
};
|
||||
|
||||
/* SP */
|
||||
static const hrt_address SP_CTRL_BASE[N_SP_ID] = {
|
||||
(hrt_address)0x0000000000010000ULL
|
||||
};
|
||||
|
||||
static const hrt_address SP_DMEM_BASE[N_SP_ID] = {
|
||||
(hrt_address)0x0000000000300000ULL
|
||||
};
|
||||
|
||||
static const hrt_address SP_PMEM_BASE[N_SP_ID] = {
|
||||
(hrt_address)0x00000000000B0000ULL
|
||||
};
|
||||
|
||||
/* MMU */
|
||||
/*
|
||||
* MMU0_ID: The data MMU
|
||||
* MMU1_ID: The icache MMU
|
||||
*/
|
||||
static const hrt_address MMU_BASE[N_MMU_ID] = {
|
||||
(hrt_address)0x0000000000070000ULL,
|
||||
(hrt_address)0x00000000000A0000ULL
|
||||
};
|
||||
|
||||
/* DMA */
|
||||
static const hrt_address DMA_BASE[N_DMA_ID] = {
|
||||
(hrt_address)0x0000000000040000ULL
|
||||
};
|
||||
|
||||
/* IRQ */
|
||||
static const hrt_address IRQ_BASE[N_IRQ_ID] = {
|
||||
(hrt_address)0x0000000000000500ULL,
|
||||
(hrt_address)0x0000000000030A00ULL,
|
||||
(hrt_address)0x000000000008C000ULL,
|
||||
(hrt_address)0x0000000000090200ULL
|
||||
};
|
||||
|
||||
/*
|
||||
(hrt_address)0x0000000000000500ULL};
|
||||
*/
|
||||
|
||||
/* GDC */
|
||||
static const hrt_address GDC_BASE[N_GDC_ID] = {
|
||||
(hrt_address)0x0000000000050000ULL,
|
||||
(hrt_address)0x0000000000060000ULL
|
||||
};
|
||||
|
||||
/* FIFO_MONITOR (not a subset of GP_DEVICE) */
|
||||
static const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID] = {
|
||||
(hrt_address)0x0000000000000000ULL
|
||||
};
|
||||
|
||||
/*
|
||||
static const hrt_address GP_REGS_BASE[N_GP_REGS_ID] = {
|
||||
(hrt_address)0x0000000000000000ULL};
|
||||
|
||||
static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = {
|
||||
(hrt_address)0x0000000000090000ULL};
|
||||
*/
|
||||
|
||||
/* GP_DEVICE (single base for all separate GP_REG instances) */
|
||||
static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = {
|
||||
(hrt_address)0x0000000000000000ULL
|
||||
};
|
||||
|
||||
/*GP TIMER , all timer registers are inter-twined,
|
||||
* so, having multiple base addresses for
|
||||
* different timers does not help*/
|
||||
static const hrt_address GP_TIMER_BASE =
|
||||
(hrt_address)0x0000000000000600ULL;
|
||||
/* GPIO */
|
||||
static const hrt_address GPIO_BASE[N_GPIO_ID] = {
|
||||
(hrt_address)0x0000000000000400ULL
|
||||
};
|
||||
|
||||
/* TIMED_CTRL */
|
||||
static const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID] = {
|
||||
(hrt_address)0x0000000000000100ULL
|
||||
};
|
||||
|
||||
/* INPUT_FORMATTER */
|
||||
static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = {
|
||||
(hrt_address)0x0000000000030000ULL,
|
||||
(hrt_address)0x0000000000030200ULL,
|
||||
(hrt_address)0x0000000000030400ULL,
|
||||
(hrt_address)0x0000000000030600ULL
|
||||
}; /* memcpy() */
|
||||
|
||||
/* INPUT_SYSTEM */
|
||||
static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = {
|
||||
(hrt_address)0x0000000000080000ULL
|
||||
};
|
||||
|
||||
/* (hrt_address)0x0000000000081000ULL, */ /* capture A */
|
||||
/* (hrt_address)0x0000000000082000ULL, */ /* capture B */
|
||||
/* (hrt_address)0x0000000000083000ULL, */ /* capture C */
|
||||
/* (hrt_address)0x0000000000084000ULL, */ /* Acquisition */
|
||||
/* (hrt_address)0x0000000000085000ULL, */ /* DMA */
|
||||
/* (hrt_address)0x0000000000089000ULL, */ /* ctrl */
|
||||
/* (hrt_address)0x000000000008A000ULL, */ /* GP regs */
|
||||
/* (hrt_address)0x000000000008B000ULL, */ /* FIFO */
|
||||
/* (hrt_address)0x000000000008C000ULL, */ /* IRQ */
|
||||
|
||||
/* RX, the MIPI lane control regs start at offset 0 */
|
||||
static const hrt_address RX_BASE[N_RX_ID] = {
|
||||
(hrt_address)0x0000000000080100ULL
|
||||
};
|
||||
|
||||
#elif HRT_ADDRESS_WIDTH == 32
|
||||
|
||||
#define GP_FIFO_BASE ((hrt_address)0x00090104) /* This is NOT a base address */
|
||||
|
||||
/* DDR : Attention, this value not defined in 32-bit */
|
||||
static const hrt_address DDR_BASE[N_DDR_ID] = {
|
||||
(hrt_address)0x00000000UL
|
||||
};
|
||||
|
||||
/* ISP */
|
||||
static const hrt_address ISP_CTRL_BASE[N_ISP_ID] = {
|
||||
(hrt_address)0x00020000UL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_DMEM_BASE[N_ISP_ID] = {
|
||||
(hrt_address)0x00200000UL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID] = {
|
||||
(hrt_address)0x100000UL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_VAMEM_BASE[N_VAMEM_ID] = {
|
||||
(hrt_address)0xffffffffUL,
|
||||
(hrt_address)0xffffffffUL,
|
||||
(hrt_address)0xffffffffUL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_HMEM_BASE[N_HMEM_ID] = {
|
||||
(hrt_address)0xffffffffUL
|
||||
};
|
||||
|
||||
/* SP */
|
||||
static const hrt_address SP_CTRL_BASE[N_SP_ID] = {
|
||||
(hrt_address)0x00010000UL
|
||||
};
|
||||
|
||||
static const hrt_address SP_DMEM_BASE[N_SP_ID] = {
|
||||
(hrt_address)0x00300000UL
|
||||
};
|
||||
|
||||
static const hrt_address SP_PMEM_BASE[N_SP_ID] = {
|
||||
(hrt_address)0x000B0000UL
|
||||
};
|
||||
|
||||
/* MMU */
|
||||
/*
|
||||
* MMU0_ID: The data MMU
|
||||
* MMU1_ID: The icache MMU
|
||||
*/
|
||||
static const hrt_address MMU_BASE[N_MMU_ID] = {
|
||||
(hrt_address)0x00070000UL,
|
||||
(hrt_address)0x000A0000UL
|
||||
};
|
||||
|
||||
/* DMA */
|
||||
static const hrt_address DMA_BASE[N_DMA_ID] = {
|
||||
(hrt_address)0x00040000UL
|
||||
};
|
||||
|
||||
/* IRQ */
|
||||
static const hrt_address IRQ_BASE[N_IRQ_ID] = {
|
||||
(hrt_address)0x00000500UL,
|
||||
(hrt_address)0x00030A00UL,
|
||||
(hrt_address)0x0008C000UL,
|
||||
(hrt_address)0x00090200UL
|
||||
};
|
||||
|
||||
/*
|
||||
(hrt_address)0x00000500UL};
|
||||
*/
|
||||
|
||||
/* GDC */
|
||||
static const hrt_address GDC_BASE[N_GDC_ID] = {
|
||||
(hrt_address)0x00050000UL,
|
||||
(hrt_address)0x00060000UL
|
||||
};
|
||||
|
||||
/* FIFO_MONITOR (not a subset of GP_DEVICE) */
|
||||
static const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID] = {
|
||||
(hrt_address)0x00000000UL
|
||||
};
|
||||
|
||||
/*
|
||||
static const hrt_address GP_REGS_BASE[N_GP_REGS_ID] = {
|
||||
(hrt_address)0x00000000UL};
|
||||
|
||||
static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = {
|
||||
(hrt_address)0x00090000UL};
|
||||
*/
|
||||
|
||||
/* GP_DEVICE (single base for all separate GP_REG instances) */
|
||||
static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = {
|
||||
(hrt_address)0x00000000UL
|
||||
};
|
||||
|
||||
/*GP TIMER , all timer registers are inter-twined,
|
||||
* so, having multiple base addresses for
|
||||
* different timers does not help*/
|
||||
static const hrt_address GP_TIMER_BASE =
|
||||
(hrt_address)0x00000600UL;
|
||||
|
||||
/* GPIO */
|
||||
static const hrt_address GPIO_BASE[N_GPIO_ID] = {
|
||||
(hrt_address)0x00000400UL
|
||||
};
|
||||
|
||||
/* TIMED_CTRL */
|
||||
static const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID] = {
|
||||
(hrt_address)0x00000100UL
|
||||
};
|
||||
|
||||
/* INPUT_FORMATTER */
|
||||
static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = {
|
||||
(hrt_address)0x00030000UL,
|
||||
(hrt_address)0x00030200UL,
|
||||
(hrt_address)0x00030400UL
|
||||
};
|
||||
|
||||
/* (hrt_address)0x00030600UL, */ /* memcpy() */
|
||||
|
||||
/* INPUT_SYSTEM */
|
||||
static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = {
|
||||
(hrt_address)0x00080000UL
|
||||
};
|
||||
|
||||
/* (hrt_address)0x00081000UL, */ /* capture A */
|
||||
/* (hrt_address)0x00082000UL, */ /* capture B */
|
||||
/* (hrt_address)0x00083000UL, */ /* capture C */
|
||||
/* (hrt_address)0x00084000UL, */ /* Acquisition */
|
||||
/* (hrt_address)0x00085000UL, */ /* DMA */
|
||||
/* (hrt_address)0x00089000UL, */ /* ctrl */
|
||||
/* (hrt_address)0x0008A000UL, */ /* GP regs */
|
||||
/* (hrt_address)0x0008B000UL, */ /* FIFO */
|
||||
/* (hrt_address)0x0008C000UL, */ /* IRQ */
|
||||
|
||||
/* RX, the MIPI lane control regs start at offset 0 */
|
||||
static const hrt_address RX_BASE[N_RX_ID] = {
|
||||
(hrt_address)0x00080100UL
|
||||
};
|
||||
|
||||
#else
|
||||
#error "system_local.h: HRT_ADDRESS_WIDTH must be one of {32,64}"
|
||||
#endif
|
||||
|
||||
#endif /* __SYSTEM_LOCAL_H_INCLUDED__ */
|
|
@ -13,415 +13,7 @@
|
|||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef __SYSTEM_GLOBAL_H_INCLUDED__
|
||||
#define __SYSTEM_GLOBAL_H_INCLUDED__
|
||||
|
||||
#include <hive_isp_css_defs.h>
|
||||
#include <type_support.h>
|
||||
|
||||
/*
|
||||
* The longest allowed (uninteruptible) bus transfer, does not
|
||||
* take stalling into account
|
||||
*/
|
||||
#define HIVE_ISP_MAX_BURST_LENGTH 1024
|
||||
|
||||
/*
|
||||
* Maximum allowed burst length in words for the ISP DMA
|
||||
* This value is set to 2 to prevent the ISP DMA from blocking
|
||||
* the bus for too long; as the input system can only buffer
|
||||
* 2 lines on Moorefield and Cherrytrail, the input system buffers
|
||||
* may overflow if blocked for too long (BZ 2726).
|
||||
*/
|
||||
#define ISP_DMA_MAX_BURST_LENGTH 2
|
||||
|
||||
/*
|
||||
* Create a list of HAS and IS properties that defines the system
|
||||
*
|
||||
* The configuration assumes the following
|
||||
* - The system is hetereogeneous; Multiple cells and devices classes
|
||||
* - The cell and device instances are homogeneous, each device type
|
||||
* belongs to the same class
|
||||
* - Device instances supporting a subset of the class capabilities are
|
||||
* allowed
|
||||
*
|
||||
* We could manage different device classes through the enumerated
|
||||
* lists (C) or the use of classes (C++), but that is presently not
|
||||
* fully supported
|
||||
*
|
||||
* N.B. the 3 input formatters are of 2 different classess
|
||||
*/
|
||||
|
||||
#define USE_INPUT_SYSTEM_VERSION_2401
|
||||
|
||||
#define HAS_MMU_VERSION_2
|
||||
#define HAS_DMA_VERSION_2
|
||||
#define HAS_GDC_VERSION_2
|
||||
#define HAS_VAMEM_VERSION_2
|
||||
#define HAS_HMEM_VERSION_1
|
||||
#define HAS_BAMEM_VERSION_2
|
||||
#define HAS_IRQ_VERSION_2
|
||||
#define HAS_IRQ_MAP_VERSION_2
|
||||
#define HAS_INPUT_FORMATTER_VERSION_2
|
||||
/* 2401: HAS_INPUT_SYSTEM_VERSION_3 */
|
||||
/* 2400: HAS_INPUT_SYSTEM_VERSION_2 */
|
||||
#define HAS_INPUT_SYSTEM_VERSION_2
|
||||
#define HAS_INPUT_SYSTEM_VERSION_2401
|
||||
#define HAS_BUFFERED_SENSOR
|
||||
#define HAS_FIFO_MONITORS_VERSION_2
|
||||
/* #define HAS_GP_REGS_VERSION_2 */
|
||||
#define HAS_GP_DEVICE_VERSION_2
|
||||
#define HAS_GPIO_VERSION_1
|
||||
#define HAS_TIMED_CTRL_VERSION_1
|
||||
#define HAS_RX_VERSION_2
|
||||
#define HAS_NO_INPUT_FORMATTER
|
||||
/*#define HAS_NO_PACKED_RAW_PIXELS*/
|
||||
/*#define HAS_NO_DVS_6AXIS_CONFIG_UPDATE*/
|
||||
|
||||
#define DMA_DDR_TO_VAMEM_WORKAROUND
|
||||
#define DMA_DDR_TO_HMEM_WORKAROUND
|
||||
|
||||
/*
|
||||
* Semi global. "HRT" is accessible from SP, but
|
||||
* the HRT types do not fully apply
|
||||
*/
|
||||
#define HRT_VADDRESS_WIDTH 32
|
||||
/* Surprise, this is a local property*/
|
||||
/*#define HRT_ADDRESS_WIDTH 64 */
|
||||
#define HRT_DATA_WIDTH 32
|
||||
|
||||
#define SIZEOF_HRT_REG (HRT_DATA_WIDTH >> 3)
|
||||
#define HIVE_ISP_CTRL_DATA_BYTES (HIVE_ISP_CTRL_DATA_WIDTH / 8)
|
||||
|
||||
/* The main bus connecting all devices */
|
||||
#define HRT_BUS_WIDTH HIVE_ISP_CTRL_DATA_WIDTH
|
||||
#define HRT_BUS_BYTES HIVE_ISP_CTRL_DATA_BYTES
|
||||
|
||||
#define USE_INPUT_SYSTEM_VERSION_2401
|
||||
#define HAS_INPUT_SYSTEM_VERSION_2401
|
||||
#define CSI2P_DISABLE_ISYS2401_ONLINE_MODE
|
||||
|
||||
/* per-frame parameter handling support */
|
||||
#define SH_CSS_ENABLE_PER_FRAME_PARAMS
|
||||
|
||||
typedef u32 hrt_bus_align_t;
|
||||
|
||||
/*
|
||||
* Enumerate the devices, device access through the API is by ID,
|
||||
* through the DLI by address. The enumerator terminators are used
|
||||
* to size the wiring arrays and as an exception value.
|
||||
*/
|
||||
typedef enum {
|
||||
DDR0_ID = 0,
|
||||
N_DDR_ID
|
||||
} ddr_ID_t;
|
||||
|
||||
typedef enum {
|
||||
ISP0_ID = 0,
|
||||
N_ISP_ID
|
||||
} isp_ID_t;
|
||||
|
||||
typedef enum {
|
||||
SP0_ID = 0,
|
||||
N_SP_ID
|
||||
} sp_ID_t;
|
||||
|
||||
typedef enum {
|
||||
MMU0_ID = 0,
|
||||
MMU1_ID,
|
||||
N_MMU_ID
|
||||
} mmu_ID_t;
|
||||
|
||||
typedef enum {
|
||||
DMA0_ID = 0,
|
||||
N_DMA_ID
|
||||
} dma_ID_t;
|
||||
|
||||
typedef enum {
|
||||
GDC0_ID = 0,
|
||||
GDC1_ID,
|
||||
N_GDC_ID
|
||||
} gdc_ID_t;
|
||||
|
||||
/* this extra define is needed because we want to use it also
|
||||
in the preprocessor, and that doesn't work with enums.
|
||||
*/
|
||||
#define N_GDC_ID_CPP 2
|
||||
|
||||
typedef enum {
|
||||
VAMEM0_ID = 0,
|
||||
VAMEM1_ID,
|
||||
VAMEM2_ID,
|
||||
N_VAMEM_ID
|
||||
} vamem_ID_t;
|
||||
|
||||
typedef enum {
|
||||
BAMEM0_ID = 0,
|
||||
N_BAMEM_ID
|
||||
} bamem_ID_t;
|
||||
|
||||
typedef enum {
|
||||
HMEM0_ID = 0,
|
||||
N_HMEM_ID
|
||||
} hmem_ID_t;
|
||||
|
||||
typedef enum {
|
||||
ISYS_IRQ0_ID = 0, /* port a */
|
||||
ISYS_IRQ1_ID, /* port b */
|
||||
ISYS_IRQ2_ID, /* port c */
|
||||
N_ISYS_IRQ_ID
|
||||
} isys_irq_ID_t;
|
||||
|
||||
typedef enum {
|
||||
IRQ0_ID = 0, /* GP IRQ block */
|
||||
IRQ1_ID, /* Input formatter */
|
||||
IRQ2_ID, /* input system */
|
||||
IRQ3_ID, /* input selector */
|
||||
N_IRQ_ID
|
||||
} irq_ID_t;
|
||||
|
||||
typedef enum {
|
||||
FIFO_MONITOR0_ID = 0,
|
||||
N_FIFO_MONITOR_ID
|
||||
} fifo_monitor_ID_t;
|
||||
|
||||
/*
|
||||
* Deprecated: Since all gp_reg instances are different
|
||||
* and put in the address maps of other devices we cannot
|
||||
* enumerate them as that assumes the instrances are the
|
||||
* same.
|
||||
*
|
||||
* We define a single GP_DEVICE containing all gp_regs
|
||||
* w.r.t. a single base address
|
||||
*
|
||||
typedef enum {
|
||||
GP_REGS0_ID = 0,
|
||||
N_GP_REGS_ID
|
||||
} gp_regs_ID_t;
|
||||
*/
|
||||
typedef enum {
|
||||
GP_DEVICE0_ID = 0,
|
||||
N_GP_DEVICE_ID
|
||||
} gp_device_ID_t;
|
||||
|
||||
typedef enum {
|
||||
GP_TIMER0_ID = 0,
|
||||
GP_TIMER1_ID,
|
||||
GP_TIMER2_ID,
|
||||
GP_TIMER3_ID,
|
||||
GP_TIMER4_ID,
|
||||
GP_TIMER5_ID,
|
||||
GP_TIMER6_ID,
|
||||
GP_TIMER7_ID,
|
||||
N_GP_TIMER_ID
|
||||
} gp_timer_ID_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO0_ID = 0,
|
||||
N_GPIO_ID
|
||||
} gpio_ID_t;
|
||||
|
||||
typedef enum {
|
||||
TIMED_CTRL0_ID = 0,
|
||||
N_TIMED_CTRL_ID
|
||||
} timed_ctrl_ID_t;
|
||||
|
||||
typedef enum {
|
||||
INPUT_FORMATTER0_ID = 0,
|
||||
INPUT_FORMATTER1_ID,
|
||||
INPUT_FORMATTER2_ID,
|
||||
INPUT_FORMATTER3_ID,
|
||||
N_INPUT_FORMATTER_ID
|
||||
} input_formatter_ID_t;
|
||||
|
||||
/* The IF RST is outside the IF */
|
||||
#define INPUT_FORMATTER0_SRST_OFFSET 0x0824
|
||||
#define INPUT_FORMATTER1_SRST_OFFSET 0x0624
|
||||
#define INPUT_FORMATTER2_SRST_OFFSET 0x0424
|
||||
#define INPUT_FORMATTER3_SRST_OFFSET 0x0224
|
||||
|
||||
#define INPUT_FORMATTER0_SRST_MASK 0x0001
|
||||
#define INPUT_FORMATTER1_SRST_MASK 0x0002
|
||||
#define INPUT_FORMATTER2_SRST_MASK 0x0004
|
||||
#define INPUT_FORMATTER3_SRST_MASK 0x0008
|
||||
|
||||
typedef enum {
|
||||
INPUT_SYSTEM0_ID = 0,
|
||||
N_INPUT_SYSTEM_ID
|
||||
} input_system_ID_t;
|
||||
|
||||
typedef enum {
|
||||
RX0_ID = 0,
|
||||
N_RX_ID
|
||||
} rx_ID_t;
|
||||
|
||||
enum mipi_port_id {
|
||||
MIPI_PORT0_ID = 0,
|
||||
MIPI_PORT1_ID,
|
||||
MIPI_PORT2_ID,
|
||||
N_MIPI_PORT_ID
|
||||
};
|
||||
|
||||
#define N_RX_CHANNEL_ID 4
|
||||
|
||||
/* Generic port enumeration with an internal port type ID */
|
||||
typedef enum {
|
||||
CSI_PORT0_ID = 0,
|
||||
CSI_PORT1_ID,
|
||||
CSI_PORT2_ID,
|
||||
TPG_PORT0_ID,
|
||||
PRBS_PORT0_ID,
|
||||
FIFO_PORT0_ID,
|
||||
MEMORY_PORT0_ID,
|
||||
N_INPUT_PORT_ID
|
||||
} input_port_ID_t;
|
||||
|
||||
typedef enum {
|
||||
CAPTURE_UNIT0_ID = 0,
|
||||
CAPTURE_UNIT1_ID,
|
||||
CAPTURE_UNIT2_ID,
|
||||
ACQUISITION_UNIT0_ID,
|
||||
DMA_UNIT0_ID,
|
||||
CTRL_UNIT0_ID,
|
||||
GPREGS_UNIT0_ID,
|
||||
FIFO_UNIT0_ID,
|
||||
IRQ_UNIT0_ID,
|
||||
N_SUB_SYSTEM_ID
|
||||
} sub_system_ID_t;
|
||||
|
||||
#define N_CAPTURE_UNIT_ID 3
|
||||
#define N_ACQUISITION_UNIT_ID 1
|
||||
#define N_CTRL_UNIT_ID 1
|
||||
|
||||
/*
|
||||
* Input-buffer Controller.
|
||||
*/
|
||||
typedef enum {
|
||||
IBUF_CTRL0_ID = 0, /* map to ISYS2401_IBUF_CNTRL_A */
|
||||
IBUF_CTRL1_ID, /* map to ISYS2401_IBUF_CNTRL_B */
|
||||
IBUF_CTRL2_ID, /* map ISYS2401_IBUF_CNTRL_C */
|
||||
N_IBUF_CTRL_ID
|
||||
} ibuf_ctrl_ID_t;
|
||||
/* end of Input-buffer Controller */
|
||||
|
||||
/*
|
||||
* Stream2MMIO.
|
||||
*/
|
||||
typedef enum {
|
||||
STREAM2MMIO0_ID = 0, /* map to ISYS2401_S2M_A */
|
||||
STREAM2MMIO1_ID, /* map to ISYS2401_S2M_B */
|
||||
STREAM2MMIO2_ID, /* map to ISYS2401_S2M_C */
|
||||
N_STREAM2MMIO_ID
|
||||
} stream2mmio_ID_t;
|
||||
|
||||
typedef enum {
|
||||
/*
|
||||
* Stream2MMIO 0 has 8 SIDs that are indexed by
|
||||
* [STREAM2MMIO_SID0_ID...STREAM2MMIO_SID7_ID].
|
||||
*
|
||||
* Stream2MMIO 1 has 4 SIDs that are indexed by
|
||||
* [STREAM2MMIO_SID0_ID...TREAM2MMIO_SID3_ID].
|
||||
*
|
||||
* Stream2MMIO 2 has 4 SIDs that are indexed by
|
||||
* [STREAM2MMIO_SID0_ID...STREAM2MMIO_SID3_ID].
|
||||
*/
|
||||
STREAM2MMIO_SID0_ID = 0,
|
||||
STREAM2MMIO_SID1_ID,
|
||||
STREAM2MMIO_SID2_ID,
|
||||
STREAM2MMIO_SID3_ID,
|
||||
STREAM2MMIO_SID4_ID,
|
||||
STREAM2MMIO_SID5_ID,
|
||||
STREAM2MMIO_SID6_ID,
|
||||
STREAM2MMIO_SID7_ID,
|
||||
N_STREAM2MMIO_SID_ID
|
||||
} stream2mmio_sid_ID_t;
|
||||
/* end of Stream2MMIO */
|
||||
|
||||
/**
|
||||
* Input System 2401: CSI-MIPI recevier.
|
||||
*/
|
||||
typedef enum {
|
||||
CSI_RX_BACKEND0_ID = 0, /* map to ISYS2401_MIPI_BE_A */
|
||||
CSI_RX_BACKEND1_ID, /* map to ISYS2401_MIPI_BE_B */
|
||||
CSI_RX_BACKEND2_ID, /* map to ISYS2401_MIPI_BE_C */
|
||||
N_CSI_RX_BACKEND_ID
|
||||
} csi_rx_backend_ID_t;
|
||||
|
||||
typedef enum {
|
||||
CSI_RX_FRONTEND0_ID = 0, /* map to ISYS2401_CSI_RX_A */
|
||||
CSI_RX_FRONTEND1_ID, /* map to ISYS2401_CSI_RX_B */
|
||||
CSI_RX_FRONTEND2_ID, /* map to ISYS2401_CSI_RX_C */
|
||||
#define N_CSI_RX_FRONTEND_ID (CSI_RX_FRONTEND2_ID + 1)
|
||||
} csi_rx_frontend_ID_t;
|
||||
|
||||
typedef enum {
|
||||
CSI_RX_DLANE0_ID = 0, /* map to DLANE0 in CSI RX */
|
||||
CSI_RX_DLANE1_ID, /* map to DLANE1 in CSI RX */
|
||||
CSI_RX_DLANE2_ID, /* map to DLANE2 in CSI RX */
|
||||
CSI_RX_DLANE3_ID, /* map to DLANE3 in CSI RX */
|
||||
N_CSI_RX_DLANE_ID
|
||||
} csi_rx_fe_dlane_ID_t;
|
||||
/* end of CSI-MIPI receiver */
|
||||
|
||||
typedef enum {
|
||||
ISYS2401_DMA0_ID = 0,
|
||||
N_ISYS2401_DMA_ID
|
||||
} isys2401_dma_ID_t;
|
||||
|
||||
/**
|
||||
* Pixel-generator. ("system_global.h")
|
||||
*/
|
||||
typedef enum {
|
||||
PIXELGEN0_ID = 0,
|
||||
PIXELGEN1_ID,
|
||||
PIXELGEN2_ID,
|
||||
N_PIXELGEN_ID
|
||||
} pixelgen_ID_t;
|
||||
/* end of pixel-generator. ("system_global.h") */
|
||||
|
||||
typedef enum {
|
||||
INPUT_SYSTEM_CSI_PORT0_ID = 0,
|
||||
INPUT_SYSTEM_CSI_PORT1_ID,
|
||||
INPUT_SYSTEM_CSI_PORT2_ID,
|
||||
|
||||
INPUT_SYSTEM_PIXELGEN_PORT0_ID,
|
||||
INPUT_SYSTEM_PIXELGEN_PORT1_ID,
|
||||
INPUT_SYSTEM_PIXELGEN_PORT2_ID,
|
||||
|
||||
N_INPUT_SYSTEM_INPUT_PORT_ID
|
||||
} input_system_input_port_ID_t;
|
||||
|
||||
#define N_INPUT_SYSTEM_CSI_PORT 3
|
||||
|
||||
typedef enum {
|
||||
ISYS2401_DMA_CHANNEL_0 = 0,
|
||||
ISYS2401_DMA_CHANNEL_1,
|
||||
ISYS2401_DMA_CHANNEL_2,
|
||||
ISYS2401_DMA_CHANNEL_3,
|
||||
ISYS2401_DMA_CHANNEL_4,
|
||||
ISYS2401_DMA_CHANNEL_5,
|
||||
ISYS2401_DMA_CHANNEL_6,
|
||||
ISYS2401_DMA_CHANNEL_7,
|
||||
ISYS2401_DMA_CHANNEL_8,
|
||||
ISYS2401_DMA_CHANNEL_9,
|
||||
ISYS2401_DMA_CHANNEL_10,
|
||||
ISYS2401_DMA_CHANNEL_11,
|
||||
N_ISYS2401_DMA_CHANNEL
|
||||
} isys2401_dma_channel;
|
||||
|
||||
enum ia_css_isp_memories {
|
||||
IA_CSS_ISP_PMEM0 = 0,
|
||||
IA_CSS_ISP_DMEM0,
|
||||
IA_CSS_ISP_VMEM0,
|
||||
IA_CSS_ISP_VAMEM0,
|
||||
IA_CSS_ISP_VAMEM1,
|
||||
IA_CSS_ISP_VAMEM2,
|
||||
IA_CSS_ISP_HMEM0,
|
||||
IA_CSS_SP_DMEM0,
|
||||
IA_CSS_DDR,
|
||||
N_IA_CSS_MEMORIES
|
||||
};
|
||||
|
||||
#define IA_CSS_NUM_MEMORIES 9
|
||||
/* For driver compatibility */
|
||||
#define N_IA_CSS_ISP_MEMORIES IA_CSS_NUM_MEMORIES
|
||||
#define IA_CSS_NUM_ISP_MEMORIES IA_CSS_NUM_MEMORIES
|
||||
|
||||
#endif /* __SYSTEM_GLOBAL_H_INCLUDED__ */
|
||||
|
|
|
@ -1,402 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Support for Intel Camera Imaging ISP subsystem.
|
||||
* Copyright (c) 2015, Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY 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_LOCAL_H_INCLUDED__
|
||||
#define __SYSTEM_LOCAL_H_INCLUDED__
|
||||
|
||||
#ifdef HRT_ISP_CSS_CUSTOM_HOST
|
||||
#ifndef HRT_USE_VIR_ADDRS
|
||||
#define HRT_USE_VIR_ADDRS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "system_global.h"
|
||||
|
||||
#define HRT_ADDRESS_WIDTH 64 /* Surprise, this is a local property */
|
||||
|
||||
/* This interface is deprecated */
|
||||
#include "hive_types.h"
|
||||
|
||||
/*
|
||||
* Cell specific address maps
|
||||
*/
|
||||
#if HRT_ADDRESS_WIDTH == 64
|
||||
|
||||
#define GP_FIFO_BASE ((hrt_address)0x0000000000090104) /* This is NOT a base address */
|
||||
|
||||
/* DDR */
|
||||
static const hrt_address DDR_BASE[N_DDR_ID] = {
|
||||
0x0000000120000000ULL
|
||||
};
|
||||
|
||||
/* ISP */
|
||||
static const hrt_address ISP_CTRL_BASE[N_ISP_ID] = {
|
||||
0x0000000000020000ULL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_DMEM_BASE[N_ISP_ID] = {
|
||||
0x0000000000200000ULL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID] = {
|
||||
0x0000000000100000ULL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_VAMEM_BASE[N_VAMEM_ID] = {
|
||||
0x00000000001C0000ULL,
|
||||
0x00000000001D0000ULL,
|
||||
0x00000000001E0000ULL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_HMEM_BASE[N_HMEM_ID] = {
|
||||
0x00000000001F0000ULL
|
||||
};
|
||||
|
||||
/* SP */
|
||||
static const hrt_address SP_CTRL_BASE[N_SP_ID] = {
|
||||
0x0000000000010000ULL
|
||||
};
|
||||
|
||||
static const hrt_address SP_DMEM_BASE[N_SP_ID] = {
|
||||
0x0000000000300000ULL
|
||||
};
|
||||
|
||||
/* MMU */
|
||||
/*
|
||||
* MMU0_ID: The data MMU
|
||||
* MMU1_ID: The icache MMU
|
||||
*/
|
||||
static const hrt_address MMU_BASE[N_MMU_ID] = {
|
||||
0x0000000000070000ULL,
|
||||
0x00000000000A0000ULL
|
||||
};
|
||||
|
||||
/* DMA */
|
||||
static const hrt_address DMA_BASE[N_DMA_ID] = {
|
||||
0x0000000000040000ULL
|
||||
};
|
||||
|
||||
static const hrt_address ISYS2401_DMA_BASE[N_ISYS2401_DMA_ID] = {
|
||||
0x00000000000CA000ULL
|
||||
};
|
||||
|
||||
/* IRQ */
|
||||
static const hrt_address IRQ_BASE[N_IRQ_ID] = {
|
||||
0x0000000000000500ULL,
|
||||
0x0000000000030A00ULL,
|
||||
0x000000000008C000ULL,
|
||||
0x0000000000090200ULL
|
||||
};
|
||||
|
||||
/*
|
||||
0x0000000000000500ULL};
|
||||
*/
|
||||
|
||||
/* GDC */
|
||||
static const hrt_address GDC_BASE[N_GDC_ID] = {
|
||||
0x0000000000050000ULL,
|
||||
0x0000000000060000ULL
|
||||
};
|
||||
|
||||
/* FIFO_MONITOR (not a subset of GP_DEVICE) */
|
||||
static const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID] = {
|
||||
0x0000000000000000ULL
|
||||
};
|
||||
|
||||
/*
|
||||
static const hrt_address GP_REGS_BASE[N_GP_REGS_ID] = {
|
||||
0x0000000000000000ULL};
|
||||
|
||||
static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = {
|
||||
0x0000000000090000ULL};
|
||||
*/
|
||||
|
||||
/* GP_DEVICE (single base for all separate GP_REG instances) */
|
||||
static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = {
|
||||
0x0000000000000000ULL
|
||||
};
|
||||
|
||||
/*GP TIMER , all timer registers are inter-twined,
|
||||
* so, having multiple base addresses for
|
||||
* different timers does not help*/
|
||||
static const hrt_address GP_TIMER_BASE =
|
||||
(hrt_address)0x0000000000000600ULL;
|
||||
|
||||
/* GPIO */
|
||||
static const hrt_address GPIO_BASE[N_GPIO_ID] = {
|
||||
0x0000000000000400ULL
|
||||
};
|
||||
|
||||
/* TIMED_CTRL */
|
||||
static const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID] = {
|
||||
0x0000000000000100ULL
|
||||
};
|
||||
|
||||
/* INPUT_FORMATTER */
|
||||
static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = {
|
||||
0x0000000000030000ULL,
|
||||
0x0000000000030200ULL,
|
||||
0x0000000000030400ULL,
|
||||
0x0000000000030600ULL
|
||||
}; /* memcpy() */
|
||||
|
||||
/* INPUT_SYSTEM */
|
||||
static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = {
|
||||
0x0000000000080000ULL
|
||||
};
|
||||
|
||||
/* 0x0000000000081000ULL, */ /* capture A */
|
||||
/* 0x0000000000082000ULL, */ /* capture B */
|
||||
/* 0x0000000000083000ULL, */ /* capture C */
|
||||
/* 0x0000000000084000ULL, */ /* Acquisition */
|
||||
/* 0x0000000000085000ULL, */ /* DMA */
|
||||
/* 0x0000000000089000ULL, */ /* ctrl */
|
||||
/* 0x000000000008A000ULL, */ /* GP regs */
|
||||
/* 0x000000000008B000ULL, */ /* FIFO */
|
||||
/* 0x000000000008C000ULL, */ /* IRQ */
|
||||
|
||||
/* RX, the MIPI lane control regs start at offset 0 */
|
||||
static const hrt_address RX_BASE[N_RX_ID] = {
|
||||
0x0000000000080100ULL
|
||||
};
|
||||
|
||||
/* IBUF_CTRL, part of the Input System 2401 */
|
||||
static const hrt_address IBUF_CTRL_BASE[N_IBUF_CTRL_ID] = {
|
||||
0x00000000000C1800ULL, /* ibuf controller A */
|
||||
0x00000000000C3800ULL, /* ibuf controller B */
|
||||
0x00000000000C5800ULL /* ibuf controller C */
|
||||
};
|
||||
|
||||
/* ISYS IRQ Controllers, part of the Input System 2401 */
|
||||
static const hrt_address ISYS_IRQ_BASE[N_ISYS_IRQ_ID] = {
|
||||
0x00000000000C1400ULL, /* port a */
|
||||
0x00000000000C3400ULL, /* port b */
|
||||
0x00000000000C5400ULL /* port c */
|
||||
};
|
||||
|
||||
/* CSI FE, part of the Input System 2401 */
|
||||
static const hrt_address CSI_RX_FE_CTRL_BASE[N_CSI_RX_FRONTEND_ID] = {
|
||||
0x00000000000C0400ULL, /* csi fe controller A */
|
||||
0x00000000000C2400ULL, /* csi fe controller B */
|
||||
0x00000000000C4400ULL /* csi fe controller C */
|
||||
};
|
||||
|
||||
/* CSI BE, part of the Input System 2401 */
|
||||
static const hrt_address CSI_RX_BE_CTRL_BASE[N_CSI_RX_BACKEND_ID] = {
|
||||
0x00000000000C0800ULL, /* csi be controller A */
|
||||
0x00000000000C2800ULL, /* csi be controller B */
|
||||
0x00000000000C4800ULL /* csi be controller C */
|
||||
};
|
||||
|
||||
/* PIXEL Generator, part of the Input System 2401 */
|
||||
static const hrt_address PIXELGEN_CTRL_BASE[N_PIXELGEN_ID] = {
|
||||
0x00000000000C1000ULL, /* pixel gen controller A */
|
||||
0x00000000000C3000ULL, /* pixel gen controller B */
|
||||
0x00000000000C5000ULL /* pixel gen controller C */
|
||||
};
|
||||
|
||||
/* Stream2MMIO, part of the Input System 2401 */
|
||||
static const hrt_address STREAM2MMIO_CTRL_BASE[N_STREAM2MMIO_ID] = {
|
||||
0x00000000000C0C00ULL, /* stream2mmio controller A */
|
||||
0x00000000000C2C00ULL, /* stream2mmio controller B */
|
||||
0x00000000000C4C00ULL /* stream2mmio controller C */
|
||||
};
|
||||
#elif HRT_ADDRESS_WIDTH == 32
|
||||
|
||||
#define GP_FIFO_BASE ((hrt_address)0x00090104) /* This is NOT a base address */
|
||||
|
||||
/* DDR : Attention, this value not defined in 32-bit */
|
||||
static const hrt_address DDR_BASE[N_DDR_ID] = {
|
||||
0x00000000UL
|
||||
};
|
||||
|
||||
/* ISP */
|
||||
static const hrt_address ISP_CTRL_BASE[N_ISP_ID] = {
|
||||
0x00020000UL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_DMEM_BASE[N_ISP_ID] = {
|
||||
0xffffffffUL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID] = {
|
||||
0xffffffffUL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_VAMEM_BASE[N_VAMEM_ID] = {
|
||||
0xffffffffUL,
|
||||
0xffffffffUL,
|
||||
0xffffffffUL
|
||||
};
|
||||
|
||||
static const hrt_address ISP_HMEM_BASE[N_HMEM_ID] = {
|
||||
0xffffffffUL
|
||||
};
|
||||
|
||||
/* SP */
|
||||
static const hrt_address SP_CTRL_BASE[N_SP_ID] = {
|
||||
0x00010000UL
|
||||
};
|
||||
|
||||
static const hrt_address SP_DMEM_BASE[N_SP_ID] = {
|
||||
0x00300000UL
|
||||
};
|
||||
|
||||
/* MMU */
|
||||
/*
|
||||
* MMU0_ID: The data MMU
|
||||
* MMU1_ID: The icache MMU
|
||||
*/
|
||||
static const hrt_address MMU_BASE[N_MMU_ID] = {
|
||||
0x00070000UL,
|
||||
0x000A0000UL
|
||||
};
|
||||
|
||||
/* DMA */
|
||||
static const hrt_address DMA_BASE[N_DMA_ID] = {
|
||||
0x00040000UL
|
||||
};
|
||||
|
||||
static const hrt_address ISYS2401_DMA_BASE[N_ISYS2401_DMA_ID] = {
|
||||
0x000CA000UL
|
||||
};
|
||||
|
||||
/* IRQ */
|
||||
static const hrt_address IRQ_BASE[N_IRQ_ID] = {
|
||||
0x00000500UL,
|
||||
0x00030A00UL,
|
||||
0x0008C000UL,
|
||||
0x00090200UL
|
||||
};
|
||||
|
||||
/*
|
||||
0x00000500UL};
|
||||
*/
|
||||
|
||||
/* GDC */
|
||||
static const hrt_address GDC_BASE[N_GDC_ID] = {
|
||||
0x00050000UL,
|
||||
0x00060000UL
|
||||
};
|
||||
|
||||
/* FIFO_MONITOR (not a subset of GP_DEVICE) */
|
||||
static const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID] = {
|
||||
0x00000000UL
|
||||
};
|
||||
|
||||
/*
|
||||
static const hrt_address GP_REGS_BASE[N_GP_REGS_ID] = {
|
||||
0x00000000UL};
|
||||
|
||||
static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = {
|
||||
0x00090000UL};
|
||||
*/
|
||||
|
||||
/* GP_DEVICE (single base for all separate GP_REG instances) */
|
||||
static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = {
|
||||
0x00000000UL
|
||||
};
|
||||
|
||||
/*GP TIMER , all timer registers are inter-twined,
|
||||
* so, having multiple base addresses for
|
||||
* different timers does not help*/
|
||||
static const hrt_address GP_TIMER_BASE =
|
||||
(hrt_address)0x00000600UL;
|
||||
/* GPIO */
|
||||
static const hrt_address GPIO_BASE[N_GPIO_ID] = {
|
||||
0x00000400UL
|
||||
};
|
||||
|
||||
/* TIMED_CTRL */
|
||||
static const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID] = {
|
||||
0x00000100UL
|
||||
};
|
||||
|
||||
/* INPUT_FORMATTER */
|
||||
static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = {
|
||||
0x00030000UL,
|
||||
0x00030200UL,
|
||||
0x00030400UL
|
||||
};
|
||||
|
||||
/* 0x00030600UL, */ /* memcpy() */
|
||||
|
||||
/* INPUT_SYSTEM */
|
||||
static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = {
|
||||
0x00080000UL
|
||||
};
|
||||
|
||||
/* 0x00081000UL, */ /* capture A */
|
||||
/* 0x00082000UL, */ /* capture B */
|
||||
/* 0x00083000UL, */ /* capture C */
|
||||
/* 0x00084000UL, */ /* Acquisition */
|
||||
/* 0x00085000UL, */ /* DMA */
|
||||
/* 0x00089000UL, */ /* ctrl */
|
||||
/* 0x0008A000UL, */ /* GP regs */
|
||||
/* 0x0008B000UL, */ /* FIFO */
|
||||
/* 0x0008C000UL, */ /* IRQ */
|
||||
|
||||
/* RX, the MIPI lane control regs start at offset 0 */
|
||||
static const hrt_address RX_BASE[N_RX_ID] = {
|
||||
0x00080100UL
|
||||
};
|
||||
|
||||
/* IBUF_CTRL, part of the Input System 2401 */
|
||||
static const hrt_address IBUF_CTRL_BASE[N_IBUF_CTRL_ID] = {
|
||||
0x000C1800UL, /* ibuf controller A */
|
||||
0x000C3800UL, /* ibuf controller B */
|
||||
0x000C5800UL /* ibuf controller C */
|
||||
};
|
||||
|
||||
/* ISYS IRQ Controllers, part of the Input System 2401 */
|
||||
static const hrt_address ISYS_IRQ_BASE[N_ISYS_IRQ_ID] = {
|
||||
0x000C1400ULL, /* port a */
|
||||
0x000C3400ULL, /* port b */
|
||||
0x000C5400ULL /* port c */
|
||||
};
|
||||
|
||||
/* CSI FE, part of the Input System 2401 */
|
||||
static const hrt_address CSI_RX_FE_CTRL_BASE[N_CSI_RX_FRONTEND_ID] = {
|
||||
0x000C0400UL, /* csi fe controller A */
|
||||
0x000C2400UL, /* csi fe controller B */
|
||||
0x000C4400UL /* csi fe controller C */
|
||||
};
|
||||
|
||||
/* CSI BE, part of the Input System 2401 */
|
||||
static const hrt_address CSI_RX_FE_CTRL_BASE[N_CSI_RX_BACKEND_ID] = {
|
||||
0x000C0800UL, /* csi be controller A */
|
||||
0x000C2800UL, /* csi be controller B */
|
||||
0x000C4800UL /* csi be controller C */
|
||||
};
|
||||
|
||||
/* PIXEL Generator, part of the Input System 2401 */
|
||||
static const hrt_address PIXELGEN_CTRL_BASE[N_PIXELGEN_ID] = {
|
||||
0x000C1000UL, /* pixel gen controller A */
|
||||
0x000C3000UL, /* pixel gen controller B */
|
||||
0x000C5000UL /* pixel gen controller C */
|
||||
};
|
||||
|
||||
/* Stream2MMIO, part of the Input System 2401 */
|
||||
static const hrt_address STREAM2MMIO_CTRL_BASE[N_STREAM2MMIO_ID] = {
|
||||
0x000C0C00UL, /* stream2mmio controller A */
|
||||
0x000C2C00UL, /* stream2mmio controller B */
|
||||
0x000C4C00UL /* stream2mmio controller C */
|
||||
};
|
||||
|
||||
#else
|
||||
#error "system_local.h: HRT_ADDRESS_WIDTH must be one of {32,64}"
|
||||
#endif
|
||||
|
||||
#endif /* __SYSTEM_LOCAL_H_INCLUDED__ */
|
|
@ -1841,8 +1841,13 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
|
|||
#endif
|
||||
|
||||
#if !defined(HAS_NO_INPUT_SYSTEM)
|
||||
dma_set_max_burst_size(DMA0_ID, HIVE_DMA_BUS_DDR_CONN,
|
||||
ISP_DMA_MAX_BURST_LENGTH);
|
||||
|
||||
if (!IS_ISP2401)
|
||||
dma_set_max_burst_size(DMA0_ID, HIVE_DMA_BUS_DDR_CONN,
|
||||
ISP2400_DMA_MAX_BURST_LENGTH);
|
||||
else
|
||||
dma_set_max_burst_size(DMA0_ID, HIVE_DMA_BUS_DDR_CONN,
|
||||
ISP2401_DMA_MAX_BURST_LENGTH);
|
||||
|
||||
if (ia_css_isys_init() != INPUT_SYSTEM_ERR_NO_ERROR)
|
||||
err = -EINVAL;
|
||||
|
|
|
@ -4,8 +4,403 @@
|
|||
* (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
|
||||
*/
|
||||
|
||||
#ifndef __SYSTEM_GLOBAL_H_INCLUDED__
|
||||
#define __SYSTEM_GLOBAL_H_INCLUDED__
|
||||
|
||||
/*
|
||||
* Create a list of HAS and IS properties that defines the system
|
||||
* Those are common for both ISP2400 and ISP2401
|
||||
*
|
||||
* The configuration assumes the following
|
||||
* - The system is hetereogeneous; Multiple cells and devices classes
|
||||
* - The cell and device instances are homogeneous, each device type
|
||||
* belongs to the same class
|
||||
* - Device instances supporting a subset of the class capabilities are
|
||||
* allowed
|
||||
*
|
||||
* We could manage different device classes through the enumerated
|
||||
* lists (C) or the use of classes (C++), but that is presently not
|
||||
* fully supported
|
||||
*
|
||||
* N.B. the 3 input formatters are of 2 different classess
|
||||
*/
|
||||
|
||||
#define HAS_MMU_VERSION_2
|
||||
#define HAS_DMA_VERSION_2
|
||||
#define HAS_GDC_VERSION_2
|
||||
#define HAS_VAMEM_VERSION_2
|
||||
#define HAS_HMEM_VERSION_1
|
||||
#define HAS_BAMEM_VERSION_2
|
||||
#define HAS_IRQ_VERSION_2
|
||||
#define HAS_IRQ_MAP_VERSION_2
|
||||
#define HAS_INPUT_FORMATTER_VERSION_2
|
||||
#define HAS_INPUT_SYSTEM_VERSION_2
|
||||
#define HAS_BUFFERED_SENSOR
|
||||
#define HAS_FIFO_MONITORS_VERSION_2
|
||||
#define HAS_GP_DEVICE_VERSION_2
|
||||
#define HAS_GPIO_VERSION_1
|
||||
#define HAS_TIMED_CTRL_VERSION_1
|
||||
#define HAS_RX_VERSION_2
|
||||
|
||||
/* per-frame parameter handling support */
|
||||
#define SH_CSS_ENABLE_PER_FRAME_PARAMS
|
||||
|
||||
#define DMA_DDR_TO_VAMEM_WORKAROUND
|
||||
#define DMA_DDR_TO_HMEM_WORKAROUND
|
||||
|
||||
/*
|
||||
* The longest allowed (uninteruptible) bus transfer, does not
|
||||
* take stalling into account
|
||||
*/
|
||||
#define HIVE_ISP_MAX_BURST_LENGTH 1024
|
||||
|
||||
/*
|
||||
* Maximum allowed burst length in words for the ISP DMA
|
||||
* This value is set to 2 to prevent the ISP DMA from blocking
|
||||
* the bus for too long; as the input system can only buffer
|
||||
* 2 lines on Moorefield and Cherrytrail, the input system buffers
|
||||
* may overflow if blocked for too long (BZ 2726).
|
||||
*/
|
||||
#define ISP2400_DMA_MAX_BURST_LENGTH 128
|
||||
#define ISP2401_DMA_MAX_BURST_LENGTH 2
|
||||
|
||||
#ifdef ISP2401
|
||||
# include "isp2401_system_global.h"
|
||||
#else
|
||||
# include "isp2400_system_global.h"
|
||||
#endif
|
||||
|
||||
#include <hive_isp_css_defs.h>
|
||||
#include <type_support.h>
|
||||
|
||||
/* This interface is deprecated */
|
||||
#include "hive_types.h"
|
||||
|
||||
/*
|
||||
* Semi global. "HRT" is accessible from SP, but the HRT types do not fully apply
|
||||
*/
|
||||
#define HRT_VADDRESS_WIDTH 32
|
||||
|
||||
#define SIZEOF_HRT_REG (HRT_DATA_WIDTH >> 3)
|
||||
#define HIVE_ISP_CTRL_DATA_BYTES (HIVE_ISP_CTRL_DATA_WIDTH / 8)
|
||||
|
||||
/* The main bus connecting all devices */
|
||||
#define HRT_BUS_WIDTH HIVE_ISP_CTRL_DATA_WIDTH
|
||||
#define HRT_BUS_BYTES HIVE_ISP_CTRL_DATA_BYTES
|
||||
|
||||
typedef u32 hrt_bus_align_t;
|
||||
|
||||
/*
|
||||
* Enumerate the devices, device access through the API is by ID,
|
||||
* through the DLI by address. The enumerator terminators are used
|
||||
* to size the wiring arrays and as an exception value.
|
||||
*/
|
||||
typedef enum {
|
||||
DDR0_ID = 0,
|
||||
N_DDR_ID
|
||||
} ddr_ID_t;
|
||||
|
||||
typedef enum {
|
||||
ISP0_ID = 0,
|
||||
N_ISP_ID
|
||||
} isp_ID_t;
|
||||
|
||||
typedef enum {
|
||||
SP0_ID = 0,
|
||||
N_SP_ID
|
||||
} sp_ID_t;
|
||||
|
||||
typedef enum {
|
||||
MMU0_ID = 0,
|
||||
MMU1_ID,
|
||||
N_MMU_ID
|
||||
} mmu_ID_t;
|
||||
|
||||
typedef enum {
|
||||
DMA0_ID = 0,
|
||||
N_DMA_ID
|
||||
} dma_ID_t;
|
||||
|
||||
typedef enum {
|
||||
GDC0_ID = 0,
|
||||
GDC1_ID,
|
||||
N_GDC_ID
|
||||
} gdc_ID_t;
|
||||
|
||||
/* this extra define is needed because we want to use it also
|
||||
in the preprocessor, and that doesn't work with enums.
|
||||
*/
|
||||
#define N_GDC_ID_CPP 2
|
||||
|
||||
typedef enum {
|
||||
VAMEM0_ID = 0,
|
||||
VAMEM1_ID,
|
||||
VAMEM2_ID,
|
||||
N_VAMEM_ID
|
||||
} vamem_ID_t;
|
||||
|
||||
typedef enum {
|
||||
BAMEM0_ID = 0,
|
||||
N_BAMEM_ID
|
||||
} bamem_ID_t;
|
||||
|
||||
typedef enum {
|
||||
HMEM0_ID = 0,
|
||||
N_HMEM_ID
|
||||
} hmem_ID_t;
|
||||
|
||||
typedef enum {
|
||||
IRQ0_ID = 0, /* GP IRQ block */
|
||||
IRQ1_ID, /* Input formatter */
|
||||
IRQ2_ID, /* input system */
|
||||
IRQ3_ID, /* input selector */
|
||||
N_IRQ_ID
|
||||
} irq_ID_t;
|
||||
|
||||
typedef enum {
|
||||
FIFO_MONITOR0_ID = 0,
|
||||
N_FIFO_MONITOR_ID
|
||||
} fifo_monitor_ID_t;
|
||||
|
||||
typedef enum {
|
||||
GP_DEVICE0_ID = 0,
|
||||
N_GP_DEVICE_ID
|
||||
} gp_device_ID_t;
|
||||
|
||||
typedef enum {
|
||||
GP_TIMER0_ID = 0,
|
||||
GP_TIMER1_ID,
|
||||
GP_TIMER2_ID,
|
||||
GP_TIMER3_ID,
|
||||
GP_TIMER4_ID,
|
||||
GP_TIMER5_ID,
|
||||
GP_TIMER6_ID,
|
||||
GP_TIMER7_ID,
|
||||
N_GP_TIMER_ID
|
||||
} gp_timer_ID_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO0_ID = 0,
|
||||
N_GPIO_ID
|
||||
} gpio_ID_t;
|
||||
|
||||
typedef enum {
|
||||
TIMED_CTRL0_ID = 0,
|
||||
N_TIMED_CTRL_ID
|
||||
} timed_ctrl_ID_t;
|
||||
|
||||
typedef enum {
|
||||
INPUT_FORMATTER0_ID = 0,
|
||||
INPUT_FORMATTER1_ID,
|
||||
INPUT_FORMATTER2_ID,
|
||||
INPUT_FORMATTER3_ID,
|
||||
N_INPUT_FORMATTER_ID
|
||||
} input_formatter_ID_t;
|
||||
|
||||
/* The IF RST is outside the IF */
|
||||
#define INPUT_FORMATTER0_SRST_OFFSET 0x0824
|
||||
#define INPUT_FORMATTER1_SRST_OFFSET 0x0624
|
||||
#define INPUT_FORMATTER2_SRST_OFFSET 0x0424
|
||||
#define INPUT_FORMATTER3_SRST_OFFSET 0x0224
|
||||
|
||||
#define INPUT_FORMATTER0_SRST_MASK 0x0001
|
||||
#define INPUT_FORMATTER1_SRST_MASK 0x0002
|
||||
#define INPUT_FORMATTER2_SRST_MASK 0x0004
|
||||
#define INPUT_FORMATTER3_SRST_MASK 0x0008
|
||||
|
||||
typedef enum {
|
||||
INPUT_SYSTEM0_ID = 0,
|
||||
N_INPUT_SYSTEM_ID
|
||||
} input_system_ID_t;
|
||||
|
||||
typedef enum {
|
||||
RX0_ID = 0,
|
||||
N_RX_ID
|
||||
} rx_ID_t;
|
||||
|
||||
enum mipi_port_id {
|
||||
MIPI_PORT0_ID = 0,
|
||||
MIPI_PORT1_ID,
|
||||
MIPI_PORT2_ID,
|
||||
N_MIPI_PORT_ID
|
||||
};
|
||||
|
||||
#define N_RX_CHANNEL_ID 4
|
||||
|
||||
/* Generic port enumeration with an internal port type ID */
|
||||
typedef enum {
|
||||
CSI_PORT0_ID = 0,
|
||||
CSI_PORT1_ID,
|
||||
CSI_PORT2_ID,
|
||||
TPG_PORT0_ID,
|
||||
PRBS_PORT0_ID,
|
||||
FIFO_PORT0_ID,
|
||||
MEMORY_PORT0_ID,
|
||||
N_INPUT_PORT_ID
|
||||
} input_port_ID_t;
|
||||
|
||||
typedef enum {
|
||||
CAPTURE_UNIT0_ID = 0,
|
||||
CAPTURE_UNIT1_ID,
|
||||
CAPTURE_UNIT2_ID,
|
||||
ACQUISITION_UNIT0_ID,
|
||||
DMA_UNIT0_ID,
|
||||
CTRL_UNIT0_ID,
|
||||
GPREGS_UNIT0_ID,
|
||||
FIFO_UNIT0_ID,
|
||||
IRQ_UNIT0_ID,
|
||||
N_SUB_SYSTEM_ID
|
||||
} sub_system_ID_t;
|
||||
|
||||
#define N_CAPTURE_UNIT_ID 3
|
||||
#define N_ACQUISITION_UNIT_ID 1
|
||||
#define N_CTRL_UNIT_ID 1
|
||||
|
||||
|
||||
enum ia_css_isp_memories {
|
||||
IA_CSS_ISP_PMEM0 = 0,
|
||||
IA_CSS_ISP_DMEM0,
|
||||
IA_CSS_ISP_VMEM0,
|
||||
IA_CSS_ISP_VAMEM0,
|
||||
IA_CSS_ISP_VAMEM1,
|
||||
IA_CSS_ISP_VAMEM2,
|
||||
IA_CSS_ISP_HMEM0,
|
||||
IA_CSS_SP_DMEM0,
|
||||
IA_CSS_DDR,
|
||||
N_IA_CSS_MEMORIES
|
||||
};
|
||||
|
||||
#define IA_CSS_NUM_MEMORIES 9
|
||||
/* For driver compatibility */
|
||||
#define N_IA_CSS_ISP_MEMORIES IA_CSS_NUM_MEMORIES
|
||||
#define IA_CSS_NUM_ISP_MEMORIES IA_CSS_NUM_MEMORIES
|
||||
|
||||
/*
|
||||
* ISP2401 specific enums
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
ISYS_IRQ0_ID = 0, /* port a */
|
||||
ISYS_IRQ1_ID, /* port b */
|
||||
ISYS_IRQ2_ID, /* port c */
|
||||
N_ISYS_IRQ_ID
|
||||
} isys_irq_ID_t;
|
||||
|
||||
|
||||
/*
|
||||
* Input-buffer Controller.
|
||||
*/
|
||||
typedef enum {
|
||||
IBUF_CTRL0_ID = 0, /* map to ISYS2401_IBUF_CNTRL_A */
|
||||
IBUF_CTRL1_ID, /* map to ISYS2401_IBUF_CNTRL_B */
|
||||
IBUF_CTRL2_ID, /* map ISYS2401_IBUF_CNTRL_C */
|
||||
N_IBUF_CTRL_ID
|
||||
} ibuf_ctrl_ID_t;
|
||||
/* end of Input-buffer Controller */
|
||||
|
||||
/*
|
||||
* Stream2MMIO.
|
||||
*/
|
||||
typedef enum {
|
||||
STREAM2MMIO0_ID = 0, /* map to ISYS2401_S2M_A */
|
||||
STREAM2MMIO1_ID, /* map to ISYS2401_S2M_B */
|
||||
STREAM2MMIO2_ID, /* map to ISYS2401_S2M_C */
|
||||
N_STREAM2MMIO_ID
|
||||
} stream2mmio_ID_t;
|
||||
|
||||
typedef enum {
|
||||
/*
|
||||
* Stream2MMIO 0 has 8 SIDs that are indexed by
|
||||
* [STREAM2MMIO_SID0_ID...STREAM2MMIO_SID7_ID].
|
||||
*
|
||||
* Stream2MMIO 1 has 4 SIDs that are indexed by
|
||||
* [STREAM2MMIO_SID0_ID...TREAM2MMIO_SID3_ID].
|
||||
*
|
||||
* Stream2MMIO 2 has 4 SIDs that are indexed by
|
||||
* [STREAM2MMIO_SID0_ID...STREAM2MMIO_SID3_ID].
|
||||
*/
|
||||
STREAM2MMIO_SID0_ID = 0,
|
||||
STREAM2MMIO_SID1_ID,
|
||||
STREAM2MMIO_SID2_ID,
|
||||
STREAM2MMIO_SID3_ID,
|
||||
STREAM2MMIO_SID4_ID,
|
||||
STREAM2MMIO_SID5_ID,
|
||||
STREAM2MMIO_SID6_ID,
|
||||
STREAM2MMIO_SID7_ID,
|
||||
N_STREAM2MMIO_SID_ID
|
||||
} stream2mmio_sid_ID_t;
|
||||
/* end of Stream2MMIO */
|
||||
|
||||
/**
|
||||
* Input System 2401: CSI-MIPI recevier.
|
||||
*/
|
||||
typedef enum {
|
||||
CSI_RX_BACKEND0_ID = 0, /* map to ISYS2401_MIPI_BE_A */
|
||||
CSI_RX_BACKEND1_ID, /* map to ISYS2401_MIPI_BE_B */
|
||||
CSI_RX_BACKEND2_ID, /* map to ISYS2401_MIPI_BE_C */
|
||||
N_CSI_RX_BACKEND_ID
|
||||
} csi_rx_backend_ID_t;
|
||||
|
||||
typedef enum {
|
||||
CSI_RX_FRONTEND0_ID = 0, /* map to ISYS2401_CSI_RX_A */
|
||||
CSI_RX_FRONTEND1_ID, /* map to ISYS2401_CSI_RX_B */
|
||||
CSI_RX_FRONTEND2_ID, /* map to ISYS2401_CSI_RX_C */
|
||||
#define N_CSI_RX_FRONTEND_ID (CSI_RX_FRONTEND2_ID + 1)
|
||||
} csi_rx_frontend_ID_t;
|
||||
|
||||
typedef enum {
|
||||
CSI_RX_DLANE0_ID = 0, /* map to DLANE0 in CSI RX */
|
||||
CSI_RX_DLANE1_ID, /* map to DLANE1 in CSI RX */
|
||||
CSI_RX_DLANE2_ID, /* map to DLANE2 in CSI RX */
|
||||
CSI_RX_DLANE3_ID, /* map to DLANE3 in CSI RX */
|
||||
N_CSI_RX_DLANE_ID
|
||||
} csi_rx_fe_dlane_ID_t;
|
||||
/* end of CSI-MIPI receiver */
|
||||
|
||||
typedef enum {
|
||||
ISYS2401_DMA0_ID = 0,
|
||||
N_ISYS2401_DMA_ID
|
||||
} isys2401_dma_ID_t;
|
||||
|
||||
/**
|
||||
* Pixel-generator. ("system_global.h")
|
||||
*/
|
||||
typedef enum {
|
||||
PIXELGEN0_ID = 0,
|
||||
PIXELGEN1_ID,
|
||||
PIXELGEN2_ID,
|
||||
N_PIXELGEN_ID
|
||||
} pixelgen_ID_t;
|
||||
/* end of pixel-generator. ("system_global.h") */
|
||||
|
||||
typedef enum {
|
||||
INPUT_SYSTEM_CSI_PORT0_ID = 0,
|
||||
INPUT_SYSTEM_CSI_PORT1_ID,
|
||||
INPUT_SYSTEM_CSI_PORT2_ID,
|
||||
|
||||
INPUT_SYSTEM_PIXELGEN_PORT0_ID,
|
||||
INPUT_SYSTEM_PIXELGEN_PORT1_ID,
|
||||
INPUT_SYSTEM_PIXELGEN_PORT2_ID,
|
||||
|
||||
N_INPUT_SYSTEM_INPUT_PORT_ID
|
||||
} input_system_input_port_ID_t;
|
||||
|
||||
#define N_INPUT_SYSTEM_CSI_PORT 3
|
||||
|
||||
typedef enum {
|
||||
ISYS2401_DMA_CHANNEL_0 = 0,
|
||||
ISYS2401_DMA_CHANNEL_1,
|
||||
ISYS2401_DMA_CHANNEL_2,
|
||||
ISYS2401_DMA_CHANNEL_3,
|
||||
ISYS2401_DMA_CHANNEL_4,
|
||||
ISYS2401_DMA_CHANNEL_5,
|
||||
ISYS2401_DMA_CHANNEL_6,
|
||||
ISYS2401_DMA_CHANNEL_7,
|
||||
ISYS2401_DMA_CHANNEL_8,
|
||||
ISYS2401_DMA_CHANNEL_9,
|
||||
ISYS2401_DMA_CHANNEL_10,
|
||||
ISYS2401_DMA_CHANNEL_11,
|
||||
N_ISYS2401_DMA_CHANNEL
|
||||
} isys2401_dma_channel;
|
||||
|
||||
#endif /* __SYSTEM_GLOBAL_H_INCLUDED__ */
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Support for Intel Camera Imaging ISP subsystem.
|
||||
* Copyright (c) 2015, Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* 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 "system_local.h"
|
||||
|
||||
/* ISP */
|
||||
const hrt_address ISP_CTRL_BASE[N_ISP_ID] = {
|
||||
0x0000000000020000ULL
|
||||
};
|
||||
|
||||
const hrt_address ISP_DMEM_BASE[N_ISP_ID] = {
|
||||
0x0000000000200000ULL
|
||||
};
|
||||
|
||||
const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID] = {
|
||||
0x0000000000100000ULL
|
||||
};
|
||||
|
||||
/* SP */
|
||||
const hrt_address SP_CTRL_BASE[N_SP_ID] = {
|
||||
0x0000000000010000ULL
|
||||
};
|
||||
|
||||
const hrt_address SP_DMEM_BASE[N_SP_ID] = {
|
||||
0x0000000000300000ULL
|
||||
};
|
||||
|
||||
/* MMU */
|
||||
/*
|
||||
* MMU0_ID: The data MMU
|
||||
* MMU1_ID: The icache MMU
|
||||
*/
|
||||
const hrt_address MMU_BASE[N_MMU_ID] = {
|
||||
0x0000000000070000ULL,
|
||||
0x00000000000A0000ULL
|
||||
};
|
||||
|
||||
/* DMA */
|
||||
const hrt_address DMA_BASE[N_DMA_ID] = {
|
||||
0x0000000000040000ULL
|
||||
};
|
||||
|
||||
const hrt_address ISYS2401_DMA_BASE[N_ISYS2401_DMA_ID] = {
|
||||
0x00000000000CA000ULL
|
||||
};
|
||||
|
||||
/* IRQ */
|
||||
const hrt_address IRQ_BASE[N_IRQ_ID] = {
|
||||
0x0000000000000500ULL,
|
||||
0x0000000000030A00ULL,
|
||||
0x000000000008C000ULL,
|
||||
0x0000000000090200ULL
|
||||
};
|
||||
|
||||
/*
|
||||
0x0000000000000500ULL};
|
||||
*/
|
||||
|
||||
/* GDC */
|
||||
const hrt_address GDC_BASE[N_GDC_ID] = {
|
||||
0x0000000000050000ULL,
|
||||
0x0000000000060000ULL
|
||||
};
|
||||
|
||||
/* FIFO_MONITOR (not a subset of GP_DEVICE) */
|
||||
const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID] = {
|
||||
0x0000000000000000ULL
|
||||
};
|
||||
|
||||
/*
|
||||
const hrt_address GP_REGS_BASE[N_GP_REGS_ID] = {
|
||||
0x0000000000000000ULL};
|
||||
|
||||
const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = {
|
||||
0x0000000000090000ULL};
|
||||
*/
|
||||
|
||||
/* GP_DEVICE (single base for all separate GP_REG instances) */
|
||||
const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = {
|
||||
0x0000000000000000ULL
|
||||
};
|
||||
|
||||
/*GP TIMER , all timer registers are inter-twined,
|
||||
* so, having multiple base addresses for
|
||||
* different timers does not help*/
|
||||
const hrt_address GP_TIMER_BASE =
|
||||
(hrt_address)0x0000000000000600ULL;
|
||||
|
||||
/* GPIO */
|
||||
const hrt_address GPIO_BASE[N_GPIO_ID] = {
|
||||
0x0000000000000400ULL
|
||||
};
|
||||
|
||||
/* TIMED_CTRL */
|
||||
const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID] = {
|
||||
0x0000000000000100ULL
|
||||
};
|
||||
|
||||
/* INPUT_FORMATTER */
|
||||
const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = {
|
||||
0x0000000000030000ULL,
|
||||
0x0000000000030200ULL,
|
||||
0x0000000000030400ULL,
|
||||
0x0000000000030600ULL
|
||||
}; /* memcpy() */
|
||||
|
||||
/* INPUT_SYSTEM */
|
||||
const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = {
|
||||
0x0000000000080000ULL
|
||||
};
|
||||
|
||||
/* 0x0000000000081000ULL, */ /* capture A */
|
||||
/* 0x0000000000082000ULL, */ /* capture B */
|
||||
/* 0x0000000000083000ULL, */ /* capture C */
|
||||
/* 0x0000000000084000ULL, */ /* Acquisition */
|
||||
/* 0x0000000000085000ULL, */ /* DMA */
|
||||
/* 0x0000000000089000ULL, */ /* ctrl */
|
||||
/* 0x000000000008A000ULL, */ /* GP regs */
|
||||
/* 0x000000000008B000ULL, */ /* FIFO */
|
||||
/* 0x000000000008C000ULL, */ /* IRQ */
|
||||
|
||||
/* RX, the MIPI lane control regs start at offset 0 */
|
||||
const hrt_address RX_BASE[N_RX_ID] = {
|
||||
0x0000000000080100ULL
|
||||
};
|
||||
|
||||
/* IBUF_CTRL, part of the Input System 2401 */
|
||||
const hrt_address IBUF_CTRL_BASE[N_IBUF_CTRL_ID] = {
|
||||
0x00000000000C1800ULL, /* ibuf controller A */
|
||||
0x00000000000C3800ULL, /* ibuf controller B */
|
||||
0x00000000000C5800ULL /* ibuf controller C */
|
||||
};
|
||||
|
||||
/* ISYS IRQ Controllers, part of the Input System 2401 */
|
||||
const hrt_address ISYS_IRQ_BASE[N_ISYS_IRQ_ID] = {
|
||||
0x00000000000C1400ULL, /* port a */
|
||||
0x00000000000C3400ULL, /* port b */
|
||||
0x00000000000C5400ULL /* port c */
|
||||
};
|
||||
|
||||
/* CSI FE, part of the Input System 2401 */
|
||||
const hrt_address CSI_RX_FE_CTRL_BASE[N_CSI_RX_FRONTEND_ID] = {
|
||||
0x00000000000C0400ULL, /* csi fe controller A */
|
||||
0x00000000000C2400ULL, /* csi fe controller B */
|
||||
0x00000000000C4400ULL /* csi fe controller C */
|
||||
};
|
||||
|
||||
/* CSI BE, part of the Input System 2401 */
|
||||
const hrt_address CSI_RX_BE_CTRL_BASE[N_CSI_RX_BACKEND_ID] = {
|
||||
0x00000000000C0800ULL, /* csi be controller A */
|
||||
0x00000000000C2800ULL, /* csi be controller B */
|
||||
0x00000000000C4800ULL /* csi be controller C */
|
||||
};
|
||||
|
||||
/* PIXEL Generator, part of the Input System 2401 */
|
||||
const hrt_address PIXELGEN_CTRL_BASE[N_PIXELGEN_ID] = {
|
||||
0x00000000000C1000ULL, /* pixel gen controller A */
|
||||
0x00000000000C3000ULL, /* pixel gen controller B */
|
||||
0x00000000000C5000ULL /* pixel gen controller C */
|
||||
};
|
||||
|
||||
/* Stream2MMIO, part of the Input System 2401 */
|
||||
const hrt_address STREAM2MMIO_CTRL_BASE[N_STREAM2MMIO_ID] = {
|
||||
0x00000000000C0C00ULL, /* stream2mmio controller A */
|
||||
0x00000000000C2C00ULL, /* stream2mmio controller B */
|
||||
0x00000000000C4C00ULL /* stream2mmio controller C */
|
||||
};
|
|
@ -1,11 +1,103 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
|
||||
* Support for Intel Camera Imaging ISP subsystem.
|
||||
* Copyright (c) 2015, Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* 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 ISP2401
|
||||
# include "isp2401_system_local.h"
|
||||
#else
|
||||
# include "isp2400_system_local.h"
|
||||
#ifndef __SYSTEM_LOCAL_H_INCLUDED__
|
||||
#define __SYSTEM_LOCAL_H_INCLUDED__
|
||||
|
||||
#ifdef HRT_ISP_CSS_CUSTOM_HOST
|
||||
#ifndef HRT_USE_VIR_ADDRS
|
||||
#define HRT_USE_VIR_ADDRS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "system_global.h"
|
||||
|
||||
/* This interface is deprecated */
|
||||
#include "hive_types.h"
|
||||
|
||||
/*
|
||||
* Cell specific address maps
|
||||
*/
|
||||
|
||||
#define GP_FIFO_BASE ((hrt_address)0x0000000000090104) /* This is NOT a base address */
|
||||
|
||||
/* ISP */
|
||||
extern const hrt_address ISP_CTRL_BASE[N_ISP_ID];
|
||||
extern const hrt_address ISP_DMEM_BASE[N_ISP_ID];
|
||||
extern const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID];
|
||||
|
||||
/* SP */
|
||||
extern const hrt_address SP_CTRL_BASE[N_SP_ID];
|
||||
extern const hrt_address SP_DMEM_BASE[N_SP_ID];
|
||||
|
||||
/* MMU */
|
||||
|
||||
extern const hrt_address MMU_BASE[N_MMU_ID];
|
||||
|
||||
/* DMA */
|
||||
extern const hrt_address DMA_BASE[N_DMA_ID];
|
||||
extern const hrt_address ISYS2401_DMA_BASE[N_ISYS2401_DMA_ID];
|
||||
|
||||
/* IRQ */
|
||||
extern const hrt_address IRQ_BASE[N_IRQ_ID];
|
||||
|
||||
/* GDC */
|
||||
extern const hrt_address GDC_BASE[N_GDC_ID];
|
||||
|
||||
/* FIFO_MONITOR (not a subset of GP_DEVICE) */
|
||||
extern const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID];
|
||||
|
||||
/* GP_DEVICE (single base for all separate GP_REG instances) */
|
||||
extern const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID];
|
||||
|
||||
/*GP TIMER , all timer registers are inter-twined,
|
||||
* so, having multiple base addresses for
|
||||
* different timers does not help*/
|
||||
extern const hrt_address GP_TIMER_BASE;
|
||||
|
||||
/* GPIO */
|
||||
extern const hrt_address GPIO_BASE[N_GPIO_ID];
|
||||
|
||||
/* TIMED_CTRL */
|
||||
extern const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID];
|
||||
|
||||
/* INPUT_FORMATTER */
|
||||
extern const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID];
|
||||
|
||||
/* INPUT_SYSTEM */
|
||||
extern const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID];
|
||||
|
||||
/* RX, the MIPI lane control regs start at offset 0 */
|
||||
extern const hrt_address RX_BASE[N_RX_ID];
|
||||
|
||||
/* IBUF_CTRL, part of the Input System 2401 */
|
||||
extern const hrt_address IBUF_CTRL_BASE[N_IBUF_CTRL_ID];
|
||||
|
||||
/* ISYS IRQ Controllers, part of the Input System 2401 */
|
||||
extern const hrt_address ISYS_IRQ_BASE[N_ISYS_IRQ_ID];
|
||||
|
||||
/* CSI FE, part of the Input System 2401 */
|
||||
extern const hrt_address CSI_RX_FE_CTRL_BASE[N_CSI_RX_FRONTEND_ID];
|
||||
|
||||
/* CSI BE, part of the Input System 2401 */
|
||||
extern const hrt_address CSI_RX_BE_CTRL_BASE[N_CSI_RX_BACKEND_ID];
|
||||
|
||||
/* PIXEL Generator, part of the Input System 2401 */
|
||||
extern const hrt_address PIXELGEN_CTRL_BASE[N_PIXELGEN_ID];
|
||||
|
||||
/* Stream2MMIO, part of the Input System 2401 */
|
||||
extern const hrt_address STREAM2MMIO_CTRL_BASE[N_STREAM2MMIO_ID];
|
||||
|
||||
#endif /* __SYSTEM_LOCAL_H_INCLUDED__ */
|
||||
|
|
Loading…
Reference in New Issue