diff options
author | Vincent Abriou <vincent.abriou@st.com> | 2015-07-31 11:32:13 +0200 |
---|---|---|
committer | Benjamin Gaignard <benjamin.gaignard@linaro.org> | 2015-08-03 14:25:01 +0200 |
commit | 871bcdfea68560991bd650406e47a801ab9d635d (patch) | |
tree | 8a760b230480bb3227e916b157b3b4ff628cd603 /drivers/gpu/drm/sti/sti_hqvdp.c | |
parent | drm/sti: fix dynamic z-ordering (diff) | |
download | linux-871bcdfea68560991bd650406e47a801ab9d635d.tar.xz linux-871bcdfea68560991bd650406e47a801ab9d635d.zip |
drm/sti: code clean up
Purpose is to simplify the STI driver:
- remove layer structure
- consider video subdev as part of the compositor (like mixer subdev)
- remove useless STI_VID0 and STI_VID1 enum
Signed-off-by: Vincent Abriou <vincent.abriou@st.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Diffstat (limited to 'drivers/gpu/drm/sti/sti_hqvdp.c')
-rw-r--r-- | drivers/gpu/drm/sti/sti_hqvdp.c | 201 |
1 files changed, 97 insertions, 104 deletions
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c index b0eb62de1b2e..54e8c2f06cf4 100644 --- a/drivers/gpu/drm/sti/sti_hqvdp.c +++ b/drivers/gpu/drm/sti/sti_hqvdp.c @@ -14,9 +14,7 @@ #include <drm/drmP.h> #include "sti_drm_plane.h" -#include "sti_hqvdp.h" #include "sti_hqvdp_lut.h" -#include "sti_layer.h" #include "sti_vtg.h" /* Firmware name */ @@ -322,8 +320,7 @@ struct sti_hqvdp_cmd { * @dev: driver device * @drm_dev: the drm device * @regs: registers - * @layer: layer structure for hqvdp it self - * @vid_plane: VID plug used as link with compositor IP + * @plane: plane structure for hqvdp it self * @clk: IP clock * @clk_pix_main: pix main clock * @reset: reset control @@ -334,13 +331,13 @@ struct sti_hqvdp_cmd { * @hqvdp_cmd: buffer of commands * @hqvdp_cmd_paddr: physical address of hqvdp_cmd * @vtg: vtg for main data path + * @xp70_initialized: true if xp70 is already initialized */ struct sti_hqvdp { struct device *dev; struct drm_device *drm_dev; void __iomem *regs; - struct sti_layer layer; - struct drm_plane *vid_plane; + struct sti_plane plane; struct clk *clk; struct clk *clk_pix_main; struct reset_control *reset; @@ -351,20 +348,21 @@ struct sti_hqvdp { void *hqvdp_cmd; dma_addr_t hqvdp_cmd_paddr; struct sti_vtg *vtg; + bool xp70_initialized; }; -#define to_sti_hqvdp(x) container_of(x, struct sti_hqvdp, layer) +#define to_sti_hqvdp(x) container_of(x, struct sti_hqvdp, plane) static const uint32_t hqvdp_supported_formats[] = { DRM_FORMAT_NV12, }; -static const uint32_t *sti_hqvdp_get_formats(struct sti_layer *layer) +static const uint32_t *sti_hqvdp_get_formats(struct sti_plane *plane) { return hqvdp_supported_formats; } -static unsigned int sti_hqvdp_get_nb_formats(struct sti_layer *layer) +static unsigned int sti_hqvdp_get_nb_formats(struct sti_plane *plane) { return ARRAY_SIZE(hqvdp_supported_formats); } @@ -484,7 +482,7 @@ static void sti_hqvdp_update_hvsrc(enum sti_hvsrc_orient orient, int scale, /** * sti_hqvdp_check_hw_scaling - * @layer: hqvdp layer + * @plane: hqvdp plane * * Check if the HW is able to perform the scaling request * The firmware scaling limitation is "CEIL(1/Zy) <= FLOOR(LFW)" where: @@ -498,23 +496,23 @@ static void sti_hqvdp_update_hvsrc(enum sti_hvsrc_orient orient, int scale, * RETURNS: * True if the HW can scale. */ -static bool sti_hqvdp_check_hw_scaling(struct sti_layer *layer) +static bool sti_hqvdp_check_hw_scaling(struct sti_plane *plane) { - struct sti_hqvdp *hqvdp = to_sti_hqvdp(layer); + struct sti_hqvdp *hqvdp = to_sti_hqvdp(plane); unsigned long lfw; unsigned int inv_zy; - lfw = layer->mode->htotal * (clk_get_rate(hqvdp->clk) / 1000000); - lfw /= max(layer->src_w, layer->dst_w) * layer->mode->clock / 1000; + lfw = plane->mode->htotal * (clk_get_rate(hqvdp->clk) / 1000000); + lfw /= max(plane->src_w, plane->dst_w) * plane->mode->clock / 1000; - inv_zy = DIV_ROUND_UP(layer->src_h, layer->dst_h); + inv_zy = DIV_ROUND_UP(plane->src_h, plane->dst_h); return (inv_zy <= lfw) ? true : false; } /** - * sti_hqvdp_prepare_layer - * @layer: hqvdp layer + * sti_hqvdp_prepare + * @plane: hqvdp plane * @first_prepare: true if it is the first time this function is called * * Prepares a command for the firmware @@ -522,22 +520,14 @@ static bool sti_hqvdp_check_hw_scaling(struct sti_layer *layer) * RETURNS: * 0 on success. */ -static int sti_hqvdp_prepare_layer(struct sti_layer *layer, bool first_prepare) +static int sti_hqvdp_prepare(struct sti_plane *plane, bool first_prepare) { - struct sti_hqvdp *hqvdp = to_sti_hqvdp(layer); + struct sti_hqvdp *hqvdp = to_sti_hqvdp(plane); struct sti_hqvdp_cmd *cmd; int scale_h, scale_v; int cmd_offset; - dev_dbg(hqvdp->dev, "%s %s\n", __func__, sti_layer_to_str(layer)); - - /* prepare and commit VID plane */ - hqvdp->vid_plane->funcs->update_plane(hqvdp->vid_plane, - layer->crtc, layer->fb, - layer->dst_x, layer->dst_y, - layer->dst_w, layer->dst_h, - layer->src_x, layer->src_y, - layer->src_w, layer->src_h); + dev_dbg(hqvdp->dev, "%s %s\n", __func__, sti_plane_to_str(plane)); cmd_offset = sti_hqvdp_get_free_cmd(hqvdp); if (cmd_offset == -1) { @@ -546,7 +536,7 @@ static int sti_hqvdp_prepare_layer(struct sti_layer *layer, bool first_prepare) } cmd = hqvdp->hqvdp_cmd + cmd_offset; - if (!sti_hqvdp_check_hw_scaling(layer)) { + if (!sti_hqvdp_check_hw_scaling(plane)) { DRM_ERROR("Scaling beyond HW capabilities\n"); return -EINVAL; } @@ -565,42 +555,42 @@ static int sti_hqvdp_prepare_layer(struct sti_layer *layer, bool first_prepare) cmd->iqi.pxf_conf = IQI_PXF_CONF_DFLT; /* Buffer planes address */ - cmd->top.current_luma = (u32) layer->paddr + layer->offsets[0]; - cmd->top.current_chroma = (u32) layer->paddr + layer->offsets[1]; + cmd->top.current_luma = (u32)plane->paddr + plane->offsets[0]; + cmd->top.current_chroma = (u32)plane->paddr + plane->offsets[1]; /* Pitches */ cmd->top.luma_processed_pitch = cmd->top.luma_src_pitch = - layer->pitches[0]; + plane->pitches[0]; cmd->top.chroma_processed_pitch = cmd->top.chroma_src_pitch = - layer->pitches[1]; + plane->pitches[1]; /* Input / output size * Align to upper even value */ - layer->dst_w = ALIGN(layer->dst_w, 2); - layer->dst_h = ALIGN(layer->dst_h, 2); + plane->dst_w = ALIGN(plane->dst_w, 2); + plane->dst_h = ALIGN(plane->dst_h, 2); - if ((layer->src_w > MAX_WIDTH) || (layer->src_w < MIN_WIDTH) || - (layer->src_h > MAX_HEIGHT) || (layer->src_h < MIN_HEIGHT) || - (layer->dst_w > MAX_WIDTH) || (layer->dst_w < MIN_WIDTH) || - (layer->dst_h > MAX_HEIGHT) || (layer->dst_h < MIN_HEIGHT)) { + if ((plane->src_w > MAX_WIDTH) || (plane->src_w < MIN_WIDTH) || + (plane->src_h > MAX_HEIGHT) || (plane->src_h < MIN_HEIGHT) || + (plane->dst_w > MAX_WIDTH) || (plane->dst_w < MIN_WIDTH) || + (plane->dst_h > MAX_HEIGHT) || (plane->dst_h < MIN_HEIGHT)) { DRM_ERROR("Invalid in/out size %dx%d -> %dx%d\n", - layer->src_w, layer->src_h, - layer->dst_w, layer->dst_h); + plane->src_w, plane->src_h, + plane->dst_w, plane->dst_h); return -EINVAL; } cmd->top.input_viewport_size = cmd->top.input_frame_size = - layer->src_h << 16 | layer->src_w; - cmd->hvsrc.output_picture_size = layer->dst_h << 16 | layer->dst_w; - cmd->top.input_viewport_ori = layer->src_y << 16 | layer->src_x; + plane->src_h << 16 | plane->src_w; + cmd->hvsrc.output_picture_size = plane->dst_h << 16 | plane->dst_w; + cmd->top.input_viewport_ori = plane->src_y << 16 | plane->src_x; /* Handle interlaced */ - if (layer->fb->flags & DRM_MODE_FB_INTERLACED) { + if (plane->fb->flags & DRM_MODE_FB_INTERLACED) { /* Top field to display */ cmd->top.config = TOP_CONFIG_INTER_TOP; /* Update pitches and vert size */ - cmd->top.input_frame_size = (layer->src_h / 2) << 16 | - layer->src_w; + cmd->top.input_frame_size = (plane->src_h / 2) << 16 | + plane->src_w; cmd->top.luma_processed_pitch *= 2; cmd->top.luma_src_pitch *= 2; cmd->top.chroma_processed_pitch *= 2; @@ -613,10 +603,10 @@ static int sti_hqvdp_prepare_layer(struct sti_layer *layer, bool first_prepare) } /* Update hvsrc lut coef */ - scale_h = SCALE_FACTOR * layer->dst_w / layer->src_w; + scale_h = SCALE_FACTOR * plane->dst_w / plane->src_w; sti_hqvdp_update_hvsrc(HVSRC_HORI, scale_h, &cmd->hvsrc); - scale_v = SCALE_FACTOR * layer->dst_h / layer->src_h; + scale_v = SCALE_FACTOR * plane->dst_h / plane->src_h; sti_hqvdp_update_hvsrc(HVSRC_VERT, scale_v, &cmd->hvsrc); if (first_prepare) { @@ -627,9 +617,9 @@ static int sti_hqvdp_prepare_layer(struct sti_layer *layer, bool first_prepare) } /* Register VTG Vsync callback to handle bottom fields */ - if ((layer->fb->flags & DRM_MODE_FB_INTERLACED) && - sti_vtg_register_client(hqvdp->vtg, - &hqvdp->vtg_nb, layer->mixer_id)) { + if ((plane->fb->flags & DRM_MODE_FB_INTERLACED) && + sti_vtg_register_client(hqvdp->vtg, &hqvdp->vtg_nb, + plane->mixer_id)) { DRM_ERROR("Cannot register VTG notifier\n"); return -ENXIO; } @@ -638,12 +628,21 @@ static int sti_hqvdp_prepare_layer(struct sti_layer *layer, bool first_prepare) return 0; } -static int sti_hqvdp_commit_layer(struct sti_layer *layer) +/** + * sti_hqvdp_commit + * @plane: hqvdp plane + * + * Enables the HQVDP plane + * + * RETURNS: + * 0 on success. + */ +static int sti_hqvdp_commit(struct sti_plane *plane) { - struct sti_hqvdp *hqvdp = to_sti_hqvdp(layer); + struct sti_hqvdp *hqvdp = to_sti_hqvdp(plane); int cmd_offset; - dev_dbg(hqvdp->dev, "%s %s\n", __func__, sti_layer_to_str(layer)); + dev_dbg(hqvdp->dev, "%s %s\n", __func__, sti_plane_to_str(plane)); cmd_offset = sti_hqvdp_get_free_cmd(hqvdp); if (cmd_offset == -1) { @@ -657,7 +656,7 @@ static int sti_hqvdp_commit_layer(struct sti_layer *layer) hqvdp->curr_field_count++; /* Interlaced : get ready to display the bottom field at next Vsync */ - if (layer->fb->flags & DRM_MODE_FB_INTERLACED) + if (plane->fb->flags & DRM_MODE_FB_INTERLACED) hqvdp->btm_field_pending = true; dev_dbg(hqvdp->dev, "%s Posted command:0x%x\n", @@ -666,16 +665,25 @@ static int sti_hqvdp_commit_layer(struct sti_layer *layer) return 0; } -static int sti_hqvdp_disable_layer(struct sti_layer *layer) +/** + * sti_hqvdp_disable + * @plane: hqvdp plane + * + * Disables the HQVDP plane + * + * RETURNS: + * 0 on success. + */ +static int sti_hqvdp_disable(struct sti_plane *plane) { - struct sti_hqvdp *hqvdp = to_sti_hqvdp(layer); + struct sti_hqvdp *hqvdp = to_sti_hqvdp(plane); int i; - DRM_DEBUG_DRIVER("%s\n", sti_layer_to_str(layer)); + DRM_DEBUG_DRIVER("%s\n", sti_plane_to_str(plane)); /* Unregister VTG Vsync callback */ - if ((layer->fb->flags & DRM_MODE_FB_INTERLACED) && - sti_vtg_unregister_client(hqvdp->vtg, &hqvdp->vtg_nb)) + if ((plane->fb->flags & DRM_MODE_FB_INTERLACED) && + sti_vtg_unregister_client(hqvdp->vtg, &hqvdp->vtg_nb)) DRM_DEBUG_DRIVER("Warning: cannot unregister VTG notifier\n"); /* Set next cmd to NULL */ @@ -696,9 +704,6 @@ static int sti_hqvdp_disable_layer(struct sti_layer *layer) return -ENXIO; } - /* disable VID plane */ - hqvdp->vid_plane->funcs->disable_plane(hqvdp->vid_plane); - return 0; } @@ -758,32 +763,10 @@ int sti_hqvdp_vtg_cb(struct notifier_block *nb, unsigned long evt, void *data) return 0; } -static struct drm_plane *sti_hqvdp_find_vid(struct drm_device *dev, int id) -{ - struct drm_plane *plane; - - list_for_each_entry(plane, &dev->mode_config.plane_list, head) { - struct sti_layer *layer = to_sti_layer(plane); - - if (layer->desc == id) - return plane; - } - - return NULL; -} - -static void sti_hqvd_init(struct sti_layer *layer) +static void sti_hqvdp_init(struct sti_hqvdp *hqvdp) { - struct sti_hqvdp *hqvdp = to_sti_hqvdp(layer); int size; - /* find the plane macthing with vid 0 */ - hqvdp->vid_plane = sti_hqvdp_find_vid(hqvdp->drm_dev, STI_VID_0); - if (!hqvdp->vid_plane) { - DRM_ERROR("Cannot find Main video layer\n"); - return; - } - hqvdp->vtg_nb.notifier_call = sti_hqvdp_vtg_cb; /* Allocate memory for the VDP commands */ @@ -799,24 +782,25 @@ static void sti_hqvd_init(struct sti_layer *layer) memset(hqvdp->hqvdp_cmd, 0, size); } -static const struct sti_layer_funcs hqvdp_ops = { +static const struct sti_plane_funcs hqvdp_plane_ops = { .get_formats = sti_hqvdp_get_formats, .get_nb_formats = sti_hqvdp_get_nb_formats, - .init = sti_hqvd_init, - .prepare = sti_hqvdp_prepare_layer, - .commit = sti_hqvdp_commit_layer, - .disable = sti_hqvdp_disable_layer, + .prepare = sti_hqvdp_prepare, + .commit = sti_hqvdp_commit, + .disable = sti_hqvdp_disable, }; -struct sti_layer *sti_hqvdp_create(struct device *dev) +struct sti_plane *sti_hqvdp_create(struct device *dev, int desc) { struct sti_hqvdp *hqvdp = dev_get_drvdata(dev); - hqvdp->layer.ops = &hqvdp_ops; + hqvdp->plane.desc = desc; + hqvdp->plane.ops = &hqvdp_plane_ops; - return &hqvdp->layer; + sti_hqvdp_init(hqvdp); + + return &hqvdp->plane; } -EXPORT_SYMBOL(sti_hqvdp_create); static void sti_hqvdp_init_plugs(struct sti_hqvdp *hqvdp) { @@ -859,6 +843,12 @@ static void sti_hqvdp_start_xp70(const struct firmware *firmware, void *ctxt) } *header; DRM_DEBUG_DRIVER("\n"); + + if (hqvdp->xp70_initialized) { + DRM_INFO("HQVDP XP70 already initialized\n"); + return; + } + /* Check firmware parts */ if (!firmware) { DRM_ERROR("Firmware not available\n"); @@ -946,7 +936,10 @@ static void sti_hqvdp_start_xp70(const struct firmware *firmware, void *ctxt) /* Launch Vsync */ writel(SOFT_VSYNC_HW, hqvdp->regs + HQVDP_MBX_SOFT_VSYNC); - DRM_INFO("HQVDP XP70 started\n"); + DRM_INFO("HQVDP XP70 initialized\n"); + + hqvdp->xp70_initialized = true; + out: release_firmware(firmware); } @@ -955,7 +948,7 @@ int sti_hqvdp_bind(struct device *dev, struct device *master, void *data) { struct sti_hqvdp *hqvdp = dev_get_drvdata(dev); struct drm_device *drm_dev = data; - struct sti_layer *layer; + struct sti_plane *plane; int err; DRM_DEBUG_DRIVER("\n"); @@ -971,13 +964,13 @@ int sti_hqvdp_bind(struct device *dev, struct device *master, void *data) return err; } - layer = sti_layer_create(hqvdp->dev, STI_HQVDP_0, hqvdp->regs); - if (!layer) { + /* Create HQVDP plane once xp70 is initialized */ + plane = sti_hqvdp_create(hqvdp->dev, STI_HQVDP_0); + if (plane) + sti_drm_plane_init(hqvdp->drm_dev, plane, 1, + DRM_PLANE_TYPE_OVERLAY); + else DRM_ERROR("Can't create HQVDP plane\n"); - return -ENOMEM; - } - - sti_drm_plane_init(drm_dev, layer, 1, DRM_PLANE_TYPE_OVERLAY); return 0; } |