mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
Merge commit 'e1f3f2c568280a7dd490ad87fce7608a93ae001e'
* commit 'e1f3f2c568280a7dd490ad87fce7608a93ae001e': media: i2c: rk628: post process fix output space for BT2020 media: i2c: rk628: fix vsync/vfp/vbp calculate when scaler en media: i2c: rk628: fix mipi dphy timing set thermal: rockchip: Add support to save and restore tsadc offset for rv1126b media: rockchip: isp: support raw14 format regulator: rk806: Resolving rk806m abnormal power-off during DVS Mode media: rockchip: vicap add support RAW14 media: rockchip: vicap fixes multi combine mode error for rv1126b phy: rockchip: csi2_dphy: add hw_idx to distinguish dev phy: rockchip: csi2-dphy: fixes lvds bit-width error for rv1126b media: i2c: max96756: Add writing of 1080p & 720p & 480p EDID tables during streaming drm/rockchip: analogix_dp: Initialize the PSR helper only for the left device in split mode media: rockchip: vicap force update buf when it's return and update very close to fe Change-Id: I4eb05c530860b6a00704b7d534cfaf6fba28de98
This commit is contained in:
@@ -684,14 +684,14 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
|
||||
}
|
||||
|
||||
dp->plat_data.encoder = &dp->encoder.encoder;
|
||||
|
||||
rockchip_dp_drm_self_refresh_helper_init(dp);
|
||||
}
|
||||
|
||||
ret = analogix_dp_bind(dp->adp, drm_dev);
|
||||
if (ret)
|
||||
goto err_unregister_audio_pdev;
|
||||
|
||||
rockchip_dp_drm_self_refresh_helper_init(dp);
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_audio_pdev:
|
||||
@@ -707,7 +707,8 @@ static void rockchip_dp_unbind(struct device *dev, struct device *master,
|
||||
|
||||
if (dp->audio_pdev)
|
||||
platform_device_unregister(dp->audio_pdev);
|
||||
rockchip_dp_drm_self_refresh_helper_cleanup(dp);
|
||||
if (!dp->plat_data.left)
|
||||
rockchip_dp_drm_self_refresh_helper_cleanup(dp);
|
||||
analogix_dp_unbind(dp->adp);
|
||||
dp->encoder.encoder.funcs->destroy(&dp->encoder.encoder);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
*
|
||||
* V0.0X01.0X02
|
||||
* - Compatible with kernel-6.1 version
|
||||
*
|
||||
* V0.0X01.0X03
|
||||
* - Add writing EDID tables
|
||||
*/
|
||||
#define DEBUG
|
||||
|
||||
@@ -40,7 +43,7 @@
|
||||
#include <linux/bitfield.h>
|
||||
#include "max96756.h"
|
||||
|
||||
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x02)
|
||||
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x03)
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
@@ -64,12 +67,14 @@ MODULE_PARM_DESC(debug, "debug level (0-3)");
|
||||
|
||||
#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
|
||||
#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
|
||||
#define MAX96756_WRITEEDID_ENABLE "rockchip,max96756-writeedid-enable"
|
||||
|
||||
#define MAX96756_REG_VALUE_08BIT 1
|
||||
#define MAX96756_REG_VALUE_16BIT 2
|
||||
|
||||
#define MAX96756_NAME "max96756"
|
||||
#define MAX96756_MEDIA_BUS_FMT MEDIA_BUS_FMT_BGR888_1X24
|
||||
#define MAX96745_I2CADDR 0x40
|
||||
|
||||
static const char *const max96756_supply_names[] = {
|
||||
"vcc1v2", /* Analog power */
|
||||
@@ -77,6 +82,27 @@ static const char *const max96756_supply_names[] = {
|
||||
};
|
||||
#define MAX96756_NUM_SUPPLIES ARRAY_SIZE(max96756_supply_names)
|
||||
|
||||
#define MAX96756_EDID_COUNT 256
|
||||
|
||||
static const u8 edid_1080p60_720p_480p_rgb888[MAX96756_EDID_COUNT] = {
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x34, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x01, 0x04, 0xA5, 0xF0, 0x90, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||
0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C,
|
||||
0x45, 0x00, 0x40, 0x44, 0x21, 0x00, 0x00, 0x18, 0x01, 0x1D, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20,
|
||||
0x6E, 0x28, 0x55, 0x00, 0x40, 0x44, 0x21, 0x00, 0x00, 0x18, 0x8C, 0x0A, 0xD0, 0x8A, 0x20, 0xE0,
|
||||
0x2D, 0x10, 0x10, 0x3E, 0x96, 0x00, 0x40, 0x44, 0x21, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7F,
|
||||
0x02, 0x03, 0x09, 0xF3, 0x40, 0x23, 0x09, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85
|
||||
};
|
||||
|
||||
static struct rkmodule_csi_dphy_param rk3588_dcphy_param = {
|
||||
.vendor = PHY_VENDOR_SAMSUNG,
|
||||
.lp_vol_ref = 3,
|
||||
@@ -95,6 +121,11 @@ struct regval {
|
||||
u16 delay;
|
||||
};
|
||||
|
||||
struct edid_msg {
|
||||
u32 max_width;
|
||||
const u8 *edid_list;
|
||||
};
|
||||
|
||||
struct max96756_mode {
|
||||
u32 width;
|
||||
u32 height;
|
||||
@@ -156,6 +187,9 @@ struct max96756 {
|
||||
const char *module_facing;
|
||||
const char *module_name;
|
||||
const char *len_name;
|
||||
|
||||
bool writeedid_enable;
|
||||
const struct edid_msg *cur_edid_msg;
|
||||
};
|
||||
|
||||
#define to_max96756(sd) container_of(sd, struct max96756, subdev)
|
||||
@@ -238,6 +272,29 @@ static const struct regval max96756_mipi_1080p_60fps[] = {
|
||||
{ 0x48, REG_NULL, 0x00, 0x00 },
|
||||
};
|
||||
|
||||
static const struct regval max96745_reconfig_begin[] = {
|
||||
|
||||
{ 0x40, 0x7000, 0x00, 0x00 }, // Disable LINK_ENABLE
|
||||
{ 0x40, 0x6422, 0x05, 0x00 },
|
||||
{ 0x40, REG_NULL, 0x00, 0x00 },
|
||||
};
|
||||
|
||||
static const struct regval max96745_reconfig_end[] = {
|
||||
|
||||
{ 0x40, 0x6422, 0x73, 0x00 },
|
||||
{ 0x40, 0x7054, 0x03, 0x32 }, // video input and link reset
|
||||
{ 0x40, 0x7000, 0x01, 0x00 }, // Enable LINK_ENABLE
|
||||
{ 0x48, 0x0010, 0x25, 0x32 }, // max96756 reset one shot
|
||||
{ 0x48, REG_NULL, 0x00, 0x00 },
|
||||
};
|
||||
|
||||
static const struct edid_msg edid_msgs[] = {
|
||||
{
|
||||
.max_width = 1920,
|
||||
.edid_list = edid_1080p60_720p_480p_rgb888,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct max96756_mode supported_modes[] = {
|
||||
{
|
||||
.width = 1920,
|
||||
@@ -249,6 +306,26 @@ static const struct max96756_mode supported_modes[] = {
|
||||
.reg_list = max96756_mipi_1080p_60fps,
|
||||
.link_freq_idx = 0,
|
||||
},
|
||||
{
|
||||
.width = 1280,
|
||||
.height = 720,
|
||||
.max_fps = {
|
||||
.numerator = 10000,
|
||||
.denominator = 600000,
|
||||
},
|
||||
.reg_list = max96756_mipi_1080p_60fps,
|
||||
.link_freq_idx = 0,
|
||||
},
|
||||
{
|
||||
.width = 720,
|
||||
.height = 480,
|
||||
.max_fps = {
|
||||
.numerator = 10000,
|
||||
.denominator = 600000,
|
||||
},
|
||||
.reg_list = max96756_mipi_1080p_60fps,
|
||||
.link_freq_idx = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct max96756_mode supported_modes_dcphy[] = {
|
||||
@@ -352,6 +429,40 @@ static int max96756_read_reg(struct i2c_client *client, u16 reg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max96756_write_reg_burst(struct i2c_client *client, u16 reg,
|
||||
const u8 *val)
|
||||
{
|
||||
struct i2c_msg msgs[1];
|
||||
int ret;
|
||||
int total_len = 2 + MAX96756_EDID_COUNT;
|
||||
u8 *buf;
|
||||
|
||||
buf = kzalloc(total_len, GFP_KERNEL);
|
||||
if (buf == NULL) {
|
||||
dev_err(&client->dev, "Failed to allocate bytes\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
buf[0] = (reg >> 8) & 0xff;
|
||||
buf[1] = reg & 0xff;
|
||||
memcpy(&buf[2], val, MAX96756_EDID_COUNT);
|
||||
|
||||
/* Fill msg struct */
|
||||
msgs[0].addr = client->addr;
|
||||
msgs[0].flags = 0;
|
||||
msgs[0].len = total_len;
|
||||
msgs[0].buf = buf;
|
||||
|
||||
ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
|
||||
if (ret != ARRAY_SIZE(msgs)) {
|
||||
kfree(buf);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
kfree(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max96756_get_reso_dist(const struct max96756_mode *mode,
|
||||
struct v4l2_mbus_framefmt *framefmt)
|
||||
{
|
||||
@@ -727,6 +838,59 @@ static int max96756_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
|
||||
}
|
||||
}
|
||||
|
||||
static int max96745_reconfig_edid(struct max96756 *max96756)
|
||||
{
|
||||
int ret = -1;
|
||||
u32 val = 0, i, flag = 0;
|
||||
unsigned short temp_addr = 0;
|
||||
|
||||
temp_addr = max96756->client->addr;
|
||||
|
||||
//wait for link lock
|
||||
for (i = 0; i < 10; i++) { // Maximum waiting time 100ms
|
||||
max96756_read_reg(max96756->client, 0x0013,
|
||||
MAX96756_REG_VALUE_08BIT, &val);
|
||||
if (val & (1 << 3)) {
|
||||
dev_dbg(&max96756->client->dev, "serdes reg locked 0x%x\n", val);
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
usleep_range(10000, 10100);
|
||||
}
|
||||
|
||||
if (flag != 1) {
|
||||
dev_err(&max96756->client->dev, "%s: serdes reg still not locked ", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//common begin
|
||||
ret = max96756_write_array(max96756->client,
|
||||
max96745_reconfig_begin);
|
||||
if (ret) {
|
||||
dev_err(&max96756->client->dev, "max96745_reconfig_begin err\n");
|
||||
max96756->client->addr = temp_addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//write edid table
|
||||
max96756->client->addr = MAX96745_I2CADDR;
|
||||
ret = max96756_write_reg_burst(max96756->client, 0x6500, max96756->cur_edid_msg->edid_list);
|
||||
if (ret) {
|
||||
dev_err(&max96756->client->dev, "edid_table err\n");
|
||||
max96756->client->addr = temp_addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//common end
|
||||
ret = max96756_write_array(max96756->client,
|
||||
max96745_reconfig_end);
|
||||
if (ret)
|
||||
dev_err(&max96756->client->dev, "max96745_reconfig_end err\n");
|
||||
|
||||
max96756->client->addr = temp_addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __max96756_start_stream(struct max96756 *max96756)
|
||||
{
|
||||
int ret;
|
||||
@@ -739,10 +903,16 @@ static int __max96756_start_stream(struct max96756 *max96756)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (max96756->writeedid_enable) {
|
||||
ret = max96745_reconfig_edid(max96756);
|
||||
if (ret) {
|
||||
dev_err(&max96756->client->dev, "Failed to write edid\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* In case these controls are set before streaming */
|
||||
mutex_unlock(&max96756->mutex);
|
||||
ret = v4l2_ctrl_handler_setup(&max96756->ctrl_handler);
|
||||
mutex_lock(&max96756->mutex);
|
||||
ret = __v4l2_ctrl_handler_setup(&max96756->ctrl_handler);
|
||||
if (ret) {
|
||||
dev_warn(&max96756->client->dev, "Failed to setup ctrl\n");
|
||||
return ret;
|
||||
@@ -1329,6 +1499,8 @@ static int max96756_probe(struct i2c_client *client)
|
||||
|
||||
max96756->client = client;
|
||||
max96756->cur_mode = &supported_modes[0];
|
||||
max96756->writeedid_enable = of_property_read_bool(node, MAX96756_WRITEEDID_ENABLE);
|
||||
max96756->cur_edid_msg = &edid_msgs[0];
|
||||
|
||||
max96756->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(max96756->pwdn_gpio))
|
||||
|
||||
@@ -257,23 +257,6 @@ static const unsigned int rk628_csi_extcon_cable[] = {
|
||||
EXTCON_NONE,
|
||||
};
|
||||
|
||||
static const struct mipi_timing rk628d_csi_mipi = {
|
||||
0x0b, 0x53, 0x10, 0x5b, 0x0b, 0x43, 0x2c, 0x50, 0x0f
|
||||
};
|
||||
|
||||
static const struct mipi_timing rk628f_csi0_mipi = {
|
||||
0x0b, 0x53, 0x10, 0x5b, 0x0b, 0x43, 0x2c, 0x50, 0x0f
|
||||
};
|
||||
|
||||
static const struct mipi_timing rk628f_csi1_mipi = {
|
||||
//data_lp, data-pre, data-zero, data-trail, clk_lp, clk-pre, clk-zero, clk-trail, clk-post
|
||||
0x0b, 0x53, 0x10, 0x5b, 0x0b, 0x43, 0x2c, 0x50, 0x0f
|
||||
};
|
||||
|
||||
static const struct mipi_timing rk628f_dsi0_mipi = {
|
||||
0x10, 0x70, 0x1c, 0x7f, 0x10, 0x70, 0x3f, 0x7f, 0x1f
|
||||
};
|
||||
|
||||
static struct rkmodule_csi_dphy_param rk3588_dcphy_param = {
|
||||
.vendor = PHY_VENDOR_SAMSUNG,
|
||||
.lp_vol_ref = 0,
|
||||
@@ -466,6 +449,14 @@ static int rk628_csi_get_detected_timings(struct v4l2_subdev *sd,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
v4l2_dbg(1, debug, sd, "hfp:%d, hs:%d, hbp:%d, vfp:%d, vs:%d, vbp:%d, interlace:%d\n",
|
||||
bt->hfrontporch, bt->hsync, bt->hbackporch, bt->vfrontporch, bt->vsync,
|
||||
bt->vbackporch, bt->interlaced);
|
||||
|
||||
csi->src_timings = *timings;
|
||||
if (csi->scaler_en)
|
||||
*timings = csi->timings;
|
||||
|
||||
if ((bt->pixelclock > 300000000 && csi->rk628->version >= RK628F_VERSION) ||
|
||||
(bt->width > 2048 && csi->plat_data->tx_mode == DSI_MODE)) {
|
||||
v4l2_info(sd, "rk628f detect pixclk more than 300M, use dual mipi mode\n");
|
||||
@@ -475,14 +466,6 @@ static int rk628_csi_get_detected_timings(struct v4l2_subdev *sd,
|
||||
csi->rk628->dual_mipi = false;
|
||||
}
|
||||
|
||||
v4l2_dbg(1, debug, sd, "hfp:%d, hs:%d, hbp:%d, vfp:%d, vs:%d, vbp:%d, interlace:%d\n",
|
||||
bt->hfrontporch, bt->hsync, bt->hbackporch, bt->vfrontporch, bt->vsync,
|
||||
bt->vbackporch, bt->interlaced);
|
||||
|
||||
csi->src_timings = *timings;
|
||||
if (csi->scaler_en)
|
||||
*timings = csi->timings;
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
@@ -1018,6 +1001,16 @@ static void rk628_post_process_setup(struct v4l2_subdev *sd)
|
||||
dst.vback_porch = dst_bt->vbackporch;
|
||||
dst.pixelclock = dst_bt->pixelclock;
|
||||
|
||||
if (csi->scaler_en) {
|
||||
dst.vfront_porch = DIV_ROUND_UP(src.vfront_porch * dst_bt->height, src.vactive);
|
||||
dst.vsync_len = DIV_ROUND_UP(src.vsync_len * dst_bt->height, src.vactive);
|
||||
dst.vback_porch = DIV_ROUND_UP(src.vback_porch * dst_bt->height, src.vactive);
|
||||
v4l2_info(sd, "%s: src timing: vfp: %d, vs: %d, vbp: %d\n",
|
||||
__func__, src.vfront_porch, src.vsync_len, src.vback_porch);
|
||||
v4l2_info(sd, "%s: dst timing: vfp: %d, vs: %d, vbp: %d\n",
|
||||
__func__, dst.vfront_porch, dst.vsync_len, dst.vback_porch);
|
||||
}
|
||||
|
||||
rk628_post_process_en(csi->rk628, &src, &dst, &dst_pclk);
|
||||
dst_bt->pixelclock = dst_pclk;
|
||||
}
|
||||
@@ -1488,17 +1481,6 @@ static void rk628_csi_initial_setup(struct v4l2_subdev *sd)
|
||||
struct rk628_csi *csi = to_csi(sd);
|
||||
|
||||
rk628_csi_initial(sd);
|
||||
if (csi->rk628->version >= RK628F_VERSION) {
|
||||
csi->rk628->mipi_timing[0] = rk628f_csi0_mipi;
|
||||
csi->rk628->mipi_timing[1] = rk628f_csi1_mipi;
|
||||
} else {
|
||||
csi->rk628->mipi_timing[0] = rk628d_csi_mipi;
|
||||
}
|
||||
|
||||
if (csi->plat_data->tx_mode == DSI_MODE) {
|
||||
csi->rk628->mipi_timing[0] = rk628f_dsi0_mipi;
|
||||
csi->rk628->mipi_timing[1] = rk628f_dsi0_mipi;
|
||||
}
|
||||
|
||||
csi->rk628->dphy_lane_en = 0x1f;
|
||||
csi->txphy_pwron = true;
|
||||
@@ -2156,11 +2138,37 @@ static int rk628_csi_enum_frame_interval(struct v4l2_subdev *sd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 rk628_csi_get_lane_rate_mbps(struct rk628_csi *csi)
|
||||
{
|
||||
u32 lane_rate;
|
||||
u32 max_lane_rate = 1300;
|
||||
u8 bpp, lanes;
|
||||
u64 pixelclock = csi->timings.bt.pixelclock;
|
||||
|
||||
bpp = 16;
|
||||
lanes = csi->csi_lanes_in_use;
|
||||
pixelclock = div_u64(pixelclock, 1000 * 1000);
|
||||
lane_rate = pixelclock * bpp;
|
||||
lane_rate = div_u64(lane_rate, lanes);
|
||||
if (csi->rk628->dual_mipi)
|
||||
lane_rate /= 2;
|
||||
|
||||
if (lane_rate > 1300)
|
||||
lane_rate = max_lane_rate;
|
||||
else if (lane_rate > 700 && lane_rate <= 1300)
|
||||
lane_rate = 1300;
|
||||
else
|
||||
lane_rate = 700;
|
||||
|
||||
return lane_rate;
|
||||
}
|
||||
|
||||
static int rk628_csi_get_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *format)
|
||||
{
|
||||
struct rk628_csi *csi = to_csi(sd);
|
||||
u32 rate;
|
||||
|
||||
if (!tx_5v_power_present(sd) || csi->nosignal) {
|
||||
v4l2_info(sd, "%s hdmirx no signal\n", __func__);
|
||||
@@ -2178,47 +2186,24 @@ static int rk628_csi_get_fmt(struct v4l2_subdev *sd,
|
||||
V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
|
||||
|
||||
if (csi->plat_data->tx_mode == CSI_MODE) {
|
||||
if (csi->timings.bt.pixelclock > 150000000 || csi->csi_lanes_in_use <= 2) {
|
||||
v4l2_dbg(1, debug, sd,
|
||||
"%s res wxh:%dx%d, link freq:%llu, pixrate:%u\n",
|
||||
__func__, csi->timings.bt.width, csi->timings.bt.height,
|
||||
link_freq_menu_items[1], RK628_CSI_PIXEL_RATE_HIGH);
|
||||
__v4l2_ctrl_s_ctrl(csi->link_freq, 1);
|
||||
__v4l2_ctrl_s_ctrl_int64(csi->pixel_rate,
|
||||
RK628_CSI_PIXEL_RATE_HIGH);
|
||||
} else {
|
||||
v4l2_dbg(1, debug, sd,
|
||||
"%s res wxh:%dx%d, link freq:%llu, pixrate:%u\n",
|
||||
__func__, csi->timings.bt.width, csi->timings.bt.height,
|
||||
link_freq_menu_items[0], RK628_CSI_PIXEL_RATE_LOW);
|
||||
__v4l2_ctrl_s_ctrl(csi->link_freq, 0);
|
||||
__v4l2_ctrl_s_ctrl_int64(csi->pixel_rate,
|
||||
RK628_CSI_PIXEL_RATE_LOW);
|
||||
}
|
||||
rate = rk628_csi_get_lane_rate_mbps(csi);
|
||||
} else {
|
||||
u32 rate;
|
||||
|
||||
csi->dsi.rk628 = csi->rk628;
|
||||
csi->dsi.timings = csi->timings;
|
||||
rate = rk628_dsi_get_lane_rate_mbps(&csi->dsi);
|
||||
v4l2_dbg(1, debug, sd, "%s mipi bitrate:%u mbps\n", __func__, rate);
|
||||
|
||||
if (rate > 1300) {
|
||||
csi->rk628->mipi_timing[0] = rk628f_dsi0_mipi;
|
||||
csi->rk628->mipi_timing[1] = rk628f_dsi0_mipi;
|
||||
__v4l2_ctrl_s_ctrl(csi->link_freq, 2);
|
||||
} else if (rate <= 1300 && rate > 700) {
|
||||
csi->rk628->mipi_timing[0] = rk628f_csi0_mipi;
|
||||
csi->rk628->mipi_timing[1] = rk628f_csi0_mipi;
|
||||
__v4l2_ctrl_s_ctrl(csi->link_freq, 1);
|
||||
} else {
|
||||
csi->rk628->mipi_timing[0] = rk628f_csi0_mipi;
|
||||
csi->rk628->mipi_timing[1] = rk628f_csi0_mipi;
|
||||
__v4l2_ctrl_s_ctrl(csi->link_freq, 0);
|
||||
}
|
||||
__v4l2_ctrl_s_ctrl_int64(csi->pixel_rate, RK628_CSI_PIXEL_RATE_HIGH);
|
||||
}
|
||||
|
||||
v4l2_dbg(1, debug, sd, "%s mipi bitrate:%u mbps\n", __func__, rate);
|
||||
|
||||
if (rate > 1300)
|
||||
__v4l2_ctrl_s_ctrl(csi->link_freq, 2);
|
||||
else if (rate <= 1300 && rate > 700)
|
||||
__v4l2_ctrl_s_ctrl(csi->link_freq, 1);
|
||||
else
|
||||
__v4l2_ctrl_s_ctrl(csi->link_freq, 0);
|
||||
|
||||
__v4l2_ctrl_s_ctrl_int64(csi->pixel_rate, RK628_CSI_PIXEL_RATE_HIGH);
|
||||
|
||||
mutex_unlock(&csi->confctl_mutex);
|
||||
v4l2_dbg(1, debug, sd, "%s: fmt code:%d, w:%d, h:%d, field code:%d\n",
|
||||
__func__, format->format.code, format->format.width,
|
||||
@@ -2649,19 +2634,13 @@ static int mipi_dphy_power_on(struct rk628_csi *csi)
|
||||
struct v4l2_subdev *sd = &csi->sd;
|
||||
int ret;
|
||||
|
||||
if (csi->timings.bt.pixelclock > 150000000 || csi->csi_lanes_in_use <= 2) {
|
||||
csi->lane_mbps = MIPI_DATARATE_MBPS_HIGH;
|
||||
} else {
|
||||
csi->lane_mbps = MIPI_DATARATE_MBPS_LOW;
|
||||
}
|
||||
if (csi->rk628->dual_mipi)
|
||||
csi->lane_mbps = MIPI_DATARATE_MBPS_HIGH;
|
||||
csi->lane_mbps = rk628_csi_get_lane_rate_mbps(csi);
|
||||
bus_width = csi->lane_mbps << 8;
|
||||
bus_width |= COMBTXPHY_MODULEA_EN;
|
||||
if (csi->rk628->version >= RK628F_VERSION)
|
||||
bus_width |= COMBTXPHY_MODULEB_EN;
|
||||
v4l2_dbg(1, debug, sd, "%s mipi bitrate:%llu mbps\n", __func__,
|
||||
csi->lane_mbps);
|
||||
v4l2_info(sd, "%s mipi bitrate:%llu mbps\n", __func__, csi->lane_mbps);
|
||||
|
||||
rk628_mipi_dphy_reset_assert(csi->rk628);
|
||||
rk628_mipi_dphy_reset_deassert(csi->rk628);
|
||||
|
||||
@@ -2672,18 +2651,6 @@ static int mipi_dphy_power_on(struct rk628_csi *csi)
|
||||
if (csi->rk628->version >= RK628F_VERSION)
|
||||
rk628_mipi_dphy_init_hsfreqrange(csi->rk628, csi->lane_mbps, 1);
|
||||
|
||||
if (csi->rk628->dual_mipi) {
|
||||
rk628_mipi_dphy_init_hsmanual(csi->rk628, true, 0);
|
||||
rk628_mipi_dphy_init_hsmanual(csi->rk628, true, 1);
|
||||
} else if (csi->lane_mbps == MIPI_DATARATE_MBPS_HIGH && !csi->rk628->dual_mipi) {
|
||||
rk628_mipi_dphy_init_hsmanual(csi->rk628, true, 0);
|
||||
if (csi->rk628->version >= RK628F_VERSION)
|
||||
rk628_mipi_dphy_init_hsmanual(csi->rk628, false, 1);
|
||||
} else {
|
||||
rk628_mipi_dphy_init_hsmanual(csi->rk628, false, 0);
|
||||
if (csi->rk628->version >= RK628F_VERSION)
|
||||
rk628_mipi_dphy_init_hsmanual(csi->rk628, false, 1);
|
||||
}
|
||||
rk628_txphy_power_on(csi->rk628);
|
||||
|
||||
usleep_range(1500, 2000);
|
||||
|
||||
@@ -88,11 +88,6 @@ static void mipi_dphy_power_on_dsi(struct rk628_dsi *dsi, uint8_t mipi_id)
|
||||
rk628_testif_testclr_deassert(dsi->rk628, mipi_id);
|
||||
rk628_mipi_dphy_init_hsfreqrange(dsi->rk628, dsi->lane_mbps, mipi_id);
|
||||
|
||||
if (dsi->lane_mbps > 1100)
|
||||
rk628_mipi_dphy_init_hsmanual(dsi->rk628, true, mipi_id);
|
||||
else
|
||||
rk628_mipi_dphy_init_hsmanual(dsi->rk628, false, mipi_id);
|
||||
|
||||
dsi_update_bits(rk628, mipi_id, DSI_PHY_RSTZ,
|
||||
PHY_ENABLECLK, PHY_ENABLECLK);
|
||||
dsi_update_bits(rk628, mipi_id, DSI_PHY_RSTZ,
|
||||
|
||||
@@ -104,6 +104,15 @@ u8 rk628_testif_write(struct rk628 *rk628, u8 test_code, u8 test_data, uint8_t m
|
||||
}
|
||||
EXPORT_SYMBOL(rk628_testif_write);
|
||||
|
||||
static void rk628_testif_set_timing(struct rk628 *rk628, u8 addr,
|
||||
u8 max, u8 val, uint8_t mipi_id)
|
||||
{
|
||||
if (val > max)
|
||||
return;
|
||||
|
||||
rk628_testif_write(rk628, addr, (max + 1) | val, mipi_id);
|
||||
}
|
||||
|
||||
u8 rk628_testif_read(struct rk628 *rk628, u8 test_code, uint8_t mipi_id)
|
||||
{
|
||||
u8 test_data;
|
||||
@@ -170,6 +179,56 @@ static inline void mipi_dphy_rstz_deassert(struct rk628 *rk628)
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
static void rk628_mipi_dphy_set_timing(struct rk628 *rk628, int lane_mbps, uint8_t mipi_id)
|
||||
{
|
||||
const struct {
|
||||
unsigned int min_lane_mbps;
|
||||
unsigned int max_lane_mbps;
|
||||
u8 clk_lp;
|
||||
u8 clk_hs_prepare;
|
||||
u8 clk_hs_zero;
|
||||
u8 clk_hs_trail;
|
||||
u8 clk_post;
|
||||
u8 data_lp;
|
||||
u8 data_hs_prepare;
|
||||
u8 data_hs_zero;
|
||||
u8 data_hs_trail;
|
||||
} timing_table[] = {
|
||||
{800, 899, 0x07, 0x30, 0x25, 0x3c, 0x0f, 0x07, 0x40, 0x09, 0x40},
|
||||
{1100, 1249, 0x0a, 0x43, 0x2c, 0x50, 0x0f, 0x0a, 0x43, 0x10, 0x55},
|
||||
{1250, 1349, 0x0b, 0x43, 0x2c, 0x50, 0x0f, 0x0b, 0x53, 0x10, 0x5b},
|
||||
{1350, 1449, 0x0c, 0x43, 0x36, 0x60, 0x0f, 0x0c, 0x53, 0x10, 0x65},
|
||||
{1450, 1500, 0x0f, 0x60, 0x31, 0x60, 0x0f, 0x0e, 0x60, 0x11, 0x6a},
|
||||
{1750, 2050, 0x10, 0x70, 0x3f, 0x7f, 0x1f, 0x10, 0x70, 0x1c, 0x7f},
|
||||
};
|
||||
unsigned int index;
|
||||
|
||||
// These ranges use the controller's internal automatically calculated timing.
|
||||
if (lane_mbps < 800 || (lane_mbps >= 900 && lane_mbps < 1100))
|
||||
return;
|
||||
|
||||
if (lane_mbps < timing_table[0].min_lane_mbps)
|
||||
return;
|
||||
|
||||
for (index = 0; index < ARRAY_SIZE(timing_table); index++)
|
||||
if (lane_mbps >= timing_table[index].min_lane_mbps &&
|
||||
lane_mbps < timing_table[index].max_lane_mbps)
|
||||
break;
|
||||
|
||||
if (index == ARRAY_SIZE(timing_table))
|
||||
--index;
|
||||
|
||||
rk628_testif_set_timing(rk628, 0x60, 0x3f, timing_table[index].clk_lp, mipi_id);
|
||||
rk628_testif_set_timing(rk628, 0x61, 0x7f, timing_table[index].clk_hs_prepare, mipi_id);
|
||||
rk628_testif_set_timing(rk628, 0x62, 0x3f, timing_table[index].clk_hs_zero, mipi_id);
|
||||
rk628_testif_set_timing(rk628, 0x63, 0x7f, timing_table[index].clk_hs_trail, mipi_id);
|
||||
rk628_testif_set_timing(rk628, 0x65, 0x0f, timing_table[index].clk_post, mipi_id);
|
||||
rk628_testif_set_timing(rk628, 0x70, 0x3f, timing_table[index].data_lp, mipi_id);
|
||||
rk628_testif_set_timing(rk628, 0x71, 0x7f, timing_table[index].data_hs_prepare, mipi_id);
|
||||
rk628_testif_set_timing(rk628, 0x72, 0x3f, timing_table[index].data_hs_zero, mipi_id);
|
||||
rk628_testif_set_timing(rk628, 0x73, 0x7f, timing_table[index].data_hs_trail, mipi_id);
|
||||
}
|
||||
|
||||
void rk628_mipi_dphy_init_hsfreqrange(struct rk628 *rk628, int lane_mbps, uint8_t mipi_id)
|
||||
{
|
||||
const struct {
|
||||
@@ -199,43 +258,10 @@ void rk628_mipi_dphy_init_hsfreqrange(struct rk628 *rk628, int lane_mbps, uint8_
|
||||
|
||||
hsfreqrange = hsfreqrange_table[index].hsfreqrange;
|
||||
rk628_testif_write(rk628, 0x44, HSFREQRANGE(hsfreqrange), mipi_id);
|
||||
rk628_mipi_dphy_set_timing(rk628, lane_mbps, mipi_id);
|
||||
}
|
||||
EXPORT_SYMBOL(rk628_mipi_dphy_init_hsfreqrange);
|
||||
|
||||
void rk628_mipi_dphy_init_hsmanual(struct rk628 *rk628, bool manual, uint8_t mipi_id)
|
||||
{
|
||||
dev_info(rk628->dev,
|
||||
"mipi dphy%d hs config, manual: %s\n", mipi_id, manual ? "true" : "false");
|
||||
//config mipi timing when mipi freq is 1250Mbps
|
||||
rk628_testif_write(rk628, 0x70,
|
||||
manual ? (HSZERO(rk628->mipi_timing[mipi_id].data_lp) | BIT(6)) : 0, mipi_id);
|
||||
usleep_range(1500, 2000);
|
||||
rk628_testif_write(rk628, 0x71,
|
||||
manual ? (HSTX(rk628->mipi_timing[mipi_id].data_prepare) | BIT(7)) : 0, mipi_id);
|
||||
usleep_range(1500, 2000);
|
||||
rk628_testif_write(rk628, 0x72,
|
||||
manual ? (HSZERO(rk628->mipi_timing[mipi_id].data_zero) | BIT(6)) : 0, mipi_id);
|
||||
usleep_range(1500, 2000);
|
||||
rk628_testif_write(rk628, 0x73,
|
||||
manual ? (HSTX(rk628->mipi_timing[mipi_id].data_trail) | BIT(7)) : 0, mipi_id);
|
||||
usleep_range(1500, 2000);
|
||||
rk628_testif_write(rk628, 0x60,
|
||||
manual ? (HSZERO(rk628->mipi_timing[mipi_id].clk_lp) | BIT(6)) : 0, mipi_id);
|
||||
usleep_range(1500, 2000);
|
||||
rk628_testif_write(rk628, 0x61,
|
||||
manual ? (HSTX(rk628->mipi_timing[mipi_id].clk_prepare) | BIT(7)) : 0, mipi_id);
|
||||
usleep_range(1500, 2000);
|
||||
rk628_testif_write(rk628, 0x62,
|
||||
manual ? (HSZERO(rk628->mipi_timing[mipi_id].clk_zero) | BIT(6)) : 0, mipi_id);
|
||||
usleep_range(1500, 2000);
|
||||
rk628_testif_write(rk628, 0x63,
|
||||
manual ? (HSTX(rk628->mipi_timing[mipi_id].clk_trail) | BIT(7)) : 0, mipi_id);
|
||||
usleep_range(1500, 2000);
|
||||
rk628_testif_write(rk628, 0x65,
|
||||
manual ? (HSPOST(rk628->mipi_timing[mipi_id].clk_post) | BIT(4)) : 0, mipi_id);
|
||||
}
|
||||
EXPORT_SYMBOL(rk628_mipi_dphy_init_hsmanual);
|
||||
|
||||
int rk628_mipi_dphy_reset_assert(struct rk628 *rk628)
|
||||
{
|
||||
rk628_i2c_write(rk628, CSITX_SYS_CTRL0_IMD, 0x1);
|
||||
|
||||
@@ -22,7 +22,6 @@ void rk628_testif_testclr_assert(struct rk628 *rk628, uint8_t mipi_id);
|
||||
u8 rk628_testif_write(struct rk628 *rk628, u8 test_code, u8 test_data, uint8_t mipi_id);
|
||||
u8 rk628_testif_read(struct rk628 *rk628, u8 test_code, uint8_t mipi_id);
|
||||
void rk628_mipi_dphy_init_hsfreqrange(struct rk628 *rk628, int lane_mbps, uint8_t mipi_id);
|
||||
void rk628_mipi_dphy_init_hsmanual(struct rk628 *rk628, bool manual, uint8_t mipi_id);
|
||||
int rk628_mipi_dphy_reset_assert(struct rk628 *rk628);
|
||||
int rk628_mipi_dphy_reset_deassert(struct rk628 *rk628);
|
||||
|
||||
|
||||
@@ -1638,7 +1638,7 @@ static u8 rk628_get_output_color_space(struct rk628 *rk628, u8 input_color_space
|
||||
return rk628->tx_mode ? OPTM_CS_E_RGB : OPTM_CS_E_XV_YCC_709;
|
||||
case OPTM_CS_E_XV_YCC_2020:
|
||||
case OPTM_CS_E_RGB_2020:
|
||||
return rk628->tx_mode ? OPTM_CS_E_RGB_2020 : OPTM_CS_E_XV_YCC_709;
|
||||
return rk628->tx_mode ? OPTM_CS_E_RGB_2020 : OPTM_CS_E_XV_YCC_2020;
|
||||
case OPTM_CS_E_RGB_ADOBE:
|
||||
case OPTM_CS_E_YUV_ADOBE:
|
||||
return rk628->tx_mode ? OPTM_CS_E_RGB_ADOBE : OPTM_CS_E_XV_YCC_709;
|
||||
|
||||
@@ -273,45 +273,13 @@ static const struct cif_output_fmt out_fmts[] = {
|
||||
.raw_bpp = 12,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW12,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SBGGR16,
|
||||
.cplanes = 1,
|
||||
.mplanes = 1,
|
||||
.bpp = { 16 },
|
||||
.raw_bpp = 16,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW8,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGBRG16,
|
||||
.cplanes = 1,
|
||||
.mplanes = 1,
|
||||
.bpp = { 16 },
|
||||
.raw_bpp = 16,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW8,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGRBG16,
|
||||
.cplanes = 1,
|
||||
.mplanes = 1,
|
||||
.bpp = { 16 },
|
||||
.raw_bpp = 16,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW8,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SRGGB16,
|
||||
.cplanes = 1,
|
||||
.mplanes = 1,
|
||||
.bpp = { 16 },
|
||||
.raw_bpp = 16,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW8,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_Y16,
|
||||
.cplanes = 1,
|
||||
.mplanes = 1,
|
||||
.bpp = { 16 },
|
||||
.raw_bpp = 16,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW8,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW16,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_GREY,
|
||||
@@ -345,6 +313,13 @@ static const struct cif_output_fmt out_fmts[] = {
|
||||
.raw_bpp = 12,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW12,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_Y14,
|
||||
.cplanes = 1,
|
||||
.mplanes = 1,
|
||||
.bpp = { 16 },
|
||||
.raw_bpp = 14,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW14_RK3588,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_Y10,
|
||||
.cplanes = 1,
|
||||
@@ -385,7 +360,39 @@ static const struct cif_output_fmt out_fmts[] = {
|
||||
.raw_bpp = 16,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW16,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
}
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SBGGR14,
|
||||
.cplanes = 1,
|
||||
.mplanes = 1,
|
||||
.bpp = { 16 },
|
||||
.raw_bpp = 14,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW14_RK3588,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGBRG14,
|
||||
.cplanes = 1,
|
||||
.mplanes = 1,
|
||||
.bpp = { 16 },
|
||||
.raw_bpp = 14,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW14_RK3588,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGRBG14,
|
||||
.cplanes = 1,
|
||||
.mplanes = 1,
|
||||
.bpp = { 16 },
|
||||
.raw_bpp = 14,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW14_RK3588,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SRGGB14,
|
||||
.cplanes = 1,
|
||||
.mplanes = 1,
|
||||
.bpp = { 16 },
|
||||
.raw_bpp = 14,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW14_RK3588,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
},
|
||||
/* TODO: We can support NV12M/NV21M/NV16M/NV61M too */
|
||||
};
|
||||
|
||||
@@ -572,6 +579,12 @@ static const struct cif_input_fmt in_fmts[] = {
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW12,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
.field = V4L2_FIELD_NONE,
|
||||
}, {
|
||||
.mbus_code = MEDIA_BUS_FMT_Y14_1X14,
|
||||
.dvp_fmt_val = INPUT_MODE_RAW | RAW_DATA_WIDTH_14,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW14_RK3588,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
.field = V4L2_FIELD_NONE,
|
||||
}, {
|
||||
.mbus_code = MEDIA_BUS_FMT_EBD_1X8,
|
||||
.dvp_fmt_val = INPUT_MODE_RAW | RAW_DATA_WIDTH_8,
|
||||
@@ -614,6 +627,26 @@ static const struct cif_input_fmt in_fmts[] = {
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW16,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
.field = V4L2_FIELD_NONE,
|
||||
}, {
|
||||
.mbus_code = MEDIA_BUS_FMT_SBGGR14_1X14,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW14_RK3588,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
.field = V4L2_FIELD_NONE,
|
||||
}, {
|
||||
.mbus_code = MEDIA_BUS_FMT_SGBRG14_1X14,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW14_RK3588,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
.field = V4L2_FIELD_NONE,
|
||||
}, {
|
||||
.mbus_code = MEDIA_BUS_FMT_SGRBG14_1X14,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW14_RK3588,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
.field = V4L2_FIELD_NONE,
|
||||
}, {
|
||||
.mbus_code = MEDIA_BUS_FMT_SRGGB14_1X14,
|
||||
.csi_fmt_val = CSI_WRDDR_TYPE_RAW14_RK3588,
|
||||
.fmt_type = CIF_FMT_TYPE_RAW,
|
||||
.field = V4L2_FIELD_NONE,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -789,6 +822,18 @@ static int rkcif_output_fmt_check(struct rkcif_stream *stream,
|
||||
if (output_fmt->fourcc == V4L2_PIX_FMT_NV12)
|
||||
ret = 0;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_SBGGR14_1X14:
|
||||
case MEDIA_BUS_FMT_SGBRG14_1X14:
|
||||
case MEDIA_BUS_FMT_SGRBG14_1X14:
|
||||
case MEDIA_BUS_FMT_SRGGB14_1X14:
|
||||
case MEDIA_BUS_FMT_Y14_1X14:
|
||||
if (output_fmt->fourcc == V4L2_PIX_FMT_SRGGB14 ||
|
||||
output_fmt->fourcc == V4L2_PIX_FMT_SGRBG14 ||
|
||||
output_fmt->fourcc == V4L2_PIX_FMT_SGBRG14 ||
|
||||
output_fmt->fourcc == V4L2_PIX_FMT_SBGGR14 ||
|
||||
output_fmt->fourcc == V4L2_PIX_FMT_Y14)
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -915,6 +960,13 @@ static unsigned char get_data_type(u32 pixelformat, u8 cmd_mode_en, u8 dsi_input
|
||||
case MEDIA_BUS_FMT_SRGGB12_1X12:
|
||||
case MEDIA_BUS_FMT_Y12_1X12:
|
||||
return 0x2c;
|
||||
/* csi raw14 */
|
||||
case MEDIA_BUS_FMT_SBGGR14_1X14:
|
||||
case MEDIA_BUS_FMT_SGBRG14_1X14:
|
||||
case MEDIA_BUS_FMT_SGRBG14_1X14:
|
||||
case MEDIA_BUS_FMT_SRGGB14_1X14:
|
||||
case MEDIA_BUS_FMT_Y14_1X14:
|
||||
return 0x2d;
|
||||
/* csi raw16 */
|
||||
case MEDIA_BUS_FMT_SBGGR16_1X16:
|
||||
case MEDIA_BUS_FMT_SGBRG16_1X16:
|
||||
@@ -2568,6 +2620,23 @@ out_get_buf:
|
||||
rkcif_write_register(dev, frm_addr_y, buff_addr_y);
|
||||
}
|
||||
}
|
||||
if (buf_stream->is_force_update) {
|
||||
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CSI2_CPHY) {
|
||||
if (dev->chip_id < CHIP_RK3562_CIF)
|
||||
rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_CTRL, 0x00010000);
|
||||
else
|
||||
rkcif_write_register_or(dev, get_reg_index_of_frm0_y_vlw(stream->id), BIT(31));
|
||||
} else {
|
||||
if (dev->chip_id < CHIP_RK3562_CIF)
|
||||
rkcif_write_register_or(dev, CIF_REG_DVP_CTRL, 0x00010000);
|
||||
else if (dev->chip_id < CHIP_RK3576_CIF)
|
||||
rkcif_write_register_or(dev, CIF_REG_DVP_VIR_LINE_WIDTH, BIT(28) << stream->id);
|
||||
else
|
||||
rkcif_write_register_or(dev, CIF_REG_DVP_VIR_LINE_WIDTH, BIT(31));
|
||||
}
|
||||
buf_stream->is_force_update = false;
|
||||
}
|
||||
spin_unlock_irqrestore(&buf_stream->vbq_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
@@ -2584,6 +2653,19 @@ static int rkcif_assign_new_buffer_pingpong_toisp(struct rkcif_stream *stream,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rkcif_check_force_update_buf(struct rkcif_stream *stream)
|
||||
{
|
||||
u64 cur_time = 0;
|
||||
u64 offset = 0;
|
||||
|
||||
offset = stream->cifdev->readout_ns - 2000000;
|
||||
cur_time = rkcif_time_get_ns(stream->cifdev);
|
||||
if (stream->dma_en &&
|
||||
(cur_time - stream->readout.fs_timestamp) > offset &&
|
||||
!stream->is_in_vblank)
|
||||
stream->is_force_update = true;
|
||||
}
|
||||
|
||||
void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream)
|
||||
{
|
||||
struct rkcif_device *dev = stream->cifdev;
|
||||
@@ -2634,6 +2716,11 @@ void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream)
|
||||
buf_stream->toisp_buf_state.check_cnt == 0)
|
||||
is_dual_update = true;
|
||||
|
||||
if ((buf_stream->toisp_buf_state.state == RKCIF_TOISP_BUF_LOSS ||
|
||||
buf_stream->toisp_buf_state.state == RKCIF_TOISP_BUF_THESAME) &&
|
||||
buf_stream->toisp_buf_state.check_cnt == 0)
|
||||
rkcif_check_force_update_buf(buf_stream);
|
||||
|
||||
if ((dev->rdbk_debug > 2 &&
|
||||
stream->frame_idx < 15) ||
|
||||
rkcif_debug > 4)
|
||||
@@ -3996,6 +4083,7 @@ static int rkcif_csi_channel_init(struct rkcif_stream *stream,
|
||||
const struct cif_output_fmt *fmt;
|
||||
u32 fourcc;
|
||||
int vc = dev->channels[stream->id].vc;
|
||||
u32 raw_bpp = 0;
|
||||
|
||||
channel->enable = 1;
|
||||
channel->width = stream->pixm.width;
|
||||
@@ -4061,11 +4149,20 @@ static int rkcif_csi_channel_init(struct rkcif_stream *stream,
|
||||
if (fmt->fmt_type == CIF_FMT_TYPE_RAW && stream->is_compact &&
|
||||
fmt->csi_fmt_val != CSI_WRDDR_TYPE_RGB888 &&
|
||||
fmt->csi_fmt_val != CSI_WRDDR_TYPE_RGB565) {
|
||||
if (dev->chip_id < CHIP_RV1126B_CIF &&
|
||||
(fmt->fourcc == V4L2_PIX_FMT_Y14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SBGGR14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SGBRG14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SGRBG14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SRGGB14))
|
||||
raw_bpp = 12;
|
||||
else
|
||||
raw_bpp = fmt->raw_bpp;
|
||||
if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
|
||||
channel->virtual_width = ALIGN(channel->width * 2 * fmt->raw_bpp / 8, 256);
|
||||
channel->left_virtual_width = channel->width * fmt->raw_bpp / 8;
|
||||
channel->virtual_width = ALIGN(channel->width * 2 * raw_bpp / 8, 256);
|
||||
channel->left_virtual_width = channel->width * raw_bpp / 8;
|
||||
} else {
|
||||
channel->virtual_width = ALIGN(channel->width * fmt->raw_bpp / 8, 256);
|
||||
channel->virtual_width = ALIGN(channel->width * raw_bpp / 8, 256);
|
||||
}
|
||||
} else {
|
||||
if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
|
||||
@@ -4418,9 +4515,14 @@ static int rkcif_csi_get_output_type_mask(struct rkcif_stream *stream)
|
||||
case V4L2_PIX_FMT_SGRBG12:
|
||||
case V4L2_PIX_FMT_SGBRG12:
|
||||
case V4L2_PIX_FMT_SBGGR12:
|
||||
case V4L2_PIX_FMT_SRGGB14:
|
||||
case V4L2_PIX_FMT_SGRBG14:
|
||||
case V4L2_PIX_FMT_SGBRG14:
|
||||
case V4L2_PIX_FMT_SBGGR14:
|
||||
case V4L2_PIX_FMT_GREY:
|
||||
case V4L2_PIX_FMT_Y10:
|
||||
case V4L2_PIX_FMT_Y12:
|
||||
case V4L2_PIX_FMT_Y14:
|
||||
if (stream->is_compact)
|
||||
mask = CSI_WRDDR_TYPE_RAW_COMPACT;
|
||||
else
|
||||
@@ -4488,9 +4590,14 @@ static int rkcif_csi_get_output_type_mask_rk3576(struct rkcif_stream *stream)
|
||||
case V4L2_PIX_FMT_SGRBG12:
|
||||
case V4L2_PIX_FMT_SGBRG12:
|
||||
case V4L2_PIX_FMT_SBGGR12:
|
||||
case V4L2_PIX_FMT_SRGGB14:
|
||||
case V4L2_PIX_FMT_SGRBG14:
|
||||
case V4L2_PIX_FMT_SGBRG14:
|
||||
case V4L2_PIX_FMT_SBGGR14:
|
||||
case V4L2_PIX_FMT_GREY:
|
||||
case V4L2_PIX_FMT_Y10:
|
||||
case V4L2_PIX_FMT_Y12:
|
||||
case V4L2_PIX_FMT_Y14:
|
||||
if (stream->is_compact)
|
||||
mask = CSI_WRDDR_TYPE_RAW_COMPACT << 3;
|
||||
else
|
||||
@@ -5394,19 +5501,24 @@ static int rkcif_csi_stream_start(struct rkcif_stream *stream, unsigned int mode
|
||||
}
|
||||
if (stream->cifdev->chip_id < CHIP_RK3588_CIF) {
|
||||
rkcif_csi_channel_set(stream, channel, mbus_type);
|
||||
} else if (stream->cifdev->chip_id < CHIP_RV1126B_CIF) {
|
||||
} else {
|
||||
if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
|
||||
for (i = 0; i < channel->capture_info.multi_dev.dev_num; i++) {
|
||||
dev->csi_host_idx = channel->capture_info.multi_dev.dev_idx[i];
|
||||
rkcif_csi_channel_set_v1(stream, channel, mbus_type, mode, i);
|
||||
if (stream->cifdev->chip_id < CHIP_RV1126B_CIF)
|
||||
rkcif_csi_channel_set_v1(stream, channel, mbus_type, mode, i);
|
||||
else
|
||||
rkcif_csi_channel_set_rv1126b(stream, channel, mbus_type, mode, i);
|
||||
}
|
||||
} else {
|
||||
if (!dev->switch_info.is_use_switch ||
|
||||
atomic_inc_return(&dev->hw_dev->switch_stream_cnt[dev->switch_info.host_idx]) == 1)
|
||||
rkcif_csi_channel_set_v1(stream, channel, mbus_type, mode, 0);
|
||||
atomic_inc_return(&dev->hw_dev->switch_stream_cnt[dev->switch_info.host_idx]) == 1) {
|
||||
if (stream->cifdev->chip_id < CHIP_RV1126B_CIF)
|
||||
rkcif_csi_channel_set_v1(stream, channel, mbus_type, mode, 0);
|
||||
else
|
||||
rkcif_csi_channel_set_rv1126b(stream, channel, mbus_type, mode, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rkcif_csi_channel_set_rv1126b(stream, channel, mbus_type, mode, 0);
|
||||
}
|
||||
} else {
|
||||
if (stream->cifdev->chip_id >= CHIP_RK3588_CIF) {
|
||||
@@ -6982,6 +7094,7 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream,
|
||||
stream->crop_mask = 0;
|
||||
stream->frame_loss = 0;
|
||||
stream->is_fb_first_frame = true;
|
||||
stream->is_force_update = false;
|
||||
}
|
||||
if (mode == RKCIF_STREAM_MODE_CAPTURE) {
|
||||
tasklet_disable(&stream->vb_done_tasklet);
|
||||
@@ -7316,6 +7429,11 @@ static u32 rkcif_align_bits_per_pixel(struct rkcif_stream *stream,
|
||||
case V4l2_PIX_FMT_EBD8:
|
||||
case V4L2_PIX_FMT_Y10:
|
||||
case V4L2_PIX_FMT_Y12:
|
||||
case V4L2_PIX_FMT_Y14:
|
||||
case V4L2_PIX_FMT_SRGGB14:
|
||||
case V4L2_PIX_FMT_SGRBG14:
|
||||
case V4L2_PIX_FMT_SGBRG14:
|
||||
case V4L2_PIX_FMT_SBGGR14:
|
||||
if (stream->cifdev->chip_id < CHIP_RV1126_CIF) {
|
||||
bpp = max(fmt->bpp[plane_index], (u8)CIF_RAW_STORED_BIT_WIDTH);
|
||||
cal = CIF_RAW_STORED_BIT_WIDTH;
|
||||
@@ -7620,9 +7738,14 @@ static int rkcif_dvp_get_output_type_mask(struct rkcif_stream *stream)
|
||||
case V4L2_PIX_FMT_SGRBG12:
|
||||
case V4L2_PIX_FMT_SGBRG12:
|
||||
case V4L2_PIX_FMT_SBGGR12:
|
||||
case V4L2_PIX_FMT_SRGGB14:
|
||||
case V4L2_PIX_FMT_SGRBG14:
|
||||
case V4L2_PIX_FMT_SGBRG14:
|
||||
case V4L2_PIX_FMT_SBGGR14:
|
||||
case V4L2_PIX_FMT_GREY:
|
||||
case V4L2_PIX_FMT_Y10:
|
||||
case V4L2_PIX_FMT_Y12:
|
||||
case V4L2_PIX_FMT_Y14:
|
||||
if (stream->is_compact)
|
||||
mask = CSI_WRDDR_TYPE_RAW_COMPACT << 11;
|
||||
else
|
||||
@@ -7701,6 +7824,11 @@ static int rkcif_dvp_get_output_type_mask_rk3576(struct rkcif_stream *stream)
|
||||
case V4L2_PIX_FMT_GREY:
|
||||
case V4L2_PIX_FMT_Y10:
|
||||
case V4L2_PIX_FMT_Y12:
|
||||
case V4L2_PIX_FMT_Y14:
|
||||
case V4L2_PIX_FMT_SRGGB14:
|
||||
case V4L2_PIX_FMT_SGRBG14:
|
||||
case V4L2_PIX_FMT_SGBRG14:
|
||||
case V4L2_PIX_FMT_SBGGR14:
|
||||
if (stream->is_compact)
|
||||
mask = CSI_WRDDR_TYPE_RAW_COMPACT << 15;
|
||||
else
|
||||
@@ -8601,6 +8729,8 @@ int rkcif_do_start_stream(struct rkcif_stream *stream, enum rkcif_stream_mode mo
|
||||
tasklet_enable(&stream->vb_done_tasklet);
|
||||
|
||||
if (stream->cur_stream_mode == RKCIF_STREAM_MODE_NONE) {
|
||||
dev->sensor_linetime = rkcif_get_linetime(stream);
|
||||
dev->readout_ns = dev->terminal_sensor.raw_rect.height * dev->sensor_linetime;
|
||||
ret = dev->pipe.open(&dev->pipe, &node->vdev.entity, true);
|
||||
if (ret < 0) {
|
||||
v4l2_err(v4l2_dev, "open cif pipeline failed %d\n",
|
||||
@@ -8823,6 +8953,7 @@ int rkcif_set_fmt(struct rkcif_stream *stream,
|
||||
struct rkcif_extend_info *extend_line = &stream->extend_line;
|
||||
struct csi_channel_info *channel_info = &dev->channels[stream->id];
|
||||
int ret;
|
||||
u32 raw_bpp = 0;
|
||||
|
||||
for (i = 0; i < RKCIF_MAX_PLANE; i++)
|
||||
memset(&pixm->plane_fmt[i], 0, sizeof(struct v4l2_plane_pix_format));
|
||||
@@ -8938,13 +9069,31 @@ int rkcif_set_fmt(struct rkcif_stream *stream,
|
||||
dev->active_sensor->mbus.type == V4L2_MBUS_CCP2) &&
|
||||
fmt->csi_fmt_val != CSI_WRDDR_TYPE_RGB888 &&
|
||||
fmt->csi_fmt_val != CSI_WRDDR_TYPE_RGB565) {
|
||||
bpl = ALIGN(width * fmt->raw_bpp / 8, 256);
|
||||
if (dev->chip_id < CHIP_RV1126B_CIF &&
|
||||
(fmt->fourcc == V4L2_PIX_FMT_Y14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SBGGR14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SGBRG14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SGRBG14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SRGGB14))
|
||||
raw_bpp = 12;
|
||||
else
|
||||
raw_bpp = fmt->raw_bpp;
|
||||
bpl = ALIGN(width * raw_bpp / 8, 256);
|
||||
} else {
|
||||
if (fmt->fmt_type == CIF_FMT_TYPE_RAW && stream->is_compact &&
|
||||
fmt->csi_fmt_val != CSI_WRDDR_TYPE_RGB888 &&
|
||||
fmt->csi_fmt_val != CSI_WRDDR_TYPE_RGB565 &&
|
||||
dev->chip_id >= CHIP_RK3588_CIF) {
|
||||
bpl = ALIGN(width * fmt->raw_bpp / 8, 256);
|
||||
if (dev->chip_id < CHIP_RV1126B_CIF &&
|
||||
(fmt->fourcc == V4L2_PIX_FMT_Y14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SBGGR14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SGBRG14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SGRBG14 ||
|
||||
fmt->fourcc == V4L2_PIX_FMT_SRGGB14))
|
||||
raw_bpp = 12;
|
||||
else
|
||||
raw_bpp = fmt->raw_bpp;
|
||||
bpl = ALIGN(width * raw_bpp / 8, 256);
|
||||
} else {
|
||||
bpp = rkcif_align_bits_per_pixel(stream, fmt, i);
|
||||
bpl = ALIGN(width * bpp / CIF_YUV_STORED_BIT_WIDTH, 8);
|
||||
@@ -9095,6 +9244,7 @@ void rkcif_stream_init(struct rkcif_device *dev, u32 id)
|
||||
memset(&stream->sensor_exp_info, 0, sizeof(stream->sensor_exp_info));
|
||||
stream->frame_loss = 0;
|
||||
stream->is_pause_stream = false;
|
||||
stream->is_force_update = false;
|
||||
}
|
||||
|
||||
int rkcif_sensor_set_power(struct rkcif_stream *stream, int on)
|
||||
@@ -13088,6 +13238,21 @@ u32 rkcif_mbus_pixelcode_to_v4l2(u32 pixelcode)
|
||||
case MEDIA_BUS_FMT_SRGGB16_1X16:
|
||||
pixelformat = V4L2_PIX_FMT_SRGGB16;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_Y14_1X14:
|
||||
pixelformat = V4L2_PIX_FMT_Y14;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_SBGGR14_1X14:
|
||||
pixelformat = V4L2_PIX_FMT_SBGGR14;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_SGBRG14_1X14:
|
||||
pixelformat = V4L2_PIX_FMT_SGBRG14;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_SGRBG14_1X14:
|
||||
pixelformat = V4L2_PIX_FMT_SGRBG14;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_SRGGB14_1X14:
|
||||
pixelformat = V4L2_PIX_FMT_SRGGB14;
|
||||
break;
|
||||
default:
|
||||
pixelformat = V4L2_PIX_FMT_SRGGB10;
|
||||
}
|
||||
@@ -13179,8 +13344,10 @@ void rkcif_enable_dma_capture(struct rkcif_stream *stream, bool is_only_enable)
|
||||
} else {
|
||||
if (cif_dev->chip_id < CHIP_RK3562_CIF)
|
||||
rkcif_write_register_or(cif_dev, CIF_REG_DVP_CTRL, 0x00010000);
|
||||
else
|
||||
else if (cif_dev->chip_id < CHIP_RK3576_CIF)
|
||||
rkcif_write_register_or(cif_dev, CIF_REG_DVP_VIR_LINE_WIDTH, BIT(28) << stream->id);
|
||||
else
|
||||
rkcif_write_register_or(cif_dev, CIF_REG_DVP_VIR_LINE_WIDTH, BIT(31));
|
||||
}
|
||||
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CSI2_CPHY) {
|
||||
|
||||
@@ -680,6 +680,7 @@ struct rkcif_stream {
|
||||
bool is_m_online_fb_res;
|
||||
bool is_fb_first_frame;
|
||||
bool is_pause_stream;
|
||||
bool is_force_update;
|
||||
};
|
||||
|
||||
struct rkcif_lvds_subdev {
|
||||
@@ -1057,6 +1058,7 @@ struct rkcif_device {
|
||||
u32 early_line;
|
||||
int isp_runtime_max;
|
||||
int sensor_linetime;
|
||||
u64 readout_ns;
|
||||
u32 err_state;
|
||||
struct rkcif_err_state_work err_state_work;
|
||||
struct rkcif_sensor_work sensor_work;
|
||||
|
||||
@@ -874,6 +874,7 @@ enum cif_reg_index {
|
||||
#define RAW_DATA_WIDTH_8 (0x00 << 11)
|
||||
#define RAW_DATA_WIDTH_10 (0x01 << 11)
|
||||
#define RAW_DATA_WIDTH_12 (0x02 << 11)
|
||||
#define RAW_DATA_WIDTH_14 (0x03 << 11)
|
||||
#define MIPI_MODE_32BITS_BYPASS (0x00 << 13)
|
||||
#define MIPI_MODE_RGB (0x01 << 13)
|
||||
#define MIPI_MODE_YUV (0x02 << 13)
|
||||
|
||||
@@ -208,6 +208,27 @@ static int sditf_get_set_fmt(struct v4l2_subdev *sd,
|
||||
priv->cap_info.offset_x = 0;
|
||||
priv->cap_info .offset_y = 0;
|
||||
}
|
||||
if (cif_dev->chip_id < CHIP_RV1126B_CIF) {
|
||||
switch (fmt->format.code) {
|
||||
case MEDIA_BUS_FMT_Y14_1X14:
|
||||
fmt->format.code = MEDIA_BUS_FMT_Y12_1X12;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_SBGGR14_1X14:
|
||||
fmt->format.code = MEDIA_BUS_FMT_SBGGR12_1X12;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_SGBRG14_1X14:
|
||||
fmt->format.code = MEDIA_BUS_FMT_SGBRG12_1X12;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_SGRBG14_1X14:
|
||||
fmt->format.code = MEDIA_BUS_FMT_SGRBG12_1X12;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_SRGGB14_1X14:
|
||||
fmt->format.code = MEDIA_BUS_FMT_SRGGB12_1X12;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
priv->cap_info.width = fmt->format.width;
|
||||
priv->cap_info.height = fmt->format.height;
|
||||
pixm.pixelformat = rkcif_mbus_pixelcode_to_v4l2(fmt->format.code);
|
||||
|
||||
@@ -644,6 +644,8 @@ int rkisp_csi_config_patch(struct rkisp_device *dev, bool is_pre_cfg)
|
||||
} else {
|
||||
rkisp_unite_write(dev, CSI2RX_CTRL0,
|
||||
SW_IBUF_OP_MODE(dev->hdr.op_mode), false);
|
||||
rkisp_unite_write(dev, CSI2RX_DATA_IDS_1,
|
||||
dev->isp_sdev.in_fmt.mipi_dt, false);
|
||||
}
|
||||
/* hdr merge */
|
||||
switch (dev->hdr.op_mode) {
|
||||
|
||||
@@ -196,6 +196,26 @@ static const struct capture_fmt rawrd_fmts[] = {
|
||||
.fmt_type = FMT_YUV,
|
||||
.bpp = { 16 },
|
||||
.mplanes = 1,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SRGGB14,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.bpp = { 14 },
|
||||
.mplanes = 1,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGRBG14,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.bpp = { 14 },
|
||||
.mplanes = 1,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGBRG14,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.bpp = { 14 },
|
||||
.mplanes = 1,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SBGGR14,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.bpp = { 14 },
|
||||
.mplanes = 1,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SRGGB16,
|
||||
.fmt_type = FMT_BAYER,
|
||||
@@ -216,6 +236,11 @@ static const struct capture_fmt rawrd_fmts[] = {
|
||||
.fmt_type = FMT_BAYER,
|
||||
.bpp = { 16 },
|
||||
.mplanes = 1,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_Y14,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.bpp = { 14 },
|
||||
.mplanes = 1,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_Y16,
|
||||
.fmt_type = FMT_BAYER,
|
||||
@@ -367,6 +392,13 @@ static int rawrd_config_mi(struct rkisp_stream *stream)
|
||||
case V4L2_PIX_FMT_VYUY:
|
||||
val |= CIF_CSI2_DT_YUV422_8b;
|
||||
break;
|
||||
case V4L2_PIX_FMT_SRGGB14:
|
||||
case V4L2_PIX_FMT_SBGGR14:
|
||||
case V4L2_PIX_FMT_SGRBG14:
|
||||
case V4L2_PIX_FMT_SGBRG14:
|
||||
case V4L2_PIX_FMT_Y14:
|
||||
val |= CIF_CSI2_DT_RAW14;
|
||||
break;
|
||||
case V4L2_PIX_FMT_SRGGB16:
|
||||
case V4L2_PIX_FMT_SBGGR16:
|
||||
case V4L2_PIX_FMT_SGRBG16:
|
||||
@@ -816,6 +848,26 @@ static int rkisp_set_fmt(struct rkisp_stream *stream,
|
||||
u32 xsubs = 1, ysubs = 1;
|
||||
unsigned int i;
|
||||
|
||||
if (stream->ispdev->isp_ver < ISP_V35 &&
|
||||
(pixm->pixelformat == V4L2_PIX_FMT_SBGGR14 ||
|
||||
pixm->pixelformat == V4L2_PIX_FMT_SGBRG14 ||
|
||||
pixm->pixelformat == V4L2_PIX_FMT_SGRBG14 ||
|
||||
pixm->pixelformat == V4L2_PIX_FMT_SRGGB14 ||
|
||||
pixm->pixelformat == V4L2_PIX_FMT_Y14)) {
|
||||
if (pixm->pixelformat == V4L2_PIX_FMT_SBGGR14)
|
||||
pixm->pixelformat = V4L2_PIX_FMT_SBGGR12;
|
||||
else if (pixm->pixelformat == V4L2_PIX_FMT_SGBRG14)
|
||||
pixm->pixelformat = V4L2_PIX_FMT_SGBRG12;
|
||||
else if (pixm->pixelformat == V4L2_PIX_FMT_SGRBG14)
|
||||
pixm->pixelformat = V4L2_PIX_FMT_SGRBG12;
|
||||
else if (pixm->pixelformat == V4L2_PIX_FMT_SRGGB14)
|
||||
pixm->pixelformat = V4L2_PIX_FMT_SRGGB12;
|
||||
else
|
||||
pixm->pixelformat = V4L2_PIX_FMT_Y12;
|
||||
v4l2_warn(&stream->ispdev->v4l2_dev,
|
||||
"no support raw14, rawrd format force to raw12\n");
|
||||
}
|
||||
|
||||
fmt = find_fmt(stream, pixm->pixelformat);
|
||||
if (!fmt) {
|
||||
v4l2_err(&stream->ispdev->v4l2_dev,
|
||||
|
||||
@@ -406,6 +406,7 @@
|
||||
#define CIF_CSI2_DT_RAW8 0x2A
|
||||
#define CIF_CSI2_DT_RAW10 0x2B
|
||||
#define CIF_CSI2_DT_RAW12 0x2C
|
||||
#define CIF_CSI2_DT_RAW14 0x2D
|
||||
#define CIF_CSI2_DT_RAW16 0x2e
|
||||
#define CIF_CSI2_DT_SPD 0x2F
|
||||
|
||||
|
||||
@@ -2787,6 +2787,41 @@ static const struct ispsd_in_fmt rkisp_isp_input_formats[] = {
|
||||
.mipi_dt = CIF_CSI2_DT_RAW12,
|
||||
.yuv_seq = CIF_ISP_ACQ_PROP_YCBYCR,
|
||||
.bus_width = 12,
|
||||
}, {
|
||||
.name = "Y14_1X14",
|
||||
.mbus_code = MEDIA_BUS_FMT_Y14_1X14,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.mipi_dt = CIF_CSI2_DT_RAW14,
|
||||
.yuv_seq = CIF_ISP_ACQ_PROP_YCBYCR,
|
||||
.bus_width = 14,
|
||||
}, {
|
||||
.name = "SRGGB14_1X14",
|
||||
.mbus_code = MEDIA_BUS_FMT_SRGGB14_1X14,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.mipi_dt = CIF_CSI2_DT_RAW14,
|
||||
.bayer_pat = RAW_RGGB,
|
||||
.bus_width = 14,
|
||||
}, {
|
||||
.name = "SBGGR14_1X14",
|
||||
.mbus_code = MEDIA_BUS_FMT_SBGGR14_1X14,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.mipi_dt = CIF_CSI2_DT_RAW14,
|
||||
.bayer_pat = RAW_BGGR,
|
||||
.bus_width = 14,
|
||||
}, {
|
||||
.name = "SGBRG14_1X14",
|
||||
.mbus_code = MEDIA_BUS_FMT_SGBRG14_1X14,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.mipi_dt = CIF_CSI2_DT_RAW14,
|
||||
.bayer_pat = RAW_GBRG,
|
||||
.bus_width = 14,
|
||||
}, {
|
||||
.name = "SGRBG14_1X14",
|
||||
.mbus_code = MEDIA_BUS_FMT_SGRBG14_1X14,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.mipi_dt = CIF_CSI2_DT_RAW14,
|
||||
.bayer_pat = RAW_GRBG,
|
||||
.bus_width = 14,
|
||||
}, {
|
||||
.name = "SRGGB16_1X16",
|
||||
.mbus_code = MEDIA_BUS_FMT_SRGGB16_1X16,
|
||||
@@ -2795,21 +2830,21 @@ static const struct ispsd_in_fmt rkisp_isp_input_formats[] = {
|
||||
.bayer_pat = RAW_RGGB,
|
||||
.bus_width = 16,
|
||||
}, {
|
||||
.name = "SBGGR12_1X16",
|
||||
.name = "SBGGR16_1X16",
|
||||
.mbus_code = MEDIA_BUS_FMT_SBGGR16_1X16,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.mipi_dt = CIF_CSI2_DT_RAW16,
|
||||
.bayer_pat = RAW_BGGR,
|
||||
.bus_width = 16,
|
||||
}, {
|
||||
.name = "SGBRG12_1X16",
|
||||
.name = "SGBRG16_1X16",
|
||||
.mbus_code = MEDIA_BUS_FMT_SGBRG16_1X16,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.mipi_dt = CIF_CSI2_DT_RAW16,
|
||||
.bayer_pat = RAW_GBRG,
|
||||
.bus_width = 16,
|
||||
}, {
|
||||
.name = "SGRBG12_1X16",
|
||||
.name = "SGRBG16_1X16",
|
||||
.mbus_code = MEDIA_BUS_FMT_SGRBG16_1X16,
|
||||
.fmt_type = FMT_BAYER,
|
||||
.mipi_dt = CIF_CSI2_DT_RAW16,
|
||||
@@ -2974,6 +3009,25 @@ static int rkisp_isp_sd_set_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_pix_format_mplane pixm = { 0 };
|
||||
const struct ispsd_in_fmt *in_fmt;
|
||||
|
||||
if (isp_dev->isp_ver < ISP_V35 &&
|
||||
(mf->code == MEDIA_BUS_FMT_SGRBG14_1X14 ||
|
||||
mf->code == MEDIA_BUS_FMT_SGBRG14_1X14 ||
|
||||
mf->code == MEDIA_BUS_FMT_SBGGR14_1X14 ||
|
||||
mf->code == MEDIA_BUS_FMT_SRGGB14_1X14 ||
|
||||
mf->code == MEDIA_BUS_FMT_Y14_1X14)) {
|
||||
if (mf->code == MEDIA_BUS_FMT_SGRBG14_1X14)
|
||||
mf->code = MEDIA_BUS_FMT_SGRBG12_1X12;
|
||||
else if (mf->code == MEDIA_BUS_FMT_SGBRG14_1X14)
|
||||
mf->code = MEDIA_BUS_FMT_SGBRG12_1X12;
|
||||
else if (mf->code == MEDIA_BUS_FMT_SBGGR12_1X12)
|
||||
mf->code = MEDIA_BUS_FMT_SBGGR12_1X12;
|
||||
else if (mf->code == MEDIA_BUS_FMT_SRGGB14_1X14)
|
||||
mf->code = MEDIA_BUS_FMT_SRGGB12_1X12;
|
||||
else
|
||||
mf->code = MEDIA_BUS_FMT_Y12_1X12;
|
||||
v4l2_warn(&isp_dev->v4l2_dev,
|
||||
"no support raw14, isp format force to raw12\n");
|
||||
}
|
||||
in_fmt = find_in_fmt(mf->code);
|
||||
if (!in_fmt ||
|
||||
mf->width < CIF_ISP_INPUT_W_MIN ||
|
||||
|
||||
@@ -128,6 +128,7 @@ struct csi2_dphy_hw {
|
||||
int dphy_dev_num;
|
||||
enum csi2_dphy_lane_mode lane_mode;
|
||||
struct resource *res;
|
||||
int hw_idx;
|
||||
|
||||
int (*stream_on)(struct csi2_dphy *dphy, struct v4l2_subdev *sd);
|
||||
int (*stream_off)(struct csi2_dphy *dphy, struct v4l2_subdev *sd);
|
||||
|
||||
@@ -650,6 +650,40 @@ static unsigned char get_lvds_data_width(u32 pixelformat)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char get_lvds_data_width_rv1126b(u32 pixelformat)
|
||||
{
|
||||
switch (pixelformat) {
|
||||
/* csi raw8 */
|
||||
case MEDIA_BUS_FMT_SBGGR8_1X8:
|
||||
case MEDIA_BUS_FMT_SGBRG8_1X8:
|
||||
case MEDIA_BUS_FMT_SGRBG8_1X8:
|
||||
case MEDIA_BUS_FMT_SRGGB8_1X8:
|
||||
return 0x1;
|
||||
/* csi raw10 */
|
||||
case MEDIA_BUS_FMT_SBGGR10_1X10:
|
||||
case MEDIA_BUS_FMT_SGBRG10_1X10:
|
||||
case MEDIA_BUS_FMT_SGRBG10_1X10:
|
||||
case MEDIA_BUS_FMT_SRGGB10_1X10:
|
||||
return 0x2;
|
||||
/* csi raw12 */
|
||||
case MEDIA_BUS_FMT_SBGGR12_1X12:
|
||||
case MEDIA_BUS_FMT_SGBRG12_1X12:
|
||||
case MEDIA_BUS_FMT_SGRBG12_1X12:
|
||||
case MEDIA_BUS_FMT_SRGGB12_1X12:
|
||||
return 0x3;
|
||||
/* csi uyvy 422 */
|
||||
case MEDIA_BUS_FMT_UYVY8_2X8:
|
||||
case MEDIA_BUS_FMT_VYUY8_2X8:
|
||||
case MEDIA_BUS_FMT_YUYV8_2X8:
|
||||
case MEDIA_BUS_FMT_YVYU8_2X8:
|
||||
case MEDIA_BUS_FMT_RGB888_1X24:
|
||||
return 0x1;
|
||||
|
||||
default:
|
||||
return 0x2;
|
||||
}
|
||||
}
|
||||
|
||||
static void csi2_dphy_hw_do_reset(struct csi2_dphy_hw *hw)
|
||||
{
|
||||
if (hw->rsts_bulk)
|
||||
@@ -678,7 +712,7 @@ static void csi2_dphy_config_dual_mode(struct csi2_dphy *dphy,
|
||||
|
||||
if (hw->lane_mode == LANE_MODE_FULL) {
|
||||
val = !GRF_CSI2PHY_LANE_SEL_SPLIT;
|
||||
if (dphy->phy_index < 3) {
|
||||
if (hw->hw_idx == 0) {
|
||||
write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN,
|
||||
GENMASK(sensor->lanes - 1, 0));
|
||||
write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1);
|
||||
@@ -991,7 +1025,10 @@ static int csi2_dphy_hw_stream_on(struct csi2_dphy *dphy,
|
||||
write_csi2_dphy_reg(hw, CSI2PHY_PATH0_MODEL, 0x2);
|
||||
} else {
|
||||
write_csi2_dphy_reg(hw, CSI2PHY_PATH0_MODEL, 0x4);
|
||||
lvds_width = get_lvds_data_width(sensor->format.code);
|
||||
if (hw->drv_data->chip_id == CHIP_ID_RV1126B)
|
||||
lvds_width = get_lvds_data_width_rv1126b(sensor->format.code);
|
||||
else
|
||||
lvds_width = get_lvds_data_width(sensor->format.code);
|
||||
write_csi2_dphy_reg(hw, CSI2PHY_PATH0_LVDS_MODEL, (lvds_width << 4) | 0X0f);
|
||||
}
|
||||
} else {
|
||||
@@ -999,7 +1036,10 @@ static int csi2_dphy_hw_stream_on(struct csi2_dphy *dphy,
|
||||
write_csi2_dphy_reg(hw, CSI2PHY_PATH1_MODEL, 0x2);
|
||||
} else {
|
||||
write_csi2_dphy_reg(hw, CSI2PHY_PATH1_MODEL, 0x4);
|
||||
lvds_width = get_lvds_data_width(sensor->format.code);
|
||||
if (hw->drv_data->chip_id == CHIP_ID_RV1126B)
|
||||
lvds_width = get_lvds_data_width_rv1126b(sensor->format.code);
|
||||
else
|
||||
lvds_width = get_lvds_data_width(sensor->format.code);
|
||||
write_csi2_dphy_reg(hw, CSI2PHY_PATH1_LVDS_MODEL, (lvds_width << 4) | 0X0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1161,6 +1161,7 @@ static int rockchip_csi2_dphy_get_inno_phy_hw(struct csi2_dphy *dphy)
|
||||
dphy->phy_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
dphy_hw->hw_idx = i;
|
||||
dphy->dphy_hw_group[i] = dphy_hw;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -1195,6 +1195,20 @@ static int __maybe_unused rk806_suspend(struct device *dev)
|
||||
for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++)
|
||||
rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i, CTR_BY_PWRCTRL1);
|
||||
} else {
|
||||
for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++) {
|
||||
if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL1) {
|
||||
chip_ver = rk806_field_read(rk806, CHIP_VER);
|
||||
if (chip_ver & 0x08)
|
||||
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_SLP_FUN);
|
||||
else
|
||||
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_DVS_FUN);
|
||||
}
|
||||
if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL2)
|
||||
rk806_field_write(rk806, PWRCTRL2_FUN, PWRCTRL_DVS_FUN);
|
||||
if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL3)
|
||||
rk806_field_write(rk806, PWRCTRL3_FUN, PWRCTRL_DVS_FUN);
|
||||
}
|
||||
|
||||
for (i = 0; i <= RK806_ID_PLDO6 - RK806_ID_PLDO1; i++) {
|
||||
value = rk806_field_read(rk806, PLDO1_ON_VSEL + i);
|
||||
rk806_field_write(rk806, PLDO1_SLP_VSEL + i, value);
|
||||
@@ -1209,18 +1223,6 @@ static int __maybe_unused rk806_suspend(struct device *dev)
|
||||
rk806_field_write(rk806, PLDO4_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO3]);
|
||||
rk806_field_write(rk806, PLDO5_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO4]);
|
||||
rk806_field_write(rk806, PLDO6_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO5]);
|
||||
|
||||
for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++) {
|
||||
if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL2)
|
||||
rk806_field_write(rk806, PWRCTRL2_FUN, PWRCTRL_DVS_FUN);
|
||||
if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL3)
|
||||
rk806_field_write(rk806, PWRCTRL3_FUN, PWRCTRL_DVS_FUN);
|
||||
}
|
||||
chip_ver = rk806_field_read(rk806, CHIP_VER);
|
||||
if (chip_ver & 0x08)
|
||||
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_SLP_FUN);
|
||||
else
|
||||
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_DVS_FUN);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -70,6 +70,7 @@ enum adc_sort_mode {
|
||||
|
||||
struct phy_config {
|
||||
unsigned int bias;
|
||||
unsigned int offset;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -337,6 +338,7 @@ struct rockchip_thermal_data {
|
||||
|
||||
#define RV1126B_GRF_TSADC_CON0 0x50
|
||||
#define RV1126B_GRF_TSADC_CON1 0x54
|
||||
#define RV1126B_GRF_TSADC_CON4 0x60
|
||||
#define RV1126B_GRF_TSADC_CON6 0x68
|
||||
#define RV1126B_GRF_TSADC_ST1 0x114
|
||||
#define RV1126B_UNLOCK_VALUE 0xa5
|
||||
@@ -345,6 +347,8 @@ struct rockchip_thermal_data {
|
||||
#define RV1126B_UNLOCK_TRIGGER_MASK (BIT(8) << 16)
|
||||
#define RV1126B_MAX_BIAS 0x7f
|
||||
#define RV1126B_BIAS_MASK (0x7f << 16)
|
||||
#define RV1126B_MAX_OFFSET 0xffff
|
||||
#define RV1126B_OFFSET_MASK (0xffff << 16)
|
||||
#define RV1126B_CTRL_MASK (0x8078 << 16)
|
||||
|
||||
#define GRF_SARADC_TESTBIT_ON (0x10001 << 2)
|
||||
@@ -1719,8 +1723,16 @@ static void rv1126b_tsadc_phy_init(struct device *dev, struct regmap *grf,
|
||||
regmap_write(grf, RV1126B_GRF_TSADC_CON6,
|
||||
phy_cfg->bias | RV1126B_BIAS_MASK);
|
||||
}
|
||||
if (!phy_cfg->offset) {
|
||||
regmap_read(grf, RV1126B_GRF_TSADC_CON4, &val);
|
||||
phy_cfg->offset = val & RV1126B_MAX_OFFSET;
|
||||
} else {
|
||||
regmap_write(grf, RV1126B_GRF_TSADC_CON4,
|
||||
phy_cfg->offset | RV1126B_OFFSET_MASK);
|
||||
}
|
||||
regmap_read(grf, RV1126B_GRF_TSADC_ST1, &val);
|
||||
dev_info(dev, "width=0x%x, bias=0x%x\n", val, phy_cfg->bias);
|
||||
dev_info(dev, "width=0x%x, bias=0x%x, offset=0x%x\n", val, phy_cfg->bias,
|
||||
phy_cfg->offset);
|
||||
regmap_write(grf, RV1126B_GRF_TSADC_CON0, RV1126B_CTRL_MASK);
|
||||
regmap_write(grf, RV1126B_GRF_TSADC_CON1,
|
||||
RV1126B_UNLOCK_VALUE | RV1126B_UNLOCK_VALUE_MASK);
|
||||
|
||||
Reference in New Issue
Block a user