Skip to content

Commit 02addd9

Browse files
committed
fbtft: spi: asynchronous SPI refresh
Signed-off-by: Vincent-FK <vincent.buso@funkey-project.com>
1 parent 245ff7f commit 02addd9

7 files changed

Lines changed: 435 additions & 34 deletions

File tree

arch/arm/boot/dts/sun8i-v3s-funkey.dts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,9 @@
177177
reg = <0>;
178178
spi-max-frequency = <50000000>;
179179
txbuflen = <115202>;
180+
spi_async_mode = "true";
180181
rotate = <0>;
181-
fps = <50>;
182+
fps = <100>;
182183
buswidth = <8>;
183184
reset-gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; //PB2
184185
dc-gpios = <&pio 2 0 GPIO_ACTIVE_LOW>; //PC0 (MISO)

drivers/staging/fbtft/fb_st7789v.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,16 @@ static int init_display(struct fbtft_par *par)
152152
/* Display Inversion of colors */
153153
write_reg(par, 0x21);
154154

155-
/* 39Hz refresh rate */
156-
write_reg(par, 0xC6,0x1F);
155+
/* refresh rate */
156+
//write_reg(par, 0xC6,0x1F); //39Hz
157+
//write_reg(par, 0xC6,0x1A); //44Hz
158+
//write_reg(par, 0xC6,0x17); //48Hz
159+
//write_reg(par, 0xC6,0x15); //50Hz
160+
//write_reg(par, 0xC6,0x12); //55Hz
161+
//write_reg(par, 0xC6,0x10); //58Hz
162+
//write_reg(par, 0xC6,0x0F); //60Hz
163+
write_reg(par, 0xC6,0x09); //60Hz
164+
//write_reg(par, 0xC6,0x03); //99Hz
157165

158166
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
159167

drivers/staging/fbtft/fbtft-bus.c

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
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
}
106108
EXPORT_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

Comments
 (0)