On Mon, Apr 11, 2016 at 07:46:31PM +0300, Jyri Sarha wrote:
> Add tilcdc_crtc_mode_set_nofb(). The mode_set_nofb() semantics do not
> fit well to LCDC, because of the mandatory framebuffer. However, when
> the primary plane is required in the check phase, it and the
> framebuffer can be found from the atomic state struct.
> 
> Signed-off-by: Jyri Sarha <jsarha at ti.com>

Yeah, if your hw always requires a primary plane then 2 bits needed: a)
make sure in the crtc's atomic_check it's there and set b) just use the
hooks whoever you want to. Atomic allows planes to be entirely independent
of the display pipeline, but doesn't require it really.
-Daniel

> ---
>  drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 172 
> +++++++++++++++++++++++++++++++++++
>  1 file changed, 172 insertions(+)
> 
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
> b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> index 919c901..35f5682 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> @@ -310,6 +310,177 @@ static void tilcdc_crtc_commit(struct drm_crtc *crtc)
>       tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
>  }
>  
> +static void tilcdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
> +{
> +     struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
> +     struct drm_device *dev = crtc->dev;
> +     struct tilcdc_drm_private *priv = dev->dev_private;
> +     const struct tilcdc_panel_info *info = tilcdc_crtc->info;
> +     uint32_t reg, hbp, hfp, hsw, vbp, vfp, vsw;
> +     struct drm_display_mode *mode = &crtc->state->adjusted_mode;
> +     struct drm_framebuffer *fb = crtc->primary->state->fb;
> +
> +     if (WARN_ON(!info))
> +             return;
> +
> +     if (WARN_ON(!fb))
> +             return;
> +
> +     pm_runtime_get_sync(dev->dev);
> +
> +     /* Configure the Burst Size and fifo threshold of DMA: */
> +     reg = tilcdc_read(dev, LCDC_DMA_CTRL_REG) & ~0x00000770;
> +     switch (info->dma_burst_sz) {
> +     case 1:
> +             reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_1);
> +             break;
> +     case 2:
> +             reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_2);
> +             break;
> +     case 4:
> +             reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_4);
> +             break;
> +     case 8:
> +             reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_8);
> +             break;
> +     case 16:
> +             reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_16);
> +             break;
> +     default:
> +             dev_err(dev->dev, "invalid burst size\n");
> +             return;
> +     }
> +     reg |= (info->fifo_th << 8);
> +     tilcdc_write(dev, LCDC_DMA_CTRL_REG, reg);
> +
> +     /* Configure timings: */
> +     hbp = mode->htotal - mode->hsync_end;
> +     hfp = mode->hsync_start - mode->hdisplay;
> +     hsw = mode->hsync_end - mode->hsync_start;
> +     vbp = mode->vtotal - mode->vsync_end;
> +     vfp = mode->vsync_start - mode->vdisplay;
> +     vsw = mode->vsync_end - mode->vsync_start;
> +
> +     DBG("%dx%d, hbp=%u, hfp=%u, hsw=%u, vbp=%u, vfp=%u, vsw=%u",
> +         mode->hdisplay, mode->vdisplay, hbp, hfp, hsw, vbp, vfp, vsw);
> +
> +     /* Set AC Bias Period and Number of Transitions per Interrupt: */
> +     reg = tilcdc_read(dev, LCDC_RASTER_TIMING_2_REG) & ~0x000fff00;
> +     reg |= LCDC_AC_BIAS_FREQUENCY(info->ac_bias) |
> +             LCDC_AC_BIAS_TRANSITIONS_PER_INT(info->ac_bias_intrpt);
> +
> +     /*
> +      * subtract one from hfp, hbp, hsw because the hardware uses
> +      * a value of 0 as 1
> +      */
> +     if (priv->rev == 2) {
> +             /* clear bits we're going to set */
> +             reg &= ~0x78000033;
> +             reg |= ((hfp-1) & 0x300) >> 8;
> +             reg |= ((hbp-1) & 0x300) >> 4;
> +             reg |= ((hsw-1) & 0x3c0) << 21;
> +     }
> +     tilcdc_write(dev, LCDC_RASTER_TIMING_2_REG, reg);
> +
> +     reg = (((mode->hdisplay >> 4) - 1) << 4) |
> +             (((hbp-1) & 0xff) << 24) |
> +             (((hfp-1) & 0xff) << 16) |
> +             (((hsw-1) & 0x3f) << 10);
> +     if (priv->rev == 2)
> +             reg |= (((mode->hdisplay >> 4) - 1) & 0x40) >> 3;
> +     tilcdc_write(dev, LCDC_RASTER_TIMING_0_REG, reg);
> +
> +     reg = ((mode->vdisplay - 1) & 0x3ff) |
> +             ((vbp & 0xff) << 24) |
> +             ((vfp & 0xff) << 16) |
> +             (((vsw-1) & 0x3f) << 10);
> +     tilcdc_write(dev, LCDC_RASTER_TIMING_1_REG, reg);
> +
> +     /*
> +      * be sure to set Bit 10 for the V2 LCDC controller,
> +      * otherwise limited to 1024 pixels width, stopping
> +      * 1920x1080 being supported.
> +      */
> +     if (priv->rev == 2) {
> +             if ((mode->vdisplay - 1) & 0x400) {
> +                     tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG,
> +                             LCDC_LPP_B10);
> +             } else {
> +                     tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG,
> +                             LCDC_LPP_B10);
> +             }
> +     }
> +
> +     /* Configure display type: */
> +     reg = tilcdc_read(dev, LCDC_RASTER_CTRL_REG) &
> +             ~(LCDC_TFT_MODE | LCDC_MONO_8BIT_MODE | LCDC_MONOCHROME_MODE |
> +               LCDC_V2_TFT_24BPP_MODE | LCDC_V2_TFT_24BPP_UNPACK |
> +               0x000ff000 /* Palette Loading Delay bits */);
> +     reg |= LCDC_TFT_MODE; /* no monochrome/passive support */
> +     if (info->tft_alt_mode)
> +             reg |= LCDC_TFT_ALT_ENABLE;
> +     if (priv->rev == 2) {
> +             unsigned int depth, bpp;
> +
> +             drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
> +             switch (bpp) {
> +             case 16:
> +                     break;
> +             case 32:
> +                     reg |= LCDC_V2_TFT_24BPP_UNPACK;
> +                     /* fallthrough */
> +             case 24:
> +                     reg |= LCDC_V2_TFT_24BPP_MODE;
> +                     break;
> +             default:
> +                     dev_err(dev->dev, "invalid pixel format\n");
> +                     return;
> +             }
> +     }
> +     reg |= info->fdd < 12;
> +     tilcdc_write(dev, LCDC_RASTER_CTRL_REG, reg);
> +
> +     if (info->invert_pxl_clk)
> +             tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, 
> LCDC_INVERT_PIXEL_CLOCK);
> +     else
> +             tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, 
> LCDC_INVERT_PIXEL_CLOCK);
> +
> +     if (info->sync_ctrl)
> +             tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_CTRL);
> +     else
> +             tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_CTRL);
> +
> +     if (info->sync_edge)
> +             tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE);
> +     else
> +             tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE);
> +
> +     if (mode->flags & DRM_MODE_FLAG_NHSYNC)
> +             tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC);
> +     else
> +             tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC);
> +
> +     if (mode->flags & DRM_MODE_FLAG_NVSYNC)
> +             tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_VSYNC);
> +     else
> +             tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_VSYNC);
> +
> +     if (info->raster_order)
> +             tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ORDER);
> +     else
> +             tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ORDER);
> +
> +     drm_framebuffer_reference(fb);
> +
> +     set_scanout(crtc, fb);
> +
> +     tilcdc_crtc_update_clk(crtc);
> +
> +     pm_runtime_put_sync(dev->dev);
> +
> +     crtc->hwmode = crtc->state->adjusted_mode;
> +}
> +
>  static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
>               struct drm_display_mode *mode,
>               struct drm_display_mode *adjusted_mode,
> @@ -526,6 +697,7 @@ static const struct drm_crtc_helper_funcs 
> tilcdc_crtc_helper_funcs = {
>               .commit         = tilcdc_crtc_commit,
>               .mode_set       = tilcdc_crtc_mode_set,
>               .mode_set_base  = tilcdc_crtc_mode_set_base,
> +             .mode_set_nofb  = tilcdc_crtc_mode_set_nofb,
>  };
>  
>  int tilcdc_crtc_max_width(struct drm_crtc *crtc)
> -- 
> 1.9.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

Reply via email to