128 lines
3.0 KiB
C
Raw Permalink Normal View History

2025-05-10 21:58:58 +08:00
/* 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 <linux/mutex.h>
#include <media/media-device.h>
#include <media/media-entity.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/videobuf2-v4l2.h>
#include <media/v4l2-mc.h>
#include <linux/rk-camera-module.h>
#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