2 * Copyright 2014 Freescale Semiconductor, Inc.
3 * Author: Priyanka Jain <Priyanka.Jain@freescale.com>
5 * SPDX-License-Identifier: GPL-2.0+
10 #include <linux/ctype.h>
12 #include <stdio_dev.h>
14 #include <fsl_diu_fb.h>
15 #include "../common/qixis.h"
17 #include "t1040qds_qixis.h"
21 #define I2C_DVI_INPUT_DATA_FORMAT_REG 0x1F
22 #define I2C_DVI_PLL_CHARGE_CNTL_REG 0x33
23 #define I2C_DVI_PLL_DIVIDER_REG 0x34
24 #define I2C_DVI_PLL_SUPPLY_CNTL_REG 0x35
25 #define I2C_DVI_PLL_FILTER_REG 0x36
26 #define I2C_DVI_TEST_PATTERN_REG 0x48
27 #define I2C_DVI_POWER_MGMT_REG 0x49
28 #define I2C_DVI_LOCK_STATE_REG 0x4D
29 #define I2C_DVI_SYNC_POLARITY_REG 0x56
32 * Set VSYNC/HSYNC to active high. This is polarity of sync signals
33 * from DIU->DVI. The DIU default is active igh, so DVI is set to
36 #define I2C_DVI_INPUT_DATA_FORMAT_VAL 0x98
38 #define I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL 0x06
39 #define I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL 0x26
40 #define I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL 0xA0
41 #define I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL 0x08
42 #define I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL 0x16
43 #define I2C_DVI_PLL_FILTER_LOW_SPEED_VAL 0x60
45 /* Clear test pattern */
46 #define I2C_DVI_TEST_PATTERN_VAL 0x18
47 /* Exit Power-down mode */
48 #define I2C_DVI_POWER_MGMT_VAL 0xC0
50 /* Monitor polarity is handled via DVI Sync Polarity Register */
51 #define I2C_DVI_SYNC_POLARITY_VAL 0x00
56 * Note that we need to byte-swap the value before it's written to the AD
57 * register. So even though the registers don't look like they're in the same
58 * bit positions as they are on the MPC8610, the same value is written to the
59 * AD register on the MPC8610 and on the P1022.
61 #define AD_BYTE_F 0x10000000
62 #define AD_ALPHA_C_SHIFT 25
63 #define AD_BLUE_C_SHIFT 23
64 #define AD_GREEN_C_SHIFT 21
65 #define AD_RED_C_SHIFT 19
66 #define AD_PIXEL_S_SHIFT 16
67 #define AD_COMP_3_SHIFT 12
68 #define AD_COMP_2_SHIFT 8
69 #define AD_COMP_1_SHIFT 4
70 #define AD_COMP_0_SHIFT 0
72 /* Programming of HDMI Chrontel CH7301 connector */
73 int diu_set_dvi_encoder(unsigned int pixclock)
77 select_i2c_ch_pca9547(I2C_MUX_CH_DIU);
79 temp = I2C_DVI_TEST_PATTERN_VAL;
80 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_TEST_PATTERN_REG, 1,
83 puts("I2C: failed to select proper dvi test pattern\n");
86 temp = I2C_DVI_INPUT_DATA_FORMAT_VAL;
87 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_INPUT_DATA_FORMAT_REG,
90 puts("I2C: failed to select dvi input data format\n");
94 /* Set Sync polarity register */
95 temp = I2C_DVI_SYNC_POLARITY_VAL;
96 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_SYNC_POLARITY_REG, 1,
99 puts("I2C: failed to select dvi syc polarity\n");
103 /* Set PLL registers based on pixel clock rate*/
104 if (pixclock > 65000000) {
105 temp = I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL;
106 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
107 I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1);
109 puts("I2C: failed to select dvi pll charge_cntl\n");
112 temp = I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL;
113 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
114 I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
116 puts("I2C: failed to select dvi pll divider\n");
119 temp = I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL;
120 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
121 I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
123 puts("I2C: failed to select dvi pll filter\n");
127 temp = I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL;
128 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
129 I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1);
131 puts("I2C: failed to select dvi pll charge_cntl\n");
134 temp = I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL;
135 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
136 I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
138 puts("I2C: failed to select dvi pll divider\n");
141 temp = I2C_DVI_PLL_FILTER_LOW_SPEED_VAL;
142 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
143 I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
145 puts("I2C: failed to select dvi pll filter\n");
150 temp = I2C_DVI_POWER_MGMT_VAL;
151 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_POWER_MGMT_REG, 1,
154 puts("I2C: failed to select dvi power mgmt\n");
160 select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
164 void diu_set_pixel_clock(unsigned int pixclock)
166 unsigned long speed_ccb, temp;
169 speed_ccb = get_bus_freq(0);
170 temp = 1000000000 / pixclock;
172 pixval = speed_ccb / temp;
174 /* Program HDMI encoder */
175 ret = diu_set_dvi_encoder(temp);
177 puts("Failed to set DVI encoder\n");
181 /* Program pixel clock */
182 out_be32((unsigned *)CONFIG_SYS_FSL_SCFG_PIXCLK_ADDR,
183 ((pixval << PXCK_BITS_START) & PXCK_MASK));
185 out_be32((unsigned *)CONFIG_SYS_FSL_SCFG_PIXCLK_ADDR, PXCKEN_MASK |
186 ((pixval << PXCK_BITS_START) & PXCK_MASK));
189 int platform_diu_init(unsigned int xres, unsigned int yres, const char *port)
194 /*Route I2C4 to DIU system as HSYNC/VSYNC*/
195 sw = QIXIS_READ(brdcfg[5]);
196 QIXIS_WRITE(brdcfg[5],
197 ((sw & ~(BRDCFG5_IMX_MASK)) | (BRDCFG5_IMX_DIU)));
199 /*Configure Display ouput port as HDMI*/
200 sw = QIXIS_READ(brdcfg[15]);
201 QIXIS_WRITE(brdcfg[15],
202 ((sw & ~(BRDCFG15_LCDPD_MASK | BRDCFG15_DIUSEL_MASK))
203 | (BRDCFG15_LCDPD_ENABLED | BRDCFG15_DIUSEL_HDMI)));
205 pixel_format = cpu_to_le32(AD_BYTE_F | (3 << AD_ALPHA_C_SHIFT) |
206 (0 << AD_BLUE_C_SHIFT) | (1 << AD_GREEN_C_SHIFT) |
207 (2 << AD_RED_C_SHIFT) | (8 << AD_COMP_3_SHIFT) |
208 (8 << AD_COMP_2_SHIFT) | (8 << AD_COMP_1_SHIFT) |
209 (8 << AD_COMP_0_SHIFT) | (3 << AD_PIXEL_S_SHIFT));
211 printf("DIU: Switching to monitor @ %ux%u\n", xres, yres);
214 return fsl_diu_init(xres, yres, pixel_format, 0);