blob: bb204e5f8f256333e74fdb291f8453a439e3344b [file] [log] [blame]
Werner Zehc42a6132015-02-12 12:40:15 +01001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Siemens AG
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <console/console.h>
21#include "baytrail/i2c.h"
22#include "ptn3460.h"
23
24/** \brief This functions sets up the DP2LVDS-converter to be used with the
25 * appropriate lcd panel
26 * @param lcd_type Type of LCD we should set up the converter for
27 * @param *sib Pointer to short info block structure
28 * @param *eib Pointer to EDID info block structure
29 * @return 0 on success or error code
30 */
31int ptn3460_init(char lcd_type, struct edidinfo *eib, struct shortinfo *sib)
32{
33 struct ptn_3460_config cfg;
34 int status;
35
36
37 status = i2c_init(PTN_I2C_CONTROLER);
38 if (status)
39 return (PTN_BUS_ERROR | status);
40
41 /* If we are here, we have all the desired information for setting up */
42 /* DP2LVDS converter. In addition, the information matches the connected */
43 /* LCD-panel and therefore, we do not have to distinguish between */
44 /* different panels here for the timing. Inside the converter, table 6 */
45 /* will be used for the timings. */
46 status = ptn3460_write_edid(6, eib->edid);
47 if (status)
48 return status;
49 /* Select this table to be emulated */
50 ptn_select_edid(6);
51 /* Read PTN configuration data */
52 status = i2c_read(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF,
53 (u8*)&cfg, PTN_CONFIG_LEN);
54 if (status)
55 return (PTN_BUS_ERROR | status);
56
57 /* Set up configuration data according to the information blocks we get */
58 cfg.dp_interface_ctrl = 0;
59 cfg.lvds_interface_ctrl1 = 0x00;
60 if (sib->panelFeatures[SIB_DISP_CON_IDX] == SIB_LVDS_DUAL_LANE)
61 cfg.lvds_interface_ctrl1 |= 0x0b; /* Turn on dual LVDS lane and clock */
62 if ((sib->panelFeatures[SIB_HWINIT_IDX] & 0x03) == SIB_COLOR_6BIT)
63 cfg.lvds_interface_ctrl1 |= 0x20; /* Use 18 bits per pixel */
64
65 cfg.lvds_interface_ctrl2 = 0x03; /* no clock spreading, 300 mV LVDS swing */
66 cfg.lvds_interface_ctrl3 = 0x00; /* no LVDS signal swap */
67 cfg.t2_delay = 1; /* Delay T2 (VDD to LVDS active) by 16 ms */
68 cfg.t3_timing = 5; /* 250 ms from LVDS to backlight active */
69 cfg.t12_timing = 20; /* 1 second re-power delay */
70 cfg.t4_timing = 3; /* 150 ms backlight off to LVDS inactive */
71 cfg.t5_delay = 1; /* Delay T5 (LVDS to VDD inactive) by 16 ms */
72 cfg.backlight_ctrl = 0; /* Enable backlight control */
73
74 /* Write back configuration data to PTN3460 */
75 status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF,
76 (u8*)&cfg, PTN_CONFIG_LEN);
77 if (status)
78 return (PTN_BUS_ERROR | status);
79 else
80 return PTN_NO_ERROR;
81}
82
83/** \brief This functions reads one desired EDID data structure from PTN3460
84 * @param edid_num Number of EDID that must be read (0..6)
85 * @param *data Pointer to a buffer where to store read data
86 * @return 0 on success or error code
87 */
88int ptn3460_read_edid(u8 edid_num, u8 *data)
89{
90 int status;
91
92 if (edid_num > PTN_MAX_EDID_NUM)
93 return PTN_INVALID_EDID;
94 /* First enable access to the desired EDID table */
95 status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF + 5,
96 &edid_num, 1);
97 if (status)
98 return (PTN_BUS_ERROR | status);
99
100 /* Now we can simply read back EDID-data */
101 status = i2c_read(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_EDID_OFF,
102 data, PTN_EDID_LEN);
103 if (status)
104 return (PTN_BUS_ERROR | status);
105 else
106 return PTN_NO_ERROR;
107}
108
109/** \brief This functions writes one EDID data structure to PTN3460
110 * @param edid_num Number of EDID that must be written (0..6)
111 * @param *data Pointer to a buffer where data to write is stored in
112 * @return 0 on success or error code
113 */
114int ptn3460_write_edid(u8 edid_num, u8 *data)
115{
116 int status;
117
118 if (edid_num > PTN_MAX_EDID_NUM)
119 return PTN_INVALID_EDID;
120 /* First enable access to the desired EDID table */
121 status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF + 5,
122 &edid_num, 1);
123 if (status)
124 return (PTN_BUS_ERROR | status);
125
126 /* Now we can simply write EDID-data to ptn3460 */
127 status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_EDID_OFF,
128 data, PTN_EDID_LEN);
129 if (status)
130 return (PTN_BUS_ERROR | status);
131 else
132 return PTN_NO_ERROR;
133}
134
135/** \brief This functions selects one of 7 EDID-tables inside PTN3460
136 * which should be emulated on display port and turn emulation ON
137 * @param edid_num Number of EDID to emulate (0..6)
138 * @return 0 on success or error code
139 */
140int ptn_select_edid (u8 edid_num)
141{
142 int status;
143 u8 val;
144
145 if (edid_num > PTN_MAX_EDID_NUM)
146 return PTN_INVALID_EDID;
147 /* Enable emulation of the desired EDID table */
148 val = (edid_num << 1) | 1;
149 status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF + 4,
150 &val, 1);
151 if (status)
152 return (PTN_BUS_ERROR | status);
153 else
154 return PTN_NO_ERROR;
155}
156
157/** \brief This functions performs a flash operation which will write
158 * current configuration table (all the EDID-tables and the
159 * configuration space with a total amount of 1 KByte)
160 * to the internal flash of PTN3460
161 * @param none
162 * @return 0 on success or error code
163 */
164int ptn3460_flash_config(void)
165{
166 int status;
167 struct ptn_3460_flash flash;
168
169 flash.cmd = 0x01; /* perform erase and flash cycle */
170 flash.magic = 0x7845; /* Magic number to protect flash operation */
171 flash.trigger = 0x56; /* This value starts flash operation */
172 status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_FLASH_CFG_OFF,
173 (u8*)&flash, PTN_FLASH_CFG_LEN);
174 if (status) {
175 return (PTN_BUS_ERROR | status);
176 } else {
177 /* To ensure the flash operation is finished, we have to wait 300 ms */
178 mdelay(300);
179 return PTN_NO_ERROR;
180 }
181}