Lines Matching +full:lcd +full:- +full:controller
11 * StrongARM 1100 LCD Controller Frame Buffer Driver
16 * linux-arm-kernel@lists.arm.linux.org.uk
26 * - With the Neponset plugged into an Assabet, LCD powerdown
27 * doesn't work (LCD stays powered up). Therefore we shouldn't
29 * - We don't limit the CPU clock rate nor the mode selection
33 * - Linear grayscale palettes and the kernel.
44 * - The following must never be specified in a panel definition:
47 * - The following should be specified:
57 * - Driver appears to be working for Brutus 320x200x8bpp mode. Other
66 * - FrameBuffer memory is now allocated at run-time when the
70 * - Big cleanup for dynamic selection of machine type at run time.
73 * - Support for Bitsy aka Compaq iPAQ H3600 added.
75 * 2000/08/07: Tak-Shing Chan <tchan.rd@idthk.com>
77 * - Resolved an issue caused by a change made to the Assabet's PLD
83 * - XP860 support added
86 * - Allows standard options to be passed on the kernel command line
90 * - s/save_flags_cli/local_irq_save/
91 * - remove unneeded extra save_flags_cli in sa1100fb_enable_lcd_controller
94 * - Updated LART stuff. Fixed some minor bugs.
97 * - Pangolin support added
99 * 2000/10/31: Roman Jordan <jor@hoeft-wessel.de>
100 * - Huw Webpanel support added
103 * - Freebird add
107 * - Added PM callback
110 * - Fix 16bpp so that (a) we use the right colours rather than some
112 * we don't de-reference a NULL pointer.
113 * - remove duplicated implementation of consistent_alloc()
114 * - convert dma address types to dma_addr_t
115 * - remove unused 'montype' stuff
116 * - remove redundant zero inits of init_var after the initial
118 * - remove allow_modeset (acornfb idea does not belong here)
121 * - massive cleanup - move machine dependent data into structures
122 * - I've left various #warnings in - if you see one, and know
126 * - Fix LCCR1 HSW value, fix all machine type specifications to
130 * - Fiddle with the LCD controller from task context only; mainly
132 * - Convert #warnings into #errors. No pain, no gain. ;)
135 * - Make the palette BPS value for 12bpp come out correctly.
136 * - Take notice of "greyscale" on any colour depth.
137 * - Make truecolor visuals use the RGB channel encoding information.
140 * - Fix colourmap problems.
143 * - Added support for the ICP LCD-Kit01 on LART. This LCD is
147 * - Hand merge version from handhelds.org CVS tree. See patch
149 * - Drop 12bpp (it's 16bpp with different colour register mappings).
150 * - This hardware can not do direct colour. Therefore we don't
154 * - Halve YRES on dual scan LCDs.
157 * - Add b/w iPAQ pixclock value.
160 * - Add patch 681/1 and clean up stork definitions.
178 #include <linux/dma-mapping.h>
186 #include <asm/mach-types.h>
234 if (fbi->task_state == C_ENABLE && state == C_REENABLE) in sa1100fb_schedule_work()
235 state = (u_int) -1; in sa1100fb_schedule_work()
236 if (fbi->task_state == C_DISABLE && state == C_ENABLE) in sa1100fb_schedule_work()
239 if (state != (u_int)-1) { in sa1100fb_schedule_work()
240 fbi->task_state = state; in sa1100fb_schedule_work()
241 schedule_work(&fbi->task); in sa1100fb_schedule_work()
249 chan >>= 16 - bf->length; in chan_to_field()
250 return chan << bf->offset; in chan_to_field()
254 * Convert bits-per-pixel to a hardware palette PBS value.
259 switch (var->bits_per_pixel) { in palette_pbs()
275 if (regno < fbi->palette_size) { in sa1100fb_setpalettereg()
281 val |= palette_pbs(&fbi->fb.var); in sa1100fb_setpalettereg()
283 fbi->palette_cpu[regno] = val; in sa1100fb_setpalettereg()
304 if (fbi->inf->cmap_inverse) { in sa1100fb_setcolreg()
305 red = 0xffff - red; in sa1100fb_setcolreg()
306 green = 0xffff - green; in sa1100fb_setcolreg()
307 blue = 0xffff - blue; in sa1100fb_setcolreg()
314 if (fbi->fb.var.grayscale) in sa1100fb_setcolreg()
318 switch (fbi->fb.fix.visual) { in sa1100fb_setcolreg()
321 * 12 or 16-bit True Colour. We encode the RGB value in sa1100fb_setcolreg()
325 val = chan_to_field(red, &fbi->fb.var.red); in sa1100fb_setcolreg()
326 val |= chan_to_field(green, &fbi->fb.var.green); in sa1100fb_setcolreg()
327 val |= chan_to_field(blue, &fbi->fb.var.blue); in sa1100fb_setcolreg()
329 fbi->pseudo_palette[regno] = val; in sa1100fb_setcolreg()
347 * requests for the LCD controller. If we hit this, it means we're
348 * doing nothing but LCD DMA.
356 return var->pixclock * 8 * 16 / var->bits_per_pixel; in sa1100fb_display_dma_period()
373 if (var->xres < MIN_XRES) in sa1100fb_check_var()
374 var->xres = MIN_XRES; in sa1100fb_check_var()
375 if (var->yres < MIN_YRES) in sa1100fb_check_var()
376 var->yres = MIN_YRES; in sa1100fb_check_var()
377 if (var->xres > fbi->inf->xres) in sa1100fb_check_var()
378 var->xres = fbi->inf->xres; in sa1100fb_check_var()
379 if (var->yres > fbi->inf->yres) in sa1100fb_check_var()
380 var->yres = fbi->inf->yres; in sa1100fb_check_var()
381 var->xres_virtual = max(var->xres_virtual, var->xres); in sa1100fb_check_var()
382 var->yres_virtual = max(var->yres_virtual, var->yres); in sa1100fb_check_var()
384 dev_dbg(fbi->dev, "var->bits_per_pixel=%d\n", var->bits_per_pixel); in sa1100fb_check_var()
385 switch (var->bits_per_pixel) { in sa1100fb_check_var()
396 return -EINVAL; in sa1100fb_check_var()
403 var->red = fbi->rgb[rgbidx]->red; in sa1100fb_check_var()
404 var->green = fbi->rgb[rgbidx]->green; in sa1100fb_check_var()
405 var->blue = fbi->rgb[rgbidx]->blue; in sa1100fb_check_var()
406 var->transp = fbi->rgb[rgbidx]->transp; in sa1100fb_check_var()
408 dev_dbg(fbi->dev, "RGBT length = %d:%d:%d:%d\n", in sa1100fb_check_var()
409 var->red.length, var->green.length, var->blue.length, in sa1100fb_check_var()
410 var->transp.length); in sa1100fb_check_var()
412 dev_dbg(fbi->dev, "RGBT offset = %d:%d:%d:%d\n", in sa1100fb_check_var()
413 var->red.offset, var->green.offset, var->blue.offset, in sa1100fb_check_var()
414 var->transp.offset); in sa1100fb_check_var()
417 dev_dbg(fbi->dev, "dma period = %d ps, clock = %ld kHz\n", in sa1100fb_check_var()
419 clk_get_rate(fbi->clk) / 1000); in sa1100fb_check_var()
427 if (fbi->inf->set_visual) in sa1100fb_set_visual()
428 fbi->inf->set_visual(visual); in sa1100fb_set_visual()
439 struct fb_var_screeninfo *var = &info->var; in sa1100fb_set_par()
442 dev_dbg(fbi->dev, "set_par\n"); in sa1100fb_set_par()
444 if (var->bits_per_pixel == 16) in sa1100fb_set_par()
445 fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR; in sa1100fb_set_par()
446 else if (!fbi->inf->cmap_static) in sa1100fb_set_par()
447 fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; in sa1100fb_set_par()
454 fbi->fb.fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; in sa1100fb_set_par()
457 fbi->fb.fix.line_length = var->xres_virtual * in sa1100fb_set_par()
458 var->bits_per_pixel / 8; in sa1100fb_set_par()
459 fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16; in sa1100fb_set_par()
461 palette_mem_size = fbi->palette_size * sizeof(u16); in sa1100fb_set_par()
463 dev_dbg(fbi->dev, "palette_mem_size = 0x%08lx\n", palette_mem_size); in sa1100fb_set_par()
465 fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); in sa1100fb_set_par()
466 fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; in sa1100fb_set_par()
471 sa1100fb_set_visual(fbi, fbi->fb.fix.visual); in sa1100fb_set_par()
487 if (!kspc && (fbi->fb.var.bits_per_pixel == 16 || fbi->inf->cmap_static))
488 return -EINVAL;
498 * Stand-By
504 * recovery time from this state than from the Stand-by state
507 * and is non-operational. Recovery from this state may optionally require
512 * video itself: think of it semantically between on and Stand-By.
535 dev_dbg(fbi->dev, "sa1100fb_blank: blank=%d\n", blank); in sa1100fb_blank()
542 if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || in sa1100fb_blank()
543 fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) in sa1100fb_blank()
544 for (i = 0; i < fbi->palette_size; i++) in sa1100fb_blank()
550 if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || in sa1100fb_blank()
551 fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) in sa1100fb_blank()
552 fb_set_cmap(&fbi->fb.cmap, info); in sa1100fb_blank()
563 unsigned long off = vma->vm_pgoff << PAGE_SHIFT; in sa1100fb_mmap()
565 vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); in sa1100fb_mmap()
567 if (off < info->fix.smem_len) { in sa1100fb_mmap()
568 vma->vm_pgoff += 1; /* skip over the palette */ in sa1100fb_mmap()
569 return dma_mmap_wc(fbi->dev, vma, fbi->map_cpu, fbi->map_dma, in sa1100fb_mmap()
570 fbi->map_size); in sa1100fb_mmap()
573 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); in sa1100fb_mmap()
575 return vm_iomap_memory(vma, info->fix.mmio_start, info->fix.mmio_len); in sa1100fb_mmap()
597 unsigned int pcd = clk_get_rate(fbi->clk) / 100 / 1000; in get_pcd()
607 * Configures LCD Controller based on entries in var parameter. Settings are
608 * only written to the controller if changes were made.
616 dev_dbg(fbi->dev, "Configuring SA1100 LCD\n"); in sa1100fb_activate_var()
618 dev_dbg(fbi->dev, "var: xres=%d hslen=%d lm=%d rm=%d\n", in sa1100fb_activate_var()
619 var->xres, var->hsync_len, in sa1100fb_activate_var()
620 var->left_margin, var->right_margin); in sa1100fb_activate_var()
621 dev_dbg(fbi->dev, "var: yres=%d vslen=%d um=%d bm=%d\n", in sa1100fb_activate_var()
622 var->yres, var->vsync_len, in sa1100fb_activate_var()
623 var->upper_margin, var->lower_margin); in sa1100fb_activate_var()
626 if (var->xres < 16 || var->xres > 1024) in sa1100fb_activate_var()
627 dev_err(fbi->dev, "%s: invalid xres %d\n", in sa1100fb_activate_var()
628 fbi->fb.fix.id, var->xres); in sa1100fb_activate_var()
629 if (var->hsync_len < 1 || var->hsync_len > 64) in sa1100fb_activate_var()
630 dev_err(fbi->dev, "%s: invalid hsync_len %d\n", in sa1100fb_activate_var()
631 fbi->fb.fix.id, var->hsync_len); in sa1100fb_activate_var()
632 if (var->left_margin < 1 || var->left_margin > 255) in sa1100fb_activate_var()
633 dev_err(fbi->dev, "%s: invalid left_margin %d\n", in sa1100fb_activate_var()
634 fbi->fb.fix.id, var->left_margin); in sa1100fb_activate_var()
635 if (var->right_margin < 1 || var->right_margin > 255) in sa1100fb_activate_var()
636 dev_err(fbi->dev, "%s: invalid right_margin %d\n", in sa1100fb_activate_var()
637 fbi->fb.fix.id, var->right_margin); in sa1100fb_activate_var()
638 if (var->yres < 1 || var->yres > 1024) in sa1100fb_activate_var()
639 dev_err(fbi->dev, "%s: invalid yres %d\n", in sa1100fb_activate_var()
640 fbi->fb.fix.id, var->yres); in sa1100fb_activate_var()
641 if (var->vsync_len < 1 || var->vsync_len > 64) in sa1100fb_activate_var()
642 dev_err(fbi->dev, "%s: invalid vsync_len %d\n", in sa1100fb_activate_var()
643 fbi->fb.fix.id, var->vsync_len); in sa1100fb_activate_var()
644 if (var->upper_margin < 0 || var->upper_margin > 255) in sa1100fb_activate_var()
645 dev_err(fbi->dev, "%s: invalid upper_margin %d\n", in sa1100fb_activate_var()
646 fbi->fb.fix.id, var->upper_margin); in sa1100fb_activate_var()
647 if (var->lower_margin < 0 || var->lower_margin > 255) in sa1100fb_activate_var()
648 dev_err(fbi->dev, "%s: invalid lower_margin %d\n", in sa1100fb_activate_var()
649 fbi->fb.fix.id, var->lower_margin); in sa1100fb_activate_var()
652 new_regs.lccr0 = fbi->inf->lccr0 | in sa1100fb_activate_var()
657 LCCR1_DisWdth(var->xres) + in sa1100fb_activate_var()
658 LCCR1_HorSnchWdth(var->hsync_len) + in sa1100fb_activate_var()
659 LCCR1_BegLnDel(var->left_margin) + in sa1100fb_activate_var()
660 LCCR1_EndLnDel(var->right_margin); in sa1100fb_activate_var()
663 * If we have a dual scan LCD, then we need to halve in sa1100fb_activate_var()
666 yres = var->yres; in sa1100fb_activate_var()
667 if (fbi->inf->lccr0 & LCCR0_Dual) in sa1100fb_activate_var()
672 LCCR2_VrtSnchWdth(var->vsync_len) + in sa1100fb_activate_var()
673 LCCR2_BegFrmDel(var->upper_margin) + in sa1100fb_activate_var()
674 LCCR2_EndFrmDel(var->lower_margin); in sa1100fb_activate_var()
676 pcd = get_pcd(fbi, var->pixclock); in sa1100fb_activate_var()
677 new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->inf->lccr3 | in sa1100fb_activate_var()
678 (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) | in sa1100fb_activate_var()
679 (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL); in sa1100fb_activate_var()
681 dev_dbg(fbi->dev, "nlccr0 = 0x%08lx\n", new_regs.lccr0); in sa1100fb_activate_var()
682 dev_dbg(fbi->dev, "nlccr1 = 0x%08lx\n", new_regs.lccr1); in sa1100fb_activate_var()
683 dev_dbg(fbi->dev, "nlccr2 = 0x%08lx\n", new_regs.lccr2); in sa1100fb_activate_var()
684 dev_dbg(fbi->dev, "nlccr3 = 0x%08lx\n", new_regs.lccr3); in sa1100fb_activate_var()
686 half_screen_size = var->bits_per_pixel; in sa1100fb_activate_var()
687 half_screen_size = half_screen_size * var->xres * var->yres / 16; in sa1100fb_activate_var()
691 fbi->dbar1 = fbi->palette_dma; in sa1100fb_activate_var()
692 fbi->dbar2 = fbi->screen_dma + half_screen_size; in sa1100fb_activate_var()
694 fbi->reg_lccr0 = new_regs.lccr0; in sa1100fb_activate_var()
695 fbi->reg_lccr1 = new_regs.lccr1; in sa1100fb_activate_var()
696 fbi->reg_lccr2 = new_regs.lccr2; in sa1100fb_activate_var()
697 fbi->reg_lccr3 = new_regs.lccr3; in sa1100fb_activate_var()
701 * Only update the registers if the controller is enabled in sa1100fb_activate_var()
704 if (readl_relaxed(fbi->base + LCCR0) != fbi->reg_lccr0 || in sa1100fb_activate_var()
705 readl_relaxed(fbi->base + LCCR1) != fbi->reg_lccr1 || in sa1100fb_activate_var()
706 readl_relaxed(fbi->base + LCCR2) != fbi->reg_lccr2 || in sa1100fb_activate_var()
707 readl_relaxed(fbi->base + LCCR3) != fbi->reg_lccr3 || in sa1100fb_activate_var()
708 readl_relaxed(fbi->base + DBAR1) != fbi->dbar1 || in sa1100fb_activate_var()
709 readl_relaxed(fbi->base + DBAR2) != fbi->dbar2) in sa1100fb_activate_var()
719 * -- rmk
723 dev_dbg(fbi->dev, "backlight o%s\n", on ? "n" : "ff"); in __sa1100fb_backlight_power()
725 if (fbi->inf->backlight_power) in __sa1100fb_backlight_power()
726 fbi->inf->backlight_power(on); in __sa1100fb_backlight_power()
731 dev_dbg(fbi->dev, "LCD power o%s\n", on ? "n" : "ff"); in __sa1100fb_lcd_power()
733 if (fbi->inf->lcd_power) in __sa1100fb_lcd_power()
734 fbi->inf->lcd_power(on); in __sa1100fb_lcd_power()
742 * Enable GPIO<9:2> for LCD use if: in sa1100fb_setup_gpio()
746 * see table 11.8 on page 11-27 in the SA1100 manual in sa1100fb_setup_gpio()
747 * -- Erik. in sa1100fb_setup_gpio()
753 if ((fbi->reg_lccr0 & LCCR0_CMS) == LCCR0_Color && in sa1100fb_setup_gpio()
754 (fbi->reg_lccr0 & (LCCR0_Dual|LCCR0_Act)) != 0) { in sa1100fb_setup_gpio()
757 if (fbi->fb.var.bits_per_pixel > 8 || in sa1100fb_setup_gpio()
758 (fbi->reg_lccr0 & (LCCR0_Dual|LCCR0_Act)) == LCCR0_Dual) in sa1100fb_setup_gpio()
767 * SA-1100 requires the GPIO direction register set in sa1100fb_setup_gpio()
770 * fiddling via the GPIO subsystem - and even then in sa1100fb_setup_gpio()
782 dev_dbg(fbi->dev, "Enabling LCD controller\n"); in sa1100fb_enable_controller()
787 fbi->palette_cpu[0] &= 0xcfff; in sa1100fb_enable_controller()
788 fbi->palette_cpu[0] |= palette_pbs(&fbi->fb.var); in sa1100fb_enable_controller()
790 /* enable LCD controller clock */ in sa1100fb_enable_controller()
791 clk_prepare_enable(fbi->clk); in sa1100fb_enable_controller()
794 writel_relaxed(fbi->reg_lccr3, fbi->base + LCCR3); in sa1100fb_enable_controller()
795 writel_relaxed(fbi->reg_lccr2, fbi->base + LCCR2); in sa1100fb_enable_controller()
796 writel_relaxed(fbi->reg_lccr1, fbi->base + LCCR1); in sa1100fb_enable_controller()
797 writel_relaxed(fbi->reg_lccr0 & ~LCCR0_LEN, fbi->base + LCCR0); in sa1100fb_enable_controller()
798 writel_relaxed(fbi->dbar1, fbi->base + DBAR1); in sa1100fb_enable_controller()
799 writel_relaxed(fbi->dbar2, fbi->base + DBAR2); in sa1100fb_enable_controller()
800 writel_relaxed(fbi->reg_lccr0 | LCCR0_LEN, fbi->base + LCCR0); in sa1100fb_enable_controller()
802 if (fbi->shannon_lcden) in sa1100fb_enable_controller()
803 gpiod_set_value(fbi->shannon_lcden, 1); in sa1100fb_enable_controller()
805 dev_dbg(fbi->dev, "DBAR1: 0x%08x\n", readl_relaxed(fbi->base + DBAR1)); in sa1100fb_enable_controller()
806 dev_dbg(fbi->dev, "DBAR2: 0x%08x\n", readl_relaxed(fbi->base + DBAR2)); in sa1100fb_enable_controller()
807 dev_dbg(fbi->dev, "LCCR0: 0x%08x\n", readl_relaxed(fbi->base + LCCR0)); in sa1100fb_enable_controller()
808 dev_dbg(fbi->dev, "LCCR1: 0x%08x\n", readl_relaxed(fbi->base + LCCR1)); in sa1100fb_enable_controller()
809 dev_dbg(fbi->dev, "LCCR2: 0x%08x\n", readl_relaxed(fbi->base + LCCR2)); in sa1100fb_enable_controller()
810 dev_dbg(fbi->dev, "LCCR3: 0x%08x\n", readl_relaxed(fbi->base + LCCR3)); in sa1100fb_enable_controller()
818 dev_dbg(fbi->dev, "Disabling LCD controller\n"); in sa1100fb_disable_controller()
820 if (fbi->shannon_lcden) in sa1100fb_disable_controller()
821 gpiod_set_value(fbi->shannon_lcden, 0); in sa1100fb_disable_controller()
824 add_wait_queue(&fbi->ctrlr_wait, &wait); in sa1100fb_disable_controller()
826 /* Clear LCD Status Register */ in sa1100fb_disable_controller()
827 writel_relaxed(~0, fbi->base + LCSR); in sa1100fb_disable_controller()
829 lccr0 = readl_relaxed(fbi->base + LCCR0); in sa1100fb_disable_controller()
830 lccr0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */ in sa1100fb_disable_controller()
831 writel_relaxed(lccr0, fbi->base + LCCR0); in sa1100fb_disable_controller()
832 lccr0 &= ~LCCR0_LEN; /* Disable LCD Controller */ in sa1100fb_disable_controller()
833 writel_relaxed(lccr0, fbi->base + LCCR0); in sa1100fb_disable_controller()
836 remove_wait_queue(&fbi->ctrlr_wait, &wait); in sa1100fb_disable_controller()
838 /* disable LCD controller clock */ in sa1100fb_disable_controller()
839 clk_disable_unprepare(fbi->clk); in sa1100fb_disable_controller()
843 * sa1100fb_handle_irq: Handle 'LCD DONE' interrupts.
848 unsigned int lcsr = readl_relaxed(fbi->base + LCSR); in sa1100fb_handle_irq()
851 u32 lccr0 = readl_relaxed(fbi->base + LCCR0) | LCCR0_LDM; in sa1100fb_handle_irq()
852 writel_relaxed(lccr0, fbi->base + LCCR0); in sa1100fb_handle_irq()
853 wake_up(&fbi->ctrlr_wait); in sa1100fb_handle_irq()
856 writel_relaxed(lcsr, fbi->base + LCSR); in sa1100fb_handle_irq()
862 * sleep when disabling the LCD controller, or if we get two contending
869 mutex_lock(&fbi->ctrlr_lock); in set_ctrlr_state()
871 old_state = fbi->state; in set_ctrlr_state()
882 * Disable controller for clock change. If the in set_ctrlr_state()
883 * controller is already disabled, then do nothing. in set_ctrlr_state()
886 fbi->state = state; in set_ctrlr_state()
894 * Disable controller in set_ctrlr_state()
897 fbi->state = state; in set_ctrlr_state()
908 * Enable the controller after clock change. Only in set_ctrlr_state()
912 fbi->state = C_ENABLE; in set_ctrlr_state()
919 * Re-enable the controller only if it was already in set_ctrlr_state()
932 * Re-enable the controller after PM. This is not in set_ctrlr_state()
933 * perfect - think about the case where we were doing in set_ctrlr_state()
934 * a clock change, and we suspended half-way through. in set_ctrlr_state()
942 * Power up the LCD screen, enable controller, and in set_ctrlr_state()
946 fbi->state = C_ENABLE; in set_ctrlr_state()
954 mutex_unlock(&fbi->ctrlr_lock); in set_ctrlr_state()
958 * Our LCD controller task (which is called when we blank or unblank)
964 u_int state = xchg(&fbi->task_state, -1); in sa1100fb_task()
971 * CPU clock speed change handler. We need to adjust the LCD timing
988 pcd = get_pcd(fbi, fbi->fb.var.pixclock); in sa1100fb_freq_transition()
989 fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd); in sa1100fb_freq_transition()
1025 * remapped into a non-cached, non-buffered, memory region to
1036 fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE); in sa1100fb_map_video_memory()
1037 fbi->map_cpu = dma_alloc_wc(fbi->dev, fbi->map_size, &fbi->map_dma, in sa1100fb_map_video_memory()
1040 if (fbi->map_cpu) { in sa1100fb_map_video_memory()
1041 fbi->fb.screen_base = fbi->map_cpu + PAGE_SIZE; in sa1100fb_map_video_memory()
1042 fbi->screen_dma = fbi->map_dma + PAGE_SIZE; in sa1100fb_map_video_memory()
1049 fbi->fb.fix.smem_start = fbi->screen_dma; in sa1100fb_map_video_memory()
1052 return fbi->map_cpu ? 0 : -ENOMEM; in sa1100fb_map_video_memory()
1074 fbi->dev = dev; in sa1100fb_init_fbinfo()
1076 strcpy(fbi->fb.fix.id, SA1100_NAME); in sa1100fb_init_fbinfo()
1078 fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; in sa1100fb_init_fbinfo()
1079 fbi->fb.fix.type_aux = 0; in sa1100fb_init_fbinfo()
1080 fbi->fb.fix.xpanstep = 0; in sa1100fb_init_fbinfo()
1081 fbi->fb.fix.ypanstep = 0; in sa1100fb_init_fbinfo()
1082 fbi->fb.fix.ywrapstep = 0; in sa1100fb_init_fbinfo()
1083 fbi->fb.fix.accel = FB_ACCEL_NONE; in sa1100fb_init_fbinfo()
1085 fbi->fb.var.nonstd = 0; in sa1100fb_init_fbinfo()
1086 fbi->fb.var.activate = FB_ACTIVATE_NOW; in sa1100fb_init_fbinfo()
1087 fbi->fb.var.height = -1; in sa1100fb_init_fbinfo()
1088 fbi->fb.var.width = -1; in sa1100fb_init_fbinfo()
1089 fbi->fb.var.accel_flags = 0; in sa1100fb_init_fbinfo()
1090 fbi->fb.var.vmode = FB_VMODE_NONINTERLACED; in sa1100fb_init_fbinfo()
1092 fbi->fb.fbops = &sa1100fb_ops; in sa1100fb_init_fbinfo()
1093 fbi->fb.monspecs = monspecs; in sa1100fb_init_fbinfo()
1094 fbi->fb.pseudo_palette = fbi->pseudo_palette; in sa1100fb_init_fbinfo()
1096 fbi->rgb[RGB_4] = &rgb_4; in sa1100fb_init_fbinfo()
1097 fbi->rgb[RGB_8] = &rgb_8; in sa1100fb_init_fbinfo()
1098 fbi->rgb[RGB_16] = &def_rgb_16; in sa1100fb_init_fbinfo()
1105 if (inf->lccr3 & (LCCR3_VrtSnchL|LCCR3_HorSnchL|0xff) || in sa1100fb_init_fbinfo()
1106 inf->pixclock == 0) in sa1100fb_init_fbinfo()
1110 fbi->fb.var.xres = inf->xres; in sa1100fb_init_fbinfo()
1111 fbi->fb.var.xres_virtual = inf->xres; in sa1100fb_init_fbinfo()
1112 fbi->fb.var.yres = inf->yres; in sa1100fb_init_fbinfo()
1113 fbi->fb.var.yres_virtual = inf->yres; in sa1100fb_init_fbinfo()
1114 fbi->fb.var.bits_per_pixel = inf->bpp; in sa1100fb_init_fbinfo()
1115 fbi->fb.var.pixclock = inf->pixclock; in sa1100fb_init_fbinfo()
1116 fbi->fb.var.hsync_len = inf->hsync_len; in sa1100fb_init_fbinfo()
1117 fbi->fb.var.left_margin = inf->left_margin; in sa1100fb_init_fbinfo()
1118 fbi->fb.var.right_margin = inf->right_margin; in sa1100fb_init_fbinfo()
1119 fbi->fb.var.vsync_len = inf->vsync_len; in sa1100fb_init_fbinfo()
1120 fbi->fb.var.upper_margin = inf->upper_margin; in sa1100fb_init_fbinfo()
1121 fbi->fb.var.lower_margin = inf->lower_margin; in sa1100fb_init_fbinfo()
1122 fbi->fb.var.sync = inf->sync; in sa1100fb_init_fbinfo()
1123 fbi->fb.var.grayscale = inf->cmap_greyscale; in sa1100fb_init_fbinfo()
1124 fbi->state = C_STARTUP; in sa1100fb_init_fbinfo()
1125 fbi->task_state = (u_char)-1; in sa1100fb_init_fbinfo()
1126 fbi->fb.fix.smem_len = inf->xres * inf->yres * in sa1100fb_init_fbinfo()
1127 inf->bpp / 8; in sa1100fb_init_fbinfo()
1128 fbi->inf = inf; in sa1100fb_init_fbinfo()
1132 if (inf->rgb[i]) in sa1100fb_init_fbinfo()
1133 fbi->rgb[i] = inf->rgb[i]; in sa1100fb_init_fbinfo()
1135 init_waitqueue_head(&fbi->ctrlr_wait); in sa1100fb_init_fbinfo()
1136 INIT_WORK(&fbi->task, sa1100fb_task); in sa1100fb_init_fbinfo()
1137 mutex_init(&fbi->ctrlr_lock); in sa1100fb_init_fbinfo()
1147 if (!dev_get_platdata(&pdev->dev)) { in sa1100fb_probe()
1148 dev_err(&pdev->dev, "no platform LCD data\n"); in sa1100fb_probe()
1149 return -EINVAL; in sa1100fb_probe()
1154 return -EINVAL; in sa1100fb_probe()
1156 fbi = sa1100fb_init_fbinfo(&pdev->dev); in sa1100fb_probe()
1158 return -ENOMEM; in sa1100fb_probe()
1160 fbi->base = devm_platform_ioremap_resource(pdev, 0); in sa1100fb_probe()
1161 if (IS_ERR(fbi->base)) in sa1100fb_probe()
1162 return PTR_ERR(fbi->base); in sa1100fb_probe()
1164 fbi->clk = devm_clk_get(&pdev->dev, NULL); in sa1100fb_probe()
1165 if (IS_ERR(fbi->clk)) in sa1100fb_probe()
1166 return PTR_ERR(fbi->clk); in sa1100fb_probe()
1168 ret = devm_request_irq(&pdev->dev, irq, sa1100fb_handle_irq, 0, in sa1100fb_probe()
1169 "LCD", fbi); in sa1100fb_probe()
1171 dev_err(&pdev->dev, "request_irq failed: %d\n", ret); in sa1100fb_probe()
1175 fbi->shannon_lcden = gpiod_get_optional(&pdev->dev, "shannon-lcden", in sa1100fb_probe()
1177 if (IS_ERR(fbi->shannon_lcden)) in sa1100fb_probe()
1178 return PTR_ERR(fbi->shannon_lcden); in sa1100fb_probe()
1189 sa1100fb_check_var(&fbi->fb.var, &fbi->fb); in sa1100fb_probe()
1193 ret = register_framebuffer(&fbi->fb); in sa1100fb_probe()
1195 dma_free_wc(fbi->dev, fbi->map_size, fbi->map_cpu, in sa1100fb_probe()
1196 fbi->map_dma); in sa1100fb_probe()
1201 fbi->freq_transition.notifier_call = sa1100fb_freq_transition; in sa1100fb_probe()
1202 cpufreq_register_notifier(&fbi->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); in sa1100fb_probe()
1214 .name = "sa11x0-fb",
1221 return -ENODEV; in sa1100fb_init()
1227 MODULE_DESCRIPTION("StrongARM-1100/1110 framebuffer driver");