summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0041-st7735fb-Working-WIP-changes-to-make-DMA-safe-and-ad.patch
blob: ffbcb6f2704e09e60e1e9f16e2550b018753b6bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
From 7f97d002d17f8de8cde7f248bb1c194172360efe Mon Sep 17 00:00:00 2001
From: Matt Porter <mporter@ti.com>
Date: Wed, 28 Mar 2012 23:35:44 -0400
Subject: [PATCH 41/79] st7735fb: Working WIP changes to make DMA safe and add
 endian fix

This removes the "from the stack" allocation of 1 byte buffers
that was a temporary thing and isn't dma safe. Now vmallocs the
user buffer to be deferred I/O safe and kmallocs a swapped
shadow buffer to support the byte swabbing hack to fix userspace
limitations.

The buffer allocation and endian hack code needs some serious
cleanup as on big endian systems if would fail miserably atm.
However, the LE path works for the moment so people can do something
with the driver.

Signed-off-by: Matt Porter <mporter@ti.com>
---
 drivers/video/st7735fb.c |   49 ++++++++++++++++++++++++++++++----------------
 include/video/st7735fb.h |    2 ++
 2 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/drivers/video/st7735fb.c b/drivers/video/st7735fb.c
index 500cc88..0931ca2 100644
--- a/drivers/video/st7735fb.c
+++ b/drivers/video/st7735fb.c
@@ -145,11 +145,9 @@ static struct fb_var_screeninfo st7735fb_var __devinitdata = {
 
 static int st7735_write(struct st7735fb_par *par, u8 data)
 {
-	u8 txbuf[2]; /* allocation from stack must go */
+	par->buf[0] = data;
 
-	txbuf[0] = data;
-
-	return spi_write(par->spi, &txbuf[0], 1);
+	return spi_write(par->spi, par->buf, 1);
 }
 
 static void st7735_write_data(struct st7735fb_par *par, u8 data)
@@ -243,16 +241,17 @@ static void st7735_reset(struct st7735fb_par *par)
 static void st7735fb_update_display(struct st7735fb_par *par)
 {
 	int ret = 0;
-	u8 *vmem = par->info->screen_base;
-
-	/*
-		TODO:
-		Allow a subset of pages to be passed in
-		(for deferred I/O).  Check pages against
-		pan display settings to see if they
-		should be updated.
-	*/
-	/* For now, just write the full 40KiB on each update */
+	u16 *vmem;
+#ifdef __LITTLE_ENDIAN
+	int i;
+	u16 *vmem16 = (u16 *)par->info->screen_base;
+	vmem = par->ssbuf;
+
+	for (i=0; i<WIDTH*HEIGHT*BPP/8/2; i++)
+		vmem[i] = swab16(vmem16[i]);
+#else
+	vmem = (u16 *)par->info->screen_base;
+#endif
 
 	/* Set row/column data window */
 	st7735_set_addr_win(par, 0, 0, WIDTH-1, HEIGHT-1);
@@ -261,7 +260,7 @@ static void st7735fb_update_display(struct st7735fb_par *par)
 	st7735_write_cmd(par, ST7735_RAMWR);
 
 	/* Blast framebuffer to ST7735 internal display RAM */
-	ret = st7735_write_data_buf(par, vmem, WIDTH*HEIGHT*BPP/8);
+	ret = st7735_write_data_buf(par, (u8 *)vmem, WIDTH*HEIGHT*BPP/8);
 	if (ret < 0)
 		pr_err("%s: spi_write failed to update display buffer\n",
 			par->info->fix.id);
@@ -369,7 +368,7 @@ static struct fb_ops st7735fb_ops = {
 };
 
 static struct fb_deferred_io st7735fb_defio = {
-	.delay		= HZ,
+	.delay		= HZ/20,
 	.deferred_io	= st7735fb_deferred_io,
 };
 
@@ -395,7 +394,11 @@ static int __devinit st7735fb_probe (struct spi_device *spi)
 		return -EINVAL;
 	}
 
-	vmem = vzalloc(vmem_size);
+#ifdef __LITTLE_ENDIAN
+	vmem = (u8 *)vmalloc(vmem_size);
+#else
+	vmem = (u8 *)kmalloc(vmem_size, GFP_KERNEL);
+#endif
 	if (!vmem)
 		return retval;
 
@@ -431,6 +434,14 @@ static int __devinit st7735fb_probe (struct spi_device *spi)
 	par->spi = spi;
 	par->rst = pdata->rst_gpio;
 	par->dc = pdata->dc_gpio;
+	par->buf = kmalloc(1, GFP_KERNEL);
+
+#ifdef __LITTLE_ENDIAN
+	/* Allocated swapped shadow buffer */
+	par->ssbuf = kmalloc(vmem_size, GFP_KERNEL);
+	if (!par->ssbuf)
+		return retval;
+#endif
 
 	retval = register_framebuffer(info);
 	if (retval < 0)
@@ -457,7 +468,11 @@ fbreg_fail:
 	framebuffer_release(info);
 
 fballoc_fail:
+#ifdef __LITTLE_ENDIAN
 	vfree(vmem);
+#else
+	kfree(vmem);
+#endif
 
 	return retval;
 }
diff --git a/include/video/st7735fb.h b/include/video/st7735fb.h
index 250f036..e99cd05 100644
--- a/include/video/st7735fb.h
+++ b/include/video/st7735fb.h
@@ -36,6 +36,8 @@ struct st7735fb_par {
 	struct fb_info *info;
 	int rst;
 	int dc;
+	u16 *ssbuf;
+	u8 *buf;
 };
 
 struct st7735fb_platform_data {
-- 
1.7.10