/*! * Probe routine for the framebuffer driver. It is called during the * driver binding process. The following functions are performed in * this routine: Framebuffer initialization, Memory allocation and * mapping, Framebuffer registration, IPU initialization. * * @return Appropriate error code to the kernel common code */ static int mxcfb_probe(struct platform_device *pdev) { struct fb_info *fbi; struct mxcfb_info *mxc_fbi; int ret; platform_set_drvdata(pdev, &mxcfb_drv_data); /* * Initialize FB structures */ fbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops); if (!fbi) { ret = -ENOMEM; goto err0; } mxcfb_drv_data.fbi = fbi; mxc_fbi = fbi->par; mxcfb_drv_data.suspended = false; init_waitqueue_head(&mxcfb_drv_data.suspend_wq); /* * Allocate memory */ ret = mxcfb_map_video_memory(fbi); if (ret < 0) { goto err1; } mxcfb_init_panel(fbi); /* * Register framebuffer */ ret = register_framebuffer(fbi); if (ret < 0) { goto err2; } dev_info(&pdev->dev, "%s registered\n", MXCFB_NAME); return 0; err2: mxcfb_unmap_video_memory(fbi); err1: if (&fbi->cmap) fb_dealloc_cmap(&fbi->cmap); framebuffer_release(fbi); err0: return ret; }
/* * Probe routine for the framebuffer driver. It is called during the * driver binding process. The following functions are performed in * this routine: Framebuffer initialization, Memory allocation and * mapping, Framebuffer registration, IPU initialization. * * @return Appropriate error code to the kernel common code */ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp, struct fb_videomode const *mode) { struct fb_info *fbi; struct mxcfb_info *mxcfbi; int ret = 0; /* * Initialize FB structures */ fbi = mxcfb_init_fbinfo(); if (!fbi) { ret = -ENOMEM; goto err0; } mxcfbi = (struct mxcfb_info *)fbi->par; if (!g_dp_in_use) { mxcfbi->ipu_ch = MEM_BG_SYNC; mxcfbi->blank = FB_BLANK_UNBLANK; } else { mxcfbi->ipu_ch = MEM_DC_SYNC; mxcfbi->blank = FB_BLANK_POWERDOWN; } mxcfbi->ipu_di = disp; ipu_disp_set_global_alpha(mxcfbi->ipu_ch, 1, 0x80); ipu_disp_set_color_key(mxcfbi->ipu_ch, 0, 0); strcpy(fbi->fix.id, "DISP3 BG"); g_dp_in_use = 1; mxcfb_info[mxcfbi->ipu_di] = fbi; /* Need dummy values until real panel is configured */ mxcfbi->ipu_di_pix_fmt = interface_pix_fmt; fb_videomode_to_var(&fbi->var, mode); fbi->var.bits_per_pixel = 16; fbi->fix.line_length = fbi->var.xres * (fbi->var.bits_per_pixel / 8); fbi->fix.smem_len = fbi->var.yres_virtual * fbi->fix.line_length; mxcfb_check_var(&fbi->var, fbi); /* Default Y virtual size is 2x panel size */ fbi->var.yres_virtual = fbi->var.yres * 2; mxcfb_set_fix(fbi); /* allocate fb first */ if (mxcfb_map_video_memory(fbi) < 0) return -ENOMEM; mxcfb_set_par(fbi); panel.winSizeX = mode->xres; panel.winSizeY = mode->yres; panel.plnSizeX = mode->xres; panel.plnSizeY = mode->yres; panel.frameAdrs = (u32)fbi->screen_base; panel.memSize = fbi->screen_size; panel.gdfBytesPP = 2; panel.gdfIndex = GDF_16BIT_565RGB; ipu_dump_registers(); return 0; err0: return ret; }
/* * Set framebuffer parameters and change the operating mode. * * @param info framebuffer information pointer */ static int mxcfb_set_par(struct fb_info *fbi) { int retval = 0; u32 mem_len; ipu_di_signal_cfg_t sig_cfg; struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par; uint32_t out_pixel_fmt; ipu_disable_channel(mxc_fbi->ipu_ch); ipu_uninit_channel(mxc_fbi->ipu_ch); mxcfb_set_fix(fbi); mem_len = fbi->var.yres_virtual * fbi->fix.line_length; if (!fbi->fix.smem_start || (mem_len > fbi->fix.smem_len)) { if (fbi->fix.smem_start) mxcfb_unmap_video_memory(fbi); if (mxcfb_map_video_memory(fbi) < 0) return -ENOMEM; } setup_disp_channel1(fbi); memset(&sig_cfg, 0, sizeof(sig_cfg)); if (fbi->var.vmode & FB_VMODE_INTERLACED) { sig_cfg.interlaced = 1; out_pixel_fmt = IPU_PIX_FMT_YUV444; } else { if (mxc_fbi->ipu_di_pix_fmt) out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt; else out_pixel_fmt = IPU_PIX_FMT_RGB666; } if (fbi->var.vmode & FB_VMODE_ODD_FLD_FIRST) /* PAL */ sig_cfg.odd_field_first = 1; if ((fbi->var.sync & FB_SYNC_EXT) || ext_clk_used) sig_cfg.ext_clk = 1; if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT) sig_cfg.Hsync_pol = 1; if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) sig_cfg.Vsync_pol = 1; if (!(fbi->var.sync & FB_SYNC_CLK_LAT_FALL)) sig_cfg.clk_pol = 1; if (fbi->var.sync & FB_SYNC_DATA_INVERT) sig_cfg.data_pol = 1; if (!(fbi->var.sync & FB_SYNC_OE_LOW_ACT)) sig_cfg.enable_pol = 1; if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN) sig_cfg.clkidle_en = 1; debug("pixclock = %lu Hz\n", PICOS2KHZ(fbi->var.pixclock) * 1000UL); if (ipu_init_sync_panel(mxc_fbi->ipu_di, (PICOS2KHZ(fbi->var.pixclock)) * 1000UL, fbi->var.xres, fbi->var.yres, out_pixel_fmt, fbi->var.left_margin, fbi->var.hsync_len, fbi->var.right_margin, fbi->var.upper_margin, fbi->var.vsync_len, fbi->var.lower_margin, 0, sig_cfg) != 0) { puts("mxcfb: Error initializing panel.\n"); return -EINVAL; } retval = setup_disp_channel2(fbi); if (retval) return retval; if (mxc_fbi->blank == FB_BLANK_UNBLANK) ipu_enable_channel(mxc_fbi->ipu_ch); return retval; }
/* * Probe routine for the framebuffer driver. It is called during the * driver binding process. The following functions are performed in * this routine: Framebuffer initialization, Memory allocation and * mapping, Framebuffer registration, IPU initialization. * * @return Appropriate error code to the kernel common code */ static int mxcfb_probe(u32 interface_pix_fmt, struct fb_videomode *mode, int di) { struct fb_info *fbi; struct mxcfb_info *mxcfbi; /* * Initialize FB structures */ fbi = mxcfb_init_fbinfo(); if (!fbi) return -ENOMEM; mxcfbi = fbi->par; if (!g_dp_in_use) { mxcfbi->ipu_ch = MEM_BG_SYNC; mxcfbi->blank = FB_BLANK_UNBLANK; } else { mxcfbi->ipu_ch = MEM_DC_SYNC; mxcfbi->blank = FB_BLANK_POWERDOWN; } mxcfbi->ipu_di = di; ipu_disp_set_global_alpha(mxcfbi->ipu_ch, 1, 0x80); ipu_disp_set_color_key(mxcfbi->ipu_ch, 0, 0); strcpy(fbi->fix.id, "DISP3 BG"); g_dp_in_use = 1; mxcfb_info[mxcfbi->ipu_di] = fbi; /* Need dummy values until real panel is configured */ fbi->var.xres = panel_info.vl_col; fbi->var.yres = panel_info.vl_row; mxcfbi->ipu_di_pix_fmt = interface_pix_fmt; fb_videomode_to_var(&fbi->var, mode); fbi->var.bits_per_pixel = NBITS(panel_info.vl_bpix); fbi->fix.line_length = fbi->var.xres * (fbi->var.bits_per_pixel / 8); fbi->fix.smem_len = fbi->var.yres_virtual * fbi->fix.line_length; mxcfb_check_var(&fbi->var, fbi); mxcfb_set_fix(fbi); /* allocate fb first */ if (mxcfb_map_video_memory(fbi) < 0) return -ENOMEM; mxcfb_set_par(fbi); lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; debug("MXC IPUV3 configured\n" "XRES = %d YRES = %d BitsXpixel = %d\n", panel_info.vl_col, panel_info.vl_row, panel_info.vl_bpix); ipu_dump_registers(); return 0; }
/* * Probe routine for the framebuffer driver. It is called during the * driver binding process. The following functions are performed in * this routine: Framebuffer initialization, Memory allocation and * mapping, Framebuffer registration, IPU initialization. * * @return Appropriate error code to the kernel common code */ static int mxcfb_probe(u32 interface_pix_fmt, struct fb_videomode *mode) { struct fb_info *fbi; struct mxcfb_info *mxcfbi; int ret = 0; /* * Initialize FB structures */ fbi = mxcfb_init_fbinfo(); if (!fbi) { ret = -ENOMEM; goto err0; } mxcfbi = (struct mxcfb_info *)fbi->par; if (!g_dp_in_use) { mxcfbi->ipu_ch = MEM_BG_SYNC; mxcfbi->blank = FB_BLANK_UNBLANK; } else { mxcfbi->ipu_ch = MEM_DC_SYNC; mxcfbi->blank = FB_BLANK_POWERDOWN; } mxcfbi->ipu_di = 0; ipu_disp_set_global_alpha(mxcfbi->ipu_ch, 1, 0x80); ipu_disp_set_color_key(mxcfbi->ipu_ch, 0, 0); strcpy(fbi->fix.id, "DISP3 BG"); g_dp_in_use = 1; mxcfb_info[mxcfbi->ipu_di] = fbi; /* Need dummy values until real panel is configured */ fbi->var.xres = 640; fbi->var.yres = 480; fbi->var.bits_per_pixel = 16; mxcfbi->ipu_di_pix_fmt = interface_pix_fmt; fb_videomode_to_var(&fbi->var, mode); mxcfb_check_var(&fbi->var, fbi); /* Default Y virtual size is 2x panel size */ fbi->var.yres_virtual = fbi->var.yres * 2; mxcfb_set_fix(fbi); /* alocate fb first */ if (mxcfb_map_video_memory(fbi) < 0) return -ENOMEM; mxcfb_set_par(fbi); /* Setting panel_info for lcd */ panel_info.cmap = NULL; panel_info.vl_col = fbi->var.xres; panel_info.vl_row = fbi->var.yres; panel_info.vl_bpix = LCD_BPP; lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; debug("MXC IPUV3 configured\n" "XRES = %d YRES = %d BitsXpixel = %d\n", panel_info.vl_col, panel_info.vl_row, panel_info.vl_bpix); ipu_dump_registers(); return 0; err0: return ret; }