hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
....@@ -20,7 +20,6 @@
2020 #ifdef CONFIG_DRM_ANALOGIX_DP
2121 #include <drm/bridge/analogix_dp.h>
2222 #endif
23
-#include <dt-bindings/soc/rockchip-system-status.h>
2423
2524 #include <linux/debugfs.h>
2625 #include <linux/fixp-arith.h>
....@@ -46,6 +45,7 @@
4645 #include <linux/rockchip/cpu.h>
4746 #include <linux/workqueue.h>
4847 #include <linux/types.h>
48
+#include <soc/rockchip/rockchip_csu.h>
4949 #include <soc/rockchip/rockchip_dmc.h>
5050 #include <soc/rockchip/rockchip-system-status.h>
5151 #include <uapi/linux/videodev2.h>
....@@ -885,6 +885,7 @@
885885 struct clk *pclk;
886886 struct reset_control *ahb_rst;
887887 struct reset_control *axi_rst;
888
+ struct csu_clk *csu_aclk;
888889
889890 /* list_head of extend clk */
890891 struct list_head extend_clk_list_head;
....@@ -929,6 +930,7 @@
929930 { MEDIA_BUS_FMT_UYYVYY8_0_5X24, "UYYVYY8_0_5X24" },
930931 { MEDIA_BUS_FMT_YUV10_1X30, "YUV10_1X30" },
931932 { MEDIA_BUS_FMT_UYYVYY10_0_5X30, "UYYVYY10_0_5X30" },
933
+ { MEDIA_BUS_FMT_RGB565_2X8_LE, "RGB565_2X8_LE" },
932934 { MEDIA_BUS_FMT_RGB888_3X8, "RGB888_3X8" },
933935 { MEDIA_BUS_FMT_RGB888_DUMMY_4X8, "RGB888_DUMMY_4X8" },
934936 { MEDIA_BUS_FMT_RGB888_1X24, "RGB888_1X24" },
....@@ -3243,8 +3245,21 @@
32433245 return 0;
32443246 }
32453247
3248
+static void vop2_wb_encoder_atomic_disable(struct drm_encoder *encoder,
3249
+ struct drm_atomic_state *state)
3250
+{
3251
+ struct drm_crtc *crtc = encoder->crtc;
3252
+ struct vop2_video_port *vp = to_vop2_video_port(crtc);
3253
+
3254
+ if (!crtc->state->active_changed && !crtc->state->mode_changed) {
3255
+ crtc->state->connectors_changed = false;
3256
+ DRM_DEBUG("VP%d force change connectors_changed to false when disable wb\n", vp->id);
3257
+ }
3258
+}
3259
+
32463260 static const struct drm_encoder_helper_funcs vop2_wb_encoder_helper_funcs = {
32473261 .atomic_check = vop2_wb_encoder_atomic_check,
3262
+ .atomic_disable = vop2_wb_encoder_atomic_disable,
32483263 };
32493264
32503265 static const struct drm_connector_helper_funcs vop2_wb_connector_helper_funcs = {
....@@ -5142,7 +5157,7 @@
51425157 actual_w = drm_rect_width(src) >> 16;
51435158 actual_h = drm_rect_height(src) >> 16;
51445159
5145
- if (!actual_w || !actual_h) {
5160
+ if (!actual_w || !actual_h || !bpp) {
51465161 vop2_win_disable(win, true);
51475162 return;
51485163 }
....@@ -5263,10 +5278,6 @@
52635278 /* AFBC pic_vir_width is count by pixel, this is different
52645279 * with WIN_VIR_STRIDE.
52655280 */
5266
- if (!bpp) {
5267
- WARN(1, "bpp is zero\n");
5268
- bpp = 1;
5269
- }
52705281 stride = (fb->pitches[0] << 3) / bpp;
52715282 if ((stride & 0x3f) &&
52725283 (vpstate->xmirror_en || vpstate->rotate_90_en || vpstate->rotate_270_en))
....@@ -6111,6 +6122,27 @@
61116122 return 0;
61126123 }
61136124
6125
+static void vop2_crtc_csu_set_rate(struct drm_crtc *crtc)
6126
+{
6127
+ struct vop2_video_port *vp = to_vop2_video_port(crtc);
6128
+ struct vop2 *vop2 = vp->vop2;
6129
+ unsigned long aclk_rate = 0, dclk_rate = 0;
6130
+ u32 csu_div = 0;
6131
+
6132
+ if (!vop2->csu_aclk)
6133
+ return;
6134
+
6135
+ aclk_rate = clk_get_rate(vop2->aclk);
6136
+ dclk_rate = clk_get_rate(vp->dclk);
6137
+ if (!dclk_rate)
6138
+ return;
6139
+
6140
+ /* aclk >= 1/2 * dclk */
6141
+ csu_div = aclk_rate * 2 / dclk_rate;
6142
+
6143
+ rockchip_csu_set_div(vop2->csu_aclk, csu_div);
6144
+}
6145
+
61146146 static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on, void *data)
61156147 {
61166148 struct vop2_video_port *vp = to_vop2_video_port(crtc);
....@@ -6190,6 +6222,8 @@
61906222 cubic_lut_mst = cubic_lut->offset + private->cubic_lut_dma_addr;
61916223 VOP_MODULE_SET(vop2, vp, cubic_lut_mst, cubic_lut_mst);
61926224 }
6225
+
6226
+ vop2_crtc_csu_set_rate(crtc);
61936227 } else {
61946228 vop2_crtc_atomic_disable(crtc, NULL);
61956229 }
....@@ -6330,7 +6364,8 @@
63306364
63316365 /* only need to dump once at first active crtc for vop2 */
63326366 for (i = 0; i < vop2_data->nr_vps; i++) {
6333
- if (vop2->vps[i].rockchip_crtc.crtc.state->active) {
6367
+ if (vop2->vps[i].rockchip_crtc.crtc.state &&
6368
+ vop2->vps[i].rockchip_crtc.crtc.state->active) {
63346369 first_active_crtc = &vop2->vps[i].rockchip_crtc.crtc;
63356370 break;
63366371 }
....@@ -6373,7 +6408,8 @@
63736408
63746409 /* only need to dump once at first active crtc for vop2 */
63756410 for (i = 0; i < vop2_data->nr_vps; i++) {
6376
- if (vop2->vps[i].rockchip_crtc.crtc.state->active) {
6411
+ if (vop2->vps[i].rockchip_crtc.crtc.state &&
6412
+ vop2->vps[i].rockchip_crtc.crtc.state->active) {
63776413 first_active_crtc = &vop2->vps[i].rockchip_crtc.crtc;
63786414 break;
63796415 }
....@@ -6543,7 +6579,8 @@
65436579 } else {
65446580 if (request_clock > VOP2_MAX_DCLK_RATE)
65456581 request_clock = request_clock >> 2;
6546
- clock = clk_round_rate(vp->dclk, request_clock * 1000) / 1000;
6582
+ clock = rockchip_drm_dclk_round_rate(vop2->version, vp->dclk,
6583
+ request_clock * 1000) / 1000;
65476584 }
65486585
65496586 /*
....@@ -6586,7 +6623,7 @@
65866623 size_t bandwidth;
65876624
65886625 if (src_width <= 0 || src_height <= 0 || dst_width <= 0 ||
6589
- dst_height <= 0)
6626
+ dst_height <= 0 || !bpp)
65906627 return 0;
65916628
65926629 bandwidth = src_width * bpp / 8;
....@@ -6832,6 +6869,14 @@
68326869 if (mode->flags & DRM_MODE_FLAG_DBLCLK || vcstate->output_if & VOP_OUTPUT_IF_BT656)
68336870 adj_mode->crtc_clock *= 2;
68346871
6872
+ /*
6873
+ * For RK3528, the path of CVBS output is like:
6874
+ * VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC
6875
+ * The vop2 dclk should be four times crtc_clock for CVBS sampling clock needs.
6876
+ */
6877
+ if (vop2->version == VOP_VERSION_RK3528 && vcstate->output_if & VOP_OUTPUT_IF_BT656)
6878
+ adj_mode->crtc_clock *= 4;
6879
+
68356880 if (vp->mcu_timing.mcu_pix_total)
68366881 adj_mode->crtc_clock *= rockchip_drm_get_cycles_per_pixel(vcstate->bus_format) *
68376882 (vp->mcu_timing.mcu_pix_total + 1);
....@@ -6847,9 +6892,11 @@
68476892 }
68486893 drm_connector_list_iter_end(&conn_iter);
68496894
6850
- if (adj_mode->crtc_clock <= VOP2_MAX_DCLK_RATE)
6851
- adj_mode->crtc_clock = DIV_ROUND_UP(clk_round_rate(vp->dclk,
6852
- adj_mode->crtc_clock * 1000), 1000);
6895
+ if (adj_mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
6896
+ adj_mode->crtc_clock = rockchip_drm_dclk_round_rate(vop2->version, vp->dclk,
6897
+ adj_mode->crtc_clock * 1000);
6898
+ adj_mode->crtc_clock = DIV_ROUND_UP(adj_mode->crtc_clock, 1000);
6899
+ }
68536900 return true;
68546901 }
68556902
....@@ -7745,11 +7792,11 @@
77457792 vop2_set_system_status(vop2);
77467793
77477794 vop2_lock(vop2);
7748
- DRM_DEV_INFO(vop2->dev, "Update mode to %dx%d%s%d, type: %d(if:%x, flag:0x%x) for vp%d dclk: %d\n",
7795
+ DRM_DEV_INFO(vop2->dev, "Update mode to %dx%d%s%d, type: %d(if:%x, flag:0x%x) for vp%d dclk: %llu\n",
77497796 hdisplay, adjusted_mode->vdisplay, interlaced ? "i" : "p",
77507797 drm_mode_vrefresh(adjusted_mode),
77517798 vcstate->output_type, vcstate->output_if, vcstate->output_flags,
7752
- vp->id, adjusted_mode->crtc_clock * 1000);
7799
+ vp->id, (unsigned long long)adjusted_mode->crtc_clock * 1000);
77537800
77547801 if (adjusted_mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
77557802 vcstate->splice_mode = true;
....@@ -8081,19 +8128,12 @@
80818128 if (ret < 0)
80828129 goto out;
80838130
8084
- clk_set_rate(vp->dclk, dclk->rate);
8131
+ rockchip_drm_dclk_set_rate(vop2->version, vp->dclk, dclk->rate);
80858132 DRM_DEV_INFO(vop2->dev, "set %s to %ld, get %ld\n",
80868133 __clk_get_name(vp->dclk), dclk->rate, clk_get_rate(vp->dclk));
80878134 } else {
8088
- /*
8089
- * For RK3528, the path of CVBS output is like:
8090
- * VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC
8091
- * The vop2 dclk should be four times crtc_clock for CVBS sampling clock needs.
8092
- */
8093
- if (vop2->version == VOP_VERSION_RK3528 && vcstate->output_if & VOP_OUTPUT_IF_BT656)
8094
- clk_set_rate(vp->dclk, 4 * adjusted_mode->crtc_clock * 1000);
8095
- else
8096
- clk_set_rate(vp->dclk, adjusted_mode->crtc_clock * 1000);
8135
+ rockchip_drm_dclk_set_rate(vop2->version, vp->dclk,
8136
+ adjusted_mode->crtc_clock * 1000);
80978137 }
80988138
80998139 if (vp_data->feature & VOP_FEATURE_OVERSCAN)
....@@ -8122,6 +8162,7 @@
81228162 if (is_vop3(vop2))
81238163 vop3_setup_pipe_dly(vp, NULL);
81248164
8165
+ vop2_crtc_csu_set_rate(crtc);
81258166 vop2_cfg_done(crtc);
81268167
81278168 /*
....@@ -8158,6 +8199,30 @@
81588199 vop2_crtc_load_lut(crtc);
81598200 vop2_cfg_done(crtc);
81608201 vop2_wait_for_fs_by_done_bit_status(vp);
8202
+ }
8203
+
8204
+ /*
8205
+ * In RK3588 VOP, HDMI1/eDP1 MUX1 module's reset signal should be released
8206
+ * when PD_VOP turn on. If this reset signal is not be released, the HDMI1
8207
+ * or eDP1 output interface can't work normally.
8208
+ * However, If the deassert signal want to transfer to HDMI1/eDP1 MUX1 and
8209
+ * take effect, it need the video port0 dclk's source clk work a few moment.
8210
+ * In some cases, the video port0 dclk's source clk is disabled(now only the
8211
+ * hdmi0/1 phy pll as the dclk source parent will appear) after PD_VOP turn
8212
+ * on, for example, vidoe port0 dclk source select hdmi phy pll. To fix
8213
+ * this issue, enable video port0 dclk for a few monent when active a video
8214
+ * port which attach to eDP1/HDMI1.
8215
+ */
8216
+ if (vop2->version == VOP_VERSION_RK3588) {
8217
+ if (vp->id != 0 && (vp->output_if & (VOP_OUTPUT_IF_eDP1 | VOP_OUTPUT_IF_HDMI1))) {
8218
+ struct vop2_video_port *vp0 = &vop2->vps[0];
8219
+
8220
+ clk_prepare_enable(vp0->dclk);
8221
+ if (!clk_get_rate(vp0->dclk))
8222
+ clk_set_rate(vp0->dclk, 148500000);
8223
+ udelay(20);
8224
+ clk_disable_unprepare(vp0->dclk);
8225
+ }
81618226 }
81628227 out:
81638228 vop2_unlock(vop2);
....@@ -10941,25 +11006,14 @@
1094111006 return 0;
1094211007 }
1094311008
10944
-static struct drm_plane *vop2_cursor_plane_init(struct vop2_video_port *vp)
11009
+static struct drm_plane *vop2_cursor_plane_init(struct vop2_video_port *vp, u32 possible_crtcs)
1094511010 {
1094611011 struct vop2 *vop2 = vp->vop2;
1094711012 struct drm_plane *cursor = NULL;
1094811013 struct vop2_win *win;
10949
- unsigned long possible_crtcs = 0;
1095011014
1095111015 win = vop2_find_win_by_phys_id(vop2, vp->cursor_win_id);
1095211016 if (win) {
10953
- if (vop2->disable_win_move) {
10954
- const struct vop2_data *vop2_data = vop2->data;
10955
- struct drm_crtc *crtc = vop2_find_crtc_by_plane_mask(vop2, win->phys_id);
10956
-
10957
- if (crtc)
10958
- possible_crtcs = drm_crtc_mask(crtc);
10959
- else
10960
- possible_crtcs = (1 << vop2_data->nr_vps) - 1;
10961
- }
10962
-
1096311017 if (win->possible_crtcs)
1096411018 possible_crtcs = win->possible_crtcs;
1096511019 win->type = DRM_PLANE_TYPE_CURSOR;
....@@ -11263,11 +11317,13 @@
1126311317 possible_crtcs = BIT(registered_num_crtcs);
1126411318
1126511319 /*
11266
- * we assume a vp with a zere plane_mask(set from dts or bootloader)
11320
+ * we assume a vp with a zero plane_mask(set from dts or bootloader)
1126711321 * as unused.
1126811322 */
11269
- if (!vp->plane_mask && bootloader_initialized)
11323
+ if (!vp->plane_mask && bootloader_initialized) {
11324
+ DRM_DEV_INFO(vop2->dev, "VP%d plane_mask is zero, so ignore register crtc\n", vp->id);
1127011325 continue;
11326
+ }
1127111327
1127211328 if (vop2_soc_is_rk3566())
1127311329 soc_id = vp_data->soc_id[1];
....@@ -11389,7 +11445,7 @@
1138911445 }
1139011446
1139111447 if (vp->cursor_win_id >= 0) {
11392
- cursor = vop2_cursor_plane_init(vp);
11448
+ cursor = vop2_cursor_plane_init(vp, possible_crtcs);
1139311449 if (!cursor)
1139411450 DRM_WARN("failed to init cursor plane for vp%d\n", vp->id);
1139511451 else
....@@ -11587,6 +11643,7 @@
1158711643 struct vop2_win *win;
1158811644 struct vop2_layer *layer;
1158911645 char name[DRM_PROP_NAME_LEN];
11646
+ char area_name[DRM_PROP_NAME_LEN];
1159011647 unsigned int num_wins = 0;
1159111648 uint8_t plane_id = 0;
1159211649 unsigned int i, j;
....@@ -11662,8 +11719,8 @@
1166211719 area->phys_id = win->phys_id;
1166311720 area->area_id = j + 1;
1166411721 area->plane_id = plane_id++;
11665
- snprintf(name, min(sizeof(name), strlen(win->name)), "%s", win->name);
11666
- snprintf(name, sizeof(name), "%s%d", name, area->area_id);
11722
+ snprintf(area_name, min(sizeof(area_name), strlen(win->name)), "%s", win->name);
11723
+ snprintf(name, sizeof(name), "%s%d", area_name, area->area_id);
1166711724 area->name = devm_kstrdup(vop2->dev, name, GFP_KERNEL);
1166811725 num_wins++;
1166911726 }
....@@ -11957,6 +12014,10 @@
1195712014 return PTR_ERR(vop2->axi_rst);
1195812015 }
1195912016
12017
+ vop2->csu_aclk = rockchip_csu_get(dev, "aclk");
12018
+ if (IS_ERR(vop2->csu_aclk))
12019
+ vop2->csu_aclk = NULL;
12020
+
1196012021 vop2->irq = platform_get_irq(pdev, 0);
1196112022 if (vop2->irq < 0) {
1196212023 DRM_DEV_ERROR(dev, "cannot find irq for vop2\n");