hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* 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