H A D | s3c-fb.c | 246 struct s3c_fb *sfb = win->parent; s3c_fb_check_var() local 248 dev_dbg(sfb->dev, "checking parameters\n"); s3c_fb_check_var() 254 dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n", s3c_fb_check_var() 268 if (sfb->variant.palette[win->index] != 0) { s3c_fb_check_var() 331 dev_err(sfb->dev, "invalid bpp\n"); s3c_fb_check_var() 335 dev_dbg(sfb->dev, "%s: verified parameters\n", __func__); s3c_fb_check_var() 341 * @sfb: The hardware state. 347 static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) s3c_fb_calc_pixclk() argument 353 if (sfb->variant.has_clksel) s3c_fb_calc_pixclk() 354 clk = clk_get_rate(sfb->bus_clk); s3c_fb_calc_pixclk() 356 clk = clk_get_rate(sfb->lcd_clk); s3c_fb_calc_pixclk() 364 dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", s3c_fb_calc_pixclk() 397 struct s3c_fb *sfb = win->parent; vidosd_set_size() local 401 writel(size, sfb->regs + OSD_BASE(win->index, sfb->variant) vidosd_set_size() 413 struct s3c_fb *sfb = win->parent; vidosd_set_alpha() local 416 writel(alpha, sfb->regs + VIDOSD_C(win->index, sfb->variant)); vidosd_set_alpha() 427 struct s3c_fb *sfb = win->parent; shadow_protect_win() local 431 if (sfb->variant.has_prtcon) { shadow_protect_win() 432 writel(PRTCON_PROTECT, sfb->regs + PRTCON); shadow_protect_win() 433 } else if (sfb->variant.has_shadowcon) { shadow_protect_win() 434 reg = readl(sfb->regs + SHADOWCON); shadow_protect_win() 436 sfb->regs + SHADOWCON); shadow_protect_win() 439 if (sfb->variant.has_prtcon) { shadow_protect_win() 440 writel(0, sfb->regs + PRTCON); shadow_protect_win() 441 } else if (sfb->variant.has_shadowcon) { shadow_protect_win() 442 reg = readl(sfb->regs + SHADOWCON); shadow_protect_win() 444 sfb->regs + SHADOWCON); shadow_protect_win() 451 * @sfb: The main framebuffer state. 454 static void s3c_fb_enable(struct s3c_fb *sfb, int enable) s3c_fb_enable() argument 456 u32 vidcon0 = readl(sfb->regs + VIDCON0); s3c_fb_enable() 458 if (enable && !sfb->output_on) s3c_fb_enable() 459 pm_runtime_get_sync(sfb->dev); s3c_fb_enable() 474 writel(vidcon0, sfb->regs + VIDCON0); s3c_fb_enable() 476 if (!enable && sfb->output_on) s3c_fb_enable() 477 pm_runtime_put_sync(sfb->dev); s3c_fb_enable() 479 sfb->output_on = enable; s3c_fb_enable() 492 struct s3c_fb *sfb = win->parent; s3c_fb_set_par() local 493 void __iomem *regs = sfb->regs; s3c_fb_set_par() 500 dev_dbg(sfb->dev, "setting framebuffer parameters\n"); s3c_fb_set_par() 502 pm_runtime_get_sync(sfb->dev); s3c_fb_set_par() 535 if (!sfb->output_on) s3c_fb_set_par() 536 s3c_fb_enable(sfb, 1); s3c_fb_set_par() 543 writel(info->fix.smem_start, buf + sfb->variant.buf_start); s3c_fb_set_par() 546 writel(data, buf + sfb->variant.buf_end); s3c_fb_set_par() 553 writel(data, regs + sfb->variant.buf_size + (win_no * 4)); s3c_fb_set_par() 559 writel(data, regs + VIDOSD_A(win_no, sfb->variant)); s3c_fb_set_par() 568 writel(data, regs + VIDOSD_B(win_no, sfb->variant)); s3c_fb_set_par() 580 if (sfb->variant.has_shadowcon) { s3c_fb_set_par() 581 data = readl(sfb->regs + SHADOWCON); s3c_fb_set_par() 583 writel(data, sfb->regs + SHADOWCON); s3c_fb_set_par() 587 sfb->enabled |= (1 << win->index); s3c_fb_set_par() 650 void __iomem *keycon = regs + sfb->variant.keycon; s3c_fb_set_par() 664 writel(data, regs + sfb->variant.wincon + (win_no * 4)); s3c_fb_set_par() 665 writel(0x0, regs + sfb->variant.winmap + (win_no * 4)); s3c_fb_set_par() 668 if (sfb->variant.has_blendcon) { s3c_fb_set_par() 669 data = readl(sfb->regs + BLENDCON); s3c_fb_set_par() 675 writel(data, sfb->regs + BLENDCON); s3c_fb_set_par() 680 pm_runtime_put_sync(sfb->dev); s3c_fb_set_par() 687 * @sfb: The hardware information. 699 static void s3c_fb_update_palette(struct s3c_fb *sfb, s3c_fb_update_palette() argument 707 palreg = sfb->regs + sfb->variant.palette[win->index]; s3c_fb_update_palette() 709 dev_dbg(sfb->dev, "%s: win %d, reg %d (%p): %08x\n", s3c_fb_update_palette() 714 palcon = readl(sfb->regs + WPALCON); s3c_fb_update_palette() 715 writel(palcon | WPALCON_PAL_UPDATE, sfb->regs + WPALCON); s3c_fb_update_palette() 722 writel(palcon, sfb->regs + WPALCON); s3c_fb_update_palette() 747 struct s3c_fb *sfb = win->parent; s3c_fb_setcolreg() local 750 dev_dbg(sfb->dev, "%s: win %d: %d => rgb=%d/%d/%d\n", s3c_fb_setcolreg() 753 pm_runtime_get_sync(sfb->dev); s3c_fb_setcolreg() 776 s3c_fb_update_palette(sfb, win, regno, val); s3c_fb_setcolreg() 782 pm_runtime_put_sync(sfb->dev); s3c_fb_setcolreg() 786 pm_runtime_put_sync(sfb->dev); s3c_fb_setcolreg() 800 struct s3c_fb *sfb = win->parent; s3c_fb_blank() local 803 u32 output_on = sfb->output_on; s3c_fb_blank() 805 dev_dbg(sfb->dev, "blank mode %d\n", blank_mode); s3c_fb_blank() 807 pm_runtime_get_sync(sfb->dev); s3c_fb_blank() 809 wincon = readl(sfb->regs + sfb->variant.wincon + (index * 4)); s3c_fb_blank() 814 sfb->enabled &= ~(1 << index); s3c_fb_blank() 821 sfb->regs + sfb->variant.winmap + (index * 4)); s3c_fb_blank() 827 writel(0x0, sfb->regs + sfb->variant.winmap + (index * 4)); s3c_fb_blank() 830 sfb->enabled |= (1 << index); s3c_fb_blank() 836 pm_runtime_put_sync(sfb->dev); s3c_fb_blank() 841 writel(wincon, sfb->regs + sfb->variant.wincon + (index * 4)); s3c_fb_blank() 848 s3c_fb_enable(sfb, sfb->enabled ? 1 : 0); s3c_fb_blank() 851 pm_runtime_put_sync(sfb->dev); s3c_fb_blank() 853 return output_on == sfb->output_on; s3c_fb_blank() 871 struct s3c_fb *sfb = win->parent; s3c_fb_pan_display() local 872 void __iomem *buf = sfb->regs + win->index * 8; s3c_fb_pan_display() 875 pm_runtime_get_sync(sfb->dev); s3c_fb_pan_display() 894 dev_err(sfb->dev, "invalid bpp\n"); s3c_fb_pan_display() 895 pm_runtime_put_sync(sfb->dev); s3c_fb_pan_display() 906 writel(info->fix.smem_start + start_boff, buf + sfb->variant.buf_start); s3c_fb_pan_display() 907 writel(info->fix.smem_start + end_boff, buf + sfb->variant.buf_end); s3c_fb_pan_display() 911 pm_runtime_put_sync(sfb->dev); s3c_fb_pan_display() 917 * @sfb: main hardware state 919 static void s3c_fb_enable_irq(struct s3c_fb *sfb) s3c_fb_enable_irq() argument 921 void __iomem *regs = sfb->regs; s3c_fb_enable_irq() 924 if (!test_and_set_bit(S3C_FB_VSYNC_IRQ_EN, &sfb->irq_flags)) { s3c_fb_enable_irq() 942 * @sfb: main hardware state 944 static void s3c_fb_disable_irq(struct s3c_fb *sfb) s3c_fb_disable_irq() argument 946 void __iomem *regs = sfb->regs; s3c_fb_disable_irq() 949 if (test_and_clear_bit(S3C_FB_VSYNC_IRQ_EN, &sfb->irq_flags)) { s3c_fb_disable_irq() 962 struct s3c_fb *sfb = dev_id; s3c_fb_irq() local 963 void __iomem *regs = sfb->regs; s3c_fb_irq() 966 spin_lock(&sfb->slock); s3c_fb_irq() 975 sfb->vsync_info.count++; s3c_fb_irq() 976 wake_up_interruptible(&sfb->vsync_info.wait); s3c_fb_irq() 982 s3c_fb_disable_irq(sfb); s3c_fb_irq() 984 spin_unlock(&sfb->slock); s3c_fb_irq() 990 * @sfb: main hardware state 993 static int s3c_fb_wait_for_vsync(struct s3c_fb *sfb, u32 crtc) s3c_fb_wait_for_vsync() argument 1001 pm_runtime_get_sync(sfb->dev); s3c_fb_wait_for_vsync() 1003 count = sfb->vsync_info.count; s3c_fb_wait_for_vsync() 1004 s3c_fb_enable_irq(sfb); s3c_fb_wait_for_vsync() 1005 ret = wait_event_interruptible_timeout(sfb->vsync_info.wait, s3c_fb_wait_for_vsync() 1006 count != sfb->vsync_info.count, s3c_fb_wait_for_vsync() 1009 pm_runtime_put_sync(sfb->dev); s3c_fb_wait_for_vsync() 1021 struct s3c_fb *sfb = win->parent; s3c_fb_ioctl() local 1032 ret = s3c_fb_wait_for_vsync(sfb, crtc); s3c_fb_ioctl() 1078 * @sfb: The base resources for the hardware. 1083 static int s3c_fb_alloc_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) s3c_fb_alloc_memory() argument 1090 dev_dbg(sfb->dev, "allocating memory for display\n"); s3c_fb_alloc_memory() 1095 dev_dbg(sfb->dev, "real_size=%u (%u.%u), virt_size=%u (%u.%u)\n", s3c_fb_alloc_memory() 1106 dev_dbg(sfb->dev, "want %u bytes for window\n", size); s3c_fb_alloc_memory() 1108 fbi->screen_base = dma_alloc_writecombine(sfb->dev, size, s3c_fb_alloc_memory() 1113 dev_dbg(sfb->dev, "mapped %x to %p\n", s3c_fb_alloc_memory() 1124 * @sfb: The base resources for the hardware. 1129 static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) s3c_fb_free_memory() argument 1134 dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len), s3c_fb_free_memory() 1145 static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) s3c_fb_release_win() argument 1150 if (sfb->variant.has_shadowcon) { s3c_fb_release_win() 1151 data = readl(sfb->regs + SHADOWCON); s3c_fb_release_win() 1154 writel(data, sfb->regs + SHADOWCON); s3c_fb_release_win() 1159 s3c_fb_free_memory(sfb, win); s3c_fb_release_win() 1166 * @sfb: The base resources for the hardware 1173 static int s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, s3c_fb_probe_win() argument 1185 dev_dbg(sfb->dev, "probing window %d, variant %p\n", win_no, variant); s3c_fb_probe_win() 1187 init_waitqueue_head(&sfb->vsync_info.wait); s3c_fb_probe_win() 1192 palette_size * sizeof(u32), sfb->dev); s3c_fb_probe_win() 1194 dev_err(sfb->dev, "failed to allocate framebuffer\n"); s3c_fb_probe_win() 1198 windata = sfb->pdata->win[win_no]; s3c_fb_probe_win() 1199 initmode = *sfb->pdata->vtiming; s3c_fb_probe_win() 1210 win->parent = sfb; s3c_fb_probe_win() 1215 ret = s3c_fb_alloc_memory(sfb, win); s3c_fb_probe_win() 1217 dev_err(sfb->dev, "failed to allocate display memory\n"); s3c_fb_probe_win() 1259 dev_err(sfb->dev, "check_var failed on initial video params\n"); s3c_fb_probe_win() 1269 dev_err(sfb->dev, "failed to allocate fb cmap\n"); s3c_fb_probe_win() 1273 dev_dbg(sfb->dev, "about to register framebuffer\n"); s3c_fb_probe_win() 1279 dev_err(sfb->dev, "failed to register framebuffer\n"); s3c_fb_probe_win() 1283 dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); s3c_fb_probe_win() 1290 * @sfb: The base resources for the hardware. 1294 static void s3c_fb_set_rgb_timing(struct s3c_fb *sfb) s3c_fb_set_rgb_timing() argument 1296 struct fb_videomode *vmode = sfb->pdata->vtiming; s3c_fb_set_rgb_timing() 1297 void __iomem *regs = sfb->regs; s3c_fb_set_rgb_timing() 1304 clkdiv = s3c_fb_calc_pixclk(sfb, vmode->pixclock); s3c_fb_set_rgb_timing() 1306 data = sfb->pdata->vidcon0; s3c_fb_set_rgb_timing() 1314 if (sfb->variant.is_2443) s3c_fb_set_rgb_timing() 1321 writel(data, regs + sfb->variant.vidtcon); s3c_fb_set_rgb_timing() 1326 writel(data, regs + sfb->variant.vidtcon + 4); s3c_fb_set_rgb_timing() 1332 writel(data, regs + sfb->variant.vidtcon + 8); s3c_fb_set_rgb_timing() 1337 * @sfb: The base resources for the hardware. 1342 static void s3c_fb_clear_win(struct s3c_fb *sfb, int win) s3c_fb_clear_win() argument 1344 void __iomem *regs = sfb->regs; s3c_fb_clear_win() 1347 writel(0, regs + sfb->variant.wincon + (win * 4)); s3c_fb_clear_win() 1348 writel(0, regs + VIDOSD_A(win, sfb->variant)); s3c_fb_clear_win() 1349 writel(0, regs + VIDOSD_B(win, sfb->variant)); s3c_fb_clear_win() 1350 writel(0, regs + VIDOSD_C(win, sfb->variant)); s3c_fb_clear_win() 1352 if (sfb->variant.has_shadowcon) { s3c_fb_clear_win() 1353 reg = readl(sfb->regs + SHADOWCON); s3c_fb_clear_win() 1357 writel(reg, sfb->regs + SHADOWCON); s3c_fb_clear_win() 1367 struct s3c_fb *sfb; s3c_fb_probe() local 1387 sfb = devm_kzalloc(dev, sizeof(struct s3c_fb), GFP_KERNEL); s3c_fb_probe() 1388 if (!sfb) { s3c_fb_probe() 1393 dev_dbg(dev, "allocate new framebuffer %p\n", sfb); s3c_fb_probe() 1395 sfb->dev = dev; s3c_fb_probe() 1396 sfb->pdata = pd; s3c_fb_probe() 1397 sfb->variant = fbdrv->variant; s3c_fb_probe() 1399 spin_lock_init(&sfb->slock); s3c_fb_probe() 1401 sfb->bus_clk = devm_clk_get(dev, "lcd"); s3c_fb_probe() 1402 if (IS_ERR(sfb->bus_clk)) { s3c_fb_probe() 1404 return PTR_ERR(sfb->bus_clk); s3c_fb_probe() 1407 clk_prepare_enable(sfb->bus_clk); s3c_fb_probe() 1409 if (!sfb->variant.has_clksel) { s3c_fb_probe() 1410 sfb->lcd_clk = devm_clk_get(dev, "sclk_fimd"); s3c_fb_probe() 1411 if (IS_ERR(sfb->lcd_clk)) { s3c_fb_probe() 1413 ret = PTR_ERR(sfb->lcd_clk); s3c_fb_probe() 1417 clk_prepare_enable(sfb->lcd_clk); s3c_fb_probe() 1420 pm_runtime_enable(sfb->dev); s3c_fb_probe() 1423 sfb->regs = devm_ioremap_resource(dev, res); s3c_fb_probe() 1424 if (IS_ERR(sfb->regs)) { s3c_fb_probe() 1425 ret = PTR_ERR(sfb->regs); s3c_fb_probe() 1435 sfb->irq_no = res->start; s3c_fb_probe() 1436 ret = devm_request_irq(dev, sfb->irq_no, s3c_fb_irq, s3c_fb_probe() 1437 0, "s3c_fb", sfb); s3c_fb_probe() 1443 dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs); s3c_fb_probe() 1445 platform_set_drvdata(pdev, sfb); s3c_fb_probe() 1446 pm_runtime_get_sync(sfb->dev); s3c_fb_probe() 1452 writel(pd->vidcon1, sfb->regs + VIDCON1); s3c_fb_probe() 1455 if (sfb->variant.has_fixvclk) { s3c_fb_probe() 1456 reg = readl(sfb->regs + VIDCON1); s3c_fb_probe() 1459 writel(reg, sfb->regs + VIDCON1); s3c_fb_probe() 1465 s3c_fb_clear_win(sfb, win); s3c_fb_probe() 1469 void __iomem *regs = sfb->regs + sfb->variant.keycon; s3c_fb_probe() 1476 s3c_fb_set_rgb_timing(sfb); s3c_fb_probe() 1484 ret = s3c_fb_probe_win(sfb, win, fbdrv->win[win], s3c_fb_probe() 1485 &sfb->windows[win]); s3c_fb_probe() 1489 s3c_fb_release_win(sfb, sfb->windows[win]); s3c_fb_probe() 1494 platform_set_drvdata(pdev, sfb); s3c_fb_probe() 1495 pm_runtime_put_sync(sfb->dev); s3c_fb_probe() 1500 pm_runtime_put_sync(sfb->dev); s3c_fb_probe() 1503 pm_runtime_disable(sfb->dev); s3c_fb_probe() 1505 if (!sfb->variant.has_clksel) s3c_fb_probe() 1506 clk_disable_unprepare(sfb->lcd_clk); s3c_fb_probe() 1509 clk_disable_unprepare(sfb->bus_clk); s3c_fb_probe() 1523 struct s3c_fb *sfb = platform_get_drvdata(pdev); s3c_fb_remove() local 1526 pm_runtime_get_sync(sfb->dev); s3c_fb_remove() 1529 if (sfb->windows[win]) s3c_fb_remove() 1530 s3c_fb_release_win(sfb, sfb->windows[win]); s3c_fb_remove() 1532 if (!sfb->variant.has_clksel) s3c_fb_remove() 1533 clk_disable_unprepare(sfb->lcd_clk); s3c_fb_remove() 1535 clk_disable_unprepare(sfb->bus_clk); s3c_fb_remove() 1537 pm_runtime_put_sync(sfb->dev); s3c_fb_remove() 1538 pm_runtime_disable(sfb->dev); s3c_fb_remove() 1546 struct s3c_fb *sfb = dev_get_drvdata(dev); s3c_fb_suspend() local 1550 pm_runtime_get_sync(sfb->dev); s3c_fb_suspend() 1553 win = sfb->windows[win_no]; s3c_fb_suspend() 1561 if (!sfb->variant.has_clksel) s3c_fb_suspend() 1562 clk_disable_unprepare(sfb->lcd_clk); s3c_fb_suspend() 1564 clk_disable_unprepare(sfb->bus_clk); s3c_fb_suspend() 1566 pm_runtime_put_sync(sfb->dev); s3c_fb_suspend() 1573 struct s3c_fb *sfb = dev_get_drvdata(dev); s3c_fb_resume() local 1574 struct s3c_fb_platdata *pd = sfb->pdata; s3c_fb_resume() 1579 pm_runtime_get_sync(sfb->dev); s3c_fb_resume() 1581 clk_prepare_enable(sfb->bus_clk); s3c_fb_resume() 1583 if (!sfb->variant.has_clksel) s3c_fb_resume() 1584 clk_prepare_enable(sfb->lcd_clk); s3c_fb_resume() 1588 writel(pd->vidcon1, sfb->regs + VIDCON1); s3c_fb_resume() 1591 if (sfb->variant.has_fixvclk) { s3c_fb_resume() 1592 reg = readl(sfb->regs + VIDCON1); s3c_fb_resume() 1595 writel(reg, sfb->regs + VIDCON1); s3c_fb_resume() 1599 for (win_no = 0; win_no < sfb->variant.nr_windows; win_no++) s3c_fb_resume() 1600 s3c_fb_clear_win(sfb, win_no); s3c_fb_resume() 1602 for (win_no = 0; win_no < sfb->variant.nr_windows - 1; win_no++) { s3c_fb_resume() 1603 void __iomem *regs = sfb->regs + sfb->variant.keycon; s3c_fb_resume() 1604 win = sfb->windows[win_no]; s3c_fb_resume() 1615 s3c_fb_set_rgb_timing(sfb); s3c_fb_resume() 1619 win = sfb->windows[win_no]; s3c_fb_resume() 1627 pm_runtime_put_sync(sfb->dev); s3c_fb_resume() 1636 struct s3c_fb *sfb = dev_get_drvdata(dev); s3c_fb_runtime_suspend() local 1638 if (!sfb->variant.has_clksel) s3c_fb_runtime_suspend() 1639 clk_disable_unprepare(sfb->lcd_clk); s3c_fb_runtime_suspend() 1641 clk_disable_unprepare(sfb->bus_clk); s3c_fb_runtime_suspend() 1648 struct s3c_fb *sfb = dev_get_drvdata(dev); s3c_fb_runtime_resume() local 1649 struct s3c_fb_platdata *pd = sfb->pdata; s3c_fb_runtime_resume() 1651 clk_prepare_enable(sfb->bus_clk); s3c_fb_runtime_resume() 1653 if (!sfb->variant.has_clksel) s3c_fb_runtime_resume() 1654 clk_prepare_enable(sfb->lcd_clk); s3c_fb_runtime_resume() 1658 writel(pd->vidcon1, sfb->regs + VIDCON1); s3c_fb_runtime_resume()
|