Skip to content

Commit fdac4ce

Browse files
committed
media: rkisp1: Configure gasket on i.MX8MP
The i.MX8MP has a gasket between the CSI-2 receiver and the ISP. Configure and enable it when starting the ISP, and disable it when stopping. Signed-off-by: Laurent Pinchart <[email protected]> Signed-off-by: Paul Elder <[email protected]> Tested-by: Alexander Stein <[email protected]> Tested-by: Adam Ford <[email protected]> Reviewed-by: Tomi Valkeinen <[email protected]>
1 parent 6e68228 commit fdac4ce

File tree

3 files changed

+149
-3
lines changed

3 files changed

+149
-3
lines changed

drivers/media/platform/rockchip/rkisp1/rkisp1-common.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "rkisp1-regs.h"
2525

2626
struct dentry;
27+
struct regmap;
2728

2829
/*
2930
* flags on the 'direction' field in struct rkisp1_mbus_info' that indicate
@@ -444,6 +445,8 @@ struct rkisp1_debug {
444445
* @dev: a pointer to the struct device
445446
* @clk_size: number of clocks
446447
* @clks: array of clocks
448+
* @gasket: the gasket - i.MX8MP only
449+
* @gasket_id: the gasket ID (0 or 1) - i.MX8MP only
447450
* @v4l2_dev: v4l2_device variable
448451
* @media_dev: media_device variable
449452
* @notifier: a notifier to register on the v4l2-async API to be notified on the sensor
@@ -465,6 +468,8 @@ struct rkisp1_device {
465468
struct device *dev;
466469
unsigned int clk_size;
467470
struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK];
471+
struct regmap *gasket;
472+
unsigned int gasket_id;
468473
struct v4l2_device v4l2_dev;
469474
struct media_device media_dev;
470475
struct v4l2_async_notifier notifier;

drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <linux/clk.h>
1212
#include <linux/interrupt.h>
13+
#include <linux/mfd/syscon.h>
1314
#include <linux/module.h>
1415
#include <linux/of.h>
1516
#include <linux/of_graph.h>
@@ -579,6 +580,21 @@ static int rkisp1_probe(struct platform_device *pdev)
579580
return ret;
580581
rkisp1->clk_size = info->clk_size;
581582

583+
if (info->isp_ver == RKISP1_V_IMX8MP) {
584+
unsigned int id;
585+
586+
rkisp1->gasket = syscon_regmap_lookup_by_phandle_args(dev->of_node,
587+
"fsl,blk-ctrl",
588+
1, &id);
589+
if (IS_ERR(rkisp1->gasket)) {
590+
ret = PTR_ERR(rkisp1->gasket);
591+
dev_err(dev, "failed to get gasket: %d\n", ret);
592+
return ret;
593+
}
594+
595+
rkisp1->gasket_id = id;
596+
}
597+
582598
pm_runtime_enable(&pdev->dev);
583599

584600
ret = pm_runtime_resume_and_get(&pdev->dev);

drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c

Lines changed: 128 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <linux/iopoll.h>
1212
#include <linux/pm_runtime.h>
13+
#include <linux/regmap.h>
1314
#include <linux/videodev2.h>
1415
#include <linux/vmalloc.h>
1516

@@ -53,6 +54,115 @@
5354
* +---------------------------------------------------------+
5455
*/
5556

57+
/* -----------------------------------------------------------------------------
58+
* Media block control (i.MX8MP only)
59+
*/
60+
61+
#define ISP_DEWARP_CONTROL 0x0138
62+
63+
#define ISP_DEWARP_CONTROL_MIPI_CSI2_HS_POLARITY BIT(22)
64+
#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_RISING (0 << 20)
65+
#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_NEGATIVE (1 << 20)
66+
#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_POSITIVE (2 << 20)
67+
#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_FALLING (3 << 20)
68+
#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_MASK GENMASK(21, 20)
69+
#define ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE BIT(19)
70+
#define ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE(dt) ((dt) << 13)
71+
#define ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK GENMASK(18, 13)
72+
73+
#define ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY BIT(12)
74+
#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_RISING (0 << 10)
75+
#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_NEGATIVE (1 << 10)
76+
#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_POSITIVE (2 << 10)
77+
#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_FALLING (3 << 10)
78+
#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_MASK GENMASK(11, 10)
79+
#define ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE BIT(9)
80+
#define ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE(dt) ((dt) << 3)
81+
#define ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK GENMASK(8, 3)
82+
83+
#define ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE BIT(1)
84+
#define ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE BIT(0)
85+
86+
static int rkisp1_gasket_enable(struct rkisp1_device *rkisp1,
87+
struct media_pad *source)
88+
{
89+
struct v4l2_subdev *source_sd;
90+
struct v4l2_mbus_frame_desc fd;
91+
unsigned int dt;
92+
u32 mask;
93+
u32 val;
94+
int ret;
95+
96+
/*
97+
* Configure and enable the gasket with the CSI-2 data type. Set the
98+
* vsync polarity as active high, as that is what the ISP is configured
99+
* to expect in ISP_ACQ_PROP. Enable left justification, as the i.MX8MP
100+
* ISP has a 16-bit wide input and expects data to be left-aligned.
101+
*/
102+
103+
source_sd = media_entity_to_v4l2_subdev(source->entity);
104+
ret = v4l2_subdev_call(source_sd, pad, get_frame_desc,
105+
source->index, &fd);
106+
if (ret) {
107+
dev_err(rkisp1->dev,
108+
"failed to get frame descriptor from '%s':%u: %d\n",
109+
source_sd->name, 0, ret);
110+
return ret;
111+
}
112+
113+
if (fd.num_entries != 1) {
114+
dev_err(rkisp1->dev, "invalid frame descriptor for '%s':%u\n",
115+
source_sd->name, 0);
116+
return -EINVAL;
117+
}
118+
119+
dt = fd.entry[0].bus.csi2.dt;
120+
121+
if (rkisp1->gasket_id == 0) {
122+
mask = ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY
123+
| ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_MASK
124+
| ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
125+
| ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK
126+
| ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
127+
val = ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_POSITIVE
128+
| ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
129+
| ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE(dt);
130+
} else {
131+
mask = ISP_DEWARP_CONTROL_MIPI_CSI2_HS_POLARITY
132+
| ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_MASK
133+
| ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
134+
| ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK
135+
| ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
136+
val = ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_POSITIVE
137+
| ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
138+
| ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE(dt);
139+
}
140+
141+
regmap_update_bits(rkisp1->gasket, ISP_DEWARP_CONTROL, mask, val);
142+
143+
return 0;
144+
}
145+
146+
static void rkisp1_gasket_disable(struct rkisp1_device *rkisp1)
147+
{
148+
u32 mask;
149+
u32 val;
150+
151+
if (rkisp1->gasket_id == 1) {
152+
mask = ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
153+
| ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK
154+
| ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
155+
val = ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
156+
} else {
157+
mask = ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
158+
| ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK
159+
| ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
160+
val = ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
161+
}
162+
163+
regmap_update_bits(rkisp1->gasket, ISP_DEWARP_CONTROL, mask, val);
164+
}
165+
56166
/* ----------------------------------------------------------------------------
57167
* Camera Interface registers configurations
58168
*/
@@ -291,6 +401,9 @@ static void rkisp1_isp_stop(struct rkisp1_isp *isp)
291401
RKISP1_CIF_VI_IRCL_MIPI_SW_RST |
292402
RKISP1_CIF_VI_IRCL_ISP_SW_RST);
293403
rkisp1_write(rkisp1, RKISP1_CIF_VI_IRCL, 0x0);
404+
405+
if (rkisp1->info->isp_ver == RKISP1_V_IMX8MP)
406+
rkisp1_gasket_disable(rkisp1);
294407
}
295408

296409
static void rkisp1_config_clk(struct rkisp1_isp *isp)
@@ -315,16 +428,24 @@ static void rkisp1_config_clk(struct rkisp1_isp *isp)
315428
}
316429
}
317430

318-
static void rkisp1_isp_start(struct rkisp1_isp *isp,
319-
struct v4l2_subdev_state *sd_state)
431+
static int rkisp1_isp_start(struct rkisp1_isp *isp,
432+
struct v4l2_subdev_state *sd_state,
433+
struct media_pad *source)
320434
{
321435
struct rkisp1_device *rkisp1 = isp->rkisp1;
322436
const struct v4l2_mbus_framefmt *src_fmt;
323437
const struct rkisp1_mbus_info *src_info;
324438
u32 val;
439+
int ret;
325440

326441
rkisp1_config_clk(isp);
327442

443+
if (rkisp1->info->isp_ver == RKISP1_V_IMX8MP) {
444+
ret = rkisp1_gasket_enable(rkisp1, source);
445+
if (ret)
446+
return ret;
447+
}
448+
328449
/* Activate ISP */
329450
val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
330451
val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD |
@@ -338,6 +459,8 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp,
338459

339460
if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER)
340461
rkisp1_params_post_configure(&rkisp1->params);
462+
463+
return 0;
341464
}
342465

343466
/* ----------------------------------------------------------------------------
@@ -848,7 +971,9 @@ static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
848971
if (ret)
849972
goto out_unlock;
850973

851-
rkisp1_isp_start(isp, sd_state);
974+
ret = rkisp1_isp_start(isp, sd_state, source_pad);
975+
if (ret)
976+
goto out_unlock;
852977

853978
ret = v4l2_subdev_call(rkisp1->source, video, s_stream, true);
854979
if (ret) {

0 commit comments

Comments
 (0)