1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright 2017 Linaro Ltd.
4 * Copyright 2017 ZTE Corporation.
8 #include <linux/component.h>
9 #include <linux/mfd/syscon.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/regmap.h>
14 #include <drm/drm_atomic_helper.h>
15 #include <drm/drm_print.h>
16 #include <drm/drm_probe_helper.h>
17 #include <drm/drm_simple_kms_helper.h>
19 #include "zx_drm_drv.h"
20 #include "zx_tvenc_regs.h"
23 struct zx_tvenc_pwrctrl
{
24 struct regmap
*regmap
;
30 struct drm_connector connector
;
31 struct drm_encoder encoder
;
34 const struct vou_inf
*inf
;
35 struct zx_tvenc_pwrctrl pwrctrl
;
38 #define to_zx_tvenc(x) container_of(x, struct zx_tvenc, x)
40 struct zx_tvenc_mode
{
41 struct drm_display_mode mode
;
50 u32 line_timing_param
;
52 u32 blank_black_level
;
55 u32 sub_carrier_phase1
;
56 u32 phase_line_incr_cvbs
;
60 * The CRM cannot directly provide a suitable frequency, and we have to
61 * ask a multiplied rate from CRM and use the divider in VOU to get the
64 #define TVENC_CLOCK_MULTIPLIER 4
66 static const struct zx_tvenc_mode tvenc_mode_pal
= {
68 .clock
= 13500 * TVENC_CLOCK_MULTIPLIER
,
70 .hsync_start
= 720 + 12,
71 .hsync_end
= 720 + 12 + 2,
72 .htotal
= 720 + 12 + 2 + 130,
74 .vsync_start
= 576 + 2,
75 .vsync_end
= 576 + 2 + 2,
76 .vtotal
= 576 + 2 + 2 + 20,
77 .flags
= DRM_MODE_FLAG_NHSYNC
| DRM_MODE_FLAG_NVSYNC
|
78 DRM_MODE_FLAG_INTERLACE
,
80 .video_info
= 0x00040040,
81 .video_res
= 0x05a9c760,
82 .field1_param
= 0x0004d416,
83 .field2_param
= 0x0009b94f,
84 .burst_line_odd1
= 0x0004d406,
85 .burst_line_even1
= 0x0009b53e,
86 .burst_line_odd2
= 0x0004d805,
87 .burst_line_even2
= 0x0009b93f,
88 .line_timing_param
= 0x06a96fdf,
89 .weight_value
= 0x00c188a0,
90 .blank_black_level
= 0x0000fcfc,
91 .burst_level
= 0x00001595,
92 .control_param
= 0x00000001,
93 .sub_carrier_phase1
= 0x1504c566,
94 .phase_line_incr_cvbs
= 0xc068db8c,
97 static const struct zx_tvenc_mode tvenc_mode_ntsc
= {
99 .clock
= 13500 * TVENC_CLOCK_MULTIPLIER
,
101 .hsync_start
= 720 + 16,
102 .hsync_end
= 720 + 16 + 2,
103 .htotal
= 720 + 16 + 2 + 120,
105 .vsync_start
= 480 + 3,
106 .vsync_end
= 480 + 3 + 2,
107 .vtotal
= 480 + 3 + 2 + 17,
108 .flags
= DRM_MODE_FLAG_NHSYNC
| DRM_MODE_FLAG_NVSYNC
|
109 DRM_MODE_FLAG_INTERLACE
,
111 .video_info
= 0x00040080,
112 .video_res
= 0x05a8375a,
113 .field1_param
= 0x00041817,
114 .field2_param
= 0x0008351e,
115 .burst_line_odd1
= 0x00041006,
116 .burst_line_even1
= 0x0008290d,
117 .burst_line_odd2
= 0x00000000,
118 .burst_line_even2
= 0x00000000,
119 .line_timing_param
= 0x06a8ef9e,
120 .weight_value
= 0x00b68197,
121 .blank_black_level
= 0x0000f0f0,
122 .burst_level
= 0x0000009c,
123 .control_param
= 0x00000001,
124 .sub_carrier_phase1
= 0x10f83e10,
125 .phase_line_incr_cvbs
= 0x80000000,
128 static const struct zx_tvenc_mode
*tvenc_modes
[] = {
133 static const struct zx_tvenc_mode
*
134 zx_tvenc_find_zmode(struct drm_display_mode
*mode
)
138 for (i
= 0; i
< ARRAY_SIZE(tvenc_modes
); i
++) {
139 const struct zx_tvenc_mode
*zmode
= tvenc_modes
[i
];
141 if (drm_mode_equal(mode
, &zmode
->mode
))
148 static void zx_tvenc_encoder_mode_set(struct drm_encoder
*encoder
,
149 struct drm_display_mode
*mode
,
150 struct drm_display_mode
*adj_mode
)
152 struct zx_tvenc
*tvenc
= to_zx_tvenc(encoder
);
153 const struct zx_tvenc_mode
*zmode
;
154 struct vou_div_config configs
[] = {
155 { VOU_DIV_INF
, VOU_DIV_4
},
156 { VOU_DIV_TVENC
, VOU_DIV_1
},
157 { VOU_DIV_LAYER
, VOU_DIV_2
},
160 zx_vou_config_dividers(encoder
->crtc
, configs
, ARRAY_SIZE(configs
));
162 zmode
= zx_tvenc_find_zmode(mode
);
164 DRM_DEV_ERROR(tvenc
->dev
, "failed to find zmode\n");
168 zx_writel(tvenc
->mmio
+ VENC_VIDEO_INFO
, zmode
->video_info
);
169 zx_writel(tvenc
->mmio
+ VENC_VIDEO_RES
, zmode
->video_res
);
170 zx_writel(tvenc
->mmio
+ VENC_FIELD1_PARAM
, zmode
->field1_param
);
171 zx_writel(tvenc
->mmio
+ VENC_FIELD2_PARAM
, zmode
->field2_param
);
172 zx_writel(tvenc
->mmio
+ VENC_LINE_O_1
, zmode
->burst_line_odd1
);
173 zx_writel(tvenc
->mmio
+ VENC_LINE_E_1
, zmode
->burst_line_even1
);
174 zx_writel(tvenc
->mmio
+ VENC_LINE_O_2
, zmode
->burst_line_odd2
);
175 zx_writel(tvenc
->mmio
+ VENC_LINE_E_2
, zmode
->burst_line_even2
);
176 zx_writel(tvenc
->mmio
+ VENC_LINE_TIMING_PARAM
,
177 zmode
->line_timing_param
);
178 zx_writel(tvenc
->mmio
+ VENC_WEIGHT_VALUE
, zmode
->weight_value
);
179 zx_writel(tvenc
->mmio
+ VENC_BLANK_BLACK_LEVEL
,
180 zmode
->blank_black_level
);
181 zx_writel(tvenc
->mmio
+ VENC_BURST_LEVEL
, zmode
->burst_level
);
182 zx_writel(tvenc
->mmio
+ VENC_CONTROL_PARAM
, zmode
->control_param
);
183 zx_writel(tvenc
->mmio
+ VENC_SUB_CARRIER_PHASE1
,
184 zmode
->sub_carrier_phase1
);
185 zx_writel(tvenc
->mmio
+ VENC_PHASE_LINE_INCR_CVBS
,
186 zmode
->phase_line_incr_cvbs
);
189 static void zx_tvenc_encoder_enable(struct drm_encoder
*encoder
)
191 struct zx_tvenc
*tvenc
= to_zx_tvenc(encoder
);
192 struct zx_tvenc_pwrctrl
*pwrctrl
= &tvenc
->pwrctrl
;
194 /* Set bit to power up TVENC DAC */
195 regmap_update_bits(pwrctrl
->regmap
, pwrctrl
->reg
, pwrctrl
->mask
,
198 vou_inf_enable(VOU_TV_ENC
, encoder
->crtc
);
200 zx_writel(tvenc
->mmio
+ VENC_ENABLE
, 1);
203 static void zx_tvenc_encoder_disable(struct drm_encoder
*encoder
)
205 struct zx_tvenc
*tvenc
= to_zx_tvenc(encoder
);
206 struct zx_tvenc_pwrctrl
*pwrctrl
= &tvenc
->pwrctrl
;
208 zx_writel(tvenc
->mmio
+ VENC_ENABLE
, 0);
210 vou_inf_disable(VOU_TV_ENC
, encoder
->crtc
);
212 /* Clear bit to power down TVENC DAC */
213 regmap_update_bits(pwrctrl
->regmap
, pwrctrl
->reg
, pwrctrl
->mask
, 0);
216 static const struct drm_encoder_helper_funcs zx_tvenc_encoder_helper_funcs
= {
217 .enable
= zx_tvenc_encoder_enable
,
218 .disable
= zx_tvenc_encoder_disable
,
219 .mode_set
= zx_tvenc_encoder_mode_set
,
222 static int zx_tvenc_connector_get_modes(struct drm_connector
*connector
)
224 struct zx_tvenc
*tvenc
= to_zx_tvenc(connector
);
225 struct device
*dev
= tvenc
->dev
;
228 for (i
= 0; i
< ARRAY_SIZE(tvenc_modes
); i
++) {
229 const struct zx_tvenc_mode
*zmode
= tvenc_modes
[i
];
230 struct drm_display_mode
*mode
;
232 mode
= drm_mode_duplicate(connector
->dev
, &zmode
->mode
);
234 DRM_DEV_ERROR(dev
, "failed to duplicate drm mode\n");
238 drm_mode_set_name(mode
);
239 drm_mode_probed_add(connector
, mode
);
245 static enum drm_mode_status
246 zx_tvenc_connector_mode_valid(struct drm_connector
*connector
,
247 struct drm_display_mode
*mode
)
249 struct zx_tvenc
*tvenc
= to_zx_tvenc(connector
);
250 const struct zx_tvenc_mode
*zmode
;
252 zmode
= zx_tvenc_find_zmode(mode
);
254 DRM_DEV_ERROR(tvenc
->dev
, "unsupported mode: %s\n", mode
->name
);
261 static struct drm_connector_helper_funcs zx_tvenc_connector_helper_funcs
= {
262 .get_modes
= zx_tvenc_connector_get_modes
,
263 .mode_valid
= zx_tvenc_connector_mode_valid
,
266 static const struct drm_connector_funcs zx_tvenc_connector_funcs
= {
267 .fill_modes
= drm_helper_probe_single_connector_modes
,
268 .destroy
= drm_connector_cleanup
,
269 .reset
= drm_atomic_helper_connector_reset
,
270 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
271 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
274 static int zx_tvenc_register(struct drm_device
*drm
, struct zx_tvenc
*tvenc
)
276 struct drm_encoder
*encoder
= &tvenc
->encoder
;
277 struct drm_connector
*connector
= &tvenc
->connector
;
280 * The tvenc is designed to use aux channel, as there is a deflicker
281 * block for the channel.
283 encoder
->possible_crtcs
= BIT(1);
285 drm_simple_encoder_init(drm
, encoder
, DRM_MODE_ENCODER_TVDAC
);
286 drm_encoder_helper_add(encoder
, &zx_tvenc_encoder_helper_funcs
);
288 connector
->interlace_allowed
= true;
290 drm_connector_init(drm
, connector
, &zx_tvenc_connector_funcs
,
291 DRM_MODE_CONNECTOR_Composite
);
292 drm_connector_helper_add(connector
, &zx_tvenc_connector_helper_funcs
);
294 drm_connector_attach_encoder(connector
, encoder
);
299 static int zx_tvenc_pwrctrl_init(struct zx_tvenc
*tvenc
)
301 struct zx_tvenc_pwrctrl
*pwrctrl
= &tvenc
->pwrctrl
;
302 struct device
*dev
= tvenc
->dev
;
303 struct of_phandle_args out_args
;
304 struct regmap
*regmap
;
307 ret
= of_parse_phandle_with_fixed_args(dev
->of_node
,
308 "zte,tvenc-power-control", 2, 0, &out_args
);
312 regmap
= syscon_node_to_regmap(out_args
.np
);
313 if (IS_ERR(regmap
)) {
314 ret
= PTR_ERR(regmap
);
318 pwrctrl
->regmap
= regmap
;
319 pwrctrl
->reg
= out_args
.args
[0];
320 pwrctrl
->mask
= out_args
.args
[1];
323 of_node_put(out_args
.np
);
327 static int zx_tvenc_bind(struct device
*dev
, struct device
*master
, void *data
)
329 struct platform_device
*pdev
= to_platform_device(dev
);
330 struct drm_device
*drm
= data
;
331 struct resource
*res
;
332 struct zx_tvenc
*tvenc
;
335 tvenc
= devm_kzalloc(dev
, sizeof(*tvenc
), GFP_KERNEL
);
340 dev_set_drvdata(dev
, tvenc
);
342 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
343 tvenc
->mmio
= devm_ioremap_resource(dev
, res
);
344 if (IS_ERR(tvenc
->mmio
)) {
345 ret
= PTR_ERR(tvenc
->mmio
);
346 DRM_DEV_ERROR(dev
, "failed to remap tvenc region: %d\n", ret
);
350 ret
= zx_tvenc_pwrctrl_init(tvenc
);
352 DRM_DEV_ERROR(dev
, "failed to init power control: %d\n", ret
);
356 ret
= zx_tvenc_register(drm
, tvenc
);
358 DRM_DEV_ERROR(dev
, "failed to register tvenc: %d\n", ret
);
365 static void zx_tvenc_unbind(struct device
*dev
, struct device
*master
,
371 static const struct component_ops zx_tvenc_component_ops
= {
372 .bind
= zx_tvenc_bind
,
373 .unbind
= zx_tvenc_unbind
,
376 static int zx_tvenc_probe(struct platform_device
*pdev
)
378 return component_add(&pdev
->dev
, &zx_tvenc_component_ops
);
381 static int zx_tvenc_remove(struct platform_device
*pdev
)
383 component_del(&pdev
->dev
, &zx_tvenc_component_ops
);
387 static const struct of_device_id zx_tvenc_of_match
[] = {
388 { .compatible
= "zte,zx296718-tvenc", },
391 MODULE_DEVICE_TABLE(of
, zx_tvenc_of_match
);
393 struct platform_driver zx_tvenc_driver
= {
394 .probe
= zx_tvenc_probe
,
395 .remove
= zx_tvenc_remove
,
398 .of_match_table
= zx_tvenc_of_match
,