Skip to content

Commit 2847b66

Browse files
committed
Merge tag 'mediatek-drm-next-6.2' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux into drm-next
Mediatek DRM Next for Linux 6.2 1. Fixup of dpi and hdmi 2. Move panel connector to head 3. Add MT8188 dpi support 4. Add MT8195 AFBC support Signed-off-by: Dave Airlie <[email protected]> From: Chun-Kuang Hu <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 9040ef6 + 76cdcb8 commit 2847b66

File tree

7 files changed

+170
-14
lines changed

7 files changed

+170
-14
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ properties:
2323
- mediatek,mt8173-dpi
2424
- mediatek,mt8183-dpi
2525
- mediatek,mt8186-dpi
26+
- mediatek,mt8188-dp-intf
2627
- mediatek,mt8192-dpi
2728
- mediatek,mt8195-dp-intf
2829

drivers/gpu/drm/mediatek/mtk_disp_ovl.c

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,22 @@
2929
#define DISP_REG_OVL_DATAPATH_CON 0x0024
3030
#define OVL_LAYER_SMI_ID_EN BIT(0)
3131
#define OVL_BGCLR_SEL_IN BIT(2)
32+
#define OVL_LAYER_AFBC_EN(n) BIT(4+n)
3233
#define DISP_REG_OVL_ROI_BGCLR 0x0028
3334
#define DISP_REG_OVL_SRC_CON 0x002c
3435
#define DISP_REG_OVL_CON(n) (0x0030 + 0x20 * (n))
3536
#define DISP_REG_OVL_SRC_SIZE(n) (0x0038 + 0x20 * (n))
3637
#define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n))
38+
#define DISP_REG_OVL_PITCH_MSB(n) (0x0040 + 0x20 * (n))
39+
#define OVL_PITCH_MSB_2ND_SUBBUF BIT(16)
3740
#define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n))
3841
#define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n))
3942
#define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n))
4043
#define DISP_REG_OVL_ADDR_MT2701 0x0040
4144
#define DISP_REG_OVL_ADDR_MT8173 0x0f40
4245
#define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n))
46+
#define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04)
47+
#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x08)
4348

4449
#define GMC_THRESHOLD_BITS 16
4550
#define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4)
@@ -67,6 +72,7 @@ struct mtk_disp_ovl_data {
6772
unsigned int layer_nr;
6873
bool fmt_rgb565_is_0;
6974
bool smi_id_en;
75+
bool supports_afbc;
7076
};
7177

7278
/*
@@ -172,7 +178,14 @@ void mtk_ovl_stop(struct device *dev)
172178
reg = reg & ~OVL_LAYER_SMI_ID_EN;
173179
writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
174180
}
181+
}
175182

183+
static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt,
184+
int idx, bool enabled)
185+
{
186+
mtk_ddp_write_mask(cmdq_pkt, enabled ? OVL_LAYER_AFBC_EN(idx) : 0,
187+
&ovl->cmdq_reg, ovl->regs,
188+
DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx));
176189
}
177190

178191
void mtk_ovl_config(struct device *dev, unsigned int w,
@@ -310,11 +323,23 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
310323
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
311324
struct mtk_plane_pending_state *pending = &state->pending;
312325
unsigned int addr = pending->addr;
313-
unsigned int pitch = pending->pitch & 0xffff;
326+
unsigned int hdr_addr = pending->hdr_addr;
327+
unsigned int pitch = pending->pitch;
328+
unsigned int hdr_pitch = pending->hdr_pitch;
314329
unsigned int fmt = pending->format;
315330
unsigned int offset = (pending->y << 16) | pending->x;
316331
unsigned int src_size = (pending->height << 16) | pending->width;
317332
unsigned int con;
333+
bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
334+
union overlay_pitch {
335+
struct split_pitch {
336+
u16 lsb;
337+
u16 msb;
338+
} split_pitch;
339+
u32 pitch;
340+
} overlay_pitch;
341+
342+
overlay_pitch.pitch = pitch;
318343

319344
if (!pending->enable) {
320345
mtk_ovl_layer_off(dev, idx, cmdq_pkt);
@@ -335,9 +360,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
335360
addr += pending->pitch - 1;
336361
}
337362

363+
if (ovl->data->supports_afbc)
364+
mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc);
365+
338366
mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
339367
DISP_REG_OVL_CON(idx));
340-
mtk_ddp_write_relaxed(cmdq_pkt, pitch, &ovl->cmdq_reg, ovl->regs,
368+
mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, &ovl->cmdq_reg, ovl->regs,
341369
DISP_REG_OVL_PITCH(idx));
342370
mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
343371
DISP_REG_OVL_SRC_SIZE(idx));
@@ -346,6 +374,20 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
346374
mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs,
347375
DISP_REG_OVL_ADDR(ovl, idx));
348376

377+
if (is_afbc) {
378+
mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
379+
DISP_REG_OVL_HDR_ADDR(ovl, idx));
380+
mtk_ddp_write_relaxed(cmdq_pkt,
381+
OVL_PITCH_MSB_2ND_SUBBUF | overlay_pitch.split_pitch.msb,
382+
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
383+
mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
384+
DISP_REG_OVL_HDR_PITCH(ovl, idx));
385+
} else {
386+
mtk_ddp_write_relaxed(cmdq_pkt,
387+
overlay_pitch.split_pitch.msb,
388+
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
389+
}
390+
349391
mtk_ovl_layer_on(dev, idx, cmdq_pkt);
350392
}
351393

@@ -492,6 +534,15 @@ static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = {
492534
.smi_id_en = true,
493535
};
494536

537+
static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
538+
.addr = DISP_REG_OVL_ADDR_MT8173,
539+
.gmc_bits = 10,
540+
.layer_nr = 4,
541+
.fmt_rgb565_is_0 = true,
542+
.smi_id_en = true,
543+
.supports_afbc = true,
544+
};
545+
495546
static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
496547
{ .compatible = "mediatek,mt2701-disp-ovl",
497548
.data = &mt2701_ovl_driver_data},
@@ -505,6 +556,8 @@ static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
505556
.data = &mt8192_ovl_driver_data},
506557
{ .compatible = "mediatek,mt8192-disp-ovl-2l",
507558
.data = &mt8192_ovl_2l_driver_data},
559+
{ .compatible = "mediatek,mt8195-disp-ovl",
560+
.data = &mt8195_ovl_driver_data},
508561
{},
509562
};
510563
MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match);

drivers/gpu/drm/mediatek/mtk_dpi.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,6 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
461461
if (--dpi->refcount != 0)
462462
return;
463463

464-
if (dpi->pinctrl && dpi->pins_gpio)
465-
pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
466-
467464
mtk_dpi_disable(dpi);
468465
clk_disable_unprepare(dpi->pixel_clk);
469466
clk_disable_unprepare(dpi->engine_clk);
@@ -488,9 +485,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
488485
goto err_pixel;
489486
}
490487

491-
if (dpi->pinctrl && dpi->pins_dpi)
492-
pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
493-
494488
return 0;
495489

496490
err_pixel:
@@ -721,12 +715,18 @@ static void mtk_dpi_bridge_disable(struct drm_bridge *bridge)
721715
struct mtk_dpi *dpi = bridge_to_dpi(bridge);
722716

723717
mtk_dpi_power_off(dpi);
718+
719+
if (dpi->pinctrl && dpi->pins_gpio)
720+
pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
724721
}
725722

726723
static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
727724
{
728725
struct mtk_dpi *dpi = bridge_to_dpi(bridge);
729726

727+
if (dpi->pinctrl && dpi->pins_dpi)
728+
pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
729+
730730
mtk_dpi_power_on(dpi);
731731
mtk_dpi_set_display_mode(dpi, &dpi->mode);
732732
mtk_dpi_enable(dpi);
@@ -929,6 +929,20 @@ static const struct mtk_dpi_conf mt8183_conf = {
929929
.csc_enable_bit = CSC_ENABLE,
930930
};
931931

932+
static const struct mtk_dpi_conf mt8188_dpintf_conf = {
933+
.cal_factor = mt8195_dpintf_calculate_factor,
934+
.max_clock_khz = 600000,
935+
.output_fmts = mt8195_output_fmts,
936+
.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
937+
.pixels_per_iter = 4,
938+
.input_2pixel = false,
939+
.dimension_mask = DPINTF_HPW_MASK,
940+
.hvsize_mask = DPINTF_HSIZE_MASK,
941+
.channel_swap_shift = DPINTF_CH_SWAP,
942+
.yuv422_en_bit = DPINTF_YUV422_EN,
943+
.csc_enable_bit = DPINTF_CSC_ENABLE,
944+
};
945+
932946
static const struct mtk_dpi_conf mt8192_conf = {
933947
.cal_factor = mt8183_calculate_factor,
934948
.reg_h_fre_con = 0xe0,
@@ -1079,6 +1093,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
10791093
{ .compatible = "mediatek,mt8183-dpi",
10801094
.data = &mt8183_conf,
10811095
},
1096+
{ .compatible = "mediatek,mt8188-dp-intf",
1097+
.data = &mt8188_dpintf_conf,
1098+
},
10821099
{ .compatible = "mediatek,mt8192-dpi",
10831100
.data = &mt8192_conf,
10841101
},

drivers/gpu/drm/mediatek/mtk_drm_drv.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,12 @@ static int mtk_drm_kms_init(struct drm_device *drm)
386386
if (ret)
387387
goto put_mutex_dev;
388388

389+
/*
390+
* Ensure internal panels are at the top of the connector list before
391+
* crtc creation.
392+
*/
393+
drm_helper_move_panel_connectors_to_head(drm);
394+
389395
/*
390396
* We currently support two fixed data streams, each optional,
391397
* and each statically assigned to a crtc:
@@ -631,6 +637,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
631637
.data = (void *)MTK_DPI },
632638
{ .compatible = "mediatek,mt8183-dpi",
633639
.data = (void *)MTK_DPI },
640+
{ .compatible = "mediatek,mt8188-dp-intf",
641+
.data = (void *)MTK_DP_INTF },
634642
{ .compatible = "mediatek,mt8192-dpi",
635643
.data = (void *)MTK_DPI },
636644
{ .compatible = "mediatek,mt8195-dp-intf",

drivers/gpu/drm/mediatek/mtk_drm_plane.c

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <drm/drm_fourcc.h>
1212
#include <drm/drm_framebuffer.h>
1313
#include <drm/drm_gem_atomic_helper.h>
14+
#include <linux/align.h>
1415

1516
#include "mtk_drm_crtc.h"
1617
#include "mtk_drm_ddp_comp.h"
@@ -32,6 +33,14 @@ static const u32 formats[] = {
3233
DRM_FORMAT_YUYV,
3334
};
3435

36+
static const u64 modifiers[] = {
37+
DRM_FORMAT_MOD_LINEAR,
38+
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
39+
AFBC_FORMAT_MOD_SPLIT |
40+
AFBC_FORMAT_MOD_SPARSE),
41+
DRM_FORMAT_MOD_INVALID,
42+
};
43+
3544
static void mtk_plane_reset(struct drm_plane *plane)
3645
{
3746
struct mtk_plane_state *state;
@@ -51,6 +60,7 @@ static void mtk_plane_reset(struct drm_plane *plane)
5160

5261
state->base.plane = plane;
5362
state->pending.format = DRM_FORMAT_RGB565;
63+
state->pending.modifier = DRM_FORMAT_MOD_LINEAR;
5464
}
5565

5666
static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane)
@@ -71,6 +81,32 @@ static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane
7181
return &state->base;
7282
}
7383

84+
static bool mtk_plane_format_mod_supported(struct drm_plane *plane,
85+
uint32_t format,
86+
uint64_t modifier)
87+
{
88+
if (modifier == DRM_FORMAT_MOD_LINEAR)
89+
return true;
90+
91+
if (modifier != DRM_FORMAT_MOD_ARM_AFBC(
92+
AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
93+
AFBC_FORMAT_MOD_SPLIT |
94+
AFBC_FORMAT_MOD_SPARSE))
95+
return false;
96+
97+
if (format != DRM_FORMAT_XRGB8888 &&
98+
format != DRM_FORMAT_ARGB8888 &&
99+
format != DRM_FORMAT_BGRX8888 &&
100+
format != DRM_FORMAT_BGRA8888 &&
101+
format != DRM_FORMAT_ABGR8888 &&
102+
format != DRM_FORMAT_XBGR8888 &&
103+
format != DRM_FORMAT_RGB888 &&
104+
format != DRM_FORMAT_BGR888)
105+
return false;
106+
107+
return true;
108+
}
109+
74110
static void mtk_drm_plane_destroy_state(struct drm_plane *plane,
75111
struct drm_plane_state *state)
76112
{
@@ -119,21 +155,52 @@ static void mtk_plane_update_new_state(struct drm_plane_state *new_state,
119155
struct drm_gem_object *gem;
120156
struct mtk_drm_gem_obj *mtk_gem;
121157
unsigned int pitch, format;
158+
u64 modifier;
122159
dma_addr_t addr;
160+
dma_addr_t hdr_addr = 0;
161+
unsigned int hdr_pitch = 0;
123162

124163
gem = fb->obj[0];
125164
mtk_gem = to_mtk_gem_obj(gem);
126165
addr = mtk_gem->dma_addr;
127166
pitch = fb->pitches[0];
128167
format = fb->format->format;
168+
modifier = fb->modifier;
129169

130-
addr += (new_state->src.x1 >> 16) * fb->format->cpp[0];
131-
addr += (new_state->src.y1 >> 16) * pitch;
170+
if (modifier == DRM_FORMAT_MOD_LINEAR) {
171+
addr += (new_state->src.x1 >> 16) * fb->format->cpp[0];
172+
addr += (new_state->src.y1 >> 16) * pitch;
173+
} else {
174+
int width_in_blocks = ALIGN(fb->width, AFBC_DATA_BLOCK_WIDTH)
175+
/ AFBC_DATA_BLOCK_WIDTH;
176+
int height_in_blocks = ALIGN(fb->height, AFBC_DATA_BLOCK_HEIGHT)
177+
/ AFBC_DATA_BLOCK_HEIGHT;
178+
int x_offset_in_blocks = (new_state->src.x1 >> 16) / AFBC_DATA_BLOCK_WIDTH;
179+
int y_offset_in_blocks = (new_state->src.y1 >> 16) / AFBC_DATA_BLOCK_HEIGHT;
180+
int hdr_size;
181+
182+
hdr_pitch = width_in_blocks * AFBC_HEADER_BLOCK_SIZE;
183+
pitch = width_in_blocks * AFBC_DATA_BLOCK_WIDTH *
184+
AFBC_DATA_BLOCK_HEIGHT * fb->format->cpp[0];
185+
186+
hdr_size = ALIGN(hdr_pitch * height_in_blocks, AFBC_HEADER_ALIGNMENT);
187+
188+
hdr_addr = addr + hdr_pitch * y_offset_in_blocks +
189+
AFBC_HEADER_BLOCK_SIZE * x_offset_in_blocks;
190+
/* The data plane is offset by 1 additional block. */
191+
addr = addr + hdr_size +
192+
pitch * y_offset_in_blocks +
193+
AFBC_DATA_BLOCK_WIDTH * AFBC_DATA_BLOCK_HEIGHT *
194+
fb->format->cpp[0] * (x_offset_in_blocks + 1);
195+
}
132196

133197
mtk_plane_state->pending.enable = true;
134198
mtk_plane_state->pending.pitch = pitch;
199+
mtk_plane_state->pending.hdr_pitch = hdr_pitch;
135200
mtk_plane_state->pending.format = format;
201+
mtk_plane_state->pending.modifier = modifier;
136202
mtk_plane_state->pending.addr = addr;
203+
mtk_plane_state->pending.hdr_addr = hdr_addr;
137204
mtk_plane_state->pending.x = new_state->dst.x1;
138205
mtk_plane_state->pending.y = new_state->dst.y1;
139206
mtk_plane_state->pending.width = drm_rect_width(&new_state->dst);
@@ -172,6 +239,7 @@ static const struct drm_plane_funcs mtk_plane_funcs = {
172239
.reset = mtk_plane_reset,
173240
.atomic_duplicate_state = mtk_plane_duplicate_state,
174241
.atomic_destroy_state = mtk_drm_plane_destroy_state,
242+
.format_mod_supported = mtk_plane_format_mod_supported,
175243
};
176244

177245
static int mtk_plane_atomic_check(struct drm_plane *plane,
@@ -253,7 +321,7 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
253321

254322
err = drm_universal_plane_init(dev, plane, possible_crtcs,
255323
&mtk_plane_funcs, formats,
256-
ARRAY_SIZE(formats), NULL, type, NULL);
324+
ARRAY_SIZE(formats), modifiers, type, NULL);
257325
if (err) {
258326
DRM_ERROR("failed to initialize plane\n");
259327
return err;

drivers/gpu/drm/mediatek/mtk_drm_plane.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,20 @@
1010
#include <drm/drm_crtc.h>
1111
#include <linux/types.h>
1212

13+
#define AFBC_DATA_BLOCK_WIDTH 32
14+
#define AFBC_DATA_BLOCK_HEIGHT 8
15+
#define AFBC_HEADER_BLOCK_SIZE 16
16+
#define AFBC_HEADER_ALIGNMENT 1024
17+
1318
struct mtk_plane_pending_state {
1419
bool config;
1520
bool enable;
1621
dma_addr_t addr;
22+
dma_addr_t hdr_addr;
1723
unsigned int pitch;
24+
unsigned int hdr_pitch;
1825
unsigned int format;
26+
unsigned long long modifier;
1927
unsigned int x;
2028
unsigned int y;
2129
unsigned int width;

0 commit comments

Comments
 (0)