summaryrefslogtreecommitdiffstats
path: root/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0504-media-i2c-max9296-add-MIPI-GMSL2-support.patch
blob: 5301e0a38a7192f187e715dc9288b005833fa5a4 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
From ebdaf5ec6d7040c1c7c9a3486ea16ea60f5f127f Mon Sep 17 00:00:00 2001
From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
Date: Wed, 29 Apr 2020 01:31:03 +0300
Subject: [PATCH] media: i2c: max9296: add MIPI GMSL2 support

This adds MIPI stream from serializer

Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
---
 drivers/media/i2c/soc_camera/gmsl/max9296.c | 75 +++++++++++++++++------------
 drivers/media/i2c/soc_camera/gmsl/max9296.h |  6 +--
 2 files changed, 47 insertions(+), 34 deletions(-)

diff --git a/drivers/media/i2c/soc_camera/gmsl/max9296.c b/drivers/media/i2c/soc_camera/gmsl/max9296.c
index a6d286f..85b45ca 100644
--- a/drivers/media/i2c/soc_camera/gmsl/max9296.c
+++ b/drivers/media/i2c/soc_camera/gmsl/max9296.c
@@ -94,7 +94,7 @@ static int gmsl = MODE_GMSL2;
 module_param(gmsl, int, 0644);
 MODULE_PARM_DESC(gmsl, " GMSL mode (default: 2 - GMSL2)");
 
-static char *mbus = "dvp";
+static char *mbus = mbus_default;
 module_param(mbus, charp, 0644);
 MODULE_PARM_DESC(mbus, " Interfaces mipi,dvp (default: dvp)");
 
@@ -165,7 +165,7 @@ static void max9296_reset_oneshot(struct max9296_priv *priv)
 		if (!(reg & BIT(5)))
 			break;
 
-		msleep(1);
+		mdelay(1);
 	}
 
 	if (reg & BIT(5))
@@ -745,9 +745,12 @@ static int max9296_gmsl2_reverse_channel_setup(struct max9296_priv *priv, int li
 	des_update_bits(MAX9296_CTRL0, 0x13, BIT(link_n));	/* enable GMSL link# */
 	max9296_reset_oneshot(priv);
 
-	/* wait 100ms for link to be established, indicated when status bit LOCKED goes high */
-	while ((!max9296_gmsl2_get_link_lock(priv, link_n)) && (--timeout))
-		msleep(1);
+	/* wait the link to be established, indicated when status bit LOCKED goes high */
+	for (; timeout > 0; timeout--) {
+		if (max9296_gmsl2_get_link_lock(priv, link_n))
+			break;
+		mdelay(1);
+	}
 
 	if (!timeout) {
 		ret = -ETIMEDOUT;
@@ -785,36 +788,42 @@ static int max9296_gmsl2_link_serializer_setup(struct max9296_priv *priv, int li
 	struct max9296_link *link = priv->link[link_n];
 	int i;
 
-	//ser_write(MAX9295_CTRL0, 0x31);		/* link reset */
-	//msleep(100);
-	ser_write(MAX9295_REG2, 0x03);			/* disable all pipes */
-
 	if (strcmp(priv->mbus, "dvp") == 0) {
-		ser_write(MAX9295_VIDEO_TX0(0),  BIT(6) |	/* line CRC enable */
+		ser_write(MAX9295_VIDEO_TX0(0), BIT(6) |	/* line CRC enable */
 						(priv->hven ? BIT(5) : 0)); /* HS/VS encoding */
 		ser_write(MAX9295_VIDEO_TX1(0), 0x0a);	/* BPP = 10 */
 		ser_write(MAX9295_REG7, 0x07);		/* DVP stream, enable HS/VS, rising edge */
-	}
-
-	ser_write(MAX9295_REG2, 0x13);			/* enable Pipe X */
 
-	switch (priv->dt) {
-	case MIPI_DT_YUV8:
-	case MIPI_DT_RAW12:
-		/* setup crossbar: strait DVP mapping */
-		ser_write(MAX9295_CROSS(0), priv->cb[0]);
-		ser_write(MAX9295_CROSS(1), priv->cb[1]);
-		ser_write(MAX9295_CROSS(2), priv->cb[2]);
-		ser_write(MAX9295_CROSS(3), priv->cb[3]);
-		ser_write(MAX9295_CROSS(4), priv->cb[4]);
-		ser_write(MAX9295_CROSS(5), priv->cb[5]);
-		ser_write(MAX9295_CROSS(6), priv->cb[6]);
-		ser_write(MAX9295_CROSS(7), priv->cb[7]);
-		ser_write(MAX9295_CROSS(8), priv->cb[8]);
-		ser_write(MAX9295_CROSS(9), priv->cb[9]);
-		ser_write(MAX9295_CROSS(10), priv->cb[10]);
-		ser_write(MAX9295_CROSS(11), priv->cb[11]);
-		break;
+		switch (priv->dt) {
+		case MIPI_DT_YUV8:
+		case MIPI_DT_RAW12:
+			/* setup crossbar: strait DVP mapping */
+			ser_write(MAX9295_CROSS(0), priv->cb[0]);
+			ser_write(MAX9295_CROSS(1), priv->cb[1]);
+			ser_write(MAX9295_CROSS(2), priv->cb[2]);
+			ser_write(MAX9295_CROSS(3), priv->cb[3]);
+			ser_write(MAX9295_CROSS(4), priv->cb[4]);
+			ser_write(MAX9295_CROSS(5), priv->cb[5]);
+			ser_write(MAX9295_CROSS(6), priv->cb[6]);
+			ser_write(MAX9295_CROSS(7), priv->cb[7]);
+			ser_write(MAX9295_CROSS(8), priv->cb[8]);
+			ser_write(MAX9295_CROSS(9), priv->cb[9]);
+			ser_write(MAX9295_CROSS(10), priv->cb[10]);
+			ser_write(MAX9295_CROSS(11), priv->cb[11]);
+			break;
+		}
+	} else {
+		/* defaults:
+		 *  REG2	- video enable Pipex X,Z
+		 *  MIPI_RX0	- 1x4 mode (1-port x 4-lanes)
+		 *  MIPI_RX1	- 4-lanes
+		 *  MIPI_RX2, MIPI_RX3 - merge PHY1,PHY2 to 1x4-mode
+		 *  FRONTTOP_9	- start Pipes X,Z from CSI_A,CSI_B
+		 */
+
+		ser_write(MAX9295_FRONTTOP_0, 0x71);			/* enable Pipe X from from CSI_A,CSI_B */
+		ser_write(MAX9295_FRONTTOP_12, BIT(6) | priv->dt);	/* primary DT for Pipe X */
+		ser_write(MAX9295_FRONTTOP_13, BIT(6) | MIPI_DT_EMB);	/* secondary DT for Pipe X */
 	}
 
 	for (i = 0; i < 11; i++) {
@@ -856,7 +865,9 @@ static struct {
 } gmsl2_pipe_maps[] = {
 	{0x00,		0x00},		/* FS */
 	{0x01,		0x01},		/* FE */
-	{MIPI_DT_YUV8,	MIPI_DT_YUV8}	/* payload data */
+	{MIPI_DT_YUV8,	MIPI_DT_YUV8},	/* payload data */
+	{MIPI_DT_RAW8,	MIPI_DT_RAW8},
+	{MIPI_DT_RAW12,	MIPI_DT_RAW12},
 };
 
 static void max9296_gmsl2_pipe_set_source(struct max9296_priv *priv, int pipe, int phy, int in_pipe)
@@ -1193,6 +1204,8 @@ static int max9296_parse_dt(struct i2c_client *client)
 		priv->gpio[7] = gpio7;
 	if (gpio8 >= 0)
 		priv->gpio[8] = gpio8;
+	if (strcmp(mbus, "dvp"))
+		priv->mbus = mbus;
 
 	/* parse serializer crossbar setup */
 	for (i = 0; i < 16; i++) {
diff --git a/drivers/media/i2c/soc_camera/gmsl/max9296.h b/drivers/media/i2c/soc_camera/gmsl/max9296.h
index 800df43..985b77e 100644
--- a/drivers/media/i2c/soc_camera/gmsl/max9296.h
+++ b/drivers/media/i2c/soc_camera/gmsl/max9296.h
@@ -254,11 +254,11 @@ static inline int max9296_ser_write(struct max9296_link *link, int reg, int val)
 	return ret;
 }
 
-static inline int max9296_ser_read(struct max9296_link *link, int reg, u8 *val)
+static inline int max9296_ser_read(struct max9296_link *link, int reg, int *val)
 {
 	int ret;
 
-	ret = regmap_read(link->regmap, reg, (int *)val);
+	ret = regmap_read(link->regmap, reg, val);
 	if (ret)
 		dev_dbg(&link->client->dev, "read register 0x%04x failed (%d)\n", reg, ret);
 
@@ -276,6 +276,6 @@ static inline int max9296_ser_update_bits(struct max9296_link *link, int reg, in
 	return ret;
 }
 
-#define ser_read(reg, val)			max9296_ser_read(link, reg, val)
+#define ser_read(reg, val)			max9296_ser_read(link, reg, (int *)val)
 #define ser_write(reg, val)			max9296_ser_write(link, reg, val)
 #define ser_update_bits(reg, mask, bits)	max9296_ser_update_bits(link, reg, mask, bits)
-- 
2.7.4