static int ipu_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *orig_mode, struct drm_display_mode *mode, int x, int y, struct drm_framebuffer *old_fb) { struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); struct drm_framebuffer *fb = ipu_crtc->base.fb; int ret; struct ipu_di_signal_cfg sig_cfg = {}; u32 out_pixel_fmt; struct ipu_ch_param __iomem *cpmem = ipu_get_cpmem(ipu_crtc->ipu_ch); int bpp; u32 v4l2_fmt; dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__, mode->hdisplay); dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__, mode->vdisplay); ipu_ch_param_zero(cpmem); switch (fb->pixel_format) { case DRM_FORMAT_XRGB8888: case DRM_FORMAT_ARGB8888: v4l2_fmt = V4L2_PIX_FMT_RGB32; bpp = 32; break; case DRM_FORMAT_RGB565: v4l2_fmt = V4L2_PIX_FMT_RGB565; bpp = 16; break; case DRM_FORMAT_RGB888: v4l2_fmt = V4L2_PIX_FMT_RGB24; bpp = 24; break; default: dev_err(ipu_crtc->dev, "unsupported pixel format 0x%08x\n", fb->pixel_format); return -EINVAL; } out_pixel_fmt = ipu_crtc->interface_pix_fmt; if (mode->flags & DRM_MODE_FLAG_INTERLACE) sig_cfg.interlaced = 1; if (mode->flags & DRM_MODE_FLAG_PHSYNC) sig_cfg.Hsync_pol = 1; if (mode->flags & DRM_MODE_FLAG_PVSYNC) sig_cfg.Vsync_pol = 1; sig_cfg.enable_pol = 1; sig_cfg.clk_pol = 0; sig_cfg.width = mode->hdisplay; sig_cfg.height = mode->vdisplay; sig_cfg.pixel_fmt = out_pixel_fmt; sig_cfg.h_start_width = mode->htotal - mode->hsync_end; sig_cfg.h_sync_width = mode->hsync_end - mode->hsync_start; sig_cfg.h_end_width = mode->hsync_start - mode->hdisplay; sig_cfg.v_start_width = mode->vtotal - mode->vsync_end; sig_cfg.v_sync_width = mode->vsync_end - mode->vsync_start; sig_cfg.v_end_width = mode->vsync_start - mode->vdisplay; sig_cfg.pixelclock = mode->clock * 1000; sig_cfg.clkflags = ipu_crtc->di_clkflags; sig_cfg.v_to_h_sync = 0; if (ipu_crtc->dp) { ret = ipu_dp_setup_channel(ipu_crtc->dp, IPUV3_COLORSPACE_RGB, IPUV3_COLORSPACE_RGB); if (ret) { dev_err(ipu_crtc->dev, "initializing display processor failed with %d\n", ret); return ret; } ipu_dp_set_global_alpha(ipu_crtc->dp, 1, 0, 1); } ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, sig_cfg.interlaced, out_pixel_fmt, mode->hdisplay); if (ret) { dev_err(ipu_crtc->dev, "initializing display controller failed with %d\n", ret); return ret; } ret = ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg); if (ret) { dev_err(ipu_crtc->dev, "initializing panel failed with %d\n", ret); return ret; } ipu_cpmem_set_resolution(cpmem, mode->hdisplay, mode->vdisplay); ipu_cpmem_set_fmt(cpmem, v4l2_fmt); ipu_cpmem_set_high_priority(ipu_crtc->ipu_ch); ret = ipu_dmfc_init_channel(ipu_crtc->dmfc, mode->hdisplay); if (ret) { dev_err(ipu_crtc->dev, "initializing dmfc channel failed with %d\n", ret); return ret; } ret = ipu_dmfc_alloc_bandwidth(ipu_crtc->dmfc, calc_bandwidth(mode, calc_vref(mode)), 64); if (ret) { dev_err(ipu_crtc->dev, "allocating dmfc bandwidth failed with %d\n", ret); return ret; } ipu_drm_set_base(crtc, x, y); return 0; }
static int ipu_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *orig_mode, struct drm_display_mode *mode, int x, int y, struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc->dev; struct drm_encoder *encoder; struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); struct ipu_di_signal_cfg sig_cfg = {}; unsigned long encoder_types = 0; u32 out_pixel_fmt; int ret; dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__, mode->hdisplay); dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__, mode->vdisplay); list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) if (encoder->crtc == crtc) encoder_types |= BIT(encoder->encoder_type); dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%lx\n", __func__, encoder_types); /* * If we have DAC, TVDAC or LDB, then we need the IPU DI clock * to be the same as the LDB DI clock. */ if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) | BIT(DRM_MODE_ENCODER_TVDAC) | BIT(DRM_MODE_ENCODER_LVDS))) sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT; else sig_cfg.clkflags = 0; out_pixel_fmt = ipu_crtc->interface_pix_fmt; sig_cfg.enable_pol = 1; sig_cfg.clk_pol = 0; sig_cfg.pixel_fmt = out_pixel_fmt; sig_cfg.v_to_h_sync = 0; sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin; drm_display_mode_to_videomode(mode, &sig_cfg.mode); ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, mode->flags & DRM_MODE_FLAG_INTERLACE, out_pixel_fmt, mode->hdisplay); if (ret) { dev_err(ipu_crtc->dev, "initializing display controller failed with %d\n", ret); return ret; } ret = ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg); if (ret) { dev_err(ipu_crtc->dev, "initializing panel failed with %d\n", ret); return ret; } return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, x, y, mode->hdisplay, mode->vdisplay); }
static int ipu_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *orig_mode, struct drm_display_mode *mode, int x, int y, struct drm_framebuffer *old_fb) { struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); int ret; struct ipu_di_signal_cfg sig_cfg = {}; u32 out_pixel_fmt; dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__, mode->hdisplay); dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__, mode->vdisplay); out_pixel_fmt = ipu_crtc->interface_pix_fmt; if (mode->flags & DRM_MODE_FLAG_INTERLACE) sig_cfg.interlaced = 1; if (mode->flags & DRM_MODE_FLAG_PHSYNC) sig_cfg.Hsync_pol = 1; if (mode->flags & DRM_MODE_FLAG_PVSYNC) sig_cfg.Vsync_pol = 1; sig_cfg.enable_pol = 1; sig_cfg.clk_pol = 1; sig_cfg.width = mode->hdisplay; sig_cfg.height = mode->vdisplay; sig_cfg.pixel_fmt = out_pixel_fmt; sig_cfg.h_start_width = mode->htotal - mode->hsync_end; sig_cfg.h_sync_width = mode->hsync_end - mode->hsync_start; sig_cfg.h_end_width = mode->hsync_start - mode->hdisplay; sig_cfg.v_start_width = mode->vtotal - mode->vsync_end; sig_cfg.v_sync_width = mode->vsync_end - mode->vsync_start; sig_cfg.v_end_width = mode->vsync_start - mode->vdisplay; sig_cfg.pixelclock = mode->clock * 1000; sig_cfg.clkflags = ipu_crtc->di_clkflags; sig_cfg.v_to_h_sync = 0; sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin; ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, sig_cfg.interlaced, out_pixel_fmt, mode->hdisplay); if (ret) { dev_err(ipu_crtc->dev, "initializing display controller failed with %d\n", ret); return ret; } ret = ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg); if (ret) { dev_err(ipu_crtc->dev, "initializing panel failed with %d\n", ret); return ret; } return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode, crtc->fb, 0, 0, mode->hdisplay, mode->vdisplay, x, y, mode->hdisplay, mode->vdisplay); }