Merge commit '0aa6d336c04bba5357c0b0dd2321ace7194cc1b7'

* commit '0aa6d336c04bba5357c0b0dd2321ace7194cc1b7':
  ARM: rockchip: support rv1103 suspend
  drm/rockchip: vvop: fix compile errors
  drm/rockchip: dsi2: support Auto-Calculation mode
  drm/rockchip: dsi2: fix IPI_RATIO_MAN_CFG in dsc mode
  video: rockchip: vtunnel: buffer ID should generate by instance

Change-Id: Id0ab9d06e1dfb3797f13e58aeb6f975ce381ec0c
This commit is contained in:
Tao Huang
2023-11-22 17:55:34 +08:00
3 changed files with 65 additions and 13 deletions

View File

@@ -62,6 +62,7 @@ static const char * const rockchip_board_dt_compat[] = {
"rockchip,rk3188",
"rockchip,rk3228",
"rockchip,rk3288",
"rockchip,rv1103",
"rockchip,rv1106",
"rockchip,rv1108",
NULL,

View File

@@ -246,6 +246,7 @@ struct dw_mipi_dsi2 {
union phy_configure_opts phy_opts;
bool disable_hold_mode;
bool auto_calc_mode;
bool c_option;
bool scrambling_en;
unsigned int slice_width;
@@ -270,7 +271,7 @@ struct dw_mipi_dsi2 {
u32 lanes;
u32 format;
unsigned long mode_flags;
u64 mipi_pixel_rate;
const struct dw_mipi_dsi2_plat_data *pdata;
struct rockchip_drm_sub_dev sub_dev;
@@ -609,9 +610,8 @@ static void dw_mipi_dsi2_phy_clk_mode_cfg(struct dw_mipi_dsi2 *dsi2)
static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2)
{
struct drm_display_mode *mode = &dsi2->mode;
u64 sys_clk = clk_get_rate(dsi2->sys_clk);
u64 pixel_clk, ipi_clk, phy_hsclk;
u64 ipi_clk, phy_hsclk;
u64 tmp;
/*
@@ -625,9 +625,7 @@ static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2)
phy_hsclk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_hs_rate * MSEC_PER_SEC, 16);
/* IPI_RATIO_MAN_CFG = PHY_HSTX_CLK / IPI_CLK */
pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
ipi_clk = pixel_clk / 4;
ipi_clk = dsi2->mipi_pixel_rate;
if (!sys_clk || !ipi_clk)
return;
@@ -669,6 +667,10 @@ static void dw_mipi_dsi2_phy_init(struct dw_mipi_dsi2 *dsi2)
{
dw_mipi_dsi2_phy_mode_cfg(dsi2);
dw_mipi_dsi2_phy_clk_mode_cfg(dsi2);
if (dsi2->auto_calc_mode)
return;
dw_mipi_dsi2_phy_ratio_cfg(dsi2);
dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(dsi2);
@@ -737,6 +739,9 @@ static void dw_mipi_dsi2_ipi_set(struct dw_mipi_dsi2 *dsi2)
dw_mipi_dsi2_ipi_color_coding_cfg(dsi2);
if (dsi2->auto_calc_mode)
return;
/*
* if the controller is intended to operate in data stream mode,
* no more steps are required.
@@ -810,7 +815,7 @@ static void dw_mipi_dsi2_pre_enable(struct dw_mipi_dsi2 *dsi2)
/* there may be some timeout registers may be configured if desired */
dw_mipi_dsi2_work_mode(dsi2, MANUAL_MODE_EN);
dw_mipi_dsi2_work_mode(dsi2, dsi2->auto_calc_mode ? 0 : MANUAL_MODE_EN);
dw_mipi_dsi2_phy_init(dsi2);
dw_mipi_dsi2_tx_option_set(dsi2);
dw_mipi_dsi2_irq_enable(dsi2, 1);
@@ -833,8 +838,20 @@ static void dw_mipi_dsi2_pre_enable(struct dw_mipi_dsi2 *dsi2)
static void dw_mipi_dsi2_enable(struct dw_mipi_dsi2 *dsi2)
{
u32 mode;
int ret;
dw_mipi_dsi2_ipi_set(dsi2);
if (dsi2->auto_calc_mode) {
regmap_write(dsi2->regmap, DSI2_MODE_CTRL, AUTOCALC_MODE);
ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
mode, mode == IDLE_MODE,
1000, MODE_STATUS_TIMEOUT_US);
if (ret < 0)
dev_err(dsi2->dev, "auto calculation training failed\n");
}
if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)
dw_mipi_dsi2_set_vid_mode(dsi2);
else
@@ -844,6 +861,31 @@ static void dw_mipi_dsi2_enable(struct dw_mipi_dsi2 *dsi2)
dw_mipi_dsi2_enable(dsi2->slave);
}
static void dw_mipi_dsi2_get_mipi_pixel_clk(struct dw_mipi_dsi2 *dsi2,
struct rockchip_crtc_state *s)
{
struct drm_display_mode *mode = &dsi2->mode;
u8 k = dsi2->slave ? 2 : 1;
/* 1.When MIPI works in uncompressed mode:
* (Video Timing Pixel Rate)/(4)=(MIPI Pixel ClockxK)=(dclk_out×K)=dclk_core
* 2.When MIPI works in compressed mode:
* MIPI Pixel Clock = cds_clk / 2
* MIPI is configured as double channel display mode, K=2, otherwise K=1.
*/
if (dsi2->dsc_enable) {
dsi2->mipi_pixel_rate = s->dsc_cds_clk_rate / 2;
if (dsi2->slave)
dsi2->slave->mipi_pixel_rate = dsi2->mipi_pixel_rate;
return;
}
dsi2->mipi_pixel_rate = (mode->crtc_clock * MSEC_PER_SEC) / (4 * k);
if (dsi2->slave)
dsi2->slave->mipi_pixel_rate = dsi2->mipi_pixel_rate;
}
static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2,
struct drm_atomic_state *state)
{
@@ -851,6 +893,7 @@ static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2,
struct drm_connector *connector;
struct drm_connector_state *conn_state;
struct drm_crtc_state *crtc_state;
struct rockchip_crtc_state *vcstate;
const struct drm_display_mode *adjusted_mode;
struct drm_display_mode *mode = &dsi2->mode;
@@ -868,6 +911,7 @@ static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2,
return -ENODEV;
}
vcstate = to_rockchip_crtc_state(crtc_state);
adjusted_mode = &crtc_state->adjusted_mode;
drm_mode_copy(mode, adjusted_mode);
@@ -877,6 +921,8 @@ static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2,
if (dsi2->slave)
drm_mode_copy(&dsi2->slave->mode, mode);
dw_mipi_dsi2_get_mipi_pixel_clk(dsi2, vcstate);
return 0;
}
@@ -1167,6 +1213,7 @@ static int dw_mipi_dsi2_dual_channel_probe(struct dw_mipi_dsi2 *dsi2)
dsi2->slave->master = dsi2;
dsi2->lanes /= 2;
dsi2->slave->auto_calc_mode = dsi2->auto_calc_mode;
dsi2->slave->lanes = dsi2->lanes;
dsi2->slave->channel = dsi2->channel;
dsi2->slave->format = dsi2->format;
@@ -1642,6 +1689,9 @@ static int dw_mipi_dsi2_probe(struct platform_device *pdev)
dsi2->pdata = of_device_get_match_data(dev);
platform_set_drvdata(pdev, dsi2);
if (device_property_read_bool(dev, "auto-calculation-mode"))
dsi2->auto_calc_mode = true;
if (device_property_read_bool(dev, "disable-hold-mode"))
dsi2->disable_hold_mode = true;

View File

@@ -72,7 +72,6 @@ struct rkvt_dev {
char *dev_name;
int inst_id_generator;
atomic64_t cid_generator;
atomic64_t buf_id_generator;
struct dentry *debug_root;
};
@@ -123,6 +122,8 @@ struct rkvt_instance {
DECLARE_KFIFO_PTR(fifo_to_producer, struct rkvt_buffer*);
struct rkvt_buffer vt_buffers[RKVT_POOL_SIZE];
atomic64_t buf_id_generator;
};
static unsigned int vt_dev_dbg;
@@ -740,10 +741,10 @@ rkvt_reset_proc(struct rkvt_ctrl_data *data, struct rkvt_session *session)
mutex_lock(&inst->lock);
rkvt_inst_clear_consumer(inst);
rkvt_inst_clear_producer(inst);
read_buf_id = atomic64_read(&vt_dev->buf_id_generator);
read_buf_id = atomic64_read(&inst->buf_id_generator);
read_buf_id += 0x100;
read_buf_id &= ~0xff;
atomic64_set(&vt_dev->buf_id_generator, read_buf_id);
atomic64_set(&inst->buf_id_generator, read_buf_id);
mutex_unlock(&inst->lock);
rkvt_inst_put(inst);
@@ -950,7 +951,7 @@ rkvt_queue_buf(struct rkvt_buf_data *data, struct rkvt_session *session)
// buffer id is empty, generate a new id
if (base->buffer_id == 0)
base->buffer_id = atomic64_inc_return(&vt_dev->buf_id_generator);
base->buffer_id = atomic64_inc_return(&inst->buf_id_generator);
buffer->base = *base;
buffer->base.buf_status = RKVT_BUF_QUEUE;
buffer->session_pro = session;
@@ -1234,7 +1235,7 @@ rkvt_release_buf(struct rkvt_buf_data *data, struct rkvt_session *session)
buffer->base.buf_status = RKVT_BUF_RELEASE;
mutex_lock(&inst->lock);
read_buf_id = atomic64_read(&vt_dev->buf_id_generator);
read_buf_id = atomic64_read(&inst->buf_id_generator);
/* if producer has disconnect */
if (!inst->producer) {
rkvt_dbg(RKVT_DBG_BUFFERS, "VTRB [%d], buffer no producer\n", inst->id);
@@ -1298,7 +1299,7 @@ rkvt_cancel_buf(struct rkvt_buf_data *data, struct rkvt_session *session)
}
// buffer id is empty, generate a new id
if (buf_base->buffer_id == 0)
buf_base->buffer_id = atomic64_inc_return(&vt_dev->buf_id_generator);
buf_base->buffer_id = atomic64_inc_return(&inst->buf_id_generator);
buffer->base = *buf_base;
buffer->base.buf_status = RKVT_BUF_RELEASE;
buffer->session_pro = session;