Skip to content

Commit f5abf6f

Browse files
Niklas Söderlundmorimoto
authored andcommitted
media: rcar-csi2: Add support for C-PHY on R-Car V4H
Add support for C-PHY on R-Car V4H. While the V4H supports both D-PHY and C-PHY this patch only adds support for the C-PHY mode due to lack of documentation and hardware to test on. The V4H is the first Gen4 device that is enabled in the rcar-csi2 driver. There is much overlap with the Gen3 driver, the primary difference is in how the receiver is started. The V4H have a much larger register space and some addresses overlap with Gen3. [Sakari Ailus: Use div_u64() to divide a 64-bit integer.] Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org> (cherry picked from commit 82bc596) Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
1 parent d5d73e6 commit f5abf6f

File tree

1 file changed

+291
-0
lines changed

1 file changed

+291
-0
lines changed

drivers/media/platform/renesas/rcar-vin/rcar-csi2.c

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,111 @@ struct rcar_csi2;
133133
#define PHYFRX_FORCERX_MODE_1 BIT(1)
134134
#define PHYFRX_FORCERX_MODE_0 BIT(0)
135135

136+
/* V4H BASE registers */
137+
#define V4H_N_LANES_REG 0x0004
138+
#define V4H_CSI2_RESETN_REG 0x0008
139+
#define V4H_PHY_MODE_REG 0x001c
140+
#define V4H_PHY_SHUTDOWNZ_REG 0x0040
141+
#define V4H_DPHY_RSTZ_REG 0x0044
142+
#define V4H_FLDC_REG 0x0804
143+
#define V4H_FLDD_REG 0x0808
144+
#define V4H_IDIC_REG 0x0810
145+
#define V4H_PHY_EN_REG 0x2000
146+
147+
#define V4H_ST_PHYST_REG 0x2814
148+
#define V4H_ST_PHYST_ST_PHY_READY BIT(31)
149+
#define V4H_ST_PHYST_ST_STOPSTATE_3 BIT(3)
150+
#define V4H_ST_PHYST_ST_STOPSTATE_2 BIT(2)
151+
#define V4H_ST_PHYST_ST_STOPSTATE_1 BIT(1)
152+
#define V4H_ST_PHYST_ST_STOPSTATE_0 BIT(0)
153+
154+
/* V4H PPI registers */
155+
#define V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(n) (0x21800 + ((n) * 2)) /* n = 0 - 9 */
156+
#define V4H_PPI_STARTUP_RW_COMMON_STARTUP_1_1_REG 0x21822
157+
#define V4H_PPI_CALIBCTRL_RW_COMMON_BG_0_REG 0x2184c
158+
#define V4H_PPI_RW_LPDCOCAL_TIMEBASE_REG 0x21c02
159+
#define V4H_PPI_RW_LPDCOCAL_NREF_REG 0x21c04
160+
#define V4H_PPI_RW_LPDCOCAL_NREF_RANGE_REG 0x21c06
161+
#define V4H_PPI_RW_LPDCOCAL_TWAIT_CONFIG_REG 0x21c0a
162+
#define V4H_PPI_RW_LPDCOCAL_VT_CONFIG_REG 0x21c0c
163+
#define V4H_PPI_RW_LPDCOCAL_COARSE_CFG_REG 0x21c10
164+
#define V4H_PPI_RW_COMMON_CFG_REG 0x21c6c
165+
#define V4H_PPI_RW_TERMCAL_CFG_0_REG 0x21c80
166+
#define V4H_PPI_RW_OFFSETCAL_CFG_0_REG 0x21ca0
167+
168+
/* V4H CORE registers */
169+
#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(n) (0x22040 + ((n) * 2)) /* n = 0 - 15 */
170+
#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_REG(n) (0x22440 + ((n) * 2)) /* n = 0 - 15 */
171+
#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_REG(n) (0x22840 + ((n) * 2)) /* n = 0 - 15 */
172+
#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_REG(n) (0x22c40 + ((n) * 2)) /* n = 0 - 15 */
173+
#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_REG(n) (0x23040 + ((n) * 2)) /* n = 0 - 15 */
174+
#define V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(n) (0x23840 + ((n) * 2)) /* n = 0 - 11 */
175+
#define V4H_CORE_DIG_RW_COMMON_REG(n) (0x23880 + ((n) * 2)) /* n = 0 - 15 */
176+
#define V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(n) (0x239e0 + ((n) * 2)) /* n = 0 - 3 */
177+
#define V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG 0x2a400
178+
#define V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG 0x2a60c
179+
180+
/* V4H C-PHY */
181+
#define V4H_CORE_DIG_RW_TRIO0_REG(n) (0x22100 + ((n) * 2)) /* n = 0 - 3 */
182+
#define V4H_CORE_DIG_RW_TRIO1_REG(n) (0x22500 + ((n) * 2)) /* n = 0 - 3 */
183+
#define V4H_CORE_DIG_RW_TRIO2_REG(n) (0x22900 + ((n) * 2)) /* n = 0 - 3 */
184+
#define V4H_CORE_DIG_CLANE_0_RW_LP_0_REG 0x2a080
185+
#define V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(n) (0x2a100 + ((n) * 2)) /* n = 0 - 6 */
186+
#define V4H_CORE_DIG_CLANE_1_RW_LP_0_REG 0x2a480
187+
#define V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(n) (0x2a500 + ((n) * 2)) /* n = 0 - 6 */
188+
#define V4H_CORE_DIG_CLANE_2_RW_LP_0_REG 0x2a880
189+
#define V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(n) (0x2a900 + ((n) * 2)) /* n = 0 - 6 */
190+
191+
struct rcsi2_cphy_setting {
192+
u16 msps;
193+
u16 rx2;
194+
u16 trio0;
195+
u16 trio1;
196+
u16 trio2;
197+
u16 lane27;
198+
u16 lane29;
199+
};
200+
201+
static const struct rcsi2_cphy_setting cphy_setting_table_r8a779g0[] = {
202+
{ .msps = 80, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0134, .trio2 = 0x6a, .lane27 = 0x0000, .lane29 = 0x0a24 },
203+
{ .msps = 100, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x00f5, .trio2 = 0x55, .lane27 = 0x0000, .lane29 = 0x0a24 },
204+
{ .msps = 200, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0077, .trio2 = 0x2b, .lane27 = 0x0000, .lane29 = 0x0a44 },
205+
{ .msps = 300, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x004d, .trio2 = 0x1d, .lane27 = 0x0000, .lane29 = 0x0a44 },
206+
{ .msps = 400, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0038, .trio2 = 0x16, .lane27 = 0x0000, .lane29 = 0x0a64 },
207+
{ .msps = 500, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x002b, .trio2 = 0x12, .lane27 = 0x0000, .lane29 = 0x0a64 },
208+
{ .msps = 600, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0023, .trio2 = 0x0f, .lane27 = 0x0000, .lane29 = 0x0a64 },
209+
{ .msps = 700, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x001d, .trio2 = 0x0d, .lane27 = 0x0000, .lane29 = 0x0a84 },
210+
{ .msps = 800, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0018, .trio2 = 0x0c, .lane27 = 0x0000, .lane29 = 0x0a84 },
211+
{ .msps = 900, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0015, .trio2 = 0x0b, .lane27 = 0x0000, .lane29 = 0x0a84 },
212+
{ .msps = 1000, .rx2 = 0x3e, .trio0 = 0x024a, .trio1 = 0x0012, .trio2 = 0x0a, .lane27 = 0x0400, .lane29 = 0x0a84 },
213+
{ .msps = 1100, .rx2 = 0x44, .trio0 = 0x024a, .trio1 = 0x000f, .trio2 = 0x09, .lane27 = 0x0800, .lane29 = 0x0a84 },
214+
{ .msps = 1200, .rx2 = 0x4a, .trio0 = 0x024a, .trio1 = 0x000e, .trio2 = 0x08, .lane27 = 0x0c00, .lane29 = 0x0a84 },
215+
{ .msps = 1300, .rx2 = 0x51, .trio0 = 0x024a, .trio1 = 0x000c, .trio2 = 0x08, .lane27 = 0x0c00, .lane29 = 0x0aa4 },
216+
{ .msps = 1400, .rx2 = 0x57, .trio0 = 0x024a, .trio1 = 0x000b, .trio2 = 0x07, .lane27 = 0x1000, .lane29 = 0x0aa4 },
217+
{ .msps = 1500, .rx2 = 0x5d, .trio0 = 0x044a, .trio1 = 0x0009, .trio2 = 0x07, .lane27 = 0x1000, .lane29 = 0x0aa4 },
218+
{ .msps = 1600, .rx2 = 0x63, .trio0 = 0x044a, .trio1 = 0x0008, .trio2 = 0x07, .lane27 = 0x1400, .lane29 = 0x0aa4 },
219+
{ .msps = 1700, .rx2 = 0x6a, .trio0 = 0x044a, .trio1 = 0x0007, .trio2 = 0x06, .lane27 = 0x1400, .lane29 = 0x0aa4 },
220+
{ .msps = 1800, .rx2 = 0x70, .trio0 = 0x044a, .trio1 = 0x0007, .trio2 = 0x06, .lane27 = 0x1400, .lane29 = 0x0aa4 },
221+
{ .msps = 1900, .rx2 = 0x76, .trio0 = 0x044a, .trio1 = 0x0006, .trio2 = 0x06, .lane27 = 0x1400, .lane29 = 0x0aa4 },
222+
{ .msps = 2000, .rx2 = 0x7c, .trio0 = 0x044a, .trio1 = 0x0005, .trio2 = 0x06, .lane27 = 0x1800, .lane29 = 0x0aa4 },
223+
{ .msps = 2100, .rx2 = 0x83, .trio0 = 0x044a, .trio1 = 0x0005, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 },
224+
{ .msps = 2200, .rx2 = 0x89, .trio0 = 0x064a, .trio1 = 0x0004, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 },
225+
{ .msps = 2300, .rx2 = 0x8f, .trio0 = 0x064a, .trio1 = 0x0003, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 },
226+
{ .msps = 2400, .rx2 = 0x95, .trio0 = 0x064a, .trio1 = 0x0003, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 },
227+
{ .msps = 2500, .rx2 = 0x9c, .trio0 = 0x064a, .trio1 = 0x0003, .trio2 = 0x05, .lane27 = 0x1c00, .lane29 = 0x0aa4 },
228+
{ .msps = 2600, .rx2 = 0xa2, .trio0 = 0x064a, .trio1 = 0x0002, .trio2 = 0x05, .lane27 = 0x1c00, .lane29 = 0x0ad4 },
229+
{ .msps = 2700, .rx2 = 0xa8, .trio0 = 0x064a, .trio1 = 0x0002, .trio2 = 0x05, .lane27 = 0x1c00, .lane29 = 0x0ad4 },
230+
{ .msps = 2800, .rx2 = 0xae, .trio0 = 0x064a, .trio1 = 0x0002, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 },
231+
{ .msps = 2900, .rx2 = 0xb5, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 },
232+
{ .msps = 3000, .rx2 = 0xbb, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 },
233+
{ .msps = 3100, .rx2 = 0xc1, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 },
234+
{ .msps = 3200, .rx2 = 0xc7, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 },
235+
{ .msps = 3300, .rx2 = 0xce, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 },
236+
{ .msps = 3400, .rx2 = 0xd4, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 },
237+
{ .msps = 3500, .rx2 = 0xda, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 },
238+
{ /* sentinel */ },
239+
};
240+
136241
struct phtw_value {
137242
u16 data;
138243
u16 code;
@@ -538,6 +643,11 @@ static void rcsi2_write(struct rcar_csi2 *priv, unsigned int reg, u32 data)
538643
iowrite32(data, priv->base + reg);
539644
}
540645

646+
static void rcsi2_write16(struct rcar_csi2 *priv, unsigned int reg, u16 data)
647+
{
648+
iowrite16(data, priv->base + reg);
649+
}
650+
541651
static void rcsi2_enter_standby_gen3(struct rcar_csi2 *priv)
542652
{
543653
rcsi2_write(priv, PHYCNT_REG, 0);
@@ -645,6 +755,10 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp,
645755
mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * bpp;
646756
do_div(mbps, lanes * 1000000);
647757

758+
/* Adjust for C-PHY, divide by 2.8. */
759+
if (priv->cphy)
760+
mbps = div_u64(mbps * 5, 14);
761+
648762
return mbps;
649763
}
650764

@@ -834,6 +948,173 @@ static int rcsi2_start_receiver_gen3(struct rcar_csi2 *priv)
834948
return 0;
835949
}
836950

951+
static int rcsi2_wait_phy_start_v4h(struct rcar_csi2 *priv, u32 match)
952+
{
953+
unsigned int timeout;
954+
u32 status;
955+
956+
for (timeout = 0; timeout <= 10; timeout++) {
957+
status = rcsi2_read(priv, V4H_ST_PHYST_REG);
958+
if ((status & match) == match)
959+
return 0;
960+
961+
usleep_range(1000, 2000);
962+
}
963+
964+
return -ETIMEDOUT;
965+
}
966+
967+
static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps)
968+
{
969+
const struct rcsi2_cphy_setting *conf;
970+
971+
for (conf = cphy_setting_table_r8a779g0; conf->msps != 0; conf++) {
972+
if (conf->msps > msps)
973+
break;
974+
}
975+
976+
if (!conf->msps) {
977+
dev_err(priv->dev, "Unsupported PHY speed for msps setting (%u Msps)", msps);
978+
return -ERANGE;
979+
}
980+
981+
/* C-PHY specific */
982+
rcsi2_write16(priv, V4H_CORE_DIG_RW_COMMON_REG(7), 0x0155);
983+
rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(7), 0x0068);
984+
rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(8), 0x0010);
985+
986+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_LP_0_REG, 0x463c);
987+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_LP_0_REG, 0x463c);
988+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_LP_0_REG, 0x463c);
989+
990+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(0), 0x00d5);
991+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(0), 0x00d5);
992+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(0), 0x00d5);
993+
994+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(1), 0x0013);
995+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(1), 0x0013);
996+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(1), 0x0013);
997+
998+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(5), 0x0013);
999+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(5), 0x0013);
1000+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(5), 0x0013);
1001+
1002+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(6), 0x000a);
1003+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(6), 0x000a);
1004+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(6), 0x000a);
1005+
1006+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(2), conf->rx2);
1007+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(2), conf->rx2);
1008+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(2), conf->rx2);
1009+
1010+
rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(2), 0x0001);
1011+
rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_REG(2), 0);
1012+
rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_REG(2), 0x0001);
1013+
rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_REG(2), 0x0001);
1014+
rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_REG(2), 0);
1015+
1016+
rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(0), conf->trio0);
1017+
rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(0), conf->trio0);
1018+
rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO2_REG(0), conf->trio0);
1019+
1020+
rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(2), conf->trio2);
1021+
rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(2), conf->trio2);
1022+
rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO2_REG(2), conf->trio2);
1023+
1024+
rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(1), conf->trio1);
1025+
rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(1), conf->trio1);
1026+
rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO2_REG(1), conf->trio1);
1027+
1028+
/*
1029+
* Configure pin-swap.
1030+
* TODO: This registers is not documented yet, the values should depend
1031+
* on the 'clock-lanes' and 'data-lanes' devicetree properties.
1032+
*/
1033+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG, 0xf5);
1034+
rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG, 0x5000);
1035+
1036+
/* Leave Shutdown mode */
1037+
rcsi2_write(priv, V4H_DPHY_RSTZ_REG, BIT(0));
1038+
rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, BIT(0));
1039+
1040+
/* Wait for calibration */
1041+
if (rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_PHY_READY)) {
1042+
dev_err(priv->dev, "PHY calibration failed\n");
1043+
return -ETIMEDOUT;
1044+
}
1045+
1046+
/* C-PHY setting - analog programing*/
1047+
rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(9), conf->lane29);
1048+
rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(7), conf->lane27);
1049+
1050+
return 0;
1051+
}
1052+
1053+
static int rcsi2_start_receiver_v4h(struct rcar_csi2 *priv)
1054+
{
1055+
const struct rcar_csi2_format *format;
1056+
unsigned int lanes;
1057+
int msps;
1058+
int ret;
1059+
1060+
/* Calculate parameters */
1061+
format = rcsi2_code_to_fmt(priv->mf.code);
1062+
if (!format)
1063+
return -EINVAL;
1064+
1065+
ret = rcsi2_get_active_lanes(priv, &lanes);
1066+
if (ret)
1067+
return ret;
1068+
1069+
msps = rcsi2_calc_mbps(priv, format->bpp, lanes);
1070+
if (msps < 0)
1071+
return msps;
1072+
1073+
/* Reset LINK and PHY*/
1074+
rcsi2_write(priv, V4H_CSI2_RESETN_REG, 0);
1075+
rcsi2_write(priv, V4H_DPHY_RSTZ_REG, 0);
1076+
rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, 0);
1077+
1078+
/* PHY static setting */
1079+
rcsi2_write(priv, V4H_PHY_EN_REG, BIT(0));
1080+
rcsi2_write(priv, V4H_FLDC_REG, 0);
1081+
rcsi2_write(priv, V4H_FLDD_REG, 0);
1082+
rcsi2_write(priv, V4H_IDIC_REG, 0);
1083+
rcsi2_write(priv, V4H_PHY_MODE_REG, BIT(0));
1084+
rcsi2_write(priv, V4H_N_LANES_REG, lanes - 1);
1085+
1086+
/* Reset CSI2 */
1087+
rcsi2_write(priv, V4H_CSI2_RESETN_REG, BIT(0));
1088+
1089+
/* Registers static setting through APB */
1090+
/* Common setting */
1091+
rcsi2_write16(priv, V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(0), 0x1bfd);
1092+
rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_STARTUP_1_1_REG, 0x0233);
1093+
rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(6), 0x0027);
1094+
rcsi2_write16(priv, V4H_PPI_CALIBCTRL_RW_COMMON_BG_0_REG, 0x01f4);
1095+
rcsi2_write16(priv, V4H_PPI_RW_TERMCAL_CFG_0_REG, 0x0013);
1096+
rcsi2_write16(priv, V4H_PPI_RW_OFFSETCAL_CFG_0_REG, 0x0003);
1097+
rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_TIMEBASE_REG, 0x004f);
1098+
rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_NREF_REG, 0x0320);
1099+
rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_NREF_RANGE_REG, 0x000f);
1100+
rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_TWAIT_CONFIG_REG, 0xfe18);
1101+
rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_VT_CONFIG_REG, 0x0c3c);
1102+
rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_COARSE_CFG_REG, 0x0105);
1103+
rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(6), 0x1000);
1104+
rcsi2_write16(priv, V4H_PPI_RW_COMMON_CFG_REG, 0x0003);
1105+
1106+
/* C-PHY settings */
1107+
ret = rcsi2_c_phy_setting_v4h(priv, msps);
1108+
if (ret)
1109+
return ret;
1110+
1111+
rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_STOPSTATE_0 |
1112+
V4H_ST_PHYST_ST_STOPSTATE_1 |
1113+
V4H_ST_PHYST_ST_STOPSTATE_2);
1114+
1115+
return 0;
1116+
}
1117+
8371118
static int rcsi2_start(struct rcar_csi2 *priv)
8381119
{
8391120
int ret;
@@ -1496,6 +1777,12 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = {
14961777
.support_dphy = true,
14971778
};
14981779

1780+
static const struct rcar_csi2_info rcar_csi2_info_r8a779g0 = {
1781+
.start_receiver = rcsi2_start_receiver_v4h,
1782+
.use_isp = true,
1783+
.support_cphy = true,
1784+
};
1785+
14991786
static const struct of_device_id rcar_csi2_of_table[] = {
15001787
{
15011788
.compatible = "renesas,r8a774a1-csi2",
@@ -1545,6 +1832,10 @@ static const struct of_device_id rcar_csi2_of_table[] = {
15451832
.compatible = "renesas,r8a779a0-csi2",
15461833
.data = &rcar_csi2_info_r8a779a0,
15471834
},
1835+
{
1836+
.compatible = "renesas,r8a779g0-csi2",
1837+
.data = &rcar_csi2_info_r8a779g0,
1838+
},
15481839
{ /* sentinel */ },
15491840
};
15501841
MODULE_DEVICE_TABLE(of, rcar_csi2_of_table);

0 commit comments

Comments
 (0)