mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 20:32:04 +09:00
Merge commit '34c17d0724d5e26a4efda23502cfbbb612bcb994'
* commit '34c17d0724d5e26a4efda23502cfbbb612bcb994': drm/rockchip: vop2: Support invalid phy id for vop2_plane_id_to_string media: rockchip: vpss: online support 8k arm64: dts: rockchip: rk3576: enable VOP aclk auto cs drm/rockchip: vop2: add support dynamic adjust vop aclk auto cs div drm/rockchip: analogix_dp: add support for color format yuv444/yuv422 video: rockchip: rga3: modify workaround for RK3576 issue pinctrl: rockchip: Fix iterator 'j' not incremented in rk_iomux_set() input: touchscreen: ft5726: Fix abnormal sleep power drm/rockchip: vop: Fix mixing irqsave and irq in vop_crtc_atomic_flush() media: i2c: rk628: fix YUV format color range detect Change-Id: I70a19db1e092a5397c73710bd5fb8ccaa47ef02e
This commit is contained in:
@@ -2777,6 +2777,8 @@
|
||||
rockchip,aclk-reset-mode-rates = <594000000>;
|
||||
rockchip,aclk-advanced-mode-rates = <702000000>;
|
||||
operating-points-v2 = <&vop_opp_table>;
|
||||
rockchip,csu = <&csu CSU_VOP_ACLK>;
|
||||
rockchip,csu-names = "aclk";
|
||||
iommus = <&vop_mmu>;
|
||||
power-domains = <&power RK3576_PD_VOP>;
|
||||
rockchip,grf = <&sys_grf>;
|
||||
|
||||
@@ -54,23 +54,52 @@ struct bridge_init {
|
||||
struct device_node *node;
|
||||
};
|
||||
|
||||
static const struct analogix_dp_output_format possible_output_fmts[] = {
|
||||
{ MEDIA_BUS_FMT_RGB101010_1X30, DRM_COLOR_FORMAT_RGB444, 10 },
|
||||
{ MEDIA_BUS_FMT_RGB888_1X24, DRM_COLOR_FORMAT_RGB444, 8 },
|
||||
{ MEDIA_BUS_FMT_RGB666_1X24_CPADHI, DRM_COLOR_FORMAT_RGB444, 6 },
|
||||
{ MEDIA_BUS_FMT_YUV10_1X30, DRM_COLOR_FORMAT_YCBCR444, 10 },
|
||||
{ MEDIA_BUS_FMT_YUV8_1X24, DRM_COLOR_FORMAT_YCBCR444, 8},
|
||||
{ MEDIA_BUS_FMT_YUYV10_1X20, DRM_COLOR_FORMAT_YCBCR422, 10 },
|
||||
{ MEDIA_BUS_FMT_YUYV8_1X16, DRM_COLOR_FORMAT_YCBCR422, 8 },
|
||||
};
|
||||
|
||||
static u8 analogix_dp_get_output_bpp(const struct analogix_dp_output_format *fmt)
|
||||
{
|
||||
switch (fmt->color_format) {
|
||||
case DRM_COLOR_FORMAT_YCBCR422:
|
||||
return fmt->bpc * 2;
|
||||
case DRM_COLOR_FORMAT_RGB444:
|
||||
case DRM_COLOR_FORMAT_YCBCR444:
|
||||
default:
|
||||
return fmt->bpc * 3;
|
||||
}
|
||||
}
|
||||
|
||||
const struct analogix_dp_output_format *analogix_dp_get_output_format(u32 bus_format)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(possible_output_fmts); i++)
|
||||
if (possible_output_fmts[i].bus_format == bus_format)
|
||||
return &possible_output_fmts[i];
|
||||
|
||||
return &possible_output_fmts[1];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(analogix_dp_get_output_format);
|
||||
|
||||
static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
|
||||
const struct drm_display_mode *adj_mode);
|
||||
|
||||
static bool analogix_dp_bandwidth_ok(struct analogix_dp_device *dp,
|
||||
const struct drm_display_mode *mode,
|
||||
const struct drm_display_mode *mode, u32 bpp,
|
||||
unsigned int rate, unsigned int lanes)
|
||||
{
|
||||
const struct drm_display_info *info;
|
||||
u32 max_bw, req_bw, bpp = 24;
|
||||
u32 max_bw, req_bw;
|
||||
|
||||
if (dp->plat_data->skip_connector)
|
||||
return true;
|
||||
|
||||
info = &dp->connector.display_info;
|
||||
if (info->bpc)
|
||||
bpp = 3 * info->bpc;
|
||||
|
||||
req_bw = mode->crtc_clock * bpp / 8;
|
||||
max_bw = lanes * rate;
|
||||
if (req_bw > max_bw)
|
||||
@@ -691,8 +720,9 @@ static u8 analogix_dp_select_link_rate_from_table(struct analogix_dp_device *dp)
|
||||
for (i = 0; i < dp->nr_link_rate_table; i++) {
|
||||
bw_code = drm_dp_link_rate_to_bw_code(dp->link_rate_table[i]);
|
||||
|
||||
if (!analogix_dp_bandwidth_ok(dp, &dp->video_info.mode, dp->link_rate_table[i],
|
||||
dp->link_train.lane_count))
|
||||
if (!analogix_dp_bandwidth_ok(dp, &dp->video_info.mode,
|
||||
analogix_dp_get_output_bpp(dp->output_fmt),
|
||||
dp->link_rate_table[i], dp->link_train.lane_count))
|
||||
continue;
|
||||
|
||||
if (dp->link_rate_table[i] <= max_link_rate &&
|
||||
@@ -832,7 +862,7 @@ static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!analogix_dp_bandwidth_ok(dp, &video->mode,
|
||||
if (!analogix_dp_bandwidth_ok(dp, &video->mode, analogix_dp_get_output_bpp(dp->output_fmt),
|
||||
drm_dp_bw_code_to_link_rate(dp->link_train.link_rate),
|
||||
dp->link_train.lane_count)) {
|
||||
dev_err(dp->dev, "bandwidth overflow\n");
|
||||
@@ -1746,6 +1776,12 @@ analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge,
|
||||
struct analogix_dp_device *dp = bridge->driver_private;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
|
||||
struct drm_bridge_state *new_bridge_state;
|
||||
|
||||
new_bridge_state = drm_atomic_get_new_bridge_state(old_state, bridge);
|
||||
if (WARN_ON(!new_bridge_state))
|
||||
return;
|
||||
dp->output_fmt = analogix_dp_get_output_format(new_bridge_state->output_bus_cfg.format);
|
||||
|
||||
crtc = analogix_dp_get_new_crtc(dp, old_state);
|
||||
if (!crtc)
|
||||
@@ -1967,7 +2003,6 @@ static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
|
||||
const struct drm_display_mode *adj_mode)
|
||||
{
|
||||
struct analogix_dp_device *dp = bridge->driver_private;
|
||||
struct drm_display_info *display_info = &dp->connector.display_info;
|
||||
struct video_info *video = &dp->video_info;
|
||||
struct drm_display_mode *mode = &video->mode;
|
||||
struct device_node *dp_node = dp->dev->of_node;
|
||||
@@ -1998,7 +2033,7 @@ static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
|
||||
video->dynamic_range = VESA;
|
||||
|
||||
/* Input vide bpc and color_formats */
|
||||
switch (display_info->bpc) {
|
||||
switch (dp->output_fmt->bpc) {
|
||||
case 12:
|
||||
video->color_depth = COLOR_12;
|
||||
break;
|
||||
@@ -2015,10 +2050,10 @@ static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
|
||||
video->color_depth = COLOR_8;
|
||||
break;
|
||||
}
|
||||
if (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR444) {
|
||||
if (dp->output_fmt->color_format == DRM_COLOR_FORMAT_YCBCR444) {
|
||||
video->color_space = COLOR_YCBCR444;
|
||||
video->ycbcr_coeff = COLOR_YCBCR709;
|
||||
} else if (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422) {
|
||||
} else if (dp->output_fmt->color_format == DRM_COLOR_FORMAT_YCBCR422) {
|
||||
video->color_space = COLOR_YCBCR422;
|
||||
video->ycbcr_coeff = COLOR_YCBCR709;
|
||||
} else {
|
||||
@@ -2057,18 +2092,26 @@ analogix_dp_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
struct analogix_dp_device *dp = bridge->driver_private;
|
||||
struct drm_display_mode m;
|
||||
u32 max_link_rate, max_lane_count;
|
||||
u32 min_bpp;
|
||||
|
||||
drm_mode_copy(&m, mode);
|
||||
|
||||
if (dp->plat_data->split_mode || dp->plat_data->dual_connector_split)
|
||||
dp->plat_data->convert_to_origin_mode(&m);
|
||||
|
||||
if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422)
|
||||
min_bpp = 16;
|
||||
else if (info->color_formats & DRM_COLOR_FORMAT_RGB444)
|
||||
min_bpp = 18;
|
||||
else
|
||||
min_bpp = 24;
|
||||
|
||||
max_link_rate = min_t(u32, dp->video_info.max_link_rate,
|
||||
dp->link_train.link_rate);
|
||||
max_lane_count = min_t(u32, dp->video_info.max_lane_count,
|
||||
dp->link_train.lane_count);
|
||||
if (analogix_dp_link_config_validate(max_link_rate, max_lane_count) &&
|
||||
!analogix_dp_bandwidth_ok(dp, &m,
|
||||
!analogix_dp_bandwidth_ok(dp, &m, min_bpp,
|
||||
drm_dp_bw_code_to_link_rate(max_link_rate),
|
||||
max_lane_count))
|
||||
return MODE_BAD;
|
||||
@@ -2076,10 +2119,67 @@ analogix_dp_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static u32 *analogix_dp_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *bridge_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
unsigned int *num_output_fmts)
|
||||
{
|
||||
struct analogix_dp_device *dp = bridge->driver_private;
|
||||
struct drm_display_info *di = &dp->connector.display_info;
|
||||
u32 *output_fmts;
|
||||
unsigned int i, j = 0;
|
||||
|
||||
if (dp->plat_data->panel) {
|
||||
*num_output_fmts = 1;
|
||||
|
||||
output_fmts = kzalloc(sizeof(*output_fmts), GFP_KERNEL);
|
||||
if (!output_fmts)
|
||||
return NULL;
|
||||
|
||||
if (di->num_bus_formats && di->bus_formats)
|
||||
output_fmts[0] = di->bus_formats[0];
|
||||
else
|
||||
output_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
|
||||
return output_fmts;
|
||||
}
|
||||
|
||||
*num_output_fmts = 0;
|
||||
|
||||
output_fmts = kcalloc(ARRAY_SIZE(possible_output_fmts), sizeof(*output_fmts), GFP_KERNEL);
|
||||
if (!output_fmts)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(possible_output_fmts); i++) {
|
||||
const struct analogix_dp_output_format *fmt = &possible_output_fmts[i];
|
||||
|
||||
if (fmt->bpc > conn_state->max_bpc || fmt->bpc > dp->plat_data->max_bpc)
|
||||
continue;
|
||||
|
||||
if (!(di->color_formats & fmt->color_format))
|
||||
continue;
|
||||
|
||||
if (!analogix_dp_bandwidth_ok(dp, &crtc_state->mode,
|
||||
analogix_dp_get_output_bpp(fmt),
|
||||
drm_dp_bw_code_to_link_rate(dp->link_train.link_rate),
|
||||
dp->link_train.lane_count))
|
||||
continue;
|
||||
|
||||
output_fmts[j++] = fmt->bus_format;
|
||||
}
|
||||
|
||||
*num_output_fmts = j;
|
||||
|
||||
return output_fmts;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs analogix_dp_bridge_funcs = {
|
||||
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
||||
.atomic_reset = drm_atomic_helper_bridge_reset,
|
||||
.atomic_get_input_bus_fmts = drm_atomic_helper_bridge_propagate_bus_fmt,
|
||||
.atomic_get_output_bus_fmts = analogix_dp_bridge_atomic_get_output_bus_fmts,
|
||||
.atomic_pre_enable = analogix_dp_bridge_atomic_pre_enable,
|
||||
.atomic_enable = analogix_dp_bridge_atomic_enable,
|
||||
.atomic_disable = analogix_dp_bridge_atomic_disable,
|
||||
|
||||
@@ -206,6 +206,8 @@ struct analogix_dp_device {
|
||||
struct analogix_dp_compliance compliance;
|
||||
|
||||
u32 split_area;
|
||||
|
||||
const struct analogix_dp_output_format *output_fmt;
|
||||
};
|
||||
|
||||
/* analogix_dp_reg.c */
|
||||
|
||||
@@ -70,6 +70,8 @@ struct rockchip_dp_chip_data {
|
||||
bool ssc;
|
||||
bool audio;
|
||||
bool split_mode;
|
||||
bool format_yuv;
|
||||
u8 max_bpc;
|
||||
};
|
||||
|
||||
struct rockchip_dp_device {
|
||||
@@ -230,15 +232,16 @@ static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
|
||||
static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data);
|
||||
struct drm_display_info *di = &connector->display_info;
|
||||
/* VOP couldn't output YUV video format for eDP rightly */
|
||||
u32 mask = DRM_COLOR_FORMAT_YCBCR444 | DRM_COLOR_FORMAT_YCBCR422;
|
||||
|
||||
if ((di->color_formats & mask)) {
|
||||
DRM_DEBUG_KMS("Swapping display color format from YUV to RGB\n");
|
||||
di->color_formats &= ~mask;
|
||||
di->color_formats |= DRM_COLOR_FORMAT_RGB444;
|
||||
di->bpc = 8;
|
||||
if (!dp->data->format_yuv) {
|
||||
if ((di->color_formats & mask)) {
|
||||
DRM_DEBUG_KMS("Swapping display color format from YUV to RGB\n");
|
||||
di->color_formats &= ~mask;
|
||||
di->color_formats |= DRM_COLOR_FORMAT_RGB444;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -463,12 +466,19 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
|
||||
struct rockchip_dp_device *dp = encoder_to_dp(encoder);
|
||||
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
|
||||
struct drm_display_info *di = &conn_state->connector->display_info;
|
||||
struct drm_bridge_state *new_bridge_state;
|
||||
struct drm_bridge *bridge;
|
||||
const struct analogix_dp_output_format *output_fmt;
|
||||
int refresh_rate;
|
||||
|
||||
if (di->num_bus_formats)
|
||||
s->bus_format = di->bus_formats[0];
|
||||
else
|
||||
s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
bridge = drm_bridge_chain_get_first_bridge(encoder);
|
||||
new_bridge_state = drm_atomic_get_new_bridge_state(conn_state->state, bridge);
|
||||
if (!new_bridge_state)
|
||||
return 0;
|
||||
|
||||
dev_dbg(dp->dev, "input format 0x%04x, output format 0x%04x\n",
|
||||
new_bridge_state->input_bus_cfg.format,
|
||||
new_bridge_state->output_bus_cfg.format);
|
||||
|
||||
/*
|
||||
* The hardware IC designed that VOP must output the RGB10 video
|
||||
@@ -477,8 +487,17 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
|
||||
* controller, that's why we need to hardcode the VOP output mode
|
||||
* to RGA10 here.
|
||||
*/
|
||||
|
||||
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
|
||||
output_fmt = analogix_dp_get_output_format(new_bridge_state->output_bus_cfg.format);
|
||||
switch (output_fmt->color_format) {
|
||||
case DRM_COLOR_FORMAT_YCBCR422:
|
||||
s->output_mode = ROCKCHIP_OUT_MODE_YUV422;
|
||||
break;
|
||||
case DRM_COLOR_FORMAT_RGB444:
|
||||
case DRM_COLOR_FORMAT_YCBCR444:
|
||||
default:
|
||||
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
|
||||
break;
|
||||
}
|
||||
s->output_type = DRM_MODE_CONNECTOR_eDP;
|
||||
if (dp->plat_data.split_mode) {
|
||||
s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
|
||||
@@ -495,12 +514,16 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
|
||||
s->output_if |= dp->id ? VOP_OUTPUT_IF_eDP1 : VOP_OUTPUT_IF_eDP0;
|
||||
}
|
||||
|
||||
s->output_bpc = di->bpc;
|
||||
s->bus_format = output_fmt->bus_format;
|
||||
s->output_bpc = output_fmt->bpc;
|
||||
s->bus_flags = di->bus_flags;
|
||||
s->tv_state = &conn_state->tv;
|
||||
s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
|
||||
s->color_encoding = DRM_COLOR_YCBCR_BT709;
|
||||
s->color_range = DRM_COLOR_YCBCR_FULL_RANGE;
|
||||
if (output_fmt->color_format == DRM_COLOR_FORMAT_RGB444)
|
||||
s->color_range = DRM_COLOR_YCBCR_FULL_RANGE;
|
||||
else
|
||||
s->color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
|
||||
/**
|
||||
* It's priority to user rate range define in dtsi.
|
||||
*/
|
||||
@@ -707,6 +730,7 @@ static int rockchip_dp_probe(struct platform_device *pdev)
|
||||
dp->adp = ERR_PTR(-ENODEV);
|
||||
dp->data = &dp_data[id];
|
||||
dp->plat_data.ssc = dp->data->ssc;
|
||||
dp->plat_data.max_bpc = dp->data->max_bpc ? dp->data->max_bpc : 8;
|
||||
dp->plat_data.panel = panel;
|
||||
dp->plat_data.dev_type = dp->data->chip_type;
|
||||
dp->plat_data.power_on_start = rockchip_dp_poweron_start;
|
||||
@@ -863,6 +887,8 @@ static const struct rockchip_dp_chip_data rk3576_edp[] = {
|
||||
.ssc = true,
|
||||
.audio = true,
|
||||
.split_mode = true,
|
||||
.format_yuv = true,
|
||||
.max_bpc = 10,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
@@ -876,6 +902,8 @@ static const struct rockchip_dp_chip_data rk3588_edp[] = {
|
||||
.ssc = true,
|
||||
.audio = true,
|
||||
.split_mode = true,
|
||||
.format_yuv = true,
|
||||
.max_bpc = 10,
|
||||
},
|
||||
{
|
||||
.chip_type = RK3588_EDP,
|
||||
@@ -885,6 +913,8 @@ static const struct rockchip_dp_chip_data rk3588_edp[] = {
|
||||
.ssc = true,
|
||||
.audio = true,
|
||||
.split_mode = true,
|
||||
.format_yuv = true,
|
||||
.max_bpc = 10,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
@@ -506,7 +506,7 @@ struct rockchip_crtc_funcs {
|
||||
void (*crtc_output_post_enable)(struct drm_crtc *crtc, int intf);
|
||||
void (*crtc_output_pre_disable)(struct drm_crtc *crtc, int intf);
|
||||
int (*crtc_set_color_bar)(struct drm_crtc *crtc, enum rockchip_color_bar_mode mode);
|
||||
int (*set_aclk)(struct drm_crtc *crtc, enum rockchip_drm_vop_aclk_mode aclk_mode);
|
||||
int (*set_aclk)(struct drm_crtc *crtc, enum rockchip_drm_vop_aclk_mode aclk_mode, struct dmcfreq_vop_info *vop_bw_info);
|
||||
int (*get_crc)(struct drm_crtc *crtc);
|
||||
};
|
||||
|
||||
|
||||
@@ -202,14 +202,14 @@ static int rockchip_drm_aclk_adjust(struct drm_device *dev,
|
||||
if (vop_bw_info->plane_num_4k || crtc_num > 1 ||
|
||||
crtc->state->adjusted_mode.crtc_hdisplay > 2560 ||
|
||||
crtc->state->adjusted_mode.crtc_vdisplay > 2560) {
|
||||
funcs->set_aclk(crtc, ROCKCHIP_VOP_ACLK_ADVANCED_MODE);
|
||||
funcs->set_aclk(crtc, ROCKCHIP_VOP_ACLK_ADVANCED_MODE, vop_bw_info);
|
||||
priv->aclk_adjust_frame_num = 2;
|
||||
} else {
|
||||
if (priv->aclk_adjust_frame_num >= 1) {
|
||||
funcs->set_aclk(crtc, ROCKCHIP_VOP_ACLK_ADVANCED_MODE);
|
||||
funcs->set_aclk(crtc, ROCKCHIP_VOP_ACLK_ADVANCED_MODE, vop_bw_info);
|
||||
priv->aclk_adjust_frame_num--;
|
||||
} else {
|
||||
funcs->set_aclk(crtc, ROCKCHIP_VOP_ACLK_NORMAL_MODE);
|
||||
funcs->set_aclk(crtc, ROCKCHIP_VOP_ACLK_NORMAL_MODE, vop_bw_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4351,7 +4351,7 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
*/
|
||||
vop_wait_for_irq_handler(vop);
|
||||
|
||||
spin_lock_irq(&crtc->dev->event_lock);
|
||||
spin_lock_irqsave(&crtc->dev->event_lock, flags);
|
||||
if (crtc->state->event) {
|
||||
WARN_ON(drm_crtc_vblank_get(crtc) != 0);
|
||||
WARN_ON(vop->event);
|
||||
@@ -4359,7 +4359,7 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
vop->event = crtc->state->event;
|
||||
crtc->state->event = NULL;
|
||||
}
|
||||
spin_unlock_irq(&crtc->dev->event_lock);
|
||||
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
|
||||
|
||||
for_each_old_plane_in_state(old_state, plane, old_plane_state, i) {
|
||||
if (!old_plane_state->fb)
|
||||
|
||||
@@ -968,6 +968,8 @@ struct vop2 {
|
||||
u32 aclk_mode_rate[ROCKCHIP_VOP_ACLK_MAX_MODE];
|
||||
#endif
|
||||
|
||||
/* aclk auto cs div */
|
||||
u32 csu_div;
|
||||
/* must put at the end of the struct */
|
||||
struct vop2_win win[];
|
||||
};
|
||||
@@ -1016,7 +1018,6 @@ static const struct drm_bus_format_enum_list drm_bus_format_enum_list[] = {
|
||||
};
|
||||
|
||||
static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
|
||||
static int vop2_devfreq_set_aclk(struct drm_crtc *crtc, enum rockchip_drm_vop_aclk_mode aclk_mode);
|
||||
|
||||
static inline struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
|
||||
{
|
||||
@@ -1306,6 +1307,99 @@ static struct drm_crtc *vop2_find_crtc_by_plane_mask(struct vop2 *vop2, uint8_t
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static u32 rk3562_vop2_get_csu_div(struct drm_crtc *crtc)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
unsigned long aclk_rate = 0, dclk_rate = 0;
|
||||
u32 csu_div;
|
||||
|
||||
aclk_rate = clk_get_rate(vp->vop2->aclk);
|
||||
dclk_rate = clk_get_rate(vp->dclk);
|
||||
if (!dclk_rate)
|
||||
return 0;
|
||||
|
||||
/* aclk > 1/2 * dclk */
|
||||
csu_div = (aclk_rate - 1) * 2 / dclk_rate;
|
||||
|
||||
return csu_div;
|
||||
}
|
||||
|
||||
static u32 rk3576_vop2_get_csu_div(struct drm_crtc *crtc, struct dmcfreq_vop_info *vop_bw_info)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
|
||||
u32 csu_div;
|
||||
|
||||
if (vp->vop2->aclk_mode == ROCKCHIP_VOP_ACLK_NORMAL_MODE) {
|
||||
if (adjusted_mode->crtc_clock < 250000) {
|
||||
if (vop_bw_info->plane_num == 1)
|
||||
csu_div = 3;
|
||||
else if (vop_bw_info->plane_num == 2)
|
||||
csu_div = 2;
|
||||
else
|
||||
csu_div = 1;
|
||||
} else {
|
||||
csu_div = 1;
|
||||
}
|
||||
} else {
|
||||
csu_div = 1;
|
||||
}
|
||||
|
||||
return csu_div;
|
||||
}
|
||||
|
||||
static int vop2_set_aclk_rate(struct drm_crtc *crtc,
|
||||
enum rockchip_drm_vop_aclk_mode aclk_mode,
|
||||
struct dmcfreq_vop_info *vop_bw_info)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
struct drm_crtc *first_active_crtc = NULL;
|
||||
int i = 0, ret = 0;
|
||||
u32 csu_div = 0;
|
||||
|
||||
/* all vp/crtc share one vop aclk, so only need to set once */
|
||||
for (i = 0; i < vop2->data->nr_vps; i++) {
|
||||
if (vop2->vps[i].rockchip_crtc.crtc.state &&
|
||||
vop2->vps[i].rockchip_crtc.crtc.state->active) {
|
||||
first_active_crtc = &vop2->vps[i].rockchip_crtc.crtc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (first_active_crtc != crtc)
|
||||
return 0;
|
||||
|
||||
vop2->aclk_target_freq = vop2->aclk_mode_rate[aclk_mode];
|
||||
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
if (vop2->devfreq) {
|
||||
mutex_lock(&vop2->devfreq->lock);
|
||||
ret = update_devfreq(vop2->devfreq);
|
||||
mutex_unlock(&vop2->devfreq->lock);
|
||||
if (ret)
|
||||
dev_err(vop2->dev, "failed to set rate %lu\n", vop2->aclk_target_freq);
|
||||
}
|
||||
#endif
|
||||
vop2->aclk_mode = aclk_mode;
|
||||
|
||||
if (vop2->csu_aclk && vop_bw_info) {
|
||||
if (vop2->version == VOP_VERSION_RK3562)
|
||||
csu_div = rk3562_vop2_get_csu_div(crtc);
|
||||
else
|
||||
csu_div = rk3576_vop2_get_csu_div(crtc, vop_bw_info);
|
||||
if (csu_div != vop2->csu_div) {
|
||||
rockchip_csu_set_div(vop2->csu_aclk, csu_div);
|
||||
rockchip_drm_dbg(vop2->dev, VOP_DEBUG_CLK,
|
||||
"Set aclk auto cs div from %d to %d, aclk rate:%ld, aclk mode:%d\n",
|
||||
vop2->csu_div, csu_div, clk_get_rate(vop2->aclk),
|
||||
vop2->aclk_mode);
|
||||
}
|
||||
vop2->csu_div = csu_div;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vop2_clk_reset(struct reset_control *rstc)
|
||||
{
|
||||
int ret;
|
||||
@@ -4453,7 +4547,7 @@ static void vop2_disable(struct drm_crtc *crtc)
|
||||
VOP_CTRL_SET(vop2, dma_stop, 1);
|
||||
if (vop2->aclk_mode_rate[ROCKCHIP_VOP_ACLK_RESET_MODE] &&
|
||||
clk_get_rate(vop2->aclk) > vop2->aclk_mode_rate[ROCKCHIP_VOP_ACLK_RESET_MODE])
|
||||
vop2_devfreq_set_aclk(crtc, ROCKCHIP_VOP_ACLK_RESET_MODE);
|
||||
vop2_set_aclk_rate(crtc, ROCKCHIP_VOP_ACLK_RESET_MODE, NULL);
|
||||
rockchip_drm_dma_detach_device(vop2->drm_dev, vop2->dev);
|
||||
vop2->is_iommu_enabled = false;
|
||||
}
|
||||
@@ -6949,27 +7043,6 @@ static int vop2_crtc_get_inital_acm_info(struct drm_crtc *crtc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vop2_crtc_csu_set_rate(struct drm_crtc *crtc)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
unsigned long aclk_rate = 0, dclk_rate = 0;
|
||||
u32 csu_div = 0;
|
||||
|
||||
if (!vop2->csu_aclk)
|
||||
return;
|
||||
|
||||
aclk_rate = clk_get_rate(vop2->aclk);
|
||||
dclk_rate = clk_get_rate(vp->dclk);
|
||||
if (!dclk_rate || !aclk_rate)
|
||||
return;
|
||||
|
||||
/* aclk > 1/2 * dclk */
|
||||
csu_div = (aclk_rate - 1) * 2 / dclk_rate;
|
||||
|
||||
rockchip_csu_set_div(vop2->csu_aclk, csu_div);
|
||||
}
|
||||
|
||||
static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on, void *data)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
@@ -7049,8 +7122,6 @@ static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on, void *data)
|
||||
cubic_lut_mst = cubic_lut->offset + private->cubic_lut_dma_addr;
|
||||
VOP_MODULE_SET(vop2, vp, cubic_lut_mst, cubic_lut_mst);
|
||||
}
|
||||
|
||||
vop2_crtc_csu_set_rate(crtc);
|
||||
} else {
|
||||
vop2_crtc_atomic_disable(crtc, NULL);
|
||||
}
|
||||
@@ -7847,7 +7918,7 @@ static const struct rockchip_crtc_funcs private_crtc_funcs = {
|
||||
.crtc_output_post_enable = vop2_crtc_output_post_enable,
|
||||
.crtc_output_pre_disable = vop2_crtc_output_pre_disable,
|
||||
.crtc_set_color_bar = vop2_crtc_set_color_bar,
|
||||
.set_aclk = vop2_devfreq_set_aclk,
|
||||
.set_aclk = vop2_set_aclk_rate,
|
||||
.get_crc = vop2_crtc_get_crc,
|
||||
};
|
||||
|
||||
@@ -9482,7 +9553,6 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_sta
|
||||
if (is_vop3(vop2))
|
||||
vop3_setup_pipe_dly(vp, NULL);
|
||||
|
||||
vop2_crtc_csu_set_rate(crtc);
|
||||
vop2_crtc_setup_output_mode(crtc);
|
||||
|
||||
vop2_cfg_done(crtc);
|
||||
@@ -11719,12 +11789,12 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_stat
|
||||
VOP_CTRL_SET(vop2, dma_stop, 1);
|
||||
if (vop2->aclk_mode_rate[ROCKCHIP_VOP_ACLK_RESET_MODE] &&
|
||||
clk_get_rate(vop2->aclk) > vop2->aclk_mode_rate[ROCKCHIP_VOP_ACLK_RESET_MODE]) {
|
||||
vop2_devfreq_set_aclk(crtc, ROCKCHIP_VOP_ACLK_RESET_MODE);
|
||||
vop2_set_aclk_rate(crtc, ROCKCHIP_VOP_ACLK_RESET_MODE, NULL);
|
||||
enter_vop_aclk_reset_mode = true;
|
||||
}
|
||||
ret = rockchip_drm_dma_attach_device(vop2->drm_dev, vop2->dev);
|
||||
if (enter_vop_aclk_reset_mode)
|
||||
vop2_devfreq_set_aclk(crtc, aclk_mode);
|
||||
vop2_set_aclk_rate(crtc, aclk_mode, NULL);
|
||||
if (ret) {
|
||||
vop2->is_iommu_enabled = false;
|
||||
vop2_disable_all_planes_for_crtc(crtc);
|
||||
@@ -13758,6 +13828,9 @@ static char *vop2_plane_mask_to_string(unsigned long mask)
|
||||
|
||||
static inline const char *vop2_plane_id_to_string(unsigned long phy)
|
||||
{
|
||||
if (phy == ROCKCHIP_VOP2_PHY_ID_INVALID)
|
||||
return "INVALID";
|
||||
|
||||
if (WARN_ON(phy >= ARRAY_SIZE(vop2_layer_name_list)))
|
||||
return NULL;
|
||||
|
||||
@@ -13892,39 +13965,6 @@ static struct devfreq_governor devfreq_vop2_ondemand = {
|
||||
.event_handler = devfreq_vop2_ondemand_handler,
|
||||
};
|
||||
|
||||
static int vop2_devfreq_set_aclk(struct drm_crtc *crtc, enum rockchip_drm_vop_aclk_mode aclk_mode)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
struct drm_crtc *first_active_crtc = NULL;
|
||||
int i = 0, ret = 0;
|
||||
|
||||
if (!vop2->devfreq)
|
||||
return 0;
|
||||
|
||||
/* all vp/crtc share one vop aclk, so only need to set once */
|
||||
for (i = 0; i < vop2->data->nr_vps; i++) {
|
||||
if (vop2->vps[i].rockchip_crtc.crtc.state &&
|
||||
vop2->vps[i].rockchip_crtc.crtc.state->active) {
|
||||
first_active_crtc = &vop2->vps[i].rockchip_crtc.crtc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (first_active_crtc != crtc)
|
||||
return 0;
|
||||
|
||||
vop2->aclk_target_freq = vop2->aclk_mode_rate[aclk_mode];
|
||||
|
||||
mutex_lock(&vop2->devfreq->lock);
|
||||
ret = update_devfreq(vop2->devfreq);
|
||||
mutex_unlock(&vop2->devfreq->lock);
|
||||
if (ret)
|
||||
dev_err(vop2->dev, "failed to set rate %lu\n", vop2->aclk_target_freq);
|
||||
vop2->aclk_mode = aclk_mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vop2_devfreq_target(struct device *dev, unsigned long *freq,
|
||||
u32 flags)
|
||||
{
|
||||
@@ -14074,11 +14114,6 @@ static void rockchip_vop2_devfreq_uninit(struct vop2 *vop2)
|
||||
rockchip_uninit_opp_table(vop2->dev, &vop2->opp_info);
|
||||
}
|
||||
#else
|
||||
static inline int vop2_devfreq_set_aclk(struct drm_crtc *crtc, enum rockchip_drm_vop_aclk_mode aclk_mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int rockchip_vop2_devfreq_init(struct vop2 *vop2)
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -208,7 +208,7 @@
|
||||
* enable it when customer need control TP power
|
||||
* default: disable
|
||||
*/
|
||||
#define FTS_POWER_SOURCE_CUST_EN 1
|
||||
#define FTS_POWER_SOURCE_CUST_EN 0
|
||||
|
||||
/****************************************************/
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ static const struct regmap_range rk628_hdmirx_readable_ranges[] = {
|
||||
regmap_reg_range(HDMI_RX_PDEC_STS, HDMI_RX_PDEC_STS),
|
||||
regmap_reg_range(HDMI_RX_PDEC_GCP_AVMUTE, HDMI_RX_PDEC_GCP_AVMUTE),
|
||||
regmap_reg_range(HDMI_RX_PDEC_ACR_CTS, HDMI_RX_PDEC_ACR_N),
|
||||
regmap_reg_range(HDMI_RX_PDEC_AVI_HB, HDMI_RX_PDEC_AVI_PB),
|
||||
regmap_reg_range(HDMI_RX_PDEC_AIF_CTRL, HDMI_RX_PDEC_AIF_PB0),
|
||||
regmap_reg_range(HDMI_RX_PDEC_AVI_PB, HDMI_RX_PDEC_AVI_PB),
|
||||
regmap_reg_range(HDMI_RX_HDMI20_CONTROL, HDMI_RX_CHLOCK_CONFIG),
|
||||
regmap_reg_range(HDMI_RX_SCDC_REGS0, HDMI_RX_SCDC_REGS2),
|
||||
regmap_reg_range(HDMI_RX_SCDC_WRDATA0, HDMI_RX_SCDC_WRDATA0),
|
||||
|
||||
@@ -71,6 +71,11 @@ enum hdmirx_pix_fmt {
|
||||
HDMIRX_YUV420 = 3,
|
||||
};
|
||||
|
||||
enum hdmirx_ycc_range {
|
||||
HDMIRX_YCC_LIMIT,
|
||||
HDMIRX_YCC_FULL,
|
||||
};
|
||||
|
||||
static const char * const bus_format_str[] = {
|
||||
"RGB",
|
||||
"YUV422",
|
||||
@@ -1759,13 +1764,23 @@ EXPORT_SYMBOL(rk628_hdmirx_get_timings);
|
||||
|
||||
u8 rk628_hdmirx_get_range(struct rk628 *rk628)
|
||||
{
|
||||
u8 color_range;
|
||||
u32 val, vic, fmt;
|
||||
u8 color_range, yuv_range;
|
||||
u32 val, vic, fmt, avi_hb;
|
||||
|
||||
rk628_i2c_read(rk628, HDMI_RX_PDEC_AVI_PB, &val);
|
||||
rk628_i2c_read(rk628, HDMI_RX_PDEC_AVI_HB, &avi_hb);
|
||||
color_range = (val & RGB_COLORRANGE_MASK) >> 18;
|
||||
yuv_range = (avi_hb & YUV_COLORRANGE_MASK) >> 30;
|
||||
vic = (val & VID_IDENT_CODE_MASK) >> 24;
|
||||
fmt = (val & VIDEO_FORMAT_MASK) >> 5;
|
||||
if (fmt != HDMIRX_RGB888) {
|
||||
if (yuv_range == HDMIRX_YCC_LIMIT)
|
||||
color_range = HDMIRX_LIMIT_RANGE;
|
||||
else if (yuv_range == HDMIRX_YCC_FULL)
|
||||
color_range = HDMIRX_FULL_RANGE;
|
||||
else
|
||||
color_range = HDMIRX_DEFAULT_RANGE;
|
||||
}
|
||||
if (fmt == HDMIRX_RGB888 && color_range == HDMIRX_DEFAULT_RANGE) {
|
||||
(vic) ?
|
||||
(color_range = HDMIRX_LIMIT_RANGE) :
|
||||
|
||||
@@ -267,6 +267,7 @@
|
||||
#define VIDEO_FORMAT_MASK GENMASK(6, 5)
|
||||
#define VIDEO_FORMAT(x) UPDATE(x, 6, 5)
|
||||
#define RGB_COLORRANGE_MASK GENMASK(19, 18)
|
||||
#define YUV_COLORRANGE_MASK GENMASK(31, 30)
|
||||
#define RGB_COLORRANGE(x) UPDATE(x, 19, 18)
|
||||
#define ACT_INFO_PRESENT_MASK BIT(4)
|
||||
#define HDMI_RX_PDEC_ACR_CTS (HDMI_RX_BASE + 0x0390)
|
||||
|
||||
@@ -435,9 +435,6 @@ int rkisp_stream_frame_start(struct rkisp_device *dev, u32 isp_mis)
|
||||
rkisp_dvbm_event(dev, CIF_ISP_V_START);
|
||||
rkisp_bridge_update_mi(dev, isp_mis);
|
||||
|
||||
if (dev->isp_ver == ISP_V39)
|
||||
rkisp_sditf_sof(dev, isp_mis);
|
||||
|
||||
for (i = 0; i < RKISP_MAX_STREAM; i++) {
|
||||
if (i == RKISP_STREAM_VIR || i == RKISP_STREAM_LUMA)
|
||||
continue;
|
||||
|
||||
@@ -96,6 +96,7 @@ void rkisp_sditf_sof(struct rkisp_device *dev, u32 irq)
|
||||
return;
|
||||
info.irq = irq;
|
||||
rkisp_dmarx_get_frame(dev, &info.seq, NULL, &info.timestamp, true);
|
||||
info.unite_index = dev->unite_index;
|
||||
v4l2_subdev_call(sditf->remote_sd, core, ioctl, RKISP_VPSS_CMD_SOF, &info);
|
||||
}
|
||||
|
||||
@@ -106,8 +107,18 @@ static long rkisp_sditf_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *ar
|
||||
|
||||
switch (cmd) {
|
||||
case RKISP_VPSS_CMD_EOF:
|
||||
if (*(int *)arg) {
|
||||
sditf->is_on = false;
|
||||
sditf->isp->irq_ends_mask &= ~ISP_FRAME_VPSS;
|
||||
}
|
||||
rkisp_check_idle(sditf->isp, ISP_FRAME_VPSS);
|
||||
break;
|
||||
case RKISP_VPSS_GET_UNITE_MODE:
|
||||
if (sditf->isp->unite_div == ISP_UNITE_DIV2)
|
||||
*(unsigned int *)arg = sditf->isp->unite_div;
|
||||
else
|
||||
*(unsigned int *)arg = 0;
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
@@ -8,12 +8,17 @@
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 0, struct rkisp_vpss_sof)
|
||||
|
||||
#define RKISP_VPSS_CMD_EOF \
|
||||
_IO('V', BASE_VIDIOC_PRIVATE + 1)
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 1, int)
|
||||
|
||||
#define RKISP_VPSS_GET_UNITE_MODE \
|
||||
_IOR('V', BASE_VIDIOC_PRIVATE + 2, unsigned int)
|
||||
|
||||
struct rkisp_vpss_sof {
|
||||
u32 irq;
|
||||
u32 seq;
|
||||
u64 timestamp;
|
||||
u32 unite_index;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -660,6 +660,9 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
|
||||
rkisp_stream_frame_start(dev, 0);
|
||||
}
|
||||
|
||||
if (dev->isp_ver == ISP_V39)
|
||||
rkisp_sditf_sof(dev, 0);
|
||||
|
||||
if (!hw->is_single) {
|
||||
/* multi sensor need to reset isp resize mode if scale up */
|
||||
val = 0;
|
||||
@@ -1148,6 +1151,9 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq)
|
||||
u32 state = dev->isp_state;
|
||||
struct rkisp_stream *s;
|
||||
|
||||
if (dev->sditf_dev && !dev->sditf_dev->is_on)
|
||||
dev->isp_state = ISP_STOP;
|
||||
|
||||
for (val = 0; val < RKISP_STREAM_VIR; val++) {
|
||||
s = &dev->cap_dev.stream[val];
|
||||
dev->isp_state = ISP_STOP;
|
||||
@@ -4453,6 +4459,8 @@ void rkisp_isp_isr(unsigned int isp_mis,
|
||||
dev->isp_sdev.frm_timestamp = rkisp_time_get_ns(dev);
|
||||
rkisp_isp_queue_event_sof(&dev->isp_sdev);
|
||||
rkisp_stream_frame_start(dev, isp_mis);
|
||||
if (dev->isp_ver == ISP_V39)
|
||||
rkisp_sditf_sof(dev, isp_mis);
|
||||
rkisp_rockit_frame_start(dev);
|
||||
}
|
||||
vs_skip:
|
||||
@@ -4617,6 +4625,8 @@ vs_skip:
|
||||
rkisp_isp_queue_event_sof(&dev->isp_sdev);
|
||||
rkisp_stream_frame_start(dev, isp_mis);
|
||||
rkisp_rockit_frame_start(dev);
|
||||
if (dev->isp_ver == ISP_V39)
|
||||
rkisp_sditf_sof(dev, isp_mis);
|
||||
}
|
||||
|
||||
if (isp_mis & ISP3X_OUT_FRM_QUARTER) {
|
||||
|
||||
@@ -9,49 +9,70 @@
|
||||
#include "dev.h"
|
||||
#include "regs.h"
|
||||
|
||||
void rkvpss_write(struct rkvpss_device *dev, u32 reg, u32 val)
|
||||
{
|
||||
u32 *mem = dev->sw_base_addr + reg;
|
||||
u32 *flag = dev->sw_base_addr + reg + RKVPSS_SW_REG_SIZE;
|
||||
|
||||
void rkvpss_idx_write(struct rkvpss_device *dev, u32 reg, u32 val, int idx)
|
||||
{
|
||||
u32 *mem, *flag, offset = idx * RKVPSS_SW_REG_SIZE_MAX;
|
||||
|
||||
if (!dev->unite_mode)
|
||||
offset = 0;
|
||||
|
||||
mem = dev->sw_base_addr + reg + offset;
|
||||
flag = dev->sw_base_addr + reg + RKVPSS_SW_REG_SIZE + offset;
|
||||
*mem = val;
|
||||
*flag = RKVPSS_REG_CACHE;
|
||||
if (dev->hw_dev->is_single)
|
||||
|
||||
if (dev->hw_dev->is_single && !dev->unite_mode)
|
||||
rkvpss_hw_write(dev->hw_dev, reg, val);
|
||||
}
|
||||
|
||||
u32 rkvpss_read(struct rkvpss_device *dev, u32 reg)
|
||||
void rkvpss_unite_write(struct rkvpss_device *dev, u32 reg, u32 val)
|
||||
{
|
||||
u32 val;
|
||||
rkvpss_idx_write(dev, reg, val, VPSS_UNITE_LEFT);
|
||||
if (dev->unite_mode)
|
||||
rkvpss_idx_write(dev, reg, val, VPSS_UNITE_RIGHT);
|
||||
}
|
||||
|
||||
if (dev->hw_dev->is_single)
|
||||
u32 rkvpss_idx_read(struct rkvpss_device *dev, u32 reg, int idx)
|
||||
{
|
||||
u32 val, offset = idx * RKVPSS_SW_REG_SIZE_MAX;
|
||||
|
||||
if (!dev->unite_mode)
|
||||
offset = 0;
|
||||
|
||||
if (dev->hw_dev->is_single && !dev->unite_mode)
|
||||
val = rkvpss_hw_read(dev->hw_dev, reg);
|
||||
else
|
||||
val = *(u32 *)(dev->sw_base_addr + reg);
|
||||
val = *(u32 *)(dev->sw_base_addr + reg + offset);
|
||||
return val;
|
||||
}
|
||||
|
||||
void rkvpss_set_bits(struct rkvpss_device *dev, u32 reg, u32 mask, u32 val)
|
||||
void rkvpss_idx_set_bits(struct rkvpss_device *dev, u32 reg, u32 mask, u32 val, int idx)
|
||||
{
|
||||
u32 *mem = dev->sw_base_addr + reg;
|
||||
u32 *flag = dev->sw_base_addr + reg + RKVPSS_SW_REG_SIZE;
|
||||
u32 tmp = rkvpss_idx_read(dev, reg, idx) & ~mask;
|
||||
|
||||
*mem &= ~mask;
|
||||
*mem |= val;
|
||||
*flag = RKVPSS_REG_CACHE;
|
||||
if (dev->hw_dev->is_single)
|
||||
rkvpss_hw_set_bits(dev->hw_dev, reg, mask, val);
|
||||
rkvpss_idx_write(dev, reg, val | tmp, idx);
|
||||
}
|
||||
|
||||
void rkvpss_clear_bits(struct rkvpss_device *dev, u32 reg, u32 mask)
|
||||
void rkvpss_unite_set_bits(struct rkvpss_device *dev, u32 reg, u32 mask, u32 val)
|
||||
{
|
||||
u32 *mem = dev->sw_base_addr + reg;
|
||||
u32 *flag = dev->sw_base_addr + reg + RKVPSS_SW_REG_SIZE;
|
||||
rkvpss_idx_set_bits(dev, reg, mask, val, VPSS_UNITE_LEFT);
|
||||
if (dev->unite_mode)
|
||||
rkvpss_idx_set_bits(dev, reg, mask, val, VPSS_UNITE_RIGHT);
|
||||
}
|
||||
|
||||
*mem &= ~mask;
|
||||
*flag = RKVPSS_REG_CACHE;
|
||||
if (dev->hw_dev->is_single)
|
||||
rkvpss_hw_clear_bits(dev->hw_dev, reg, mask);
|
||||
void rkvpss_idx_clear_bits(struct rkvpss_device *dev, u32 reg, u32 mask, int idx)
|
||||
{
|
||||
u32 tmp = rkvpss_idx_read(dev, reg, idx);
|
||||
|
||||
rkvpss_idx_write(dev, reg, tmp & ~mask, idx);
|
||||
}
|
||||
|
||||
void rkvpss_unite_clear_bits(struct rkvpss_device *dev, u32 reg, u32 mask)
|
||||
{
|
||||
rkvpss_idx_clear_bits(dev, reg, mask, VPSS_UNITE_LEFT);
|
||||
if (dev->unite_mode)
|
||||
rkvpss_idx_clear_bits(dev, reg, mask, VPSS_UNITE_RIGHT);
|
||||
}
|
||||
|
||||
void rkvpss_update_regs(struct rkvpss_device *dev, u32 start, u32 end)
|
||||
@@ -69,6 +90,13 @@ void rkvpss_update_regs(struct rkvpss_device *dev, u32 start, u32 end)
|
||||
u32 *val = dev->sw_base_addr + i;
|
||||
u32 *flag = dev->sw_base_addr + i + RKVPSS_SW_REG_SIZE;
|
||||
|
||||
if (dev->unite_mode &&
|
||||
((!dev->mir_en && dev->unite_index == VPSS_UNITE_RIGHT) ||
|
||||
(dev->mir_en && dev->unite_index == VPSS_UNITE_LEFT))) {
|
||||
val += (RKVPSS_SW_REG_SIZE_MAX / 4);
|
||||
flag += (RKVPSS_SW_REG_SIZE_MAX / 4);
|
||||
}
|
||||
|
||||
if (*flag != RKVPSS_REG_CACHE)
|
||||
continue;
|
||||
|
||||
@@ -86,6 +114,8 @@ void rkvpss_update_regs(struct rkvpss_device *dev, u32 start, u32 end)
|
||||
}
|
||||
}
|
||||
writel(*val, base + i);
|
||||
if (i == RKVPSS_MI_WR_INIT)
|
||||
writel(*val, base + i);
|
||||
if (IS_SYNC_REG(i))
|
||||
spin_unlock_irqrestore(&hw->reg_lock, lock_flags);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <media/videobuf2-v4l2.h>
|
||||
|
||||
#include "../isp/isp_vpss.h"
|
||||
#include <linux/rk-camera-module.h>
|
||||
|
||||
#define RKVPSS_PLANE_Y 0
|
||||
#define RKVPSS_PLANE_UV 1
|
||||
@@ -90,10 +91,13 @@ static inline struct vb2_queue *to_vb2_queue(struct file *file)
|
||||
extern int rkvpss_debug;
|
||||
extern struct platform_driver rkvpss_plat_drv;
|
||||
|
||||
void rkvpss_write(struct rkvpss_device *dev, u32 reg, u32 val);
|
||||
void rkvpss_set_bits(struct rkvpss_device *dev, u32 reg, u32 mask, u32 val);
|
||||
u32 rkvpss_read(struct rkvpss_device *dev, u32 reg);
|
||||
void rkvpss_clear_bits(struct rkvpss_device *dev, u32 reg, u32 mask);
|
||||
void rkvpss_idx_write(struct rkvpss_device *dev, u32 reg, u32 val, int idx);
|
||||
void rkvpss_unite_write(struct rkvpss_device *dev, u32 reg, u32 val);
|
||||
void rkvpss_idx_set_bits(struct rkvpss_device *dev, u32 reg, u32 mask, u32 val, int idx);
|
||||
void rkvpss_unite_set_bits(struct rkvpss_device *dev, u32 reg, u32 mask, u32 val);
|
||||
u32 rkvpss_idx_read(struct rkvpss_device *dev, u32 reg, int idx);
|
||||
void rkvpss_idx_clear_bits(struct rkvpss_device *dev, u32 reg, u32 mask, int idx);
|
||||
void rkvpss_unite_clear_bits(struct rkvpss_device *dev, u32 reg, u32 mask);
|
||||
void rkvpss_update_regs(struct rkvpss_device *dev, u32 start, u32 end);
|
||||
|
||||
int rkvpss_attach_hw(struct rkvpss_device *vpss);
|
||||
|
||||
@@ -75,6 +75,9 @@ int rkvpss_pipeline_stream(struct rkvpss_device *dev, bool on)
|
||||
(!on && atomic_dec_return(&dev->pipe_stream_cnt) > 0))
|
||||
return 0;
|
||||
|
||||
v4l2_dbg(1, rkvpss_debug, &dev->v4l2_dev,
|
||||
"%s on:%d\n", __func__, on);
|
||||
|
||||
if (on) {
|
||||
ret = v4l2_subdev_call(&dev->vpss_sdev.sd, video, s_stream, true);
|
||||
if (ret < 0)
|
||||
@@ -84,7 +87,12 @@ int rkvpss_pipeline_stream(struct rkvpss_device *dev, bool on)
|
||||
v4l2_subdev_call(&dev->vpss_sdev.sd, video, s_stream, false);
|
||||
goto err;
|
||||
}
|
||||
dev->stopping = false;
|
||||
} else {
|
||||
dev->stopping = true;
|
||||
ret = wait_event_timeout(dev->stop_done, !dev->stopping, msecs_to_jiffies(300));
|
||||
if (!ret)
|
||||
v4l2_warn(&dev->v4l2_dev, "%s timeout\n", __func__);
|
||||
v4l2_subdev_call(dev->remote_sd, video, s_stream, false);
|
||||
v4l2_subdev_call(&dev->vpss_sdev.sd, video, s_stream, false);
|
||||
}
|
||||
@@ -256,7 +264,7 @@ static int rkvpss_plat_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct v4l2_device *v4l2_dev;
|
||||
struct rkvpss_device *vpss_dev;
|
||||
int ret;
|
||||
int ret, mult = 2;
|
||||
|
||||
sprintf(rkvpss_version, "v%02x.%02x.%02x",
|
||||
RKVPSS_DRIVER_VERSION >> 16,
|
||||
@@ -268,7 +276,7 @@ static int rkvpss_plat_probe(struct platform_device *pdev)
|
||||
vpss_dev = devm_kzalloc(dev, sizeof(*vpss_dev), GFP_KERNEL);
|
||||
if (!vpss_dev)
|
||||
return -ENOMEM;
|
||||
vpss_dev->sw_base_addr = devm_kzalloc(dev, RKVPSS_SW_REG_SIZE_MAX, GFP_KERNEL);
|
||||
vpss_dev->sw_base_addr = devm_kzalloc(dev, RKVPSS_SW_REG_SIZE_MAX * mult, GFP_KERNEL);
|
||||
if (!vpss_dev->sw_base_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -314,6 +322,7 @@ static int rkvpss_plat_probe(struct platform_device *pdev)
|
||||
rkvpss_proc_init(vpss_dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
vpss_dev->is_probe_end = true;
|
||||
init_waitqueue_head(&vpss_dev->stop_done);
|
||||
return 0;
|
||||
|
||||
err_unreg_media_dev:
|
||||
|
||||
@@ -29,6 +29,12 @@ enum {
|
||||
T_CMD_END,
|
||||
};
|
||||
|
||||
enum {
|
||||
VPSS_UNITE_LEFT = 0,
|
||||
VPSS_UNITE_RIGHT,
|
||||
VPSS_UNITE_MAX,
|
||||
};
|
||||
|
||||
struct rkvpss_rdbk_info {
|
||||
u64 timestamp;
|
||||
u64 seq;
|
||||
@@ -65,6 +71,12 @@ struct rkvpss_device {
|
||||
|
||||
bool mir_en;
|
||||
bool cmsc_upd;
|
||||
u32 unite_mode;
|
||||
u8 unite_index;
|
||||
bool stopping;
|
||||
wait_queue_head_t stop_done;
|
||||
unsigned int irq_ends;
|
||||
unsigned int irq_ends_mask;
|
||||
|
||||
bool is_probe_end;
|
||||
};
|
||||
|
||||
@@ -665,8 +665,11 @@ static irqreturn_t mi_irq_hdl(int irq, void *ctx)
|
||||
|
||||
mis_val = rkvpss_hw_read(hw_dev, RKVPSS_MI_MIS);
|
||||
if (mis_val) {
|
||||
if (mis_val & RKVPSS_MI_BUS_ERR)
|
||||
dev_err(dev, "axi bus error\n");
|
||||
rkvpss_hw_write(hw_dev, RKVPSS_MI_ICR, mis_val);
|
||||
rkvpss_mi_isr(vpss, mis_val);
|
||||
if (vpss)
|
||||
rkvpss_mi_isr(vpss, mis_val);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -120,6 +120,20 @@ struct frame_debug_info {
|
||||
u32 frameloss;
|
||||
};
|
||||
|
||||
struct rkvpss_online_unite_params {
|
||||
u32 y_w_fac;
|
||||
u32 c_w_fac;
|
||||
u32 y_h_fac;
|
||||
u32 c_h_fac;
|
||||
u32 y_w_phase;
|
||||
u32 c_w_phase;
|
||||
u32 quad_crop_w;
|
||||
u32 scl_in_crop_w_y;
|
||||
u32 scl_in_crop_w_c;
|
||||
u32 right_scl_need_size_y;
|
||||
u32 right_scl_need_size_c;
|
||||
};
|
||||
|
||||
/* struct rkvpss_stream - VPSS stream video device
|
||||
* id: stream video identify
|
||||
* buf_queue: queued buffer list
|
||||
@@ -154,6 +168,7 @@ struct rkvpss_stream {
|
||||
struct v4l2_rect crop;
|
||||
struct v4l2_pix_format_mplane out_fmt;
|
||||
struct frame_debug_info dbg;
|
||||
struct rkvpss_online_unite_params unite_params;
|
||||
|
||||
int id;
|
||||
bool streaming;
|
||||
|
||||
@@ -148,8 +148,8 @@ static int rkvpss_sd_s_stream(struct v4l2_subdev *sd, int on)
|
||||
"s_stream on:%d %dx%d\n", on, w, h);
|
||||
|
||||
if (!on) {
|
||||
rkvpss_clear_bits(dev, RKVPSS_VPSS_ONLINE, RKVPSS_ONLINE_MODE_MASK);
|
||||
rkvpss_clear_bits(dev, RKVPSS_VPSS_IMSC, RKVPSS_ISP_ALL_FRM_END);
|
||||
rkvpss_unite_clear_bits(dev, RKVPSS_VPSS_ONLINE, RKVPSS_ONLINE_MODE_MASK);
|
||||
rkvpss_unite_clear_bits(dev, RKVPSS_VPSS_IMSC, RKVPSS_ISP_ALL_FRM_END);
|
||||
sdev->state = VPSS_STOP;
|
||||
atomic_dec(&dev->hw_dev->refcnt);
|
||||
return 0;
|
||||
@@ -158,18 +158,23 @@ static int rkvpss_sd_s_stream(struct v4l2_subdev *sd, int on)
|
||||
sdev->frame_seq = -1;
|
||||
sdev->frame_timestamp = 0;
|
||||
dev->isr_cnt = 0;
|
||||
dev->irq_ends = 0;
|
||||
atomic_inc(&dev->hw_dev->refcnt);
|
||||
dev->cmsc_upd = true;
|
||||
rkvpss_cmsc_config(dev, true);
|
||||
rkvpss_write(dev, RKVPSS_VPSS_ONLINE2_SIZE, h << 16 | w);
|
||||
|
||||
if (dev->unite_mode)
|
||||
w = w / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
|
||||
rkvpss_unite_write(dev, RKVPSS_VPSS_ONLINE2_SIZE, h << 16 | w);
|
||||
|
||||
val = RKVPSS_CFG_FORCE_UPD | RKVPSS_CFG_GEN_UPD | RKVPSS_MIR_GEN_UPD;
|
||||
if (!dev->hw_dev->is_ofl_cmsc)
|
||||
val |= RKVPSS_MIR_FORCE_UPD;
|
||||
|
||||
rkvpss_write(dev, RKVPSS_VPSS_UPDATE, val);
|
||||
rkvpss_unite_write(dev, RKVPSS_VPSS_UPDATE, val);
|
||||
|
||||
rkvpss_set_bits(dev, RKVPSS_VPSS_IMSC, 0, RKVPSS_ISP_ALL_FRM_END);
|
||||
rkvpss_unite_set_bits(dev, RKVPSS_VPSS_IMSC, 0, RKVPSS_ISP_ALL_FRM_END);
|
||||
sdev->state |= VPSS_START;
|
||||
return 0;
|
||||
}
|
||||
@@ -209,6 +214,8 @@ static int rkvpss_sd_s_power(struct v4l2_subdev *sd, int on)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
v4l2_subdev_call(dev->remote_sd, core, ioctl, RKISP_VPSS_GET_UNITE_MODE,
|
||||
&dev->unite_mode);
|
||||
ret = pm_runtime_get_sync(dev->dev);
|
||||
if (ret < 0) {
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
@@ -232,11 +239,17 @@ static int rkvpss_sof(struct rkvpss_subdev *sdev, struct rkisp_vpss_sof *info)
|
||||
struct rkvpss_hw_dev *hw = dev->hw_dev;
|
||||
struct rkvpss_stream *stream;
|
||||
int i;
|
||||
u32 vpss_online, val = 0;
|
||||
|
||||
if (!info)
|
||||
return -EINVAL;
|
||||
sdev->frame_seq = info->seq;
|
||||
sdev->frame_timestamp = info->timestamp;
|
||||
dev->unite_index = info->unite_index;
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &dev->v4l2_dev,
|
||||
"%s unite_mode:%u, unite_indev:%u\n", __func__,
|
||||
dev->unite_mode, dev->unite_index);
|
||||
|
||||
rkvpss_cmsc_config(dev, !info->irq);
|
||||
for (i = 0; i < RKVPSS_OUTPUT_MAX; i++) {
|
||||
@@ -247,7 +260,7 @@ static int rkvpss_sof(struct rkvpss_subdev *sdev, struct rkisp_vpss_sof *info)
|
||||
stream->ops->frame_start(stream, info->irq);
|
||||
}
|
||||
|
||||
if (!info->irq && !hw->is_single) {
|
||||
if (!info->irq && (!hw->is_single || dev->unite_mode)) {
|
||||
hw->cur_dev_id = dev->dev_id;
|
||||
rkvpss_update_regs(dev, RKVPSS_VPSS_CTRL, RKVPSS_VPSS_ONLINE2_SIZE);
|
||||
rkvpss_update_regs(dev, RKVPSS_VPSS_IRQ_CFG, RKVPSS_VPSS_IMSC);
|
||||
@@ -262,7 +275,7 @@ static int rkvpss_sof(struct rkvpss_subdev *sdev, struct rkisp_vpss_sof *info)
|
||||
rkvpss_update_regs(dev, RKVPSS_MI_WR_WRAP_CTRL, RKVPSS_MI_IMSC);
|
||||
rkvpss_update_regs(dev, RKVPSS_MI_CHN0_WR_CTRL, RKVPSS_MI_CHN3_WR_LINE_CNT);
|
||||
|
||||
rkvpss_update_regs(dev, RKVPSS_MI_WR_CTRL, RKVPSS_MI_WR_INIT);
|
||||
rkvpss_update_regs(dev, RKVPSS_MI_WR_CTRL, RKVPSS_MI_WR_CTRL);
|
||||
rkvpss_update_regs(dev, RKVPSS_SCALE3_CTRL, RKVPSS_SCALE3_UPDATE);
|
||||
rkvpss_update_regs(dev, RKVPSS_SCALE2_CTRL, RKVPSS_SCALE2_UPDATE);
|
||||
rkvpss_update_regs(dev, RKVPSS_SCALE1_CTRL, RKVPSS_SCALE1_UPDATE);
|
||||
@@ -270,6 +283,23 @@ static int rkvpss_sof(struct rkvpss_subdev *sdev, struct rkisp_vpss_sof *info)
|
||||
rkvpss_update_regs(dev, RKVPSS_CROP1_CTRL, RKVPSS_CROP1_UPDATE);
|
||||
rkvpss_update_regs(dev, RKVPSS_CMSC_CTRL, RKVPSS_CMSC_UPDATE);
|
||||
rkvpss_update_regs(dev, RKVPSS_VPSS_UPDATE, RKVPSS_VPSS_UPDATE);
|
||||
|
||||
/* force update mi write */
|
||||
vpss_online = rkvpss_hw_read(hw, RKVPSS_VPSS_ONLINE);
|
||||
for (i = 0; i < RKVPSS_OUTPUT_MAX; i++) {
|
||||
if (((vpss_online >> (2 * i)) & 0x3) == 0x2)
|
||||
val |= BIT(i);
|
||||
}
|
||||
rkvpss_unite_write(dev, RKVPSS_MI_WR_INIT, val << 4);
|
||||
rkvpss_update_regs(dev, RKVPSS_MI_WR_INIT, RKVPSS_MI_WR_INIT);
|
||||
}
|
||||
|
||||
dev->irq_ends_mask = VPSS_FRAME_END;
|
||||
for (i = 0; i < RKVPSS_OUTPUT_MAX; i++) {
|
||||
if (hw->is_ofl_ch[i])
|
||||
continue;
|
||||
if (rkvpss_hw_read(dev->hw_dev, RKVPSS_MI_CHN0_WR_CTRL_SHD + i * 0x100) & 0x1)
|
||||
dev->irq_ends_mask |= BIT(i+3);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -342,6 +372,54 @@ static void rkvpss_subdev_default_fmt(struct rkvpss_subdev *sdev)
|
||||
out_fmt->height = RKVPSS_DEFAULT_HEIGHT;
|
||||
}
|
||||
|
||||
static void rkvpss_end_notify_isp(struct rkvpss_device *dev)
|
||||
{
|
||||
int stopping;
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &dev->v4l2_dev,
|
||||
"%s stopping:%d unite_index:%d\n", __func__, dev->stopping, dev->unite_index);
|
||||
|
||||
if (dev->stopping) {
|
||||
if (dev->unite_mode) {
|
||||
if (dev->unite_index == VPSS_UNITE_LEFT) {
|
||||
stopping = 0;
|
||||
v4l2_subdev_call(dev->remote_sd, core, ioctl, RKISP_VPSS_CMD_EOF,
|
||||
&stopping);
|
||||
} else {
|
||||
dev->stopping = false;
|
||||
wake_up(&dev->stop_done);
|
||||
stopping = 1;
|
||||
v4l2_subdev_call(dev->remote_sd, core, ioctl, RKISP_VPSS_CMD_EOF,
|
||||
&stopping);
|
||||
}
|
||||
} else {
|
||||
dev->stopping = false;
|
||||
wake_up(&dev->stop_done);
|
||||
stopping = 1;
|
||||
v4l2_subdev_call(dev->remote_sd, core, ioctl, RKISP_VPSS_CMD_EOF,
|
||||
&stopping);
|
||||
}
|
||||
} else {
|
||||
stopping = 0;
|
||||
v4l2_subdev_call(dev->remote_sd, core, ioctl, RKISP_VPSS_CMD_EOF, &stopping);
|
||||
}
|
||||
}
|
||||
|
||||
void rkvpss_check_idle(struct rkvpss_device *dev, u32 irq)
|
||||
{
|
||||
dev->irq_ends |= (irq & dev->irq_ends_mask);
|
||||
|
||||
v4l2_dbg(3, rkvpss_debug, &dev->v4l2_dev,
|
||||
"%s irq:0x%x ends:0x%x mask:0x%x\n",
|
||||
__func__, irq, dev->irq_ends, dev->irq_ends_mask);
|
||||
|
||||
if ((dev->irq_ends & dev->irq_ends_mask) != dev->irq_ends_mask)
|
||||
return;
|
||||
|
||||
dev->irq_ends = 0;
|
||||
rkvpss_end_notify_isp(dev);
|
||||
}
|
||||
|
||||
int rkvpss_register_subdev(struct rkvpss_device *dev,
|
||||
struct v4l2_device *v4l2_dev)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,11 @@ enum rkvpss_state {
|
||||
VPSS_STOP = 0,
|
||||
VPSS_FS = BIT(0),
|
||||
VPSS_FE = BIT(1),
|
||||
VPSS_FRAME_END = BIT(2),
|
||||
VPSS_FRAME_SCL0 = BIT(3),
|
||||
VPSS_FRAME_SCL1 = BIT(4),
|
||||
VPSS_FRAME_SCL2 = BIT(5),
|
||||
VPSS_FRAME_SCL3 = BIT(6),
|
||||
|
||||
VPSS_START = BIT(8),
|
||||
VPSS_RX_START = BIT(9),
|
||||
@@ -46,4 +51,5 @@ struct rkvpss_subdev {
|
||||
int rkvpss_register_subdev(struct rkvpss_device *dev,
|
||||
struct v4l2_device *v4l2_dev);
|
||||
void rkvpss_unregister_subdev(struct rkvpss_device *dev);
|
||||
void rkvpss_check_idle(struct rkvpss_device *dev, u32 irq);
|
||||
#endif
|
||||
|
||||
@@ -5416,8 +5416,8 @@ int rk_iomux_set(int bank, int pin, int mux)
|
||||
mutex_lock(&iomux_lock);
|
||||
for (i = 0; i < info->ngroups; i++) {
|
||||
grp = &info->groups[i];
|
||||
for (j = 0; j < grp->npins; i++) {
|
||||
if (grp->pins[i] == (gpio->pin_base + pin)) {
|
||||
for (j = 0; j < grp->npins; j++) {
|
||||
if (grp->pins[j] == (gpio->pin_base + pin)) {
|
||||
cfg = grp->data;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2889,7 +2889,6 @@ static void rga2_set_reg_full_csc(struct rga_job *job, struct rga_scheduler_t *s
|
||||
static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
|
||||
{
|
||||
int i;
|
||||
int cur_num;
|
||||
bool master_mode_en;
|
||||
uint32_t sys_ctrl;
|
||||
uint32_t *cmd;
|
||||
@@ -2930,10 +2929,8 @@ static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
|
||||
* when RGA is running continuously, disabling auto_rst
|
||||
* requires resetting core_clk.
|
||||
*/
|
||||
cur_num = (rga_read(RGA2_STATUS1, scheduler) & m_RGA2_STATUS1_SW_CMD_CUR_NUM) >> 8;
|
||||
if (cur_num > 0)
|
||||
rga_write(m_RGA2_SYS_CTRL_AUTO_CKG | m_RGA2_SYS_CTRL_CCLK_SRESET_P,
|
||||
RGA2_SYS_CTRL, scheduler);
|
||||
rga_write(m_RGA2_SYS_CTRL_AUTO_CKG | m_RGA2_SYS_CTRL_CCLK_SRESET_P,
|
||||
RGA2_SYS_CTRL, scheduler);
|
||||
} else {
|
||||
sys_ctrl |= m_RGA2_SYS_CTRL_AUTO_RST;
|
||||
}
|
||||
@@ -2966,8 +2963,6 @@ static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
|
||||
for (i = 0; i <= 32; i++)
|
||||
rga_write(cmd[i], 0x100 + i * 4, scheduler);
|
||||
|
||||
rga_write(rga_read(RGA2_CMD_CTRL, scheduler) | m_RGA2_CMD_CTRL_CMD_LINE_ST_P,
|
||||
RGA2_CMD_CTRL, scheduler);
|
||||
rga_write(sys_ctrl, RGA2_SYS_CTRL, scheduler);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ struct analogix_dp_plat_data {
|
||||
bool dual_connector_split;
|
||||
bool left_display;
|
||||
|
||||
u8 max_bpc;
|
||||
|
||||
struct analogix_dp_device *left;
|
||||
struct analogix_dp_device *right;
|
||||
|
||||
@@ -66,6 +68,12 @@ struct analogix_dp_plat_data {
|
||||
void (*convert_to_origin_mode)(struct drm_display_mode *);
|
||||
};
|
||||
|
||||
struct analogix_dp_output_format {
|
||||
u32 bus_format;
|
||||
u32 color_format;
|
||||
u8 bpc;
|
||||
};
|
||||
|
||||
int analogix_dp_resume(struct analogix_dp_device *dp);
|
||||
int analogix_dp_suspend(struct analogix_dp_device *dp);
|
||||
int analogix_dp_runtime_resume(struct analogix_dp_device *dp);
|
||||
@@ -89,5 +97,6 @@ int analogix_dp_audio_get_eld(struct analogix_dp_device *dp,
|
||||
u8 *buf, size_t len);
|
||||
int analogix_dp_loader_protect(struct analogix_dp_device *dp);
|
||||
void analogix_dp_disable(struct analogix_dp_device *dp);
|
||||
const struct analogix_dp_output_format *analogix_dp_get_output_format(u32 bus_format);
|
||||
|
||||
#endif /* _ANALOGIX_DP_H_ */
|
||||
|
||||
Reference in New Issue
Block a user