Skip to content

Commit 5c82e61

Browse files
MarijnS95jenneronkcxt
authored
Support DSC (Display Stream Compression) panels (#25)
Co-authored-by: jenneron <[email protected]> Co-authored-by: Caleb Connolly <[email protected]>
1 parent 89c5d08 commit 5c82e61

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

driver.py

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import simple
88
import wrap
99
from generator import Options, GpioFlag
10-
from panel import Panel, BacklightControl, CommandSequence
10+
from panel import Panel, BacklightControl, CommandSequence, CompressionMode
1111

1212

1313
def generate_includes(p: Panel, options: Options) -> str:
@@ -31,6 +31,9 @@ def generate_includes(p: Panel, options: Options) -> str:
3131
includes['linux'].add('regulator/consumer.h')
3232
if p.backlight == BacklightControl.DCS or options.backlight_fallback_dcs:
3333
includes['linux'].add('backlight.h')
34+
if p.compression_mode == CompressionMode.DSC:
35+
includes['drm'].add('display/drm_dsc.h')
36+
includes['drm'].add('display/drm_dsc_helper.h')
3437

3538
for cmd in p.cmds.values():
3639
if 'MIPI_DCS_' in cmd.generated:
@@ -55,6 +58,9 @@ def generate_struct(p: Panel, options: Options) -> str:
5558
'struct mipi_dsi_device *dsi',
5659
]
5760

61+
if p.compression_mode == CompressionMode.DSC:
62+
variables.append('struct drm_dsc_config dsc')
63+
5864
if options.regulator:
5965
if len(options.regulator) > 1:
6066
variables.append(f'struct regulator_bulk_data supplies[{len(options.regulator)}]')
@@ -164,6 +170,14 @@ def generate_prepare(p: Panel, options: Options) -> str:
164170
{{
165171
struct {p.short_id} *ctx = to_{p.short_id}(panel);
166172
struct device *dev = &ctx->dsi->dev;
173+
'''
174+
175+
if p.compression_mode == CompressionMode.DSC:
176+
s += '''\
177+
struct drm_dsc_picture_parameter_set pps;
178+
'''
179+
180+
s += f'''\
167181
int ret;
168182
169183
if (ctx->prepared)
@@ -197,10 +211,31 @@ def generate_prepare(p: Panel, options: Options) -> str:
197211
dev_err(dev, "Failed to initialize panel: %d\\n", ret);{generate_cleanup(p, options, 2)}
198212
return ret;
199213
}}
214+
'''
215+
216+
if p.compression_mode == CompressionMode.DSC:
217+
s += '''
218+
drm_dsc_pps_payload_pack(&pps, &ctx->dsc);
219+
220+
ret = mipi_dsi_picture_parameter_set(ctx->dsi, &pps);
221+
if (ret < 0) {
222+
dev_err(panel->dev, "failed to transmit PPS: %d\\n", ret);
223+
return ret;
224+
}
225+
226+
ret = mipi_dsi_compression_mode(ctx->dsi, true);
227+
if (ret < 0) {
228+
dev_err(dev, "failed to enable compression mode: %d\\n", ret);
229+
return ret;
230+
}
231+
232+
msleep(28); /* TODO: Is this panel-dependent? */
233+
'''
200234

235+
s += '''
201236
ctx->prepared = true;
202237
return 0;
203-
}}
238+
}
204239
'''
205240
return s
206241

@@ -325,6 +360,9 @@ def generate_probe(p: Panel, options: Options) -> str:
325360
{{
326361
struct device *dev = &dsi->dev;
327362
struct {p.short_id} *ctx;
363+
'''
364+
365+
s += f'''\
328366
int ret;
329367
330368
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
@@ -407,14 +445,40 @@ def generate_probe(p: Panel, options: Options) -> str:
407445

408446
s += '''
409447
drm_panel_add(&ctx->panel);
448+
'''
449+
450+
if p.compression_mode == CompressionMode.DSC:
451+
s += f'''
452+
/* This panel only supports DSC; unconditionally enable it */
453+
dsi->dsc = &ctx->dsc;
454+
455+
ctx->dsc.dsc_version_major = {(p.dsc_version >> 4) & 0xf};
456+
ctx->dsc.dsc_version_minor = {p.dsc_version & 0xf};
457+
458+
/* TODO: Pass slice_per_pkt = {p.dsc_slice_per_pkt} */
459+
ctx->dsc.slice_height = {p.dsc_slice_height};
460+
ctx->dsc.slice_width = {p.dsc_slice_width};
461+
/*
462+
* TODO: hdisplay should be read from the selected mode once
463+
* it is passed back to drm_panel (in prepare?)
464+
*/
465+
WARN_ON({p.h.px} % ctx->dsc.slice_width);
466+
ctx->dsc.slice_count = {p.h.px} / ctx->dsc.slice_width;
467+
ctx->dsc.bits_per_component = {p.dsc_bit_per_component};
468+
ctx->dsc.bits_per_pixel = {p.dsc_bit_per_pixel} << 4; /* 4 fractional bits */
469+
ctx->dsc.block_pred_enable = {"true" if p.dsc_block_prediction else "false"};
470+
'''
410471

472+
s += '''
411473
ret = mipi_dsi_attach(dsi);
412474
if (ret < 0) {
413475
dev_err(dev, "Failed to attach to DSI host: %d\\n", ret);
414476
drm_panel_remove(&ctx->panel);
415477
return ret;
416478
}
479+
'''
417480

481+
s += '''
418482
return 0;
419483
}
420484
'''

panel.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ class BacklightControl(Enum):
9797
SAMSUNG_PWM = 'bl_ctrl_ss_pwm'
9898

9999

100+
@unique
101+
class CompressionMode(Enum):
102+
DSC = "dsc"
103+
104+
100105
class Dimension:
101106
@unique
102107
class Type(Enum):
@@ -308,6 +313,21 @@ def __init__(self, name: str, fdt: Fdt2, node: int) -> None:
308313
self.lp11_init = fdt.getprop_or_none(node, 'qcom,mdss-dsi-lp11-init') is not None
309314
self.init_delay = fdt.getprop_uint32(node, 'qcom,mdss-dsi-init-delay-us')
310315

316+
# Display Stream Compression
317+
compression_mode = fdt.getprop_or_none(mode_node, 'qcom,compression-mode')
318+
self.compression_mode = CompressionMode(compression_mode.as_str()) if compression_mode else None
319+
320+
if self.compression_mode == CompressionMode.DSC:
321+
self.dsc_slice_height = fdt.getprop(mode_node, 'qcom,mdss-dsc-slice-height').as_uint32()
322+
self.dsc_slice_width = fdt.getprop(mode_node, 'qcom,mdss-dsc-slice-width').as_uint32()
323+
self.dsc_slice_per_pkt = fdt.getprop(mode_node, 'qcom,mdss-dsc-slice-per-pkt').as_uint32()
324+
self.dsc_bit_per_component = fdt.getprop(mode_node, 'qcom,mdss-dsc-bit-per-component').as_uint32()
325+
self.dsc_bit_per_pixel = fdt.getprop(mode_node, 'qcom,mdss-dsc-bit-per-pixel').as_uint32()
326+
self.dsc_block_prediction = fdt.getprop_or_none(mode_node, 'qcom,mdss-dsc-block-prediction-enable') is not None
327+
328+
self.dsc_version = fdt.getprop_uint32(mode_node, 'qcom,mdss-dsc-version', default=0x11)
329+
self.dsc_scr_version = fdt.getprop_uint32(mode_node, 'qcom,mdss-dsc-scr-version', default=0)
330+
311331
@staticmethod
312332
def parse(fdt: Fdt2, node: int) -> Panel:
313333
name = fdt.getprop_or_none(node, 'qcom,mdss-dsi-panel-name')

0 commit comments

Comments
 (0)