33#include <linux/errno.h>
44#include <linux/gpio.h>
55#include <linux/spi/spi.h>
6+ #include <linux/delay.h> /* usleep_range */
7+ #include <video/mipi_display.h>
68#include "fbtft.h"
79
810/*****************************************************************************
@@ -105,6 +107,141 @@ void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...)
105107}
106108EXPORT_SYMBOL (fbtft_write_reg8_bus9 );
107109
110+ static void spi_complete_cmd_init_data_write (void * arg )
111+ {
112+ struct fbtft_par * par = (struct fbtft_par * )arg ;
113+ // printk("%s\n", __func__);
114+
115+ /* Start new data write (full display) */
116+ int len = par -> info -> var .yres * par -> info -> fix .line_length ;
117+ fbtft_write_vmem16_bus8_async (par , 0 , len );
118+ }
119+
120+ static void spi_complete_data_write (void * arg )
121+ {
122+ struct fbtft_par * par = (struct fbtft_par * )arg ;
123+ // printk("%s\n", __func__);
124+
125+ /* sleep */
126+ // msleep(1);
127+
128+ /* Start sending cmd init data */
129+ fbtft_write_init_cmd_data_transfers (par );
130+ }
131+
132+ int fbtft_write_init_cmd_data_transfers (struct fbtft_par * par )
133+ {
134+ static u8 init_data_cmd_buf = MIPI_DCS_WRITE_MEMORY_START ;
135+ int ret = 0 ;
136+
137+ // printk("%s\n", __func__);
138+
139+ /* Resetting to 0 for incoming cmd init data write */
140+ if (gpio_is_valid (par -> gpio .dc ))
141+ gpio_set_value (par -> gpio .dc , 0 );
142+
143+ /* Start sending cmd init data */
144+ ret = par -> fbtftops .write_async (par , & init_data_cmd_buf , 1 ,
145+ spi_complete_cmd_init_data_write );
146+ if (ret < 0 )
147+ dev_err (par -> info -> device , "write() failed and returned %d\n" , ret );
148+
149+ /* Debug fps */
150+ #define FPS_DEBUG 0
151+ #if FPS_DEBUG
152+ ktime_t ts_now = ktime_get ();
153+
154+ /* First measurement */
155+ if (!ktime_to_ns (par -> update_time ))
156+ par -> update_time = ts_now ;
157+
158+ long fps = ktime_us_delta (ts_now , par -> update_time );
159+ par -> update_time = ts_now ;
160+ fps = fps ? 1000000 / fps : 0 ;
161+
162+ if (fps ) {
163+ par -> avg_fps += fps ;
164+ par -> nb_fps_values ++ ;
165+
166+ if (par -> nb_fps_values == 200 ) {
167+ dev_info (par -> info -> device , "Display update: fps=%ld\n" ,
168+ par -> avg_fps / par -> nb_fps_values );
169+ par -> avg_fps = 0 ;
170+ par -> nb_fps_values = 0 ;
171+ }
172+ }
173+
174+ #endif // FPS_DEBUG
175+
176+ return ret ;
177+ }
178+ EXPORT_SYMBOL (fbtft_write_init_cmd_data_transfers );
179+
180+ /*****************************************************************************
181+ *
182+ * int (*write_vmem)(struct fbtft_par *par);
183+ *
184+ *****************************************************************************/
185+
186+ /* 16 bit pixel over 8-bit databus */
187+ int fbtft_write_vmem16_bus8_async (struct fbtft_par * par , size_t offset , size_t len )
188+ {
189+ u16 * vmem16 ;
190+ __be16 * txbuf16 = par -> txbuf .buf ;
191+ size_t remain ;
192+ size_t to_copy ;
193+ size_t tx_array_size ;
194+ int i ;
195+ int ret = 0 ;
196+ size_t startbyte_size = 0 ;
197+
198+ fbtft_par_dbg (DEBUG_WRITE_VMEM , par , "%s(offset=%zu, len=%zu)\n" ,
199+ __func__ , offset , len );
200+
201+ remain = len / 2 ;
202+ //vmem16 = (u16 *)(par->info->screen_buffer + offset);
203+ //vmem16 = (u16 *)(par->vmem_post_process + offset);
204+ vmem16 = (u16 * )(par -> vmem_ptr + offset );
205+
206+ if (par -> gpio .dc != -1 )
207+ gpio_set_value (par -> gpio .dc , 1 );
208+
209+ /* non buffered write */
210+ if (!par -> txbuf .buf ){
211+ //return par->fbtftops.write(par, vmem16, len);
212+ return par -> fbtftops .write_async (par , vmem16 , len , spi_complete_data_write );
213+ }
214+
215+ /* buffered write */
216+ tx_array_size = par -> txbuf .len / 2 ;
217+
218+ if (par -> startbyte ) {
219+ txbuf16 = par -> txbuf .buf + 1 ;
220+ tx_array_size -= 2 ;
221+ * (u8 * )(par -> txbuf .buf ) = par -> startbyte | 0x2 ;
222+ startbyte_size = 1 ;
223+ }
224+
225+ while (remain ) {
226+ to_copy = min (tx_array_size , remain );
227+ dev_dbg (par -> info -> device , " to_copy=%zu, remain=%zu\n" ,
228+ to_copy , remain - to_copy );
229+
230+ for (i = 0 ; i < to_copy ; i ++ )
231+ txbuf16 [i ] = cpu_to_be16 (vmem16 [i ]);
232+
233+ vmem16 = vmem16 + to_copy ;
234+ ret = par -> fbtftops .write_async (par , par -> txbuf .buf ,
235+ startbyte_size + to_copy * 2 , spi_complete_data_write );
236+ if (ret < 0 )
237+ return ret ;
238+ remain -= to_copy ;
239+ }
240+
241+ return ret ;
242+ }
243+ EXPORT_SYMBOL (fbtft_write_vmem16_bus8_async );
244+
108245/*****************************************************************************
109246 *
110247 * int (*write_vmem)(struct fbtft_par *par);
@@ -127,7 +264,7 @@ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
127264 __func__ , offset , len );
128265
129266 remain = len / 2 ;
130- vmem16 = (u16 * )(par -> info -> screen_buffer + offset );
267+ vmem16 = (u16 * )(par -> vmem_ptr + offset );
131268
132269 if (par -> gpio .dc != -1 )
133270 gpio_set_value (par -> gpio .dc , 1 );
0 commit comments