aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr
diff options
context:
space:
mode:
authorGustavo Diaz Prado <x0083741@ti.com>2011-08-25 02:59:17 -0400
committerPaolo Pisati <paolo.pisati@canonical.com>2012-08-17 04:18:36 -0400
commitb9be3abfe0e0dec0554ae7f34e4acebbb04a0eb9 (patch)
tree983e08e01b392ad87fd90f135140b0f2c1f143e0 /drivers/gpu/pvr
parent84a6f4ed0da3b63363bb7cea033e360316afb875 (diff)
SGX: UDD: Fix crash when cloning with FB sysfs entries
When a 3D app is runnning (avoiding the tearing effect) there is a very high chance the pointer to the display is null just after it has been extracted from the framebuffer and the UI is cloned using the sysfs entries from the framebuffer. This problem can be fixed by locking the framebuffer when the synchronization is happening and also when the frame is being pushed to the display as well. Signed-off-by: Gustavo Diaz Prado <x0083741@ti.com> Change-Id: Ia4e6cc6d52ba03f0098bc45ee019173d44925333
Diffstat (limited to 'drivers/gpu/pvr')
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb_linux.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_linux.c b/drivers/gpu/pvr/omaplfb/omaplfb_linux.c
index 9fbb66f2ef1..10805d64158 100644
--- a/drivers/gpu/pvr/omaplfb/omaplfb_linux.c
+++ b/drivers/gpu/pvr/omaplfb/omaplfb_linux.c
@@ -145,31 +145,26 @@ OMAP_ERROR OMAPLFBGetLibFuncAddr (char *szFunctionName,
145 return OMAP_OK; 145 return OMAP_OK;
146} 146}
147 147
148
149#if defined(FLIP_TECHNIQUE_FRAMEBUFFER) 148#if defined(FLIP_TECHNIQUE_FRAMEBUFFER)
150/* 149/*
151 * Presents the flip in the display with the framebuffer API 150 * Presents the flip in the display with the framebuffer API
152 * in: psSwapChain, aPhyAddr 151 * in: psSwapChain, aPhyAddr
153 */ 152 */
154void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr) 153static void OMAPLFBFlipNoLock(OMAPLFB_SWAPCHAIN *psSwapChain,
154 unsigned long aPhyAddr)
155{ 155{
156 OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)psSwapChain->pvDevInfo; 156 OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)psSwapChain->pvDevInfo;
157 struct fb_info * framebuffer = psDevInfo->psLINFBInfo; 157 struct fb_info *framebuffer = psDevInfo->psLINFBInfo;
158 struct omapfb_info *ofbi = FB2OFB(framebuffer); 158
159 struct omapfb2_device *fbdev = ofbi->fbdev;
160 /* Get the framebuffer physical address base */ 159 /* Get the framebuffer physical address base */
161 unsigned long fb_base_phyaddr = 160 unsigned long fb_base_phyaddr =
162 psDevInfo->sSystemBuffer.sSysAddr.uiAddr; 161 psDevInfo->sSystemBuffer.sSysAddr.uiAddr;
163 162
164 omapfb_lock(fbdev);
165
166 /* Calculate the virtual Y to move in the framebuffer */ 163 /* Calculate the virtual Y to move in the framebuffer */
167 framebuffer->var.yoffset = 164 framebuffer->var.yoffset =
168 (aPhyAddr - fb_base_phyaddr) / framebuffer->fix.line_length; 165 (aPhyAddr - fb_base_phyaddr) / framebuffer->fix.line_length;
169 framebuffer->var.activate = FB_ACTIVATE_FORCE; 166 framebuffer->var.activate = FB_ACTIVATE_FORCE;
170 fb_set_var(framebuffer, &framebuffer->var); 167 fb_set_var(framebuffer, &framebuffer->var);
171
172 omapfb_unlock(fbdev);
173} 168}
174 169
175#elif defined(FLIP_TECHNIQUE_OVERLAY) 170#elif defined(FLIP_TECHNIQUE_OVERLAY)
@@ -177,19 +172,17 @@ void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
177 * Presents the flip in the display with the DSS2 overlay API 172 * Presents the flip in the display with the DSS2 overlay API
178 * in: psSwapChain, aPhyAddr 173 * in: psSwapChain, aPhyAddr
179 */ 174 */
180void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr) 175static void OMAPLFBFlipNoLock(OMAPLFB_SWAPCHAIN *psSwapChain,
176 unsigned long aPhyAddr)
181{ 177{
182 OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)psSwapChain->pvDevInfo; 178 OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)psSwapChain->pvDevInfo;
183 struct fb_info * framebuffer = psDevInfo->psLINFBInfo; 179 struct fb_info * framebuffer = psDevInfo->psLINFBInfo;
184 struct omapfb_info *ofbi = FB2OFB(framebuffer); 180 struct omapfb_info *ofbi = FB2OFB(framebuffer);
185 struct omapfb2_device *fbdev = ofbi->fbdev;
186 unsigned long fb_offset; 181 unsigned long fb_offset;
187 int i; 182 int i;
188 183
189 fb_offset = aPhyAddr - psDevInfo->sSystemBuffer.sSysAddr.uiAddr; 184 fb_offset = aPhyAddr - psDevInfo->sSystemBuffer.sSysAddr.uiAddr;
190 185
191 omapfb_lock(fbdev);
192
193 for(i = 0; i < ofbi->num_overlays ; i++) 186 for(i = 0; i < ofbi->num_overlays ; i++)
194 { 187 {
195 struct omap_dss_device *display = NULL; 188 struct omap_dss_device *display = NULL;
@@ -207,9 +200,12 @@ void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
207 overlay->set_overlay_info(overlay, &overlay_info); 200 overlay->set_overlay_info(overlay, &overlay_info);
208 201
209 if (manager) { 202 if (manager) {
210 manager->apply(manager);
211 display = manager->device; 203 display = manager->device;
212 driver = display ? display->driver : NULL; 204 /* No display attached to this overlay, don't update */
205 if (!display)
206 continue;
207 driver = display->driver;
208 manager->apply(manager);
213 } 209 }
214 210
215 if (dss_ovl_manually_updated(overlay)) { 211 if (dss_ovl_manually_updated(overlay)) {
@@ -225,8 +221,6 @@ void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
225 } 221 }
226 222
227 } 223 }
228
229 omapfb_unlock(fbdev);
230} 224}
231 225
232#else 226#else
@@ -234,6 +228,18 @@ void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
234 FLIP_TECHNIQUE_FRAMEBUFFER or FLIP_TECHNIQUE_OVERLAY 228 FLIP_TECHNIQUE_FRAMEBUFFER or FLIP_TECHNIQUE_OVERLAY
235#endif 229#endif
236 230
231void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
232{
233 OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)psSwapChain->pvDevInfo;
234 struct fb_info *framebuffer = psDevInfo->psLINFBInfo;
235 struct omapfb_info *ofbi = FB2OFB(framebuffer);
236 struct omapfb2_device *fbdev = ofbi->fbdev;
237
238 omapfb_lock(fbdev);
239 OMAPLFBFlipNoLock(psSwapChain, aPhyAddr);
240 omapfb_unlock(fbdev);
241}
242
237/* 243/*
238 * Present frame and synchronize with the display to prevent tearing 244 * Present frame and synchronize with the display to prevent tearing
239 * On DSI panels the sync function is used to handle FRAMEDONE IRQ 245 * On DSI panels the sync function is used to handle FRAMEDONE IRQ
@@ -243,15 +249,22 @@ void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
243void OMAPLFBPresentSync(OMAPLFB_DEVINFO *psDevInfo, 249void OMAPLFBPresentSync(OMAPLFB_DEVINFO *psDevInfo,
244 OMAPLFB_FLIP_ITEM *psFlipItem) 250 OMAPLFB_FLIP_ITEM *psFlipItem)
245{ 251{
246 struct fb_info * framebuffer = psDevInfo->psLINFBInfo; 252 struct fb_info *framebuffer = psDevInfo->psLINFBInfo;
247 struct omap_dss_device *display = fb2display(framebuffer); 253 struct omapfb_info *ofbi = FB2OFB(framebuffer);
254 struct omap_dss_device *display;
255 struct omapfb2_device *fbdev = ofbi->fbdev;
248 struct omap_dss_driver *driver; 256 struct omap_dss_driver *driver;
249 struct omap_overlay_manager *manager; 257 struct omap_overlay_manager *manager;
250 int err = 1; 258 int err = 1;
251 259
252 if (!display) 260 omapfb_lock(fbdev);
253 WARNING_PRINTK("No DSS device to sync with display %u!", 261
254 psDevInfo->uDeviceID); 262 display = fb2display(framebuffer);
263 /* The framebuffer doesn't have a display attached, just bail out */
264 if (!display) {
265 omapfb_unlock(fbdev);
266 return;
267 }
255 268
256 driver = display->driver; 269 driver = display->driver;
257 manager = display->manager; 270 manager = display->manager;
@@ -260,14 +273,14 @@ void OMAPLFBPresentSync(OMAPLFB_DEVINFO *psDevInfo,
260 driver->get_update_mode(display) == OMAP_DSS_UPDATE_MANUAL) { 273 driver->get_update_mode(display) == OMAP_DSS_UPDATE_MANUAL) {
261 /* Wait first for the DSI bus to be released then update */ 274 /* Wait first for the DSI bus to be released then update */
262 err = driver->sync(display); 275 err = driver->sync(display);
263 OMAPLFBFlip(psDevInfo->psSwapChain, 276 OMAPLFBFlipNoLock(psDevInfo->psSwapChain,
264 (unsigned long)psFlipItem->sSysAddr->uiAddr); 277 (unsigned long)psFlipItem->sSysAddr->uiAddr);
265 } else if (manager && manager->wait_for_vsync) { 278 } else if (manager && manager->wait_for_vsync) {
266 /* 279 /*
267 * Update the video pipelines registers then wait until the 280 * Update the video pipelines registers then wait until the
268 * frame is shown with a VSYNC 281 * frame is shown with a VSYNC
269 */ 282 */
270 OMAPLFBFlip(psDevInfo->psSwapChain, 283 OMAPLFBFlipNoLock(psDevInfo->psSwapChain,
271 (unsigned long)psFlipItem->sSysAddr->uiAddr); 284 (unsigned long)psFlipItem->sSysAddr->uiAddr);
272 err = manager->wait_for_vsync(manager); 285 err = manager->wait_for_vsync(manager);
273 } 286 }
@@ -275,6 +288,8 @@ void OMAPLFBPresentSync(OMAPLFB_DEVINFO *psDevInfo,
275 if (err) 288 if (err)
276 WARNING_PRINTK("Unable to sync with display %u!", 289 WARNING_PRINTK("Unable to sync with display %u!",
277 psDevInfo->uDeviceID); 290 psDevInfo->uDeviceID);
291
292 omapfb_unlock(fbdev);
278} 293}
279 294
280#if defined(LDM_PLATFORM) 295#if defined(LDM_PLATFORM)