Lines Matching +full:scaled +full:- +full:sync
1 // SPDX-License-Identifier: GPL-2.0-or-later
7 * Authors: Hongjun Chen <hong-jun.chen@freescale.com>
22 #include <linux/dma-mapping.h>
33 #include <linux/fsl-diu-fb.h>
52 * order if increasing resolution and frequency. The 320x240-60 mode is
67 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
81 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
95 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
109 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
123 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
137 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
151 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
165 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
179 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
193 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
207 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
221 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
235 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
249 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
263 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
277 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
291 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
305 .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
345 * struct fsl_diu_data - per-DIU data structure
353 * @dummy_aoi: video buffer for the 4x4 32-bit dummy AOI
363 * This data structure must be allocated with 32-byte alignment, so that the
379 /* It's easier to parse the cursor data as little-endian */
381 /* Blank cursor data -- used to hide the cursor */
383 /* Scratch cursor data -- used to build new cursor */
390 #define DMA_ADDR(p, f) ((p)->dma_addr + offsetof(struct fsl_diu_data, f))
447 hw->desc[0], hw->desc[1], hw->desc[2], hw->gamma, in fsl_diu_dump()
448 hw->palette, hw->cursor, hw->curs_pos, hw->diu_mode, in fsl_diu_dump()
449 hw->bgnd, hw->disp_size, hw->hsyn_para, hw->vsyn_para, in fsl_diu_dump()
450 hw->syn_pol, hw->thresholds, hw->int_mask, hw->plut); in fsl_diu_dump()
456 * fsl_diu_name_to_port - convert a port name to a monitor port enum
467 * (platform-specific) is chosen instead.
502 struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par; in fsl_diu_enable_panel()
503 struct diu_ad *ad = mfbi->ad; in fsl_diu_enable_panel()
504 struct fsl_diu_data *data = mfbi->parent; in fsl_diu_enable_panel()
505 struct diu __iomem *hw = data->diu_reg; in fsl_diu_enable_panel()
507 switch (mfbi->index) { in fsl_diu_enable_panel()
509 wr_reg_wa(&hw->desc[0], ad->paddr); in fsl_diu_enable_panel()
512 cmfbi = &data->mfb[2]; in fsl_diu_enable_panel()
513 if (hw->desc[1] != ad->paddr) { /* AOI0 closed */ in fsl_diu_enable_panel()
514 if (cmfbi->count > 0) /* AOI1 open */ in fsl_diu_enable_panel()
515 ad->next_ad = in fsl_diu_enable_panel()
516 cpu_to_le32(cmfbi->ad->paddr); in fsl_diu_enable_panel()
518 ad->next_ad = 0; in fsl_diu_enable_panel()
519 wr_reg_wa(&hw->desc[1], ad->paddr); in fsl_diu_enable_panel()
523 cmfbi = &data->mfb[4]; in fsl_diu_enable_panel()
524 if (hw->desc[2] != ad->paddr) { /* AOI0 closed */ in fsl_diu_enable_panel()
525 if (cmfbi->count > 0) /* AOI1 open */ in fsl_diu_enable_panel()
526 ad->next_ad = in fsl_diu_enable_panel()
527 cpu_to_le32(cmfbi->ad->paddr); in fsl_diu_enable_panel()
529 ad->next_ad = 0; in fsl_diu_enable_panel()
530 wr_reg_wa(&hw->desc[2], ad->paddr); in fsl_diu_enable_panel()
534 pmfbi = &data->mfb[1]; in fsl_diu_enable_panel()
535 ad->next_ad = 0; in fsl_diu_enable_panel()
536 if (hw->desc[1] == data->dummy_ad.paddr) in fsl_diu_enable_panel()
537 wr_reg_wa(&hw->desc[1], ad->paddr); in fsl_diu_enable_panel()
539 pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); in fsl_diu_enable_panel()
542 pmfbi = &data->mfb[3]; in fsl_diu_enable_panel()
543 ad->next_ad = 0; in fsl_diu_enable_panel()
544 if (hw->desc[2] == data->dummy_ad.paddr) in fsl_diu_enable_panel()
545 wr_reg_wa(&hw->desc[2], ad->paddr); in fsl_diu_enable_panel()
547 pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); in fsl_diu_enable_panel()
554 struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par; in fsl_diu_disable_panel()
555 struct diu_ad *ad = mfbi->ad; in fsl_diu_disable_panel()
556 struct fsl_diu_data *data = mfbi->parent; in fsl_diu_disable_panel()
557 struct diu __iomem *hw = data->diu_reg; in fsl_diu_disable_panel()
559 switch (mfbi->index) { in fsl_diu_disable_panel()
561 wr_reg_wa(&hw->desc[0], 0); in fsl_diu_disable_panel()
564 cmfbi = &data->mfb[2]; in fsl_diu_disable_panel()
565 if (cmfbi->count > 0) /* AOI1 is open */ in fsl_diu_disable_panel()
566 wr_reg_wa(&hw->desc[1], cmfbi->ad->paddr); in fsl_diu_disable_panel()
569 wr_reg_wa(&hw->desc[1], data->dummy_ad.paddr); in fsl_diu_disable_panel()
573 cmfbi = &data->mfb[4]; in fsl_diu_disable_panel()
574 if (cmfbi->count > 0) /* AOI1 is open */ in fsl_diu_disable_panel()
575 wr_reg_wa(&hw->desc[2], cmfbi->ad->paddr); in fsl_diu_disable_panel()
578 wr_reg_wa(&hw->desc[2], data->dummy_ad.paddr); in fsl_diu_disable_panel()
582 pmfbi = &data->mfb[1]; in fsl_diu_disable_panel()
583 if (hw->desc[1] != ad->paddr) { in fsl_diu_disable_panel()
585 if (pmfbi->count > 0) in fsl_diu_disable_panel()
587 pmfbi->ad->next_ad = 0; in fsl_diu_disable_panel()
589 wr_reg_wa(&hw->desc[1], data->dummy_ad.paddr); in fsl_diu_disable_panel()
593 pmfbi = &data->mfb[3]; in fsl_diu_disable_panel()
594 if (hw->desc[2] != ad->paddr) { in fsl_diu_disable_panel()
596 if (pmfbi->count > 0) in fsl_diu_disable_panel()
598 pmfbi->ad->next_ad = 0; in fsl_diu_disable_panel()
600 wr_reg_wa(&hw->desc[2], data->dummy_ad.paddr); in fsl_diu_disable_panel()
608 struct mfb_info *mfbi = info->par; in enable_lcdc()
609 struct fsl_diu_data *data = mfbi->parent; in enable_lcdc()
610 struct diu __iomem *hw = data->diu_reg; in enable_lcdc()
612 out_be32(&hw->diu_mode, MFB_MODE1); in enable_lcdc()
617 struct mfb_info *mfbi = info->par; in disable_lcdc()
618 struct fsl_diu_data *data = mfbi->parent; in disable_lcdc()
619 struct diu __iomem *hw = data->diu_reg; in disable_lcdc()
621 out_be32(&hw->diu_mode, 0); in disable_lcdc()
627 struct mfb_info *lower_aoi_mfbi, *upper_aoi_mfbi, *mfbi = info->par; in adjust_aoi_size_position()
628 struct fsl_diu_data *data = mfbi->parent; in adjust_aoi_size_position()
630 enum mfb_index index = mfbi->index; in adjust_aoi_size_position()
634 base_plane_width = data->fsl_diu_info[0].var.xres; in adjust_aoi_size_position()
635 base_plane_height = data->fsl_diu_info[0].var.yres; in adjust_aoi_size_position()
637 if (mfbi->x_aoi_d < 0) in adjust_aoi_size_position()
638 mfbi->x_aoi_d = 0; in adjust_aoi_size_position()
639 if (mfbi->y_aoi_d < 0) in adjust_aoi_size_position()
640 mfbi->y_aoi_d = 0; in adjust_aoi_size_position()
643 if (mfbi->x_aoi_d != 0) in adjust_aoi_size_position()
644 mfbi->x_aoi_d = 0; in adjust_aoi_size_position()
645 if (mfbi->y_aoi_d != 0) in adjust_aoi_size_position()
646 mfbi->y_aoi_d = 0; in adjust_aoi_size_position()
650 lower_aoi_mfbi = data->fsl_diu_info[index+1].par; in adjust_aoi_size_position()
651 lower_aoi_is_open = lower_aoi_mfbi->count > 0 ? 1 : 0; in adjust_aoi_size_position()
652 if (var->xres > base_plane_width) in adjust_aoi_size_position()
653 var->xres = base_plane_width; in adjust_aoi_size_position()
654 if ((mfbi->x_aoi_d + var->xres) > base_plane_width) in adjust_aoi_size_position()
655 mfbi->x_aoi_d = base_plane_width - var->xres; in adjust_aoi_size_position()
658 available_height = lower_aoi_mfbi->y_aoi_d; in adjust_aoi_size_position()
661 if (var->yres > available_height) in adjust_aoi_size_position()
662 var->yres = available_height; in adjust_aoi_size_position()
663 if ((mfbi->y_aoi_d + var->yres) > available_height) in adjust_aoi_size_position()
664 mfbi->y_aoi_d = available_height - var->yres; in adjust_aoi_size_position()
668 upper_aoi_mfbi = data->fsl_diu_info[index-1].par; in adjust_aoi_size_position()
669 upper_aoi_height = data->fsl_diu_info[index-1].var.yres; in adjust_aoi_size_position()
670 upper_aoi_bottom = upper_aoi_mfbi->y_aoi_d + upper_aoi_height; in adjust_aoi_size_position()
671 upper_aoi_is_open = upper_aoi_mfbi->count > 0 ? 1 : 0; in adjust_aoi_size_position()
672 if (var->xres > base_plane_width) in adjust_aoi_size_position()
673 var->xres = base_plane_width; in adjust_aoi_size_position()
674 if ((mfbi->x_aoi_d + var->xres) > base_plane_width) in adjust_aoi_size_position()
675 mfbi->x_aoi_d = base_plane_width - var->xres; in adjust_aoi_size_position()
676 if (mfbi->y_aoi_d < 0) in adjust_aoi_size_position()
677 mfbi->y_aoi_d = 0; in adjust_aoi_size_position()
679 if (mfbi->y_aoi_d < upper_aoi_bottom) in adjust_aoi_size_position()
680 mfbi->y_aoi_d = upper_aoi_bottom; in adjust_aoi_size_position()
682 - upper_aoi_bottom; in adjust_aoi_size_position()
685 if (var->yres > available_height) in adjust_aoi_size_position()
686 var->yres = available_height; in adjust_aoi_size_position()
687 if ((mfbi->y_aoi_d + var->yres) > base_plane_height) in adjust_aoi_size_position()
688 mfbi->y_aoi_d = base_plane_height - var->yres; in adjust_aoi_size_position()
697 * a -EINVAL will be returned by the upper layers.
702 if (var->xres_virtual < var->xres) in fsl_diu_check_var()
703 var->xres_virtual = var->xres; in fsl_diu_check_var()
704 if (var->yres_virtual < var->yres) in fsl_diu_check_var()
705 var->yres_virtual = var->yres; in fsl_diu_check_var()
707 if (var->xoffset + info->var.xres > info->var.xres_virtual) in fsl_diu_check_var()
708 var->xoffset = info->var.xres_virtual - info->var.xres; in fsl_diu_check_var()
710 if (var->yoffset + info->var.yres > info->var.yres_virtual) in fsl_diu_check_var()
711 var->yoffset = info->var.yres_virtual - info->var.yres; in fsl_diu_check_var()
713 if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) && in fsl_diu_check_var()
714 (var->bits_per_pixel != 16)) in fsl_diu_check_var()
715 var->bits_per_pixel = default_bpp; in fsl_diu_check_var()
717 switch (var->bits_per_pixel) { in fsl_diu_check_var()
719 var->red.length = 5; in fsl_diu_check_var()
720 var->red.offset = 11; in fsl_diu_check_var()
721 var->red.msb_right = 0; in fsl_diu_check_var()
723 var->green.length = 6; in fsl_diu_check_var()
724 var->green.offset = 5; in fsl_diu_check_var()
725 var->green.msb_right = 0; in fsl_diu_check_var()
727 var->blue.length = 5; in fsl_diu_check_var()
728 var->blue.offset = 0; in fsl_diu_check_var()
729 var->blue.msb_right = 0; in fsl_diu_check_var()
731 var->transp.length = 0; in fsl_diu_check_var()
732 var->transp.offset = 0; in fsl_diu_check_var()
733 var->transp.msb_right = 0; in fsl_diu_check_var()
736 var->red.length = 8; in fsl_diu_check_var()
737 var->red.offset = 0; in fsl_diu_check_var()
738 var->red.msb_right = 0; in fsl_diu_check_var()
740 var->green.length = 8; in fsl_diu_check_var()
741 var->green.offset = 8; in fsl_diu_check_var()
742 var->green.msb_right = 0; in fsl_diu_check_var()
744 var->blue.length = 8; in fsl_diu_check_var()
745 var->blue.offset = 16; in fsl_diu_check_var()
746 var->blue.msb_right = 0; in fsl_diu_check_var()
748 var->transp.length = 0; in fsl_diu_check_var()
749 var->transp.offset = 0; in fsl_diu_check_var()
750 var->transp.msb_right = 0; in fsl_diu_check_var()
753 var->red.length = 8; in fsl_diu_check_var()
754 var->red.offset = 16; in fsl_diu_check_var()
755 var->red.msb_right = 0; in fsl_diu_check_var()
757 var->green.length = 8; in fsl_diu_check_var()
758 var->green.offset = 8; in fsl_diu_check_var()
759 var->green.msb_right = 0; in fsl_diu_check_var()
761 var->blue.length = 8; in fsl_diu_check_var()
762 var->blue.offset = 0; in fsl_diu_check_var()
763 var->blue.msb_right = 0; in fsl_diu_check_var()
765 var->transp.length = 8; in fsl_diu_check_var()
766 var->transp.offset = 24; in fsl_diu_check_var()
767 var->transp.msb_right = 0; in fsl_diu_check_var()
772 var->height = -1; in fsl_diu_check_var()
773 var->width = -1; in fsl_diu_check_var()
774 var->grayscale = 0; in fsl_diu_check_var()
776 /* Copy nonstd field to/from sync for fbset usage */ in fsl_diu_check_var()
777 var->sync |= var->nonstd; in fsl_diu_check_var()
778 var->nonstd |= var->sync; in fsl_diu_check_var()
786 struct fb_fix_screeninfo *fix = &info->fix; in set_fix()
787 struct fb_var_screeninfo *var = &info->var; in set_fix()
788 struct mfb_info *mfbi = info->par; in set_fix()
790 strscpy_pad(fix->id, mfbi->id); in set_fix()
791 fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; in set_fix()
792 fix->type = FB_TYPE_PACKED_PIXELS; in set_fix()
793 fix->accel = FB_ACCEL_NONE; in set_fix()
794 fix->visual = FB_VISUAL_TRUECOLOR; in set_fix()
795 fix->xpanstep = 1; in set_fix()
796 fix->ypanstep = 1; in set_fix()
801 struct fb_var_screeninfo *var = &info->var; in update_lcdc()
802 struct mfb_info *mfbi = info->par; in update_lcdc()
803 struct fsl_diu_data *data = mfbi->parent; in update_lcdc()
810 hw = data->diu_reg; in update_lcdc()
813 diu_ops.set_monitor_port(data->monitor_port); in update_lcdc()
814 gamma_table_base = data->gamma; in update_lcdc()
816 /* Prep for DIU init - gamma table, cursor table */ in update_lcdc()
823 diu_ops.set_gamma_table(data->monitor_port, data->gamma); in update_lcdc()
829 out_be32(&hw->gamma, DMA_ADDR(data, gamma)); in update_lcdc()
831 out_be32(&hw->bgnd, 0x007F7F7F); /* Set background to grey */ in update_lcdc()
832 out_be32(&hw->disp_size, (var->yres << 16) | var->xres); in update_lcdc()
835 temp = var->left_margin << 22 | /* BP_H */ in update_lcdc()
836 var->hsync_len << 11 | /* PW_H */ in update_lcdc()
837 var->right_margin; /* FP_H */ in update_lcdc()
839 out_be32(&hw->hsyn_para, temp); in update_lcdc()
841 temp = var->upper_margin << 22 | /* BP_V */ in update_lcdc()
842 var->vsync_len << 11 | /* PW_V */ in update_lcdc()
843 var->lower_margin; /* FP_V */ in update_lcdc()
845 out_be32(&hw->vsyn_para, temp); in update_lcdc()
847 diu_ops.set_pixel_clock(var->pixclock); in update_lcdc()
859 * requires delicate fine-tuning for each use-case. in update_lcdc()
861 out_be32(&hw->plut, 0x01F5F666); in update_lcdc()
870 u32 smem_len = info->fix.line_length * info->var.yres_virtual; in map_video_memory()
876 return -ENOMEM; in map_video_memory()
878 mutex_lock(&info->mm_lock); in map_video_memory()
879 info->screen_base = p; in map_video_memory()
880 info->fix.smem_start = virt_to_phys((__force const void *)info->screen_base); in map_video_memory()
881 info->fix.smem_len = smem_len; in map_video_memory()
882 mutex_unlock(&info->mm_lock); in map_video_memory()
883 info->screen_size = info->fix.smem_len; in map_video_memory()
890 void *p = info->screen_base; in unmap_video_memory()
891 size_t l = info->fix.smem_len; in unmap_video_memory()
893 mutex_lock(&info->mm_lock); in unmap_video_memory()
894 info->screen_base = NULL; in unmap_video_memory()
895 info->fix.smem_start = 0; in unmap_video_memory()
896 info->fix.smem_len = 0; in unmap_video_memory()
897 mutex_unlock(&info->mm_lock); in unmap_video_memory()
909 struct fb_var_screeninfo *var = &info->var; in fsl_diu_set_aoi()
910 struct mfb_info *mfbi = info->par; in fsl_diu_set_aoi()
911 struct diu_ad *ad = mfbi->ad; in fsl_diu_set_aoi()
914 ad->offset_xyi = cpu_to_le32((var->yoffset << 16) | var->xoffset); in fsl_diu_set_aoi()
915 ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d); in fsl_diu_set_aoi()
922 * The pixel format is a 32-bit value that determine which bits in each
967 pr_err("fsl-diu: unsupported color depth %u\n", bits_per_pixel); in fsl_diu_get_pixel_format()
983 * simplify our code by using a 32-bit big-endian integer ("line") to read in
987 * This could result in an unaligned 32-bit read. For example, if the cursor
989 * the top line of the cursor. We do a 32-bit read of 'image', but we look
992 * 'image' by 1-3 bytes, but that should not cause any problems.
998 struct mfb_info *mfbi = info->par; in fsl_diu_load_cursor_image()
999 struct fsl_diu_data *data = mfbi->parent; in fsl_diu_load_cursor_image()
1000 __le16 *cursor = data->cursor; in fsl_diu_load_cursor_image()
1025 struct mfb_info *mfbi = info->par; in fsl_diu_cursor()
1026 struct fsl_diu_data *data = mfbi->parent; in fsl_diu_cursor()
1027 struct diu __iomem *hw = data->diu_reg; in fsl_diu_cursor()
1029 if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS) in fsl_diu_cursor()
1030 return -EINVAL; in fsl_diu_cursor()
1033 if (cursor->set & FB_CUR_SETSIZE) { in fsl_diu_cursor()
1041 memset(data->cursor, 0, sizeof(data->cursor)); in fsl_diu_cursor()
1044 /* The cursor position has changed (cursor->image.dx|dy) */ in fsl_diu_cursor()
1045 if (cursor->set & FB_CUR_SETPOS) { in fsl_diu_cursor()
1048 yy = (cursor->image.dy - info->var.yoffset) & 0x7ff; in fsl_diu_cursor()
1049 xx = (cursor->image.dx - info->var.xoffset) & 0x7ff; in fsl_diu_cursor()
1051 out_be32(&hw->curs_pos, yy << 16 | xx); in fsl_diu_cursor()
1055 * FB_CUR_SETIMAGE - the cursor image has changed in fsl_diu_cursor()
1056 * FB_CUR_SETCMAP - the cursor colors has changed in fsl_diu_cursor()
1057 * FB_CUR_SETSHAPE - the cursor bitmask has changed in fsl_diu_cursor()
1059 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) { in fsl_diu_cursor()
1065 DIV_ROUND_UP(cursor->image.width, 8) * in fsl_diu_cursor()
1066 cursor->image.height; in fsl_diu_cursor()
1069 unsigned int bg_idx = cursor->image.bg_color; in fsl_diu_cursor()
1070 unsigned int fg_idx = cursor->image.fg_color; in fsl_diu_cursor()
1075 if (info->state != FBINFO_STATE_RUNNING) in fsl_diu_cursor()
1078 bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) | in fsl_diu_cursor()
1079 ((info->cmap.green[bg_idx] & 0xf8) << 2) | in fsl_diu_cursor()
1080 ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | in fsl_diu_cursor()
1083 fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) | in fsl_diu_cursor()
1084 ((info->cmap.green[fg_idx] & 0xf8) << 2) | in fsl_diu_cursor()
1085 ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | in fsl_diu_cursor()
1088 /* Use 32-bit operations on the data to improve performance */ in fsl_diu_cursor()
1089 image = (uint32_t *)data->next_cursor; in fsl_diu_cursor()
1090 source = (uint32_t *)cursor->image.data; in fsl_diu_cursor()
1091 mask = (uint32_t *)cursor->mask; in fsl_diu_cursor()
1093 if (cursor->rop == ROP_XOR) in fsl_diu_cursor()
1101 cursor->image.width, cursor->image.height); in fsl_diu_cursor()
1111 if (cursor->enable) in fsl_diu_cursor()
1112 out_be32(&hw->cursor, DMA_ADDR(data, cursor)); in fsl_diu_cursor()
1114 out_be32(&hw->cursor, DMA_ADDR(data, blank_cursor)); in fsl_diu_cursor()
1130 struct fb_var_screeninfo *var = &info->var; in fsl_diu_set_par()
1131 struct mfb_info *mfbi = info->par; in fsl_diu_set_par()
1132 struct fsl_diu_data *data = mfbi->parent; in fsl_diu_set_par()
1133 struct diu_ad *ad = mfbi->ad; in fsl_diu_set_par()
1136 hw = data->diu_reg; in fsl_diu_set_par()
1140 len = info->var.yres_virtual * info->fix.line_length; in fsl_diu_set_par()
1142 if (len != info->fix.smem_len) { in fsl_diu_set_par()
1143 if (info->fix.smem_start) in fsl_diu_set_par()
1149 return -ENOMEM; in fsl_diu_set_par()
1154 ad->pix_fmt = diu_ops.get_pixel_format(data->monitor_port, in fsl_diu_set_par()
1155 var->bits_per_pixel); in fsl_diu_set_par()
1157 ad->pix_fmt = fsl_diu_get_pixel_format(var->bits_per_pixel); in fsl_diu_set_par()
1159 ad->addr = cpu_to_le32(info->fix.smem_start); in fsl_diu_set_par()
1160 ad->src_size_g_alpha = cpu_to_le32((var->yres_virtual << 12) | in fsl_diu_set_par()
1161 var->xres_virtual) | mfbi->g_alpha; in fsl_diu_set_par()
1163 ad->aoi_size = cpu_to_le32((var->yres << 16) | var->xres); in fsl_diu_set_par()
1164 ad->offset_xyi = cpu_to_le32((var->yoffset << 16) | var->xoffset); in fsl_diu_set_par()
1165 ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d); in fsl_diu_set_par()
1168 ad->ckmax_r = 0; in fsl_diu_set_par()
1169 ad->ckmax_g = 0; in fsl_diu_set_par()
1170 ad->ckmax_b = 0; in fsl_diu_set_par()
1172 ad->ckmin_r = 255; in fsl_diu_set_par()
1173 ad->ckmin_g = 255; in fsl_diu_set_par()
1174 ad->ckmin_b = 255; in fsl_diu_set_par()
1176 if (mfbi->index == PLANE0) in fsl_diu_set_par()
1183 return ((val << width) + 0x7FFF - val) >> 16; in CNVT_TOHW()
1188 * which needs to be scaled in this function for the hardware. Things to take
1205 if (info->var.grayscale) in fsl_diu_setcolreg()
1208 switch (info->fix.visual) { in fsl_diu_setcolreg()
1211 * 16-bit True Colour. We encode the RGB value in fsl_diu_setcolreg()
1215 u32 *pal = info->pseudo_palette; in fsl_diu_setcolreg()
1218 red = CNVT_TOHW(red, info->var.red.length); in fsl_diu_setcolreg()
1219 green = CNVT_TOHW(green, info->var.green.length); in fsl_diu_setcolreg()
1220 blue = CNVT_TOHW(blue, info->var.blue.length); in fsl_diu_setcolreg()
1221 transp = CNVT_TOHW(transp, info->var.transp.length); in fsl_diu_setcolreg()
1223 v = (red << info->var.red.offset) | in fsl_diu_setcolreg()
1224 (green << info->var.green.offset) | in fsl_diu_setcolreg()
1225 (blue << info->var.blue.offset) | in fsl_diu_setcolreg()
1226 (transp << info->var.transp.offset); in fsl_diu_setcolreg()
1240 * don't fit, return -EINVAL.
1245 if ((info->var.xoffset == var->xoffset) && in fsl_diu_pan_display()
1246 (info->var.yoffset == var->yoffset)) in fsl_diu_pan_display()
1249 if (var->xoffset + info->var.xres > info->var.xres_virtual in fsl_diu_pan_display()
1250 || var->yoffset + info->var.yres > info->var.yres_virtual) in fsl_diu_pan_display()
1251 return -EINVAL; in fsl_diu_pan_display()
1253 info->var.xoffset = var->xoffset; in fsl_diu_pan_display()
1254 info->var.yoffset = var->yoffset; in fsl_diu_pan_display()
1256 if (var->vmode & FB_VMODE_YWRAP) in fsl_diu_pan_display()
1257 info->var.vmode |= FB_VMODE_YWRAP; in fsl_diu_pan_display()
1259 info->var.vmode &= ~FB_VMODE_YWRAP; in fsl_diu_pan_display()
1269 struct mfb_info *mfbi = info->par; in fsl_diu_ioctl()
1270 struct diu_ad *ad = mfbi->ad; in fsl_diu_ioctl()
1278 return -EINVAL; in fsl_diu_ioctl()
1293 return -EFAULT; in fsl_diu_ioctl()
1294 ad->pix_fmt = pix_fmt; in fsl_diu_ioctl()
1302 pix_fmt = ad->pix_fmt; in fsl_diu_ioctl()
1304 return -EFAULT; in fsl_diu_ioctl()
1308 return -EFAULT; in fsl_diu_ioctl()
1309 mfbi->x_aoi_d = aoi_d.x_aoi_d; in fsl_diu_ioctl()
1310 mfbi->y_aoi_d = aoi_d.y_aoi_d; in fsl_diu_ioctl()
1311 fsl_diu_check_var(&info->var, info); in fsl_diu_ioctl()
1315 aoi_d.x_aoi_d = mfbi->x_aoi_d; in fsl_diu_ioctl()
1316 aoi_d.y_aoi_d = mfbi->y_aoi_d; in fsl_diu_ioctl()
1318 return -EFAULT; in fsl_diu_ioctl()
1321 global_alpha = mfbi->g_alpha; in fsl_diu_ioctl()
1323 return -EFAULT; in fsl_diu_ioctl()
1328 return -EFAULT; in fsl_diu_ioctl()
1329 ad->src_size_g_alpha = (ad->src_size_g_alpha & (~0xff)) | in fsl_diu_ioctl()
1331 mfbi->g_alpha = global_alpha; in fsl_diu_ioctl()
1336 return -EFAULT; in fsl_diu_ioctl()
1342 return -EINVAL; in fsl_diu_ioctl()
1345 ad->ckmax_r = 0; in fsl_diu_ioctl()
1346 ad->ckmax_g = 0; in fsl_diu_ioctl()
1347 ad->ckmax_b = 0; in fsl_diu_ioctl()
1348 ad->ckmin_r = 255; in fsl_diu_ioctl()
1349 ad->ckmin_g = 255; in fsl_diu_ioctl()
1350 ad->ckmin_b = 255; in fsl_diu_ioctl()
1352 ad->ckmax_r = ck.red_max; in fsl_diu_ioctl()
1353 ad->ckmax_g = ck.green_max; in fsl_diu_ioctl()
1354 ad->ckmax_b = ck.blue_max; in fsl_diu_ioctl()
1355 ad->ckmin_r = ck.red_min; in fsl_diu_ioctl()
1356 ad->ckmin_g = ck.green_min; in fsl_diu_ioctl()
1357 ad->ckmin_b = ck.blue_min; in fsl_diu_ioctl()
1362 struct fsl_diu_data *data = mfbi->parent; in fsl_diu_ioctl()
1364 if (copy_from_user(data->gamma, buf, sizeof(data->gamma))) in fsl_diu_ioctl()
1365 return -EFAULT; in fsl_diu_ioctl()
1366 setbits32(&data->diu_reg->gamma, 0); /* Force table reload */ in fsl_diu_ioctl()
1370 struct fsl_diu_data *data = mfbi->parent; in fsl_diu_ioctl()
1372 if (copy_to_user(buf, data->gamma, sizeof(data->gamma))) in fsl_diu_ioctl()
1373 return -EFAULT; in fsl_diu_ioctl()
1379 return -ENOIOCTLCMD; in fsl_diu_ioctl()
1390 int_mask |= INT_VSYNC; /* enable vertical sync */ in fsl_diu_enable_interrupts()
1392 clrbits32(&data->diu_reg->int_mask, int_mask); in fsl_diu_enable_interrupts()
1399 struct mfb_info *mfbi = info->par; in fsl_diu_open()
1403 if ((mfbi->index == PLANE0) && diu_ops.release_bootmem) in fsl_diu_open()
1407 mfbi->count++; in fsl_diu_open()
1408 if (mfbi->count == 1) { in fsl_diu_open()
1409 fsl_diu_check_var(&info->var, info); in fsl_diu_open()
1412 mfbi->count--; in fsl_diu_open()
1414 fsl_diu_enable_interrupts(mfbi->parent); in fsl_diu_open()
1427 struct mfb_info *mfbi = info->par; in fsl_diu_release()
1430 mfbi->count--; in fsl_diu_release()
1431 if (mfbi->count == 0) { in fsl_diu_release()
1432 struct fsl_diu_data *data = mfbi->parent; in fsl_diu_release()
1438 struct mfb_info *mi = data->fsl_diu_info[i].par; in fsl_diu_release()
1440 if (mi->count) in fsl_diu_release()
1444 out_be32(&data->diu_reg->int_mask, 0xffffffff); in fsl_diu_release()
1468 struct mfb_info *mfbi = info->par; in install_fb()
1469 struct fsl_diu_data *data = mfbi->parent; in install_fb()
1475 info->var.activate = FB_ACTIVATE_NOW; in install_fb()
1476 info->fbops = &fsl_diu_ops; in install_fb()
1477 info->flags = FBINFO_VIRTFB | FBINFO_PARTIAL_PAN_OK | in install_fb()
1479 info->pseudo_palette = mfbi->pseudo_palette; in install_fb()
1481 rc = fb_alloc_cmap(&info->cmap, 16, 0); in install_fb()
1485 if (mfbi->index == PLANE0) { in install_fb()
1486 if (data->has_edid) { in install_fb()
1488 fb_edid_to_monspecs(data->edid_data, &info->monspecs); in install_fb()
1489 fb_videomode_to_modelist(info->monspecs.modedb, in install_fb()
1490 info->monspecs.modedb_len, in install_fb()
1491 &info->modelist); in install_fb()
1492 db = info->monspecs.modedb; in install_fb()
1493 dbsize = info->monspecs.modedb_len; in install_fb()
1499 rc = fb_find_mode(&info->var, info, aoi_mode, db, dbsize, NULL, in install_fb()
1506 if ((mfbi->index == PLANE0) && data->has_edid) in install_fb()
1509 return -EINVAL; in install_fb()
1513 rc = fb_find_mode(&info->var, info, aoi_mode, fsl_diu_mode_db, in install_fb()
1520 if (!has_default_mode && info->monspecs.modedb) { in install_fb()
1521 struct fb_monspecs *specs = &info->monspecs; in install_fb()
1522 struct fb_videomode *modedb = &specs->modedb[0]; in install_fb()
1528 if (specs->misc & FB_MISC_1ST_DETAIL) { in install_fb()
1531 for (i = 0; i < specs->modedb_len; i++) { in install_fb()
1532 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) { in install_fb()
1533 modedb = &specs->modedb[i]; in install_fb()
1539 info->var.bits_per_pixel = default_bpp; in install_fb()
1540 fb_videomode_to_var(&info->var, modedb); in install_fb()
1543 if (fsl_diu_check_var(&info->var, info)) { in install_fb()
1546 fb_dealloc_cmap(&info->cmap); in install_fb()
1547 return -EINVAL; in install_fb()
1553 fb_dealloc_cmap(&info->cmap); in install_fb()
1554 return -EINVAL; in install_fb()
1557 mfbi->registered = 1; in install_fb()
1558 fb_info(info, "%s registered successfully\n", mfbi->id); in install_fb()
1565 struct mfb_info *mfbi = info->par; in uninstall_fb()
1567 if (!mfbi->registered) in uninstall_fb()
1572 fb_dealloc_cmap(&info->cmap); in uninstall_fb()
1574 mfbi->registered = 0; in uninstall_fb()
1580 uint32_t status = in_be32(&hw->int_status); in fsl_diu_isr()
1585 out_be32(&hw->diu_mode, 0); in fsl_diu_isr()
1587 out_be32(&hw->diu_mode, 1); in fsl_diu_isr()
1614 data = dev_get_drvdata(&ofdev->dev); in fsl_diu_suspend()
1615 disable_lcdc(data->fsl_diu_info); in fsl_diu_suspend()
1625 data = dev_get_drvdata(&ofdev->dev); in fsl_diu_resume()
1628 update_lcdc(data->fsl_diu_info); in fsl_diu_resume()
1630 if (data->mfb[i].count) in fsl_diu_resume()
1631 fsl_diu_enable_panel(&data->fsl_diu_info[i]); in fsl_diu_resume()
1649 old_monitor_port = data->monitor_port; in store_monitor()
1650 data->monitor_port = fsl_diu_name_to_port(buf); in store_monitor()
1652 if (old_monitor_port != data->monitor_port) { in store_monitor()
1659 fsl_diu_set_par(&data->fsl_diu_info[i]); in store_monitor()
1670 switch (data->monitor_port) { in show_monitor()
1674 return sprintf(buf, "Single-link LVDS\n"); in show_monitor()
1676 return sprintf(buf, "Dual-link LVDS\n"); in show_monitor()
1684 struct device_node *np = pdev->dev.of_node; in fsl_diu_probe()
1692 data = dmam_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data), in fsl_diu_probe()
1695 return -ENOMEM; in fsl_diu_probe()
1696 data->dma_addr = dma_addr; in fsl_diu_probe()
1700 * always page-aligned. We need the memory to be 32-byte aligned, in fsl_diu_probe()
1706 dev_err(&pdev->dev, "misaligned allocation"); in fsl_diu_probe()
1707 ret = -ENOMEM; in fsl_diu_probe()
1711 spin_lock_init(&data->reg_lock); in fsl_diu_probe()
1714 struct fb_info *info = &data->fsl_diu_info[i]; in fsl_diu_probe()
1716 info->device = &pdev->dev; in fsl_diu_probe()
1717 info->par = &data->mfb[i]; in fsl_diu_probe()
1723 data->ad[i].paddr = DMA_ADDR(data, ad[i]); in fsl_diu_probe()
1725 info->fix.smem_start = 0; in fsl_diu_probe()
1728 mfbi = info->par; in fsl_diu_probe()
1730 mfbi->parent = data; in fsl_diu_probe()
1731 mfbi->ad = &data->ad[i]; in fsl_diu_probe()
1737 memcpy(data->edid_data, prop, EDID_LENGTH); in fsl_diu_probe()
1738 data->has_edid = true; in fsl_diu_probe()
1741 data->diu_reg = of_iomap(np, 0); in fsl_diu_probe()
1742 if (!data->diu_reg) { in fsl_diu_probe()
1743 dev_err(&pdev->dev, "cannot map DIU registers\n"); in fsl_diu_probe()
1744 ret = -EFAULT; in fsl_diu_probe()
1749 data->irq = irq_of_parse_and_map(np, 0); in fsl_diu_probe()
1751 if (!data->irq) { in fsl_diu_probe()
1752 dev_err(&pdev->dev, "could not get DIU IRQ\n"); in fsl_diu_probe()
1753 ret = -EINVAL; in fsl_diu_probe()
1756 data->monitor_port = monitor_port; in fsl_diu_probe()
1759 data->dummy_ad.addr = cpu_to_le32(DMA_ADDR(data, dummy_aoi)); in fsl_diu_probe()
1760 data->dummy_ad.pix_fmt = 0x88882317; in fsl_diu_probe()
1761 data->dummy_ad.src_size_g_alpha = cpu_to_le32((4 << 12) | 4); in fsl_diu_probe()
1762 data->dummy_ad.aoi_size = cpu_to_le32((4 << 16) | 2); in fsl_diu_probe()
1763 data->dummy_ad.offset_xyi = 0; in fsl_diu_probe()
1764 data->dummy_ad.offset_xyd = 0; in fsl_diu_probe()
1765 data->dummy_ad.next_ad = 0; in fsl_diu_probe()
1766 data->dummy_ad.paddr = DMA_ADDR(data, dummy_ad); in fsl_diu_probe()
1769 * Let DIU continue to display splash screen if it was pre-initialized in fsl_diu_probe()
1772 if (in_be32(&data->diu_reg->diu_mode) == MFB_MODE0) in fsl_diu_probe()
1773 out_be32(&data->diu_reg->desc[0], 0); in fsl_diu_probe()
1775 out_be32(&data->diu_reg->desc[1], data->dummy_ad.paddr); in fsl_diu_probe()
1776 out_be32(&data->diu_reg->desc[2], data->dummy_ad.paddr); in fsl_diu_probe()
1779 * Older versions of U-Boot leave interrupts enabled, so disable in fsl_diu_probe()
1782 out_be32(&data->diu_reg->int_mask, 0xffffffff); in fsl_diu_probe()
1783 in_be32(&data->diu_reg->int_status); in fsl_diu_probe()
1785 ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb", in fsl_diu_probe()
1786 data->diu_reg); in fsl_diu_probe()
1788 dev_err(&pdev->dev, "could not claim irq\n"); in fsl_diu_probe()
1793 ret = install_fb(&data->fsl_diu_info[i]); in fsl_diu_probe()
1795 dev_err(&pdev->dev, "could not register fb %d\n", i); in fsl_diu_probe()
1796 free_irq(data->irq, data->diu_reg); in fsl_diu_probe()
1801 sysfs_attr_init(&data->dev_attr.attr); in fsl_diu_probe()
1802 data->dev_attr.attr.name = "monitor"; in fsl_diu_probe()
1803 data->dev_attr.attr.mode = S_IRUGO|S_IWUSR; in fsl_diu_probe()
1804 data->dev_attr.show = show_monitor; in fsl_diu_probe()
1805 data->dev_attr.store = store_monitor; in fsl_diu_probe()
1806 ret = device_create_file(&pdev->dev, &data->dev_attr); in fsl_diu_probe()
1808 dev_err(&pdev->dev, "could not create sysfs file %s\n", in fsl_diu_probe()
1809 data->dev_attr.attr.name); in fsl_diu_probe()
1812 dev_set_drvdata(&pdev->dev, data); in fsl_diu_probe()
1817 uninstall_fb(&data->fsl_diu_info[i]); in fsl_diu_probe()
1819 iounmap(data->diu_reg); in fsl_diu_probe()
1829 data = dev_get_drvdata(&pdev->dev); in fsl_diu_remove()
1830 disable_lcdc(&data->fsl_diu_info[0]); in fsl_diu_remove()
1832 free_irq(data->irq, data->diu_reg); in fsl_diu_remove()
1835 uninstall_fb(&data->fsl_diu_info[i]); in fsl_diu_remove()
1837 iounmap(data->diu_reg); in fsl_diu_remove()
1868 .compatible = "fsl,mpc5121-diu",
1880 .name = "fsl-diu-fb",
1903 return -ENODEV; in fsl_diu_init()
1914 return -ENODEV; in fsl_diu_init()
1921 pr_err("fsl-diu-fb: can't find 'cpu' device node\n"); in fsl_diu_init()
1922 return -ENODEV; in fsl_diu_init()
1925 prop = of_get_property(np, "d-cache-size", NULL); in fsl_diu_init()
1927 pr_err("fsl-diu-fb: missing 'd-cache-size' property' " in fsl_diu_init()
1930 return -ENODEV; in fsl_diu_init()
1940 pr_debug("fsl-diu-fb: coherence data size is %zu bytes\n", in fsl_diu_init()
1943 prop = of_get_property(np, "d-cache-line-size", NULL); in fsl_diu_init()
1945 pr_err("fsl-diu-fb: missing 'd-cache-line-size' property' " in fsl_diu_init()
1948 return -ENODEV; in fsl_diu_init()
1952 pr_debug("fsl-diu-fb: cache lines size is %u bytes\n", in fsl_diu_init()
1958 return -ENOMEM; in fsl_diu_init()
1963 pr_err("fsl-diu-fb: failed to register platform driver\n"); in fsl_diu_init()
1988 "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
1990 MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified in 'mode'");