1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * TV encoder driver for Allwinner SoCs.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * (C) Copyright 2013-2014 Luc Verhaegen <libv@skynet.be>
5*4882a593Smuzhiyun * (C) Copyright 2014-2015 Hans de Goede <hdegoede@redhat.com>
6*4882a593Smuzhiyun * (C) Copyright 2017 Jernej Skrabec <jernej.skrabec@siol.net>
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <common.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <asm/arch/tve.h>
14*4882a593Smuzhiyun #include <asm/io.h>
15*4882a593Smuzhiyun
tvencoder_mode_set(struct sunxi_tve_reg * const tve,enum tve_mode mode)16*4882a593Smuzhiyun void tvencoder_mode_set(struct sunxi_tve_reg * const tve, enum tve_mode mode)
17*4882a593Smuzhiyun {
18*4882a593Smuzhiyun switch (mode) {
19*4882a593Smuzhiyun case tve_mode_vga:
20*4882a593Smuzhiyun writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
21*4882a593Smuzhiyun SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
22*4882a593Smuzhiyun SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl);
23*4882a593Smuzhiyun writel(SUNXI_TVE_CFG0_VGA, &tve->cfg0);
24*4882a593Smuzhiyun writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0);
25*4882a593Smuzhiyun writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1);
26*4882a593Smuzhiyun break;
27*4882a593Smuzhiyun case tve_mode_composite_pal_nc:
28*4882a593Smuzhiyun writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq);
29*4882a593Smuzhiyun /* Fall through */
30*4882a593Smuzhiyun case tve_mode_composite_pal:
31*4882a593Smuzhiyun writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
32*4882a593Smuzhiyun SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
33*4882a593Smuzhiyun SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
34*4882a593Smuzhiyun SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
35*4882a593Smuzhiyun writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0);
36*4882a593Smuzhiyun writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
37*4882a593Smuzhiyun writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
38*4882a593Smuzhiyun writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num);
39*4882a593Smuzhiyun writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num);
40*4882a593Smuzhiyun writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL,
41*4882a593Smuzhiyun &tve->blank_black_level);
42*4882a593Smuzhiyun writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
43*4882a593Smuzhiyun writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level);
44*4882a593Smuzhiyun writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
45*4882a593Smuzhiyun writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2);
46*4882a593Smuzhiyun writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
47*4882a593Smuzhiyun writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
48*4882a593Smuzhiyun writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
49*4882a593Smuzhiyun writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num);
50*4882a593Smuzhiyun writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
51*4882a593Smuzhiyun break;
52*4882a593Smuzhiyun case tve_mode_composite_pal_m:
53*4882a593Smuzhiyun writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq);
54*4882a593Smuzhiyun writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst);
55*4882a593Smuzhiyun /* Fall through */
56*4882a593Smuzhiyun case tve_mode_composite_ntsc:
57*4882a593Smuzhiyun writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
58*4882a593Smuzhiyun SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
59*4882a593Smuzhiyun SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
60*4882a593Smuzhiyun SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
61*4882a593Smuzhiyun writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0);
62*4882a593Smuzhiyun writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
63*4882a593Smuzhiyun writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
64*4882a593Smuzhiyun writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num);
65*4882a593Smuzhiyun writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num);
66*4882a593Smuzhiyun writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC,
67*4882a593Smuzhiyun &tve->blank_black_level);
68*4882a593Smuzhiyun writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
69*4882a593Smuzhiyun writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level);
70*4882a593Smuzhiyun writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase);
71*4882a593Smuzhiyun writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
72*4882a593Smuzhiyun writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2);
73*4882a593Smuzhiyun writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level);
74*4882a593Smuzhiyun writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
75*4882a593Smuzhiyun writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
76*4882a593Smuzhiyun writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
77*4882a593Smuzhiyun writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num);
78*4882a593Smuzhiyun writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
79*4882a593Smuzhiyun break;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun
tvencoder_enable(struct sunxi_tve_reg * const tve)83*4882a593Smuzhiyun void tvencoder_enable(struct sunxi_tve_reg * const tve)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE);
86*4882a593Smuzhiyun }
87