3434#include <drm/drm_panel.h>
3535
3636#include <video/display_timing.h>
37+ #include <video/mipi_display.h>
3738#include <video/of_display_timing.h>
3839#include <video/videomode.h>
3940
41+ struct dsi_ctrl_hdr {
42+ u8 dtype ; /* data type */
43+ u8 wait ; /* ms */
44+ u16 dlen ; /* payload len */
45+ } __packed ;
46+
47+ struct dsi_cmd_desc {
48+ struct dsi_ctrl_hdr dchdr ;
49+ u8 * payload ;
50+ };
51+
52+ struct dsi_panel_cmds {
53+ u8 * buf ;
54+ int blen ;
55+ struct dsi_cmd_desc * cmds ;
56+ int cmd_cnt ;
57+ };
58+
4059struct panel_desc {
4160 const struct drm_display_mode * modes ;
4261 unsigned int num_modes ;
@@ -73,6 +92,7 @@ struct panel_desc {
7392
7493struct panel_simple {
7594 struct drm_panel base ;
95+ struct mipi_dsi_device * dsi ;
7696 bool prepared ;
7797 bool enabled ;
7898
@@ -84,13 +104,143 @@ struct panel_simple {
84104 struct i2c_adapter * ddc ;
85105
86106 struct gpio_desc * enable_gpio ;
107+ struct gpio_desc * reset_gpio ;
108+ unsigned int reset_delay ;
109+
110+ struct dsi_panel_cmds * on_cmds ;
111+ struct dsi_panel_cmds * off_cmds ;
87112};
88113
89114static inline struct panel_simple * to_panel_simple (struct drm_panel * panel )
90115{
91116 return container_of (panel , struct panel_simple , base );
92117}
93118
119+ static void panel_simple_dsi_cmds_cleanup (struct panel_simple * p )
120+ {
121+ if (p -> on_cmds ) {
122+ kfree (p -> on_cmds -> buf );
123+ kfree (p -> on_cmds -> cmds );
124+ }
125+
126+ if (p -> off_cmds ) {
127+ kfree (p -> off_cmds -> buf );
128+ kfree (p -> off_cmds -> cmds );
129+ }
130+ }
131+
132+ static int panel_simple_dsi_parse_dcs_cmds (struct device * dev ,
133+ const u8 * data , int blen ,
134+ struct dsi_panel_cmds * pcmds )
135+ {
136+ int len ;
137+ char * buf , * bp ;
138+ struct dsi_ctrl_hdr * dchdr ;
139+ int i , cnt ;
140+
141+ if (!pcmds )
142+ return - EINVAL ;
143+
144+ buf = kmemdup (data , blen , GFP_KERNEL );
145+ if (!buf )
146+ return - ENOMEM ;
147+
148+ /* scan dcs commands */
149+ bp = buf ;
150+ len = blen ;
151+ cnt = 0 ;
152+ while (len > sizeof (* dchdr )) {
153+ dchdr = (struct dsi_ctrl_hdr * )bp ;
154+ dchdr -> dlen = ntohs (dchdr -> dlen );
155+
156+ if (dchdr -> dlen > len ) {
157+ dev_err (dev , "%s: error, len=%d" , __func__ ,
158+ dchdr -> dlen );
159+ return - EINVAL ;
160+ }
161+
162+ bp += sizeof (* dchdr );
163+ len -= sizeof (* dchdr );
164+ bp += dchdr -> dlen ;
165+ len -= dchdr -> dlen ;
166+ cnt ++ ;
167+ }
168+
169+ if (len != 0 ) {
170+ dev_err (dev , "%s: dcs_cmd=%x len=%d error!" ,
171+ __func__ , buf [0 ], blen );
172+ kfree (buf );
173+ return - EINVAL ;
174+ }
175+
176+ pcmds -> cmds = kcalloc (cnt , sizeof (struct dsi_cmd_desc ), GFP_KERNEL );
177+ if (!pcmds -> cmds ) {
178+ kfree (buf );
179+ return - ENOMEM ;
180+ }
181+
182+ pcmds -> cmd_cnt = cnt ;
183+ pcmds -> buf = buf ;
184+ pcmds -> blen = blen ;
185+
186+ bp = buf ;
187+ len = blen ;
188+ for (i = 0 ; i < cnt ; i ++ ) {
189+ dchdr = (struct dsi_ctrl_hdr * )bp ;
190+ len -= sizeof (* dchdr );
191+ bp += sizeof (* dchdr );
192+ pcmds -> cmds [i ].dchdr = * dchdr ;
193+ pcmds -> cmds [i ].payload = bp ;
194+ bp += dchdr -> dlen ;
195+ len -= dchdr -> dlen ;
196+ }
197+
198+ dev_info (dev , "%s: dcs_cmd=%x len=%d, cmd_cnt=%d\n" , __func__ ,
199+ pcmds -> buf [0 ], pcmds -> blen , pcmds -> cmd_cnt );
200+ return 0 ;
201+ }
202+
203+ static int panel_simple_dsi_send_cmds (struct panel_simple * panel ,
204+ struct dsi_panel_cmds * cmds )
205+ {
206+ struct mipi_dsi_device * dsi = panel -> dsi ;
207+ int i , err ;
208+
209+ if (!cmds )
210+ return - EINVAL ;
211+
212+ for (i = 0 ; i < cmds -> cmd_cnt ; i ++ ) {
213+ struct dsi_cmd_desc * cmd = & cmds -> cmds [i ];
214+
215+ switch (cmd -> dchdr .dtype ) {
216+ case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM :
217+ case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM :
218+ case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM :
219+ case MIPI_DSI_GENERIC_LONG_WRITE :
220+ err = mipi_dsi_generic_write (dsi , cmd -> payload ,
221+ cmd -> dchdr .dlen );
222+ break ;
223+ case MIPI_DSI_DCS_SHORT_WRITE :
224+ case MIPI_DSI_DCS_SHORT_WRITE_PARAM :
225+ case MIPI_DSI_DCS_LONG_WRITE :
226+ err = mipi_dsi_dcs_write_buffer (dsi , cmd -> payload ,
227+ cmd -> dchdr .dlen );
228+ break ;
229+ default :
230+ return - EINVAL ;
231+ }
232+
233+ if (err )
234+ dev_err (panel -> dev , "failed to write dcs cmd: %d\n" ,
235+ err );
236+
237+ if (cmd -> dchdr .wait )
238+ msleep (cmd -> dchdr .wait );
239+ }
240+
241+ return 0 ;
242+ }
243+
94244static int panel_simple_get_fixed_modes (struct panel_simple * panel )
95245{
96246 struct drm_connector * connector = panel -> base .connector ;
@@ -204,10 +354,20 @@ static int panel_simple_disable(struct drm_panel *panel)
204354static int panel_simple_unprepare (struct drm_panel * panel )
205355{
206356 struct panel_simple * p = to_panel_simple (panel );
357+ int err ;
207358
208359 if (!p -> prepared )
209360 return 0 ;
210361
362+ if (p -> off_cmds ) {
363+ err = panel_simple_dsi_send_cmds (p , p -> off_cmds );
364+ if (err )
365+ dev_err (p -> dev , "failed to send off cmds\n" );
366+ }
367+
368+ if (p -> reset_gpio )
369+ gpiod_direction_output (p -> reset_gpio , 1 );
370+
211371 if (p -> enable_gpio )
212372 gpiod_direction_output (p -> enable_gpio , 0 );
213373
@@ -241,6 +401,15 @@ static int panel_simple_prepare(struct drm_panel *panel)
241401 if (p -> desc && p -> desc -> delay .prepare )
242402 msleep (p -> desc -> delay .prepare );
243403
404+ if (p -> reset_gpio )
405+ gpiod_direction_output (p -> reset_gpio , 1 );
406+
407+ if (p -> reset_delay )
408+ msleep (p -> reset_delay );
409+
410+ if (p -> reset_gpio )
411+ gpiod_direction_output (p -> reset_gpio , 0 );
412+
244413 p -> prepared = true;
245414
246415 return 0 ;
@@ -249,10 +418,17 @@ static int panel_simple_prepare(struct drm_panel *panel)
249418static int panel_simple_enable (struct drm_panel * panel )
250419{
251420 struct panel_simple * p = to_panel_simple (panel );
421+ int err ;
252422
253423 if (p -> enabled )
254424 return 0 ;
255425
426+ if (p -> on_cmds ) {
427+ err = panel_simple_dsi_send_cmds (p , p -> on_cmds );
428+ if (err )
429+ dev_err (p -> dev , "failed to send on cmds\n" );
430+ }
431+
256432 if (p -> desc && p -> desc -> delay .enable )
257433 msleep (p -> desc -> delay .enable );
258434
@@ -359,7 +535,14 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
359535 panel -> enable_gpio = devm_gpiod_get_optional (dev , "enable" , 0 );
360536 if (IS_ERR (panel -> enable_gpio )) {
361537 err = PTR_ERR (panel -> enable_gpio );
362- dev_err (dev , "failed to request GPIO: %d\n" , err );
538+ dev_err (dev , "failed to request enable GPIO: %d\n" , err );
539+ return err ;
540+ }
541+
542+ panel -> reset_gpio = devm_gpiod_get_optional (dev , "reset" , 0 );
543+ if (IS_ERR (panel -> reset_gpio )) {
544+ err = PTR_ERR (panel -> reset_gpio );
545+ dev_err (dev , "failed to request reset GPIO: %d\n" , err );
363546 return err ;
364547 }
365548
@@ -420,6 +603,8 @@ static int panel_simple_remove(struct device *dev)
420603 if (panel -> backlight )
421604 put_device (& panel -> backlight -> dev );
422605
606+ panel_simple_dsi_cmds_cleanup (panel );
607+
423608 return 0 ;
424609}
425610
@@ -1718,9 +1903,12 @@ MODULE_DEVICE_TABLE(of, dsi_of_match);
17181903
17191904static int panel_simple_dsi_probe (struct mipi_dsi_device * dsi )
17201905{
1906+ struct panel_simple * panel ;
17211907 const struct panel_desc_dsi * desc ;
17221908 const struct of_device_id * id ;
17231909 const struct panel_desc * pdesc ;
1910+ const void * data ;
1911+ int len ;
17241912 u32 val ;
17251913 int err ;
17261914
@@ -1743,6 +1931,9 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
17431931 if (err < 0 )
17441932 return err ;
17451933
1934+ panel = dev_get_drvdata (& dsi -> dev );
1935+ panel -> dsi = dsi ;
1936+
17461937 if (!of_property_read_u32 (dsi -> dev .of_node , "dsi,flags" , & val ))
17471938 dsi -> mode_flags = val ;
17481939
@@ -1752,6 +1943,41 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
17521943 if (!of_property_read_u32 (dsi -> dev .of_node , "dsi,lanes" , & val ))
17531944 dsi -> lanes = val ;
17541945
1946+ if (!of_property_read_u32 (dsi -> dev .of_node , "reset-delay-ms" , & val ))
1947+ panel -> reset_delay = val ;
1948+
1949+ data = of_get_property (dsi -> dev .of_node , "panel-init-sequence" , & len );
1950+ if (data ) {
1951+ panel -> on_cmds = devm_kzalloc (& dsi -> dev ,
1952+ sizeof (* panel -> on_cmds ),
1953+ GFP_KERNEL );
1954+ if (!panel -> on_cmds )
1955+ return - ENOMEM ;
1956+
1957+ err = panel_simple_dsi_parse_dcs_cmds (& dsi -> dev , data , len ,
1958+ panel -> on_cmds );
1959+ if (err ) {
1960+ dev_err (& dsi -> dev , "failed to parse panel init sequence\n" );
1961+ return err ;
1962+ }
1963+ }
1964+
1965+ data = of_get_property (dsi -> dev .of_node , "panel-exit-sequence" , & len );
1966+ if (data ) {
1967+ panel -> off_cmds = devm_kzalloc (& dsi -> dev ,
1968+ sizeof (* panel -> off_cmds ),
1969+ GFP_KERNEL );
1970+ if (!panel -> off_cmds )
1971+ return - ENOMEM ;
1972+
1973+ err = panel_simple_dsi_parse_dcs_cmds (& dsi -> dev , data , len ,
1974+ panel -> off_cmds );
1975+ if (err ) {
1976+ dev_err (& dsi -> dev , "failed to parse panel exit sequence\n" );
1977+ return err ;
1978+ }
1979+ }
1980+
17551981 return mipi_dsi_attach (dsi );
17561982}
17571983
0 commit comments