Skip to content

Commit fddb4fd

Browse files
committed
Merge tag 'mediatek-drm-fixes-20250104' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux into drm-fixes
Mediatek DRM Fixes - 20250104 1. Revert "drm/mediatek: dsi: Correct calculation formula of PHY Timing" 2. Set private->all_drm_private[i]->drm to NULL if mtk_drm_bind returns err 3. Move mtk_crtc_finish_page_flip() to ddp_cmdq_cb() 4. Only touch DISP_REG_OVL_PITCH_MSB if AFBC is supported 5. Add support for 180-degree rotation in the display driver 6. Stop selecting foreign drivers 7. Revert "drm/mediatek: Switch to for_each_child_of_node_scoped()" 8. Fix YCbCr422 color format issue for DP 9. Fix mode valid issue for dp 10. dp: Reference common DAI properties 11. dsi: Add registers to pdata to fix MT8186/MT8188 12. Remove unneeded semicolon 13. Add return value check when reading DPCD 14. Initialize pointer in mtk_drm_of_ddp_path_build_one() Signed-off-by: Dave Airlie <[email protected]> From: Chun-Kuang Hu <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 85bf89f + f563dd9 commit fddb4fd

File tree

7 files changed

+142
-84
lines changed

7 files changed

+142
-84
lines changed

Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ properties:
4242
interrupts:
4343
maxItems: 1
4444

45+
'#sound-dai-cells':
46+
const: 0
47+
4548
ports:
4649
$ref: /schemas/graph.yaml#/properties/ports
4750
properties:
@@ -85,7 +88,21 @@ required:
8588
- ports
8689
- max-linkrate-mhz
8790

88-
additionalProperties: false
91+
allOf:
92+
- $ref: /schemas/sound/dai-common.yaml#
93+
- if:
94+
not:
95+
properties:
96+
compatible:
97+
contains:
98+
enum:
99+
- mediatek,mt8188-dp-tx
100+
- mediatek,mt8195-dp-tx
101+
then:
102+
properties:
103+
'#sound-dai-cells': false
104+
105+
unevaluatedProperties: false
89106

90107
examples:
91108
- |

drivers/gpu/drm/mediatek/Kconfig

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ config DRM_MEDIATEK
1414
select DRM_BRIDGE_CONNECTOR
1515
select DRM_MIPI_DSI
1616
select DRM_PANEL
17-
select MEMORY
18-
select MTK_SMI
19-
select PHY_MTK_MIPI_DSI
2017
select VIDEOMODE_HELPERS
2118
help
2219
Choose this option if you have a Mediatek SoCs.
@@ -27,7 +24,6 @@ config DRM_MEDIATEK
2724
config DRM_MEDIATEK_DP
2825
tristate "DRM DPTX Support for MediaTek SoCs"
2926
depends on DRM_MEDIATEK
30-
select PHY_MTK_DP
3127
select DRM_DISPLAY_HELPER
3228
select DRM_DISPLAY_DP_HELPER
3329
select DRM_DISPLAY_DP_AUX_BUS
@@ -38,6 +34,5 @@ config DRM_MEDIATEK_HDMI
3834
tristate "DRM HDMI Support for Mediatek SoCs"
3935
depends on DRM_MEDIATEK
4036
select SND_SOC_HDMI_CODEC if SND_SOC
41-
select PHY_MTK_HDMI
4237
help
4338
DRM/KMS HDMI driver for Mediatek SoCs

drivers/gpu/drm/mediatek/mtk_crtc.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
112112

113113
drm_crtc_handle_vblank(&mtk_crtc->base);
114114

115+
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
116+
if (mtk_crtc->cmdq_client.chan)
117+
return;
118+
#endif
119+
115120
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
116121
if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
117122
mtk_crtc_finish_page_flip(mtk_crtc);
@@ -284,10 +289,8 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
284289
state = to_mtk_crtc_state(mtk_crtc->base.state);
285290

286291
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
287-
if (mtk_crtc->config_updating) {
288-
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
292+
if (mtk_crtc->config_updating)
289293
goto ddp_cmdq_cb_out;
290-
}
291294

292295
state->pending_config = false;
293296

@@ -315,10 +318,15 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
315318
mtk_crtc->pending_async_planes = false;
316319
}
317320

318-
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
319-
320321
ddp_cmdq_cb_out:
321322

323+
if (mtk_crtc->pending_needs_vblank) {
324+
mtk_crtc_finish_page_flip(mtk_crtc);
325+
mtk_crtc->pending_needs_vblank = false;
326+
}
327+
328+
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
329+
322330
mtk_crtc->cmdq_vblank_cnt = 0;
323331
wake_up(&mtk_crtc->cb_blocking_queue);
324332
}
@@ -606,13 +614,18 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
606614
*/
607615
mtk_crtc->cmdq_vblank_cnt = 3;
608616

617+
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
618+
mtk_crtc->config_updating = false;
619+
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
620+
609621
mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
610622
mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
611623
}
612-
#endif
624+
#else
613625
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
614626
mtk_crtc->config_updating = false;
615627
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
628+
#endif
616629

617630
mutex_unlock(&mtk_crtc->hw_lock);
618631
}

drivers/gpu/drm/mediatek/mtk_disp_ovl.c

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -460,32 +460,44 @@ static unsigned int mtk_ovl_fmt_convert(struct mtk_disp_ovl *ovl,
460460
}
461461
}
462462

463+
static void mtk_ovl_afbc_layer_config(struct mtk_disp_ovl *ovl,
464+
unsigned int idx,
465+
struct mtk_plane_pending_state *pending,
466+
struct cmdq_pkt *cmdq_pkt)
467+
{
468+
unsigned int pitch_msb = pending->pitch >> 16;
469+
unsigned int hdr_pitch = pending->hdr_pitch;
470+
unsigned int hdr_addr = pending->hdr_addr;
471+
472+
if (pending->modifier != DRM_FORMAT_MOD_LINEAR) {
473+
mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
474+
DISP_REG_OVL_HDR_ADDR(ovl, idx));
475+
mtk_ddp_write_relaxed(cmdq_pkt,
476+
OVL_PITCH_MSB_2ND_SUBBUF | pitch_msb,
477+
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
478+
mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
479+
DISP_REG_OVL_HDR_PITCH(ovl, idx));
480+
} else {
481+
mtk_ddp_write_relaxed(cmdq_pkt, pitch_msb,
482+
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
483+
}
484+
}
485+
463486
void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
464487
struct mtk_plane_state *state,
465488
struct cmdq_pkt *cmdq_pkt)
466489
{
467490
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
468491
struct mtk_plane_pending_state *pending = &state->pending;
469492
unsigned int addr = pending->addr;
470-
unsigned int hdr_addr = pending->hdr_addr;
471-
unsigned int pitch = pending->pitch;
472-
unsigned int hdr_pitch = pending->hdr_pitch;
493+
unsigned int pitch_lsb = pending->pitch & GENMASK(15, 0);
473494
unsigned int fmt = pending->format;
495+
unsigned int rotation = pending->rotation;
474496
unsigned int offset = (pending->y << 16) | pending->x;
475497
unsigned int src_size = (pending->height << 16) | pending->width;
476498
unsigned int blend_mode = state->base.pixel_blend_mode;
477499
unsigned int ignore_pixel_alpha = 0;
478500
unsigned int con;
479-
bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
480-
union overlay_pitch {
481-
struct split_pitch {
482-
u16 lsb;
483-
u16 msb;
484-
} split_pitch;
485-
u32 pitch;
486-
} overlay_pitch;
487-
488-
overlay_pitch.pitch = pitch;
489501

490502
if (!pending->enable) {
491503
mtk_ovl_layer_off(dev, idx, cmdq_pkt);
@@ -513,22 +525,30 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
513525
ignore_pixel_alpha = OVL_CONST_BLEND;
514526
}
515527

516-
if (pending->rotation & DRM_MODE_REFLECT_Y) {
528+
/*
529+
* Treat rotate 180 as flip x + flip y, and XOR the original rotation value
530+
* to flip x + flip y to support both in the same time.
531+
*/
532+
if (rotation & DRM_MODE_ROTATE_180)
533+
rotation ^= DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
534+
535+
if (rotation & DRM_MODE_REFLECT_Y) {
517536
con |= OVL_CON_VIRT_FLIP;
518537
addr += (pending->height - 1) * pending->pitch;
519538
}
520539

521-
if (pending->rotation & DRM_MODE_REFLECT_X) {
540+
if (rotation & DRM_MODE_REFLECT_X) {
522541
con |= OVL_CON_HORZ_FLIP;
523542
addr += pending->pitch - 1;
524543
}
525544

526545
if (ovl->data->supports_afbc)
527-
mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc);
546+
mtk_ovl_set_afbc(ovl, cmdq_pkt, idx,
547+
pending->modifier != DRM_FORMAT_MOD_LINEAR);
528548

529549
mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
530550
DISP_REG_OVL_CON(idx));
531-
mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha,
551+
mtk_ddp_write_relaxed(cmdq_pkt, pitch_lsb | ignore_pixel_alpha,
532552
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx));
533553
mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
534554
DISP_REG_OVL_SRC_SIZE(idx));
@@ -537,19 +557,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
537557
mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs,
538558
DISP_REG_OVL_ADDR(ovl, idx));
539559

540-
if (is_afbc) {
541-
mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
542-
DISP_REG_OVL_HDR_ADDR(ovl, idx));
543-
mtk_ddp_write_relaxed(cmdq_pkt,
544-
OVL_PITCH_MSB_2ND_SUBBUF | overlay_pitch.split_pitch.msb,
545-
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
546-
mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
547-
DISP_REG_OVL_HDR_PITCH(ovl, idx));
548-
} else {
549-
mtk_ddp_write_relaxed(cmdq_pkt,
550-
overlay_pitch.split_pitch.msb,
551-
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
552-
}
560+
if (ovl->data->supports_afbc)
561+
mtk_ovl_afbc_layer_config(ovl, idx, pending, cmdq_pkt);
553562

554563
mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
555564
mtk_ovl_layer_on(dev, idx, cmdq_pkt);

drivers/gpu/drm/mediatek/mtk_dp.c

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -543,25 +543,28 @@ static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
543543
enum dp_pixelformat color_format)
544544
{
545545
u32 val;
546-
547-
/* update MISC0 */
548-
mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
549-
color_format << DP_TEST_COLOR_FORMAT_SHIFT,
550-
DP_TEST_COLOR_FORMAT_MASK);
546+
u32 misc0_color;
551547

552548
switch (color_format) {
553549
case DP_PIXELFORMAT_YUV422:
554550
val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422;
551+
misc0_color = DP_COLOR_FORMAT_YCbCr422;
555552
break;
556553
case DP_PIXELFORMAT_RGB:
557554
val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB;
555+
misc0_color = DP_COLOR_FORMAT_RGB;
558556
break;
559557
default:
560558
drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n",
561559
color_format);
562560
return -EINVAL;
563561
}
564562

563+
/* update MISC0 */
564+
mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
565+
misc0_color,
566+
DP_TEST_COLOR_FORMAT_MASK);
567+
565568
mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
566569
val, PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK);
567570
return 0;
@@ -2100,7 +2103,6 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
21002103
struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
21012104
enum drm_connector_status ret = connector_status_disconnected;
21022105
bool enabled = mtk_dp->enabled;
2103-
u8 sink_count = 0;
21042106

21052107
if (!mtk_dp->train_info.cable_plugged_in)
21062108
return ret;
@@ -2115,8 +2117,8 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
21152117
* function, we just need to check the HPD connection to check
21162118
* whether we connect to a sink device.
21172119
*/
2118-
drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
2119-
if (DP_GET_SINK_COUNT(sink_count))
2120+
2121+
if (drm_dp_read_sink_count(&mtk_dp->aux) > 0)
21202122
ret = connector_status_connected;
21212123

21222124
if (!enabled)
@@ -2408,12 +2410,19 @@ mtk_dp_bridge_mode_valid(struct drm_bridge *bridge,
24082410
{
24092411
struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
24102412
u32 bpp = info->color_formats & DRM_COLOR_FORMAT_YCBCR422 ? 16 : 24;
2411-
u32 rate = min_t(u32, drm_dp_max_link_rate(mtk_dp->rx_cap) *
2412-
drm_dp_max_lane_count(mtk_dp->rx_cap),
2413-
drm_dp_bw_code_to_link_rate(mtk_dp->max_linkrate) *
2414-
mtk_dp->max_lanes);
2413+
u32 lane_count_min = mtk_dp->train_info.lane_count;
2414+
u32 rate = drm_dp_bw_code_to_link_rate(mtk_dp->train_info.link_rate) *
2415+
lane_count_min;
24152416

2416-
if (rate < mode->clock * bpp / 8)
2417+
/*
2418+
*FEC overhead is approximately 2.4% from DP 1.4a spec 2.2.1.4.2.
2419+
*The down-spread amplitude shall either be disabled (0.0%) or up
2420+
*to 0.5% from 1.4a 3.5.2.6. Add up to approximately 3% total overhead.
2421+
*
2422+
*Because rate is already divided by 10,
2423+
*mode->clock does not need to be multiplied by 10
2424+
*/
2425+
if ((rate * 97 / 100) < (mode->clock * bpp / 8))
24172426
return MODE_CLOCK_HIGH;
24182427

24192428
return MODE_OK;
@@ -2454,10 +2463,9 @@ static u32 *mtk_dp_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
24542463
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
24552464
struct drm_display_info *display_info =
24562465
&conn_state->connector->display_info;
2457-
u32 rate = min_t(u32, drm_dp_max_link_rate(mtk_dp->rx_cap) *
2458-
drm_dp_max_lane_count(mtk_dp->rx_cap),
2459-
drm_dp_bw_code_to_link_rate(mtk_dp->max_linkrate) *
2460-
mtk_dp->max_lanes);
2466+
u32 lane_count_min = mtk_dp->train_info.lane_count;
2467+
u32 rate = drm_dp_bw_code_to_link_rate(mtk_dp->train_info.link_rate) *
2468+
lane_count_min;
24612469

24622470
*num_input_fmts = 0;
24632471

@@ -2466,8 +2474,8 @@ static u32 *mtk_dp_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
24662474
* datarate of YUV422 and sink device supports YUV422, we output YUV422
24672475
* format. Use this condition, we can support more resolution.
24682476
*/
2469-
if ((rate < (mode->clock * 24 / 8)) &&
2470-
(rate > (mode->clock * 16 / 8)) &&
2477+
if (((rate * 97 / 100) < (mode->clock * 24 / 8)) &&
2478+
((rate * 97 / 100) > (mode->clock * 16 / 8)) &&
24712479
(display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
24722480
input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL);
24732481
if (!input_fmts)

drivers/gpu/drm/mediatek/mtk_drm_drv.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,11 +373,12 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
373373
struct mtk_drm_private *temp_drm_priv;
374374
struct device_node *phandle = dev->parent->of_node;
375375
const struct of_device_id *of_id;
376+
struct device_node *node;
376377
struct device *drm_dev;
377378
unsigned int cnt = 0;
378379
int i, j;
379380

380-
for_each_child_of_node_scoped(phandle->parent, node) {
381+
for_each_child_of_node(phandle->parent, node) {
381382
struct platform_device *pdev;
382383

383384
of_id = of_match_node(mtk_drm_of_ids, node);
@@ -406,8 +407,10 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
406407
if (temp_drm_priv->mtk_drm_bound)
407408
cnt++;
408409

409-
if (cnt == MAX_CRTC)
410+
if (cnt == MAX_CRTC) {
411+
of_node_put(node);
410412
break;
413+
}
411414
}
412415

413416
if (drm_priv->data->mmsys_dev_num == cnt) {
@@ -673,6 +676,8 @@ static int mtk_drm_bind(struct device *dev)
673676
err_free:
674677
private->drm = NULL;
675678
drm_dev_put(drm);
679+
for (i = 0; i < private->data->mmsys_dev_num; i++)
680+
private->all_drm_private[i]->drm = NULL;
676681
return ret;
677682
}
678683

@@ -900,7 +905,7 @@ static int mtk_drm_of_ddp_path_build_one(struct device *dev, enum mtk_crtc_path
900905
const unsigned int **out_path,
901906
unsigned int *out_path_len)
902907
{
903-
struct device_node *next, *prev, *vdo = dev->parent->of_node;
908+
struct device_node *next = NULL, *prev, *vdo = dev->parent->of_node;
904909
unsigned int temp_path[DDP_COMPONENT_DRM_ID_MAX] = { 0 };
905910
unsigned int *final_ddp_path;
906911
unsigned short int idx = 0;
@@ -1089,7 +1094,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
10891094
/* No devicetree graphs support: go with hardcoded paths if present */
10901095
dev_dbg(dev, "Using hardcoded paths for MMSYS %u\n", mtk_drm_data->mmsys_id);
10911096
private->data = mtk_drm_data;
1092-
};
1097+
}
10931098

10941099
private->all_drm_private = devm_kmalloc_array(dev, private->data->mmsys_dev_num,
10951100
sizeof(*private->all_drm_private),

0 commit comments

Comments
 (0)