blob: 193786288985b72b3e1c0e75b8cd204c44032ab8 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001#include <common.h>
2#include <malloc.h>
3#include <asm/gpio.h>
4#include "lcd.h"
5
6#define LCD_SUB_ID_CNT 3
7static u8 sub_id_reg[LCD_SUB_ID_CNT] = {0xDA, 0xDB, 0xDC};
8
9struct lcd_sub_id {
10 u8 val;
11 u8 mask;
12};
13
14struct lcd_info {
15 const char *name;
16 u8 type;
17 struct lcd_sub_id sub_id[LCD_SUB_ID_CNT];
18};
19
20static struct lcd_info lcd_info[] = {
21 {"st7735", PANEL_ST7735, {{0x7C, 0x7F}, {0x89, 0xFE}, {0xF0, 0xFF}}},
22 {"gc9102", PANEL_GC9102, {{0x00, 0xFF}, {0x91, 0xFF}, {0x02, 0xFF}}},
23 {"gc9106", PANEL_GC9106, {{0x00, 0xFF}, {0x91, 0xFF}, {0x06, 0xFF}}},
24};
25
26static inline void SPI_DELAY(u16 a)
27{
28 while (a--)
29 nop();
30}
31
32static inline void LCD_SELECT_DATA_OR_CMD(u16 a)
33{
34#ifndef CONFIG_SPI_LCD_3WIRE
35 gpio_direction_output(CONFIG_SPI_LCD_RS_PIN, a);
36#endif
37}
38
39void LCD_SEND_DATA(void)
40{
41 LCD_SELECT_DATA_OR_CMD(1);
42}
43
44void LCD_SEND_CMD(void)
45{
46 LCD_SELECT_DATA_OR_CMD(0);
47}
48
49static inline void SPI_CS(u16 a)
50{
51 gpio_direction_output(CONFIG_SPI_LCD_CS_PIN, a);
52}
53
54static inline void SPI_SCL(u16 a)
55{
56 gpio_direction_output(CONFIG_SPI_LCD_SCL_PIN, a);
57}
58
59static inline void SPI_TX(u16 a)
60{
61 gpio_direction_output(CONFIG_SPI_LCD_TX_PIN, a);
62}
63
64static inline u8 SPI_READ(void)
65{
66 return !!gpio_get_value(CONFIG_SPI_LCD_TX_PIN);
67}
68
69static inline void SPI_TX_TO_RX(void)
70{
71 gpio_direction_input(CONFIG_SPI_LCD_TX_PIN);
72}
73
74static u8 __lcd_readid(u8 reg)
75{
76 LCD_SEND_CMD();
77 SPI_CS(0);
78 u16 cmd = reg;
79 int i;
80 int bits, mask;
81 /* May need to tune this delay for different panel.
82 * For ST7735, this delay can be set to 0.
83 */
84 u16 delay = 0;
85
86#ifdef CONFIG_SPI_LCD_3WIRE
87 bits = 9;
88 mask = 0x100;
89#else
90 bits = 8;
91 mask = 0x80;
92#endif
93 for (i = 0; i < bits; i++)
94 {
95 SPI_TX(cmd & mask);
96 SPI_DELAY(delay);
97 SPI_SCL(1);
98 SPI_DELAY(delay);
99 SPI_SCL(0);
100 cmd <<= 1;
101 }
102
103 SPI_TX_TO_RX();
104
105 cmd = 0;
106 for (i = 0; i < 8; i++)
107 {
108 SPI_DELAY(delay);
109 SPI_SCL(1);
110 cmd <<= 1;
111 cmd |= SPI_READ();
112 SPI_SCL(0);
113 }
114
115 SPI_CS(1);
116 printf("LCD ID 0x%x: 0x%x\n", reg, cmd);
117 return cmd;
118}
119
120static u8 check_id(u8 id, u8 mask, u8 val)
121{
122 if ((val & mask) == (id & mask))
123 return 0;
124 return 1;
125}
126
127u8 lcd_gettype(void)
128{
129 u32 id = 0;
130 int i;
131 u8 id1, id2, id3;
132 u8 type = 0;
133
134 lcd_readid_pin_config();
135 lcd_power(1);
136 lcd_reset();
137 for (i = 0; i < LCD_SUB_ID_CNT; i++) {
138 id <<= 8;
139 id |= __lcd_readid(sub_id_reg[i]);
140 }
141 lcd_readid_pin_restore();
142
143 id1 = (id & 0xFF0000) >> 16;
144 id2 = (id & 0xFF00) >> 8;
145 id3 = id & 0xFF;
146
147 for (i = 0; i < sizeof(lcd_info) / sizeof(lcd_info[0]); i++) {
148 if (check_id(id1, lcd_info[i].sub_id[0].mask, lcd_info[i].sub_id[0].val) == 0 &&
149 check_id(id2, lcd_info[i].sub_id[1].mask, lcd_info[i].sub_id[1].val) == 0 &&
150 check_id(id3, lcd_info[i].sub_id[2].mask, lcd_info[i].sub_id[2].val) == 0)
151 {
152 printf("LCD Name: %s, ID: 0x%x, Type: %d\n",
153 lcd_info[i].name, id, lcd_info[i].type);
154 type = lcd_info[i].type;
155 goto end;
156 }
157 }
158
159 printf("UNSUPPORTTED LCD ID: 0x%x, Type: 0\n", id);
160end:
161 return type;
162}