summaryrefslogtreecommitdiff
path: root/drivers/staging/media/starfive/camss/stf-camss.h
blob: e2b0cfb437bdb00336cd6fe6662769b65e2adb53 (plain)
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
128
129
130
131
132
133
134
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * stf_camss.h
 *
 * Starfive Camera Subsystem driver
 *
 * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
 */

#ifndef STF_CAMSS_H
#define STF_CAMSS_H

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/reset.h>
#include <media/media-device.h>
#include <media/media-entity.h>
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>

#include "stf-isp.h"
#include "stf-capture.h"

enum stf_port_num {
	STF_PORT_DVP = 0,
	STF_PORT_CSI2RX
};

enum stf_clk {
	STF_CLK_WRAPPER_CLK_C = 0,
	STF_CLK_ISPCORE_2X,
	STF_CLK_ISP_AXI,
	STF_CLK_NUM
};

enum stf_rst {
	STF_RST_WRAPPER_P = 0,
	STF_RST_WRAPPER_C,
	STF_RST_AXIWR,
	STF_RST_ISP_TOP_N,
	STF_RST_ISP_TOP_AXI,
	STF_RST_NUM
};

struct stf_isr_data {
	const char *name;
	irqreturn_t (*isr)(int irq, void *priv);
};

struct stfcamss {
	struct v4l2_device v4l2_dev;
	struct media_device media_dev;
	struct media_pipeline pipe;
	struct device *dev;
	struct stf_isp_dev isp_dev;
	struct stf_capture captures[STF_CAPTURE_NUM];
	struct v4l2_async_notifier notifier;
	void __iomem *syscon_base;
	void __iomem *isp_base;
	struct clk_bulk_data sys_clk[STF_CLK_NUM];
	int nclks;
	struct reset_control_bulk_data sys_rst[STF_RST_NUM];
	int nrsts;
};

struct stfcamss_async_subdev {
	struct v4l2_async_connection asd;  /* must be first */
	enum stf_port_num port;
};

static inline u32 stf_isp_reg_read(struct stfcamss *stfcamss, u32 reg)
{
	return ioread32(stfcamss->isp_base + reg);
}

static inline void stf_isp_reg_write(struct stfcamss *stfcamss,
				     u32 reg, u32 val)
{
	iowrite32(val, stfcamss->isp_base + reg);
}

static inline void stf_isp_reg_write_delay(struct stfcamss *stfcamss,
					   u32 reg, u32 val, u32 delay)
{
	iowrite32(val, stfcamss->isp_base + reg);
	usleep_range(1000 * delay, 1000 * delay + 100);
}

static inline void stf_isp_reg_set_bit(struct stfcamss *stfcamss,
				       u32 reg, u32 mask, u32 val)
{
	u32 value;

	value = ioread32(stfcamss->isp_base + reg) & ~mask;
	val &= mask;
	val |= value;
	iowrite32(val, stfcamss->isp_base + reg);
}

static inline void stf_isp_reg_set(struct stfcamss *stfcamss, u32 reg, u32 mask)
{
	iowrite32(ioread32(stfcamss->isp_base + reg) | mask,
		  stfcamss->isp_base + reg);
}

static inline u32 stf_syscon_reg_read(struct stfcamss *stfcamss, u32 reg)
{
	return ioread32(stfcamss->syscon_base + reg);
}

static inline void stf_syscon_reg_write(struct stfcamss *stfcamss,
					u32 reg, u32 val)
{
	iowrite32(val, stfcamss->syscon_base + reg);
}

static inline void stf_syscon_reg_set_bit(struct stfcamss *stfcamss,
					  u32 reg, u32 bit_mask)
{
	u32 value;

	value = ioread32(stfcamss->syscon_base + reg);
	iowrite32(value | bit_mask, stfcamss->syscon_base + reg);
}

static inline void stf_syscon_reg_clear_bit(struct stfcamss *stfcamss,
					    u32 reg, u32 bit_mask)
{
	u32 value;

	value = ioread32(stfcamss->syscon_base + reg);
	iowrite32(value & ~bit_mask, stfcamss->syscon_base + reg);
}
#endif /* STF_CAMSS_H */