aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/omapfb/omapfb-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/omapfb/omapfb-main.c')
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c204
1 files changed, 137 insertions, 67 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index bc225e46fdd2..ca585ef37f25 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -31,7 +31,6 @@
31#include <linux/omapfb.h> 31#include <linux/omapfb.h>
32 32
33#include <video/omapdss.h> 33#include <video/omapdss.h>
34#include <plat/vram.h>
35#include <video/omapvrfb.h> 34#include <video/omapvrfb.h>
36 35
37#include "omapfb.h" 36#include "omapfb.h"
@@ -1258,11 +1257,10 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1258 1257
1259 switch (blank) { 1258 switch (blank) {
1260 case FB_BLANK_UNBLANK: 1259 case FB_BLANK_UNBLANK:
1261 if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) 1260 if (display->state == OMAP_DSS_DISPLAY_ACTIVE)
1262 goto exit; 1261 goto exit;
1263 1262
1264 if (display->driver->resume) 1263 r = display->driver->enable(display);
1265 r = display->driver->resume(display);
1266 1264
1267 if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) && 1265 if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) &&
1268 d->update_mode == OMAPFB_AUTO_UPDATE && 1266 d->update_mode == OMAPFB_AUTO_UPDATE &&
@@ -1283,8 +1281,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1283 if (d->auto_update_work_enabled) 1281 if (d->auto_update_work_enabled)
1284 omapfb_stop_auto_update(fbdev, display); 1282 omapfb_stop_auto_update(fbdev, display);
1285 1283
1286 if (display->driver->suspend) 1284 display->driver->disable(display);
1287 r = display->driver->suspend(display);
1288 1285
1289 break; 1286 break;
1290 1287
@@ -1335,24 +1332,25 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
1335 1332
1336 rg = ofbi->region; 1333 rg = ofbi->region;
1337 1334
1338 WARN_ON(atomic_read(&rg->map_count)); 1335 if (rg->token == NULL)
1339 1336 return;
1340 if (rg->paddr)
1341 if (omap_vram_free(rg->paddr, rg->size))
1342 dev_err(fbdev->dev, "VRAM FREE failed\n");
1343 1337
1344 if (rg->vaddr) 1338 WARN_ON(atomic_read(&rg->map_count));
1345 iounmap(rg->vaddr);
1346 1339
1347 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 1340 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
1348 /* unmap the 0 angle rotation */ 1341 /* unmap the 0 angle rotation */
1349 if (rg->vrfb.vaddr[0]) { 1342 if (rg->vrfb.vaddr[0]) {
1350 iounmap(rg->vrfb.vaddr[0]); 1343 iounmap(rg->vrfb.vaddr[0]);
1351 omap_vrfb_release_ctx(&rg->vrfb);
1352 rg->vrfb.vaddr[0] = NULL; 1344 rg->vrfb.vaddr[0] = NULL;
1353 } 1345 }
1346
1347 omap_vrfb_release_ctx(&rg->vrfb);
1354 } 1348 }
1355 1349
1350 dma_free_attrs(fbdev->dev, rg->size, rg->token, rg->dma_handle,
1351 &rg->attrs);
1352
1353 rg->token = NULL;
1356 rg->vaddr = NULL; 1354 rg->vaddr = NULL;
1357 rg->paddr = 0; 1355 rg->paddr = 0;
1358 rg->alloc = 0; 1356 rg->alloc = 0;
@@ -1387,7 +1385,9 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
1387 struct omapfb_info *ofbi = FB2OFB(fbi); 1385 struct omapfb_info *ofbi = FB2OFB(fbi);
1388 struct omapfb2_device *fbdev = ofbi->fbdev; 1386 struct omapfb2_device *fbdev = ofbi->fbdev;
1389 struct omapfb2_mem_region *rg; 1387 struct omapfb2_mem_region *rg;
1390 void __iomem *vaddr; 1388 void *token;
1389 DEFINE_DMA_ATTRS(attrs);
1390 dma_addr_t dma_handle;
1391 int r; 1391 int r;
1392 1392
1393 rg = ofbi->region; 1393 rg = ofbi->region;
@@ -1402,42 +1402,40 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
1402 1402
1403 size = PAGE_ALIGN(size); 1403 size = PAGE_ALIGN(size);
1404 1404
1405 if (!paddr) { 1405 dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
1406 DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
1407 r = omap_vram_alloc(size, &paddr);
1408 } else {
1409 DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
1410 ofbi->id);
1411 r = omap_vram_reserve(paddr, size);
1412 }
1413 1406
1414 if (r) { 1407 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
1408 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
1409
1410 DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
1411
1412 token = dma_alloc_attrs(fbdev->dev, size, &dma_handle,
1413 GFP_KERNEL, &attrs);
1414
1415 if (token == NULL) {
1415 dev_err(fbdev->dev, "failed to allocate framebuffer\n"); 1416 dev_err(fbdev->dev, "failed to allocate framebuffer\n");
1416 return -ENOMEM; 1417 return -ENOMEM;
1417 } 1418 }
1418 1419
1419 if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) { 1420 DBG("allocated VRAM paddr %lx, vaddr %p\n",
1420 vaddr = ioremap_wc(paddr, size); 1421 (unsigned long)dma_handle, token);
1421
1422 if (!vaddr) {
1423 dev_err(fbdev->dev, "failed to ioremap framebuffer\n");
1424 omap_vram_free(paddr, size);
1425 return -ENOMEM;
1426 }
1427 1422
1428 DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr); 1423 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
1429 } else {
1430 r = omap_vrfb_request_ctx(&rg->vrfb); 1424 r = omap_vrfb_request_ctx(&rg->vrfb);
1431 if (r) { 1425 if (r) {
1426 dma_free_attrs(fbdev->dev, size, token, dma_handle,
1427 &attrs);
1432 dev_err(fbdev->dev, "vrfb create ctx failed\n"); 1428 dev_err(fbdev->dev, "vrfb create ctx failed\n");
1433 return r; 1429 return r;
1434 } 1430 }
1435
1436 vaddr = NULL;
1437 } 1431 }
1438 1432
1439 rg->paddr = paddr; 1433 rg->attrs = attrs;
1440 rg->vaddr = vaddr; 1434 rg->token = token;
1435 rg->dma_handle = dma_handle;
1436
1437 rg->paddr = (unsigned long)dma_handle;
1438 rg->vaddr = (void __iomem *)token;
1441 rg->size = size; 1439 rg->size = size;
1442 rg->alloc = 1; 1440 rg->alloc = 1;
1443 1441
@@ -1531,6 +1529,9 @@ static int omapfb_parse_vram_param(const char *param, int max_entries,
1531 1529
1532 } 1530 }
1533 1531
1532 WARN_ONCE(paddr,
1533 "reserving memory at predefined address not supported\n");
1534
1534 paddrs[fbnum] = paddr; 1535 paddrs[fbnum] = paddr;
1535 sizes[fbnum] = size; 1536 sizes[fbnum] = size;
1536 1537
@@ -1610,7 +1611,6 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1610{ 1611{
1611 struct omapfb_info *ofbi = FB2OFB(fbi); 1612 struct omapfb_info *ofbi = FB2OFB(fbi);
1612 struct omapfb2_device *fbdev = ofbi->fbdev; 1613 struct omapfb2_device *fbdev = ofbi->fbdev;
1613 struct omap_dss_device *display = fb2display(fbi);
1614 struct omapfb2_mem_region *rg = ofbi->region; 1614 struct omapfb2_mem_region *rg = ofbi->region;
1615 unsigned long old_size = rg->size; 1615 unsigned long old_size = rg->size;
1616 unsigned long old_paddr = rg->paddr; 1616 unsigned long old_paddr = rg->paddr;
@@ -1625,9 +1625,6 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1625 if (old_size == size && old_type == type) 1625 if (old_size == size && old_type == type)
1626 return 0; 1626 return 0;
1627 1627
1628 if (display && display->driver->sync)
1629 display->driver->sync(display);
1630
1631 omapfb_free_fbmem(fbi); 1628 omapfb_free_fbmem(fbi);
1632 1629
1633 if (size == 0) { 1630 if (size == 0) {
@@ -1882,7 +1879,6 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
1882 } 1879 }
1883 1880
1884 dev_set_drvdata(fbdev->dev, NULL); 1881 dev_set_drvdata(fbdev->dev, NULL);
1885 kfree(fbdev);
1886} 1882}
1887 1883
1888static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) 1884static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
@@ -2258,26 +2254,28 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
2258{ 2254{
2259 struct fb_monspecs *specs; 2255 struct fb_monspecs *specs;
2260 u8 *edid; 2256 u8 *edid;
2261 int r, i, best_xres, best_idx, len; 2257 int r, i, best_idx, len;
2262 2258
2263 if (!display->driver->read_edid) 2259 if (!display->driver->read_edid)
2264 return -ENODEV; 2260 return -ENODEV;
2265 2261
2266 len = 0x80 * 2; 2262 len = 0x80 * 2;
2267 edid = kmalloc(len, GFP_KERNEL); 2263 edid = kmalloc(len, GFP_KERNEL);
2264 if (edid == NULL)
2265 return -ENOMEM;
2268 2266
2269 r = display->driver->read_edid(display, edid, len); 2267 r = display->driver->read_edid(display, edid, len);
2270 if (r < 0) 2268 if (r < 0)
2271 goto err1; 2269 goto err1;
2272 2270
2273 specs = kzalloc(sizeof(*specs), GFP_KERNEL); 2271 specs = kzalloc(sizeof(*specs), GFP_KERNEL);
2272 if (specs == NULL) {
2273 r = -ENOMEM;
2274 goto err1;
2275 }
2274 2276
2275 fb_edid_to_monspecs(edid, specs); 2277 fb_edid_to_monspecs(edid, specs);
2276 2278
2277 if (edid[126] > 0)
2278 fb_edid_add_monspecs(edid + 0x80, specs);
2279
2280 best_xres = 0;
2281 best_idx = -1; 2279 best_idx = -1;
2282 2280
2283 for (i = 0; i < specs->modedb_len; ++i) { 2281 for (i = 0; i < specs->modedb_len; ++i) {
@@ -2293,16 +2291,20 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
2293 if (m->xres == 2880 || m->xres == 1440) 2291 if (m->xres == 2880 || m->xres == 1440)
2294 continue; 2292 continue;
2295 2293
2294 if (m->vmode & FB_VMODE_INTERLACED ||
2295 m->vmode & FB_VMODE_DOUBLE)
2296 continue;
2297
2296 fb_videomode_to_omap_timings(m, display, &t); 2298 fb_videomode_to_omap_timings(m, display, &t);
2297 2299
2298 r = display->driver->check_timings(display, &t); 2300 r = display->driver->check_timings(display, &t);
2299 if (r == 0 && best_xres < m->xres) { 2301 if (r == 0) {
2300 best_xres = m->xres;
2301 best_idx = i; 2302 best_idx = i;
2303 break;
2302 } 2304 }
2303 } 2305 }
2304 2306
2305 if (best_xres == 0) { 2307 if (best_idx == -1) {
2306 r = -ENOENT; 2308 r = -ENOENT;
2307 goto err2; 2309 goto err2;
2308 } 2310 }
@@ -2371,15 +2373,62 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
2371 return 0; 2373 return 0;
2372} 2374}
2373 2375
2376static int omapfb_init_connections(struct omapfb2_device *fbdev,
2377 struct omap_dss_device *def_dssdev)
2378{
2379 int i, r;
2380 struct omap_overlay_manager *mgr;
2381
2382 if (!def_dssdev->output) {
2383 dev_err(fbdev->dev, "no output for the default display\n");
2384 return -EINVAL;
2385 }
2386
2387 for (i = 0; i < fbdev->num_displays; ++i) {
2388 struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
2389 struct omap_dss_output *out = dssdev->output;
2390
2391 mgr = omap_dss_get_overlay_manager(dssdev->channel);
2392
2393 if (!mgr || !out)
2394 continue;
2395
2396 if (mgr->output)
2397 mgr->unset_output(mgr);
2398
2399 mgr->set_output(mgr, out);
2400 }
2401
2402 mgr = def_dssdev->output->manager;
2403
2404 if (!mgr) {
2405 dev_err(fbdev->dev, "no ovl manager for the default display\n");
2406 return -EINVAL;
2407 }
2408
2409 for (i = 0; i < fbdev->num_overlays; i++) {
2410 struct omap_overlay *ovl = fbdev->overlays[i];
2411
2412 if (ovl->manager)
2413 ovl->unset_manager(ovl);
2414
2415 r = ovl->set_manager(ovl, mgr);
2416 if (r)
2417 dev_warn(fbdev->dev,
2418 "failed to connect overlay %s to manager %s\n",
2419 ovl->name, mgr->name);
2420 }
2421
2422 return 0;
2423}
2424
2374static int __init omapfb_probe(struct platform_device *pdev) 2425static int __init omapfb_probe(struct platform_device *pdev)
2375{ 2426{
2376 struct omapfb2_device *fbdev = NULL; 2427 struct omapfb2_device *fbdev = NULL;
2377 int r = 0; 2428 int r = 0;
2378 int i; 2429 int i;
2379 struct omap_overlay *ovl;
2380 struct omap_dss_device *def_display; 2430 struct omap_dss_device *def_display;
2381 struct omap_dss_device *dssdev; 2431 struct omap_dss_device *dssdev;
2382 struct omap_dss_device *ovl_device;
2383 2432
2384 DBG("omapfb_probe\n"); 2433 DBG("omapfb_probe\n");
2385 2434
@@ -2389,7 +2438,8 @@ static int __init omapfb_probe(struct platform_device *pdev)
2389 goto err0; 2438 goto err0;
2390 } 2439 }
2391 2440
2392 fbdev = kzalloc(sizeof(struct omapfb2_device), GFP_KERNEL); 2441 fbdev = devm_kzalloc(&pdev->dev, sizeof(struct omapfb2_device),
2442 GFP_KERNEL);
2393 if (fbdev == NULL) { 2443 if (fbdev == NULL) {
2394 r = -ENOMEM; 2444 r = -ENOMEM;
2395 goto err0; 2445 goto err0;
@@ -2401,13 +2451,15 @@ static int __init omapfb_probe(struct platform_device *pdev)
2401 "ignoring the module parameter vrfb=y\n"); 2451 "ignoring the module parameter vrfb=y\n");
2402 } 2452 }
2403 2453
2454 r = omapdss_compat_init();
2455 if (r)
2456 goto err0;
2404 2457
2405 mutex_init(&fbdev->mtx); 2458 mutex_init(&fbdev->mtx);
2406 2459
2407 fbdev->dev = &pdev->dev; 2460 fbdev->dev = &pdev->dev;
2408 platform_set_drvdata(pdev, fbdev); 2461 platform_set_drvdata(pdev, fbdev);
2409 2462
2410 r = 0;
2411 fbdev->num_displays = 0; 2463 fbdev->num_displays = 0;
2412 dssdev = NULL; 2464 dssdev = NULL;
2413 for_each_dss_dev(dssdev) { 2465 for_each_dss_dev(dssdev) {
@@ -2430,9 +2482,6 @@ static int __init omapfb_probe(struct platform_device *pdev)
2430 d->update_mode = OMAPFB_AUTO_UPDATE; 2482 d->update_mode = OMAPFB_AUTO_UPDATE;
2431 } 2483 }
2432 2484
2433 if (r)
2434 goto cleanup;
2435
2436 if (fbdev->num_displays == 0) { 2485 if (fbdev->num_displays == 0) {
2437 dev_err(&pdev->dev, "no displays\n"); 2486 dev_err(&pdev->dev, "no displays\n");
2438 r = -EINVAL; 2487 r = -EINVAL;
@@ -2447,15 +2496,33 @@ static int __init omapfb_probe(struct platform_device *pdev)
2447 for (i = 0; i < fbdev->num_managers; i++) 2496 for (i = 0; i < fbdev->num_managers; i++)
2448 fbdev->managers[i] = omap_dss_get_overlay_manager(i); 2497 fbdev->managers[i] = omap_dss_get_overlay_manager(i);
2449 2498
2450 /* gfx overlay should be the default one. find a display 2499 def_display = NULL;
2451 * connected to that, and use it as default display */ 2500
2452 ovl = omap_dss_get_overlay(0); 2501 for (i = 0; i < fbdev->num_displays; ++i) {
2453 ovl_device = ovl->get_device(ovl); 2502 struct omap_dss_device *dssdev;
2454 if (ovl_device) { 2503 const char *def_name;
2455 def_display = ovl_device; 2504
2456 } else { 2505 def_name = omapdss_get_default_display_name();
2457 dev_warn(&pdev->dev, "cannot find default display\n"); 2506
2458 def_display = NULL; 2507 dssdev = fbdev->displays[i].dssdev;
2508
2509 if (def_name == NULL ||
2510 (dssdev->name && strcmp(def_name, dssdev->name) == 0)) {
2511 def_display = dssdev;
2512 break;
2513 }
2514 }
2515
2516 if (def_display == NULL) {
2517 dev_err(fbdev->dev, "failed to find default display\n");
2518 r = -EINVAL;
2519 goto cleanup;
2520 }
2521
2522 r = omapfb_init_connections(fbdev, def_display);
2523 if (r) {
2524 dev_err(fbdev->dev, "failed to init overlay connections\n");
2525 goto cleanup;
2459 } 2526 }
2460 2527
2461 if (def_mode && strlen(def_mode) > 0) { 2528 if (def_mode && strlen(def_mode) > 0) {
@@ -2506,6 +2573,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
2506 2573
2507cleanup: 2574cleanup:
2508 omapfb_free_resources(fbdev); 2575 omapfb_free_resources(fbdev);
2576 omapdss_compat_uninit();
2509err0: 2577err0:
2510 dev_err(&pdev->dev, "failed to setup omapfb\n"); 2578 dev_err(&pdev->dev, "failed to setup omapfb\n");
2511 return r; 2579 return r;
@@ -2521,6 +2589,8 @@ static int __exit omapfb_remove(struct platform_device *pdev)
2521 2589
2522 omapfb_free_resources(fbdev); 2590 omapfb_free_resources(fbdev);
2523 2591
2592 omapdss_compat_uninit();
2593
2524 return 0; 2594 return 0;
2525} 2595}
2526 2596