xref: /openbmc/u-boot/drivers/video/lg4573.c (revision e8f80a5a)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0
2fc1a79d9SHeiko Schocher /*
3fc1a79d9SHeiko Schocher  * LCD: LG4573, TFT 4.3", 480x800, RGB24
4fc1a79d9SHeiko Schocher  * LCD initialization via SPI
5fc1a79d9SHeiko Schocher  *
6fc1a79d9SHeiko Schocher  */
7fc1a79d9SHeiko Schocher #include <common.h>
8fc1a79d9SHeiko Schocher #include <errno.h>
9fc1a79d9SHeiko Schocher #include <spi.h>
10fc1a79d9SHeiko Schocher 
11fc1a79d9SHeiko Schocher #define PWR_ON_DELAY_MSECS  120
12fc1a79d9SHeiko Schocher 
lb043wv_spi_write_u16(struct spi_slave * spi,u16 val)13fc1a79d9SHeiko Schocher static int lb043wv_spi_write_u16(struct spi_slave *spi, u16 val)
14fc1a79d9SHeiko Schocher {
15fc1a79d9SHeiko Schocher 	unsigned long flags = SPI_XFER_BEGIN;
16fc1a79d9SHeiko Schocher 	unsigned short buf16 = htons(val);
17fc1a79d9SHeiko Schocher 	int ret = 0;
18fc1a79d9SHeiko Schocher 
19fc1a79d9SHeiko Schocher 	flags |= SPI_XFER_END;
20fc1a79d9SHeiko Schocher 
21fc1a79d9SHeiko Schocher 	ret = spi_xfer(spi, 16, &buf16, NULL, flags);
22fc1a79d9SHeiko Schocher 	if (ret)
23fc1a79d9SHeiko Schocher 		debug("%s: Failed to send: %d\n", __func__, ret);
24fc1a79d9SHeiko Schocher 
25fc1a79d9SHeiko Schocher 	return ret;
26fc1a79d9SHeiko Schocher }
27fc1a79d9SHeiko Schocher 
lb043wv_spi_write_u16_array(struct spi_slave * spi,u16 * buff,int size)28fc1a79d9SHeiko Schocher static void lb043wv_spi_write_u16_array(struct spi_slave *spi, u16 *buff,
29fc1a79d9SHeiko Schocher 					int size)
30fc1a79d9SHeiko Schocher {
31fc1a79d9SHeiko Schocher 	int i;
32fc1a79d9SHeiko Schocher 
33fc1a79d9SHeiko Schocher 	for (i = 0; i < size; i++)
34fc1a79d9SHeiko Schocher 		lb043wv_spi_write_u16(spi, buff[i]);
35fc1a79d9SHeiko Schocher }
36fc1a79d9SHeiko Schocher 
lb043wv_display_mode_settings(struct spi_slave * spi)37fc1a79d9SHeiko Schocher static void lb043wv_display_mode_settings(struct spi_slave *spi)
38fc1a79d9SHeiko Schocher {
39fc1a79d9SHeiko Schocher 	static u16 display_mode_settings[] = {
40fc1a79d9SHeiko Schocher 	  0x703A,
41fc1a79d9SHeiko Schocher 	  0x7270,
42fc1a79d9SHeiko Schocher 	  0x70B1,
43fc1a79d9SHeiko Schocher 	  0x7208,
44fc1a79d9SHeiko Schocher 	  0x723B,
45fc1a79d9SHeiko Schocher 	  0x720F,
46fc1a79d9SHeiko Schocher 	  0x70B2,
47fc1a79d9SHeiko Schocher 	  0x7200,
48fc1a79d9SHeiko Schocher 	  0x72C8,
49fc1a79d9SHeiko Schocher 	  0x70B3,
50fc1a79d9SHeiko Schocher 	  0x7200,
51fc1a79d9SHeiko Schocher 	  0x70B4,
52fc1a79d9SHeiko Schocher 	  0x7200,
53fc1a79d9SHeiko Schocher 	  0x70B5,
54fc1a79d9SHeiko Schocher 	  0x7242,
55fc1a79d9SHeiko Schocher 	  0x7210,
56fc1a79d9SHeiko Schocher 	  0x7210,
57fc1a79d9SHeiko Schocher 	  0x7200,
58fc1a79d9SHeiko Schocher 	  0x7220,
59fc1a79d9SHeiko Schocher 	  0x70B6,
60fc1a79d9SHeiko Schocher 	  0x720B,
61fc1a79d9SHeiko Schocher 	  0x720F,
62fc1a79d9SHeiko Schocher 	  0x723C,
63fc1a79d9SHeiko Schocher 	  0x7213,
64fc1a79d9SHeiko Schocher 	  0x7213,
65fc1a79d9SHeiko Schocher 	  0x72E8,
66fc1a79d9SHeiko Schocher 	  0x70B7,
67fc1a79d9SHeiko Schocher 	  0x7246,
68fc1a79d9SHeiko Schocher 	  0x7206,
69fc1a79d9SHeiko Schocher 	  0x720C,
70fc1a79d9SHeiko Schocher 	  0x7200,
71fc1a79d9SHeiko Schocher 	  0x7200,
72fc1a79d9SHeiko Schocher 	};
73fc1a79d9SHeiko Schocher 
74fc1a79d9SHeiko Schocher 	debug("transfer display mode settings\n");
75fc1a79d9SHeiko Schocher 	lb043wv_spi_write_u16_array(spi, display_mode_settings,
76fc1a79d9SHeiko Schocher 				    ARRAY_SIZE(display_mode_settings));
77fc1a79d9SHeiko Schocher }
78fc1a79d9SHeiko Schocher 
lb043wv_power_settings(struct spi_slave * spi)79fc1a79d9SHeiko Schocher static void lb043wv_power_settings(struct spi_slave *spi)
80fc1a79d9SHeiko Schocher {
81fc1a79d9SHeiko Schocher 	static u16 power_settings[] = {
82fc1a79d9SHeiko Schocher 	  0x70C0,
83fc1a79d9SHeiko Schocher 	  0x7201,
84fc1a79d9SHeiko Schocher 	  0x7211,
85fc1a79d9SHeiko Schocher 	  0x70C3,
86fc1a79d9SHeiko Schocher 	  0x7207,
87fc1a79d9SHeiko Schocher 	  0x7203,
88fc1a79d9SHeiko Schocher 	  0x7204,
89fc1a79d9SHeiko Schocher 	  0x7204,
90fc1a79d9SHeiko Schocher 	  0x7204,
91fc1a79d9SHeiko Schocher 	  0x70C4,
92fc1a79d9SHeiko Schocher 	  0x7212,
93fc1a79d9SHeiko Schocher 	  0x7224,
94fc1a79d9SHeiko Schocher 	  0x7218,
95fc1a79d9SHeiko Schocher 	  0x7218,
96fc1a79d9SHeiko Schocher 	  0x7202,
97fc1a79d9SHeiko Schocher 	  0x7249,
98fc1a79d9SHeiko Schocher 	  0x70C5,
99fc1a79d9SHeiko Schocher 	  0x726F,
100fc1a79d9SHeiko Schocher 	  0x70C6,
101fc1a79d9SHeiko Schocher 	  0x7241,
102fc1a79d9SHeiko Schocher 	  0x7263,
103fc1a79d9SHeiko Schocher 	};
104fc1a79d9SHeiko Schocher 
105fc1a79d9SHeiko Schocher 	debug("transfer power settings\n");
106fc1a79d9SHeiko Schocher 	lb043wv_spi_write_u16_array(spi, power_settings,
107fc1a79d9SHeiko Schocher 				    ARRAY_SIZE(power_settings));
108fc1a79d9SHeiko Schocher }
109fc1a79d9SHeiko Schocher 
lb043wv_gamma_settings(struct spi_slave * spi)110fc1a79d9SHeiko Schocher static void lb043wv_gamma_settings(struct spi_slave *spi)
111fc1a79d9SHeiko Schocher {
112fc1a79d9SHeiko Schocher 	static u16 gamma_settings[] = {
113fc1a79d9SHeiko Schocher 	  0x70D0,
114fc1a79d9SHeiko Schocher 	  0x7203,
115fc1a79d9SHeiko Schocher 	  0x7207,
116fc1a79d9SHeiko Schocher 	  0x7273,
117fc1a79d9SHeiko Schocher 	  0x7235,
118fc1a79d9SHeiko Schocher 	  0x7200,
119fc1a79d9SHeiko Schocher 	  0x7201,
120fc1a79d9SHeiko Schocher 	  0x7220,
121fc1a79d9SHeiko Schocher 	  0x7200,
122fc1a79d9SHeiko Schocher 	  0x7203,
123fc1a79d9SHeiko Schocher 	  0x70D1,
124fc1a79d9SHeiko Schocher 	  0x7203,
125fc1a79d9SHeiko Schocher 	  0x7207,
126fc1a79d9SHeiko Schocher 	  0x7273,
127fc1a79d9SHeiko Schocher 	  0x7235,
128fc1a79d9SHeiko Schocher 	  0x7200,
129fc1a79d9SHeiko Schocher 	  0x7201,
130fc1a79d9SHeiko Schocher 	  0x7220,
131fc1a79d9SHeiko Schocher 	  0x7200,
132fc1a79d9SHeiko Schocher 	  0x7203,
133fc1a79d9SHeiko Schocher 	  0x70D2,
134fc1a79d9SHeiko Schocher 	  0x7203,
135fc1a79d9SHeiko Schocher 	  0x7207,
136fc1a79d9SHeiko Schocher 	  0x7273,
137fc1a79d9SHeiko Schocher 	  0x7235,
138fc1a79d9SHeiko Schocher 	  0x7200,
139fc1a79d9SHeiko Schocher 	  0x7201,
140fc1a79d9SHeiko Schocher 	  0x7220,
141fc1a79d9SHeiko Schocher 	  0x7200,
142fc1a79d9SHeiko Schocher 	  0x7203,
143fc1a79d9SHeiko Schocher 	  0x70D3,
144fc1a79d9SHeiko Schocher 	  0x7203,
145fc1a79d9SHeiko Schocher 	  0x7207,
146fc1a79d9SHeiko Schocher 	  0x7273,
147fc1a79d9SHeiko Schocher 	  0x7235,
148fc1a79d9SHeiko Schocher 	  0x7200,
149fc1a79d9SHeiko Schocher 	  0x7201,
150fc1a79d9SHeiko Schocher 	  0x7220,
151fc1a79d9SHeiko Schocher 	  0x7200,
152fc1a79d9SHeiko Schocher 	  0x7203,
153fc1a79d9SHeiko Schocher 	  0x70D4,
154fc1a79d9SHeiko Schocher 	  0x7203,
155fc1a79d9SHeiko Schocher 	  0x7207,
156fc1a79d9SHeiko Schocher 	  0x7273,
157fc1a79d9SHeiko Schocher 	  0x7235,
158fc1a79d9SHeiko Schocher 	  0x7200,
159fc1a79d9SHeiko Schocher 	  0x7201,
160fc1a79d9SHeiko Schocher 	  0x7220,
161fc1a79d9SHeiko Schocher 	  0x7200,
162fc1a79d9SHeiko Schocher 	  0x7203,
163fc1a79d9SHeiko Schocher 	  0x70D5,
164fc1a79d9SHeiko Schocher 	  0x7203,
165fc1a79d9SHeiko Schocher 	  0x7207,
166fc1a79d9SHeiko Schocher 	  0x7273,
167fc1a79d9SHeiko Schocher 	  0x7235,
168fc1a79d9SHeiko Schocher 	  0x7200,
169fc1a79d9SHeiko Schocher 	  0x7201,
170fc1a79d9SHeiko Schocher 	  0x7220,
171fc1a79d9SHeiko Schocher 	  0x7200,
172fc1a79d9SHeiko Schocher 	  0x7203,
173fc1a79d9SHeiko Schocher 	};
174fc1a79d9SHeiko Schocher 
175fc1a79d9SHeiko Schocher 	debug("transfer gamma settings\n");
176fc1a79d9SHeiko Schocher 	lb043wv_spi_write_u16_array(spi, gamma_settings,
177fc1a79d9SHeiko Schocher 				    ARRAY_SIZE(gamma_settings));
178fc1a79d9SHeiko Schocher }
179fc1a79d9SHeiko Schocher 
lb043wv_display_on(struct spi_slave * spi)180fc1a79d9SHeiko Schocher static void lb043wv_display_on(struct spi_slave *spi)
181fc1a79d9SHeiko Schocher {
182fc1a79d9SHeiko Schocher 	static u16 sleep_out = 0x7011;
183fc1a79d9SHeiko Schocher 	static u16 display_on = 0x7029;
184fc1a79d9SHeiko Schocher 
185fc1a79d9SHeiko Schocher 	lb043wv_spi_write_u16(spi, sleep_out);
186fc1a79d9SHeiko Schocher 	mdelay(PWR_ON_DELAY_MSECS);
187fc1a79d9SHeiko Schocher 	lb043wv_spi_write_u16(spi, display_on);
188fc1a79d9SHeiko Schocher }
189fc1a79d9SHeiko Schocher 
lg4573_spi_startup(unsigned int bus,unsigned int cs,unsigned int max_hz,unsigned int spi_mode)190fc1a79d9SHeiko Schocher int lg4573_spi_startup(unsigned int bus, unsigned int cs,
191fc1a79d9SHeiko Schocher 	unsigned int max_hz, unsigned int spi_mode)
192fc1a79d9SHeiko Schocher {
193fc1a79d9SHeiko Schocher 	struct spi_slave *spi;
194fc1a79d9SHeiko Schocher 	int ret;
195fc1a79d9SHeiko Schocher 
196fc1a79d9SHeiko Schocher 	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
197fc1a79d9SHeiko Schocher 	if (!spi) {
198fc1a79d9SHeiko Schocher 		debug("%s: Failed to set up slave\n", __func__);
199fc1a79d9SHeiko Schocher 		return -1;
200fc1a79d9SHeiko Schocher 	}
201fc1a79d9SHeiko Schocher 
202fc1a79d9SHeiko Schocher 	ret = spi_claim_bus(spi);
203fc1a79d9SHeiko Schocher 	if (ret) {
204fc1a79d9SHeiko Schocher 		debug("%s: Failed to claim SPI bus: %d\n", __func__, ret);
205fc1a79d9SHeiko Schocher 		goto err_claim_bus;
206fc1a79d9SHeiko Schocher 	}
207fc1a79d9SHeiko Schocher 
208fc1a79d9SHeiko Schocher 	lb043wv_display_mode_settings(spi);
209fc1a79d9SHeiko Schocher 	lb043wv_power_settings(spi);
210fc1a79d9SHeiko Schocher 	lb043wv_gamma_settings(spi);
211fc1a79d9SHeiko Schocher 
212fc1a79d9SHeiko Schocher 	lb043wv_display_on(spi);
213fc1a79d9SHeiko Schocher 	return 0;
214fc1a79d9SHeiko Schocher err_claim_bus:
215fc1a79d9SHeiko Schocher 	spi_free_slave(spi);
216fc1a79d9SHeiko Schocher 	return -1;
217fc1a79d9SHeiko Schocher }
218fc1a79d9SHeiko Schocher 
do_lgset(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])219fc1a79d9SHeiko Schocher static int do_lgset(cmd_tbl_t *cmdtp, int flag, int argc,
220fc1a79d9SHeiko Schocher 		       char * const argv[])
221fc1a79d9SHeiko Schocher {
222c4e498d9SHeiko Schocher 	lg4573_spi_startup(CONFIG_LG4573_BUS, CONFIG_LG4573_CS, 10000000,
223c4e498d9SHeiko Schocher 			   SPI_MODE_0);
224fc1a79d9SHeiko Schocher 	return 0;
225fc1a79d9SHeiko Schocher }
226fc1a79d9SHeiko Schocher 
227fc1a79d9SHeiko Schocher U_BOOT_CMD(
228fc1a79d9SHeiko Schocher 	lgset,	2,	1,	do_lgset,
229fc1a79d9SHeiko Schocher 	"set lgdisplay",
230fc1a79d9SHeiko Schocher 	""
231fc1a79d9SHeiko Schocher );
232