/* SPDX-License-Identifier: GPL-2.0 */ /* * Rockchip CIF Driver * * Copyright (C) 2020 Rockchip Electronics Co., Ltd. */ #ifndef _RKCIF_HW_H #define _RKCIF_HW_H #include #include #include #include #include #include #include #include #include "regs.h" #include "version.h" #define RKCIF_DEV_MAX 2 #define RKCIF_HW_DRIVER_NAME "rkcifhw" #define RKCIF_MAX_BUS_CLK 8 #define RKCIF_MAX_RESET 15 #define write_cif_reg(base, addr, val) \ writel(val, (addr) + (base)) #define read_cif_reg(base, addr) \ readl((addr) + (base)) #define write_cif_reg_or(base, addr, val) \ writel(readl((addr) + (base)) | (val), (addr) + (base)) #define write_cif_reg_and(base, addr, val) \ writel(readl((addr) + (base)) & (val), (addr) + (base)) /* * add new chip id in tail in time order * by increasing to distinguish cif version */ enum rkcif_chip_id { CHIP_PX30_CIF, CHIP_RK3128_CIF, CHIP_RK3288_CIF, CHIP_RK3328_CIF, CHIP_RK3368_CIF, CHIP_RK1808_CIF, CHIP_RV1126_CIF, CHIP_RV1126_CIF_LITE, CHIP_RK3568_CIF, }; struct rkcif_hw_match_data { int chip_id; const char * const *clks; const char * const *rsts; int clks_num; int rsts_num; const struct cif_reg *cif_regs; }; /* * the detecting mode of cif reset timer * related with dts property:rockchip,cif-monitor */ enum rkcif_monitor_mode { RKCIF_MONITOR_MODE_IDLE = 0x0, RKCIF_MONITOR_MODE_CONTINUE, RKCIF_MONITOR_MODE_TRIGGER, RKCIF_MONITOR_MODE_HOTPLUG, }; struct rkcif_hw_timer { struct timer_list timer; spinlock_t timer_lock; unsigned long cycle_jif; /* unit: us */ unsigned int run_cnt; unsigned int max_run_cnt; unsigned int stop_index_of_run_cnt; unsigned int monitor_cycle; unsigned int err_ref_cnt; unsigned int err_time_interval; unsigned int is_reset_by_user; bool is_running; bool has_been_init; enum rkcif_monitor_mode monitor_mode; enum rkmodule_reset_src reset_src; }; /* * struct rkcif_device - ISP platform device * @base_addr: base register address * @active_sensor: sensor in-use, set when streaming on * @stream: capture video device */ struct rkcif_hw { struct device *dev; int irq; void __iomem *base_addr; void __iomem *csi_base; struct regmap *grf; struct clk *clks[RKCIF_MAX_BUS_CLK]; int clk_size; bool iommu_en; struct iommu_domain *domain; struct reset_control *cif_rst[RKCIF_MAX_RESET]; int chip_id; const struct cif_reg *cif_regs; bool can_be_reset; struct rkcif_device *cif_dev[RKCIF_DEV_MAX]; int dev_num; atomic_t power_cnt; const struct rkcif_hw_match_data *match_data; struct mutex dev_lock; struct rkcif_hw_timer hw_timer; struct rkcif_reset_info reset_info; spinlock_t spin_lock; bool reset_work_cancel; }; void rkcif_hw_soft_reset(struct rkcif_hw *cif_hw, bool is_rst_iommu); void rkcif_disable_sys_clk(struct rkcif_hw *cif_hw); int rkcif_enable_sys_clk(struct rkcif_hw *cif_hw); #endif