1*c53711bbSWang Dongsheng /*
2*c53711bbSWang Dongsheng * Copyright 2014 Freescale Semiconductor, Inc.
3*c53711bbSWang Dongsheng * Authors: Priyanka Jain <Priyanka.Jain@freescale.com>
4*c53711bbSWang Dongsheng * Wang Dongsheng <dongsheng.wang@freescale.com>
5*c53711bbSWang Dongsheng *
6*c53711bbSWang Dongsheng * This file is copied and modified from the original t1040qds/diu.c.
7*c53711bbSWang Dongsheng * Encoder can be used in T104x and LSx Platform.
8*c53711bbSWang Dongsheng *
9*c53711bbSWang Dongsheng * SPDX-License-Identifier: GPL-2.0+
10*c53711bbSWang Dongsheng */
11*c53711bbSWang Dongsheng
12*c53711bbSWang Dongsheng #include <common.h>
13*c53711bbSWang Dongsheng #include <stdio_dev.h>
14*c53711bbSWang Dongsheng #include <i2c.h>
15*c53711bbSWang Dongsheng
16*c53711bbSWang Dongsheng #define I2C_DVI_INPUT_DATA_FORMAT_REG 0x1F
17*c53711bbSWang Dongsheng #define I2C_DVI_PLL_CHARGE_CNTL_REG 0x33
18*c53711bbSWang Dongsheng #define I2C_DVI_PLL_DIVIDER_REG 0x34
19*c53711bbSWang Dongsheng #define I2C_DVI_PLL_SUPPLY_CNTL_REG 0x35
20*c53711bbSWang Dongsheng #define I2C_DVI_PLL_FILTER_REG 0x36
21*c53711bbSWang Dongsheng #define I2C_DVI_TEST_PATTERN_REG 0x48
22*c53711bbSWang Dongsheng #define I2C_DVI_POWER_MGMT_REG 0x49
23*c53711bbSWang Dongsheng #define I2C_DVI_LOCK_STATE_REG 0x4D
24*c53711bbSWang Dongsheng #define I2C_DVI_SYNC_POLARITY_REG 0x56
25*c53711bbSWang Dongsheng
26*c53711bbSWang Dongsheng /*
27*c53711bbSWang Dongsheng * Set VSYNC/HSYNC to active high. This is polarity of sync signals
28*c53711bbSWang Dongsheng * from DIU->DVI. The DIU default is active igh, so DVI is set to
29*c53711bbSWang Dongsheng * active high.
30*c53711bbSWang Dongsheng */
31*c53711bbSWang Dongsheng #define I2C_DVI_INPUT_DATA_FORMAT_VAL 0x98
32*c53711bbSWang Dongsheng
33*c53711bbSWang Dongsheng #define I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL 0x06
34*c53711bbSWang Dongsheng #define I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL 0x26
35*c53711bbSWang Dongsheng #define I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL 0xA0
36*c53711bbSWang Dongsheng #define I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL 0x08
37*c53711bbSWang Dongsheng #define I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL 0x16
38*c53711bbSWang Dongsheng #define I2C_DVI_PLL_FILTER_LOW_SPEED_VAL 0x60
39*c53711bbSWang Dongsheng
40*c53711bbSWang Dongsheng /* Clear test pattern */
41*c53711bbSWang Dongsheng #define I2C_DVI_TEST_PATTERN_VAL 0x18
42*c53711bbSWang Dongsheng /* Exit Power-down mode */
43*c53711bbSWang Dongsheng #define I2C_DVI_POWER_MGMT_VAL 0xC0
44*c53711bbSWang Dongsheng
45*c53711bbSWang Dongsheng /* Monitor polarity is handled via DVI Sync Polarity Register */
46*c53711bbSWang Dongsheng #define I2C_DVI_SYNC_POLARITY_VAL 0x00
47*c53711bbSWang Dongsheng
48*c53711bbSWang Dongsheng /* Programming of HDMI Chrontel CH7301 connector */
diu_set_dvi_encoder(unsigned int pixclock)49*c53711bbSWang Dongsheng int diu_set_dvi_encoder(unsigned int pixclock)
50*c53711bbSWang Dongsheng {
51*c53711bbSWang Dongsheng int ret;
52*c53711bbSWang Dongsheng u8 temp;
53*c53711bbSWang Dongsheng
54*c53711bbSWang Dongsheng temp = I2C_DVI_TEST_PATTERN_VAL;
55*c53711bbSWang Dongsheng ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_TEST_PATTERN_REG, 1,
56*c53711bbSWang Dongsheng &temp, 1);
57*c53711bbSWang Dongsheng if (ret) {
58*c53711bbSWang Dongsheng puts("I2C: failed to select proper dvi test pattern\n");
59*c53711bbSWang Dongsheng return ret;
60*c53711bbSWang Dongsheng }
61*c53711bbSWang Dongsheng temp = I2C_DVI_INPUT_DATA_FORMAT_VAL;
62*c53711bbSWang Dongsheng ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_INPUT_DATA_FORMAT_REG,
63*c53711bbSWang Dongsheng 1, &temp, 1);
64*c53711bbSWang Dongsheng if (ret) {
65*c53711bbSWang Dongsheng puts("I2C: failed to select dvi input data format\n");
66*c53711bbSWang Dongsheng return ret;
67*c53711bbSWang Dongsheng }
68*c53711bbSWang Dongsheng
69*c53711bbSWang Dongsheng /* Set Sync polarity register */
70*c53711bbSWang Dongsheng temp = I2C_DVI_SYNC_POLARITY_VAL;
71*c53711bbSWang Dongsheng ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_SYNC_POLARITY_REG, 1,
72*c53711bbSWang Dongsheng &temp, 1);
73*c53711bbSWang Dongsheng if (ret) {
74*c53711bbSWang Dongsheng puts("I2C: failed to select dvi syc polarity\n");
75*c53711bbSWang Dongsheng return ret;
76*c53711bbSWang Dongsheng }
77*c53711bbSWang Dongsheng
78*c53711bbSWang Dongsheng /* Set PLL registers based on pixel clock rate*/
79*c53711bbSWang Dongsheng if (pixclock > 65000000) {
80*c53711bbSWang Dongsheng temp = I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL;
81*c53711bbSWang Dongsheng ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
82*c53711bbSWang Dongsheng I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1);
83*c53711bbSWang Dongsheng if (ret) {
84*c53711bbSWang Dongsheng puts("I2C: failed to select dvi pll charge_cntl\n");
85*c53711bbSWang Dongsheng return ret;
86*c53711bbSWang Dongsheng }
87*c53711bbSWang Dongsheng temp = I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL;
88*c53711bbSWang Dongsheng ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
89*c53711bbSWang Dongsheng I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
90*c53711bbSWang Dongsheng if (ret) {
91*c53711bbSWang Dongsheng puts("I2C: failed to select dvi pll divider\n");
92*c53711bbSWang Dongsheng return ret;
93*c53711bbSWang Dongsheng }
94*c53711bbSWang Dongsheng temp = I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL;
95*c53711bbSWang Dongsheng ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
96*c53711bbSWang Dongsheng I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
97*c53711bbSWang Dongsheng if (ret) {
98*c53711bbSWang Dongsheng puts("I2C: failed to select dvi pll filter\n");
99*c53711bbSWang Dongsheng return ret;
100*c53711bbSWang Dongsheng }
101*c53711bbSWang Dongsheng } else {
102*c53711bbSWang Dongsheng temp = I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL;
103*c53711bbSWang Dongsheng ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
104*c53711bbSWang Dongsheng I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1);
105*c53711bbSWang Dongsheng if (ret) {
106*c53711bbSWang Dongsheng puts("I2C: failed to select dvi pll charge_cntl\n");
107*c53711bbSWang Dongsheng return ret;
108*c53711bbSWang Dongsheng }
109*c53711bbSWang Dongsheng temp = I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL;
110*c53711bbSWang Dongsheng ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
111*c53711bbSWang Dongsheng I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
112*c53711bbSWang Dongsheng if (ret) {
113*c53711bbSWang Dongsheng puts("I2C: failed to select dvi pll divider\n");
114*c53711bbSWang Dongsheng return ret;
115*c53711bbSWang Dongsheng }
116*c53711bbSWang Dongsheng temp = I2C_DVI_PLL_FILTER_LOW_SPEED_VAL;
117*c53711bbSWang Dongsheng ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
118*c53711bbSWang Dongsheng I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
119*c53711bbSWang Dongsheng if (ret) {
120*c53711bbSWang Dongsheng puts("I2C: failed to select dvi pll filter\n");
121*c53711bbSWang Dongsheng return ret;
122*c53711bbSWang Dongsheng }
123*c53711bbSWang Dongsheng }
124*c53711bbSWang Dongsheng
125*c53711bbSWang Dongsheng temp = I2C_DVI_POWER_MGMT_VAL;
126*c53711bbSWang Dongsheng ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_POWER_MGMT_REG, 1,
127*c53711bbSWang Dongsheng &temp, 1);
128*c53711bbSWang Dongsheng if (ret) {
129*c53711bbSWang Dongsheng puts("I2C: failed to select dvi power mgmt\n");
130*c53711bbSWang Dongsheng return ret;
131*c53711bbSWang Dongsheng }
132*c53711bbSWang Dongsheng
133*c53711bbSWang Dongsheng udelay(500);
134*c53711bbSWang Dongsheng
135*c53711bbSWang Dongsheng return 0;
136*c53711bbSWang Dongsheng }
137