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:
Tao Huang
2025-09-25 09:49:54 +08:00
20 changed files with 721 additions and 205 deletions

View File

@@ -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);
}

View File

@@ -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))

View File

@@ -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);

View File

@@ -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,

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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

View File

@@ -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 ||

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);