const struct dpu_format *dpu_get_dpu_format_ext( const uint32_t format, const uint64_t modifier) { uint32_t i = 0; const struct dpu_format *fmt = NULL; const struct dpu_format *map = NULL; ssize_t map_size = 0; /* * Currently only support exactly zero or one modifier. * All planes use the same modifier. */ DPU_DEBUG("plane format modifier 0x%llX\n", modifier); switch (modifier) { case 0: map = dpu_format_map; map_size = ARRAY_SIZE(dpu_format_map); break; case DRM_FORMAT_MOD_QCOM_COMPRESSED: map = dpu_format_map_ubwc; map_size = ARRAY_SIZE(dpu_format_map_ubwc); DPU_DEBUG("found fmt: %4.4s DRM_FORMAT_MOD_QCOM_COMPRESSED\n", (char *)&format); break; default: DPU_ERROR("unsupported format modifier %llX\n", modifier); return NULL; } for (i = 0; i < map_size; i++) { if (format == map[i].base.pixel_format) { fmt = &map[i]; break; } } if (fmt == NULL) DPU_ERROR("unsupported fmt: %4.4s modifier 0x%llX\n", (char *)&format, modifier); else DPU_DEBUG("fmt %4.4s mod 0x%llX ubwc %d yuv %d\n", (char *)&format, modifier, DPU_FORMAT_IS_UBWC(fmt), DPU_FORMAT_IS_YUV(fmt)); return fmt; }
static void dpu_encoder_phys_vid_setup_timing_engine( struct dpu_encoder_phys *phys_enc) { struct dpu_encoder_phys_vid *vid_enc; struct drm_display_mode mode; struct intf_timing_params timing_params = { 0 }; const struct dpu_format *fmt = NULL; u32 fmt_fourcc = DRM_FORMAT_RGB888; unsigned long lock_flags; struct dpu_hw_intf_cfg intf_cfg = { 0 }; if (!phys_enc || !phys_enc->hw_ctl->ops.setup_intf_cfg) { DPU_ERROR("invalid encoder %d\n", phys_enc != 0); return; } mode = phys_enc->cached_mode; vid_enc = to_dpu_encoder_phys_vid(phys_enc); if (!vid_enc->hw_intf->ops.setup_timing_gen) { DPU_ERROR("timing engine setup is not supported\n"); return; } DPU_DEBUG_VIDENC(vid_enc, "enabling mode:\n"); drm_mode_debug_printmodeline(&mode); if (phys_enc->split_role != ENC_ROLE_SOLO) { mode.hdisplay >>= 1; mode.htotal >>= 1; mode.hsync_start >>= 1; mode.hsync_end >>= 1; DPU_DEBUG_VIDENC(vid_enc, "split_role %d, halve horizontal %d %d %d %d\n", phys_enc->split_role, mode.hdisplay, mode.htotal, mode.hsync_start, mode.hsync_end); }
struct dpu_hw_mdp *dpu_hw_mdptop_init(enum dpu_mdp idx, void __iomem *addr, const struct dpu_mdss_cfg *m) { struct dpu_hw_mdp *mdp; const struct dpu_mdp_cfg *cfg; int rc; if (!addr || !m) return ERR_PTR(-EINVAL); mdp = kzalloc(sizeof(*mdp), GFP_KERNEL); if (!mdp) return ERR_PTR(-ENOMEM); cfg = _top_offset(idx, m, addr, &mdp->hw); if (IS_ERR_OR_NULL(cfg)) { kfree(mdp); return ERR_PTR(-EINVAL); } /* * Assign ops */ mdp->idx = idx; mdp->caps = cfg; _setup_mdp_ops(&mdp->ops, mdp->caps->features); rc = dpu_hw_blk_init(&mdp->base, DPU_HW_BLK_TOP, idx, &dpu_hw_ops); if (rc) { DPU_ERROR("failed to init hw blk %d\n", rc); goto blk_init_error; } dpu_dbg_set_dpu_top_offset(mdp->hw.blk_off); return mdp; blk_init_error: kzfree(mdp); return ERR_PTR(rc); }
struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx, void __iomem *addr, struct dpu_mdss_cfg *m) { struct dpu_hw_intf *c; struct dpu_intf_cfg *cfg; int rc; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); cfg = _intf_offset(idx, m, addr, &c->hw); if (IS_ERR_OR_NULL(cfg)) { kfree(c); pr_err("failed to create dpu_hw_intf %d\n", idx); return ERR_PTR(-EINVAL); } /* * Assign ops */ c->idx = idx; c->cap = cfg; c->mdss = m; _setup_intf_ops(&c->ops, c->cap->features); rc = dpu_hw_blk_init(&c->base, DPU_HW_BLK_INTF, idx, &dpu_hw_ops); if (rc) { DPU_ERROR("failed to init hw blk %d\n", rc); goto blk_init_error; } return c; blk_init_error: kzfree(c); return ERR_PTR(rc); }
static void drm_mode_to_intf_timing_params( const struct dpu_encoder_phys_vid *vid_enc, const struct drm_display_mode *mode, struct intf_timing_params *timing) { memset(timing, 0, sizeof(*timing)); if ((mode->htotal < mode->hsync_end) || (mode->hsync_start < mode->hdisplay) || (mode->vtotal < mode->vsync_end) || (mode->vsync_start < mode->vdisplay) || (mode->hsync_end < mode->hsync_start) || (mode->vsync_end < mode->vsync_start)) { DPU_ERROR( "invalid params - hstart:%d,hend:%d,htot:%d,hdisplay:%d\n", mode->hsync_start, mode->hsync_end, mode->htotal, mode->hdisplay); DPU_ERROR("vstart:%d,vend:%d,vtot:%d,vdisplay:%d\n", mode->vsync_start, mode->vsync_end, mode->vtotal, mode->vdisplay); return; } /* * https://www.kernel.org/doc/htmldocs/drm/ch02s05.html * Active Region Front Porch Sync Back Porch * <-----------------><------------><-----><-----------> * <- [hv]display ---> * <--------- [hv]sync_start ------> * <----------------- [hv]sync_end -------> * <---------------------------- [hv]total -------------> */ timing->width = mode->hdisplay; /* active width */ timing->height = mode->vdisplay; /* active height */ timing->xres = timing->width; timing->yres = timing->height; timing->h_back_porch = mode->htotal - mode->hsync_end; timing->h_front_porch = mode->hsync_start - mode->hdisplay; timing->v_back_porch = mode->vtotal - mode->vsync_end; timing->v_front_porch = mode->vsync_start - mode->vdisplay; timing->hsync_pulse_width = mode->hsync_end - mode->hsync_start; timing->vsync_pulse_width = mode->vsync_end - mode->vsync_start; timing->hsync_polarity = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0; timing->vsync_polarity = (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0; timing->border_clr = 0; timing->underflow_clr = 0xff; timing->hsync_skew = mode->hskew; /* DSI controller cannot handle active-low sync signals. */ if (vid_enc->hw_intf->cap->type == INTF_DSI) { timing->hsync_polarity = 0; timing->vsync_polarity = 0; } /* * For edp only: * DISPLAY_V_START = (VBP * HCYCLE) + HBP * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP */ /* * if (vid_enc->hw->cap->type == INTF_EDP) { * display_v_start += mode->htotal - mode->hsync_start; * display_v_end -= mode->hsync_start - mode->hdisplay; * } */ }