Merge tag 'efi-2020-07-rc6' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
[oweals/u-boot.git] / board / freescale / common / dcu_sii9022a.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2014 Freescale Semiconductor, Inc.
4  * Copyright 2019 NXP
5  */
6
7 #include <asm/io.h>
8 #include <common.h>
9 #include <fsl_dcu_fb.h>
10 #include <i2c.h>
11 #include <linux/fb.h>
12
13 #define PIXEL_CLK_LSB_REG               0x00
14 #define PIXEL_CLK_MSB_REG               0x01
15 #define VERT_FREQ_LSB_REG               0x02
16 #define VERT_FREQ_MSB_REG               0x03
17 #define TOTAL_PIXELS_LSB_REG            0x04
18 #define TOTAL_PIXELS_MSB_REG            0x05
19 #define TOTAL_LINES_LSB_REG             0x06
20 #define TOTAL_LINES_MSB_REG             0x07
21 #define TPI_INBUS_FMT_REG               0x08
22 #define TPI_INPUT_FMT_REG               0x09
23 #define TPI_OUTPUT_FMT_REG              0x0A
24 #define TPI_SYS_CTRL_REG                0x1A
25 #define TPI_PWR_STAT_REG                0x1E
26 #define TPI_AUDIO_HANDING_REG           0x25
27 #define TPI_AUDIO_INTF_REG              0x26
28 #define TPI_AUDIO_FREQ_REG              0x27
29 #define TPI_SET_PAGE_REG                0xBC
30 #define TPI_SET_OFFSET_REG              0xBD
31 #define TPI_RW_ACCESS_REG               0xBE
32 #define TPI_TRANS_MODE_REG              0xC7
33
34 #define TPI_INBUS_CLOCK_RATIO_1         (1 << 6)
35 #define TPI_INBUS_FULL_PIXEL_WIDE       (1 << 5)
36 #define TPI_INBUS_RISING_EDGE           (1 << 4)
37 #define TPI_INPUT_CLR_DEPTH_8BIT        (0 << 6)
38 #define TPI_INPUT_VRANGE_EXPAN_AUTO     (0 << 2)
39 #define TPI_INPUT_CLR_RGB               (0 << 0)
40 #define TPI_OUTPUT_CLR_DEPTH_8BIT       (0 << 6)
41 #define TPI_OUTPUT_VRANGE_COMPRE_AUTO   (0 << 2)
42 #define TPI_OUTPUT_CLR_HDMI_RGB         (0 << 0)
43 #define TPI_SYS_TMDS_OUTPUT             (0 << 4)
44 #define TPI_SYS_AV_NORAML               (0 << 3)
45 #define TPI_SYS_AV_MUTE                 (1 << 3)
46 #define TPI_SYS_DVI_MODE                (0 << 0)
47 #define TPI_SYS_HDMI_MODE               (1 << 0)
48 #define TPI_PWR_STAT_MASK               (3 << 0)
49 #define TPI_PWR_STAT_D0                 (0 << 0)
50 #define TPI_AUDIO_PASS_BASIC            (0 << 0)
51 #define TPI_AUDIO_INTF_I2S              (2 << 6)
52 #define TPI_AUDIO_INTF_NORMAL           (0 << 4)
53 #define TPI_AUDIO_TYPE_PCM              (1 << 0)
54 #define TPI_AUDIO_SAMP_SIZE_16BIT       (1 << 6)
55 #define TPI_AUDIO_SAMP_FREQ_44K         (2 << 3)
56 #define TPI_SET_PAGE_SII9022A           0x01
57 #define TPI_SET_OFFSET_SII9022A         0x82
58 #define TPI_RW_EN_SRC_TERMIN            (1 << 0)
59 #define TPI_TRANS_MODE_ENABLE           (0 << 7)
60
61 /* Programming of Silicon SIi9022a HDMI Transmitter */
62 int dcu_set_dvi_encoder(struct fb_videomode *videomode)
63 {
64         u8 temp;
65         u16 temp1, temp2;
66         u32 temp3;
67 #ifdef CONFIG_DM_I2C
68         struct udevice *dev;
69         int ret;
70
71         ret = i2c_get_chip_for_busnum(CONFIG_SYS_I2C_DVI_BUS_NUM,
72                                       CONFIG_SYS_I2C_DVI_ADDR,
73                                       1, &dev);
74         if (ret) {
75                 printf("%s: Cannot find udev for a bus %d\n", __func__,
76                        CONFIG_SYS_I2C_DVI_BUS_NUM);
77                 return ret;
78         }
79
80         /* Enable TPI transmitter mode */
81         temp = TPI_TRANS_MODE_ENABLE;
82         dm_i2c_write(dev, TPI_TRANS_MODE_REG, &temp, 1);
83
84         /* Enter into D0 state, full operation */
85         dm_i2c_read(dev, TPI_PWR_STAT_REG, &temp, 1);
86         temp &= ~TPI_PWR_STAT_MASK;
87         temp |= TPI_PWR_STAT_D0;
88         dm_i2c_write(dev, TPI_PWR_STAT_REG, &temp, 1);
89
90         /* Enable source termination */
91         temp = TPI_SET_PAGE_SII9022A;
92         dm_i2c_write(dev, TPI_SET_PAGE_REG, &temp, 1);
93         temp = TPI_SET_OFFSET_SII9022A;
94         dm_i2c_write(dev, TPI_SET_OFFSET_REG, &temp, 1);
95
96         dm_i2c_read(dev, TPI_RW_ACCESS_REG, &temp, 1);
97         temp |= TPI_RW_EN_SRC_TERMIN;
98         dm_i2c_write(dev, TPI_RW_ACCESS_REG, &temp, 1);
99
100         /* Set TPI system control */
101         temp = TPI_SYS_TMDS_OUTPUT | TPI_SYS_AV_NORAML | TPI_SYS_DVI_MODE;
102         dm_i2c_write(dev, TPI_SYS_CTRL_REG, &temp, 1);
103
104         /* Set pixel clock */
105         temp1 = PICOS2KHZ(videomode->pixclock) / 10;
106         temp = (u8)(temp1 & 0xFF);
107         dm_i2c_write(dev, PIXEL_CLK_LSB_REG, &temp, 1);
108         temp = (u8)(temp1 >> 8);
109         dm_i2c_write(dev, PIXEL_CLK_MSB_REG, &temp, 1);
110
111         /* Set total pixels per line */
112         temp1 = videomode->hsync_len + videomode->left_margin +
113                 videomode->xres + videomode->right_margin;
114         temp = (u8)(temp1 & 0xFF);
115         dm_i2c_write(dev, TOTAL_PIXELS_LSB_REG, &temp, 1);
116         temp = (u8)(temp1 >> 8);
117         dm_i2c_write(dev, TOTAL_PIXELS_MSB_REG, &temp, 1);
118
119         /* Set total lines */
120         temp2 = videomode->vsync_len + videomode->upper_margin +
121                 videomode->yres + videomode->lower_margin;
122         temp = (u8)(temp2 & 0xFF);
123         dm_i2c_write(dev, TOTAL_LINES_LSB_REG, &temp, 1);
124         temp = (u8)(temp2 >> 8);
125         dm_i2c_write(dev, TOTAL_LINES_MSB_REG, &temp, 1);
126
127         /* Set vertical frequency in Hz */
128         temp3 = temp1 * temp2;
129         temp3 = (PICOS2KHZ(videomode->pixclock) * 1000) / temp3;
130         temp1 = (u16)temp3 * 100;
131         temp = (u8)(temp1 & 0xFF);
132         dm_i2c_write(dev, VERT_FREQ_LSB_REG, &temp, 1);
133         temp = (u8)(temp1 >> 8);
134         dm_i2c_write(dev, VERT_FREQ_MSB_REG, &temp, 1);
135
136         /* Set TPI input bus and pixel repetition data */
137         temp = TPI_INBUS_CLOCK_RATIO_1 | TPI_INBUS_FULL_PIXEL_WIDE |
138                 TPI_INBUS_RISING_EDGE;
139         dm_i2c_write(dev, TPI_INBUS_FMT_REG, &temp, 1);
140
141         /* Set TPI AVI Input format data */
142         temp = TPI_INPUT_CLR_DEPTH_8BIT | TPI_INPUT_VRANGE_EXPAN_AUTO |
143                 TPI_INPUT_CLR_RGB;
144         dm_i2c_write(dev, TPI_INPUT_FMT_REG, &temp, 1);
145
146         /* Set TPI AVI Output format data */
147         temp = TPI_OUTPUT_CLR_DEPTH_8BIT | TPI_OUTPUT_VRANGE_COMPRE_AUTO |
148                 TPI_OUTPUT_CLR_HDMI_RGB;
149         dm_i2c_write(dev, TPI_OUTPUT_FMT_REG, &temp, 1);
150
151         /* Set TPI audio configuration write data */
152         temp = TPI_AUDIO_PASS_BASIC;
153         dm_i2c_write(dev, TPI_AUDIO_HANDING_REG, &temp, 1);
154
155         temp = TPI_AUDIO_INTF_I2S | TPI_AUDIO_INTF_NORMAL |
156                 TPI_AUDIO_TYPE_PCM;
157         dm_i2c_write(dev, TPI_AUDIO_INTF_REG, &temp, 1);
158
159         temp = TPI_AUDIO_SAMP_SIZE_16BIT | TPI_AUDIO_SAMP_FREQ_44K;
160         dm_i2c_write(dev, TPI_AUDIO_FREQ_REG, &temp, 1);
161 #else
162         i2c_set_bus_num(CONFIG_SYS_I2C_DVI_BUS_NUM);
163
164         /* Enable TPI transmitter mode */
165         temp = TPI_TRANS_MODE_ENABLE;
166         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_TRANS_MODE_REG, 1, &temp, 1);
167
168         /* Enter into D0 state, full operation */
169         i2c_read(CONFIG_SYS_I2C_DVI_ADDR, TPI_PWR_STAT_REG, 1, &temp, 1);
170         temp &= ~TPI_PWR_STAT_MASK;
171         temp |= TPI_PWR_STAT_D0;
172         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_PWR_STAT_REG, 1, &temp, 1);
173
174         /* Enable source termination */
175         temp = TPI_SET_PAGE_SII9022A;
176         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_SET_PAGE_REG, 1, &temp, 1);
177         temp = TPI_SET_OFFSET_SII9022A;
178         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_SET_OFFSET_REG, 1, &temp, 1);
179
180         i2c_read(CONFIG_SYS_I2C_DVI_ADDR, TPI_RW_ACCESS_REG, 1, &temp, 1);
181         temp |= TPI_RW_EN_SRC_TERMIN;
182         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_RW_ACCESS_REG, 1, &temp, 1);
183
184         /* Set TPI system control */
185         temp = TPI_SYS_TMDS_OUTPUT | TPI_SYS_AV_NORAML | TPI_SYS_DVI_MODE;
186         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_SYS_CTRL_REG, 1, &temp, 1);
187
188         /* Set pixel clock */
189         temp1 = PICOS2KHZ(videomode->pixclock) / 10;
190         temp = (u8)(temp1 & 0xFF);
191         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, PIXEL_CLK_LSB_REG, 1, &temp, 1);
192         temp = (u8)(temp1 >> 8);
193         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, PIXEL_CLK_MSB_REG, 1, &temp, 1);
194
195         /* Set total pixels per line */
196         temp1 = videomode->hsync_len + videomode->left_margin +
197                 videomode->xres + videomode->right_margin;
198         temp = (u8)(temp1 & 0xFF);
199         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_PIXELS_LSB_REG, 1, &temp, 1);
200         temp = (u8)(temp1 >> 8);
201         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_PIXELS_MSB_REG, 1, &temp, 1);
202
203         /* Set total lines */
204         temp2 = videomode->vsync_len + videomode->upper_margin +
205                 videomode->yres + videomode->lower_margin;
206         temp = (u8)(temp2 & 0xFF);
207         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_LINES_LSB_REG, 1, &temp, 1);
208         temp = (u8)(temp2 >> 8);
209         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_LINES_MSB_REG, 1, &temp, 1);
210
211         /* Set vertical frequency in Hz */
212         temp3 = temp1 * temp2;
213         temp3 = (PICOS2KHZ(videomode->pixclock) * 1000) / temp3;
214         temp1 = (u16)temp3 * 100;
215         temp = (u8)(temp1 & 0xFF);
216         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, VERT_FREQ_LSB_REG, 1, &temp, 1);
217         temp = (u8)(temp1 >> 8);
218         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, VERT_FREQ_MSB_REG, 1, &temp, 1);
219
220         /* Set TPI input bus and pixel repetition data */
221         temp = TPI_INBUS_CLOCK_RATIO_1 | TPI_INBUS_FULL_PIXEL_WIDE |
222                 TPI_INBUS_RISING_EDGE;
223         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_INBUS_FMT_REG, 1, &temp, 1);
224
225         /* Set TPI AVI Input format data */
226         temp = TPI_INPUT_CLR_DEPTH_8BIT | TPI_INPUT_VRANGE_EXPAN_AUTO |
227                 TPI_INPUT_CLR_RGB;
228         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_INPUT_FMT_REG, 1, &temp, 1);
229
230         /* Set TPI AVI Output format data */
231         temp = TPI_OUTPUT_CLR_DEPTH_8BIT | TPI_OUTPUT_VRANGE_COMPRE_AUTO |
232                 TPI_OUTPUT_CLR_HDMI_RGB;
233         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_OUTPUT_FMT_REG, 1, &temp, 1);
234
235         /* Set TPI audio configuration write data */
236         temp = TPI_AUDIO_PASS_BASIC;
237         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_AUDIO_HANDING_REG, 1, &temp, 1);
238
239         temp = TPI_AUDIO_INTF_I2S | TPI_AUDIO_INTF_NORMAL |
240                 TPI_AUDIO_TYPE_PCM;
241         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_AUDIO_INTF_REG, 1, &temp, 1);
242
243         temp = TPI_AUDIO_SAMP_SIZE_16BIT | TPI_AUDIO_SAMP_FREQ_44K;
244         i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_AUDIO_FREQ_REG, 1, &temp, 1);
245 #endif
246
247         return 0;
248 }