<div dir="ltr"><div dir="ltr">Hi</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Emil Velikov <<a href="mailto:emil.l.velikov@gmail.com">emil.l.velikov@gmail.com</a>> 于2019年12月11日周三 上午1:14写道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Kevin,<br>
<br>
On Tue, 10 Dec 2019 at 08:41, Kevin Tang <<a href="mailto:kevin3.tang@gmail.com" target="_blank">kevin3.tang@gmail.com</a>> wrote:<br>
><br>
> From: Kevin Tang <<a href="mailto:kevin.tang@unisoc.com" target="_blank">kevin.tang@unisoc.com</a>><br>
><br>
> Adds DPU(Display Processor Unit) support for the Unisoc's display subsystem.<br>
> It's support multi planes, scaler, rotation, PQ(Picture Quality) and more.<br>
><br>
> Cc: Orson Zhai <<a href="mailto:orsonzhai@gmail.com" target="_blank">orsonzhai@gmail.com</a>><br>
> Cc: Baolin Wang <<a href="mailto:baolin.wang@linaro.org" target="_blank">baolin.wang@linaro.org</a>><br>
> Cc: Chunyan Zhang <<a href="mailto:zhang.lyra@gmail.com" target="_blank">zhang.lyra@gmail.com</a>><br>
> Signed-off-by: Kevin Tang <<a href="mailto:kevin.tang@unisoc.com" target="_blank">kevin.tang@unisoc.com</a>><br>
> ---<br>
> drivers/gpu/drm/sprd/Makefile | 6 +-<br>
> drivers/gpu/drm/sprd/disp_lib.c | 290 +++++++<br>
> drivers/gpu/drm/sprd/disp_lib.h | 40 +<br>
> drivers/gpu/drm/sprd/dpu/Makefile | 8 +<br>
> drivers/gpu/drm/sprd/dpu/dpu_r2p0.c | 1464 +++++++++++++++++++++++++++++++++++<br>
> drivers/gpu/drm/sprd/sprd_dpu.c | 1152 +++++++++++++++++++++++++++<br>
> drivers/gpu/drm/sprd/sprd_dpu.h | 217 ++++++<br>
> 7 files changed, 3176 insertions(+), 1 deletion(-)<br>
<br>
As we can see from the diff stat this patch is huge. So it would be fairly hard<br>
to provide meaningful review as-is.<br>
<br>
One can combine my earlier suggestion (to keep modeset/atomic out of 2/8), with<br>
the following split:<br>
- 4/8 add basic atomic modeset support - one format, one rotation 0, no extra<br>
attributes<br>
- 5/8 add extra formats<br>
- 6/8 add extra rotation support<br>
- ... add custom attributes<br></blockquote><div>Ok, i will split this patch, upstream modeset and atomic at first. clock, gloabl, enhance, extra</div>attributes and so on will be upload later.<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<snip><br>
<br>
> --- /dev/null<br>
> +++ b/drivers/gpu/drm/sprd/disp_lib.c<br>
<br>
> --- /dev/null<br>
> +++ b/drivers/gpu/drm/sprd/disp_lib.h<br>
<br>
Let's keep this code out, for now. If we really need it we could revive/add it<br>
at a later stage.<br></blockquote><div>Ok </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<snip><br>
<br>
> --- /dev/null<br>
> +++ b/drivers/gpu/drm/sprd/dpu/dpu_r2p0.c<br>
> @@ -0,0 +1,1464 @@<br>
<br>
<br>
> +struct gamma_entry {<br>
> + u16 r;<br>
> + u16 g;<br>
> + u16 b;<br>
> +};<br>
> +<br>
Seem to be unused. Please drop this and double-check for other unused structs<br>
<br>
<br>
> +static struct scale_cfg scale_copy;<br>
> +static struct cm_cfg cm_copy;<br>
> +static struct slp_cfg slp_copy;<br>
> +static struct gamma_lut gamma_copy;<br>
> +static struct hsv_lut hsv_copy;<br>
> +static struct epf_cfg epf_copy;<br>
> +static u32 enhance_en;<br>
> +<br>
> +static DECLARE_WAIT_QUEUE_HEAD(wait_queue);<br>
> +static bool panel_ready = true;<br>
> +static bool need_scale;<br>
> +static bool mode_changed;<br>
> +static bool evt_update;<br>
> +static bool evt_stop;<br>
> +static u32 prev_y2r_coef;<br>
> +<br>
We should really avoid static variables. Some of the above look like enhancer<br>
state. One could create a struct keeping it alongside the rest of the display<br>
pipeline, right?<br>
<br>
<br>
<snip><br>
<br>
> +static void dpu_enhance_backup(u32 id, void *param)<br>
> +{<br>
As the enhance code is fairly large, lets keep the portions to a separate patch.<br></blockquote><div>enhance code is a big feature, so i will removed it at first commit.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
<snip><br>
<br>
> +static struct dpu_core_ops dpu_r2p0_ops = {<br>
Nit: as a general rule ops should be const.<br>
<br>
<br>
> +static int __init dpu_core_register(void)<br>
> +{<br>
> + return dpu_core_ops_register(&entry);<br>
> +}<br>
> +<br>
> +subsys_initcall(dpu_core_register);<br>
I think that subsys_initcall, __init and MODULE area applicable only<br>
when we have multiple<br>
modules. Not 100% sure though ;-)<br></blockquote><div>Yes, our display controller have multiple ip version, every version maybe different</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
> diff --git a/drivers/gpu/drm/sprd/sprd_dpu.c b/drivers/gpu/drm/sprd/sprd_dpu.c<br>
> new file mode 100644<br>
> index 0000000..43142b3<br>
> --- /dev/null<br>
> +++ b/drivers/gpu/drm/sprd/sprd_dpu.c<br>
<br>
> +struct sprd_plane {<br>
> + struct drm_plane plane;<br>
> + struct drm_property *alpha_property;<br>
> + struct drm_property *blend_mode_property;<br>
Core DRM already has alpha and blend_mode properties. Please reuse the code<br>
<br>
<br>
> + struct drm_property *fbc_hsize_r_property;<br>
> + struct drm_property *fbc_hsize_y_property;<br>
> + struct drm_property *fbc_hsize_uv_property;<br>
> + struct drm_property *y2r_coef_property;<br>
> + struct drm_property *pallete_en_property;<br>
> + struct drm_property *pallete_color_property;<br>
Let's have these properties introduced with separate follow-up patches.<br>
Please mention, in the commit message, why they are specific to the driver.<br></blockquote><div>Ok, i will split it and commit later... </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
<snip><br>
<br>
> +static int sprd_dpu_init(struct sprd_dpu *dpu)<br>
> +{<br>
> + struct dpu_context *ctx = &dpu->ctx;<br>
> +<br>
> + down(&ctx->refresh_lock);<br>
> +<br>
> + if (dpu->ctx.is_inited) {<br>
> + up(&ctx->refresh_lock);<br>
> + return 0;<br>
> + }<br>
> +<br>
> + if (dpu->glb && dpu->glb->power)<br>
> + dpu->glb->power(ctx, true);<br>
> + if (dpu->glb && dpu->glb->enable)<br>
> + dpu->glb->enable(ctx);<br>
> +<br>
> + if (ctx->is_stopped && dpu->glb && dpu->glb->reset)<br>
> + dpu->glb->reset(ctx);<br>
> +<br>
> + if (dpu->clk && dpu->clk->init)<br>
> + dpu->clk->init(ctx);<br>
> + if (dpu->clk && dpu->clk->enable)<br>
> + dpu->clk->enable(ctx);<br>
> +<br>
> + if (dpu->core && dpu->core->init)<br>
> + dpu->core->init(ctx);<br>
> + if (dpu->core && dpu->core->ifconfig)<br>
> + dpu->core->ifconfig(ctx);<br>
> +<br>
Hmm I can see the core, clk and glb (ops) being added to the respective lists.<br>
Yet the code which adds those to the dpu isn't so obvious. Where is it?<br></blockquote><div>clk and glb ops have not been submitted, so i will remove clk and glb ops at first.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
> + ctx->is_inited = true;<br>
> +<br>
Nit: is_inited -> initialized<br>
<br>
<br>
<br>
<snip><br>
<br>
> +struct dpu_core_ops {<br>
> + int (*parse_dt)(struct dpu_context *ctx,<br>
> + struct device_node *np);<br>
> + u32 (*version)(struct dpu_context *ctx);<br>
> + int (*init)(struct dpu_context *ctx);<br>
> + void (*uninit)(struct dpu_context *ctx);<br>
> + void (*run)(struct dpu_context *ctx);<br>
> + void (*stop)(struct dpu_context *ctx);<br>
> + void (*disable_vsync)(struct dpu_context *ctx);<br>
> + void (*enable_vsync)(struct dpu_context *ctx);<br>
> + u32 (*isr)(struct dpu_context *ctx);<br>
> + void (*ifconfig)(struct dpu_context *ctx);<br>
> + void (*write_back)(struct dpu_context *ctx, u8 count, bool debug);<br>
> + void (*flip)(struct dpu_context *ctx,<br>
> + struct sprd_dpu_layer layers[], u8 count);<br>
> + int (*capability)(struct dpu_context *ctx,<br>
> + struct dpu_capability *cap);<br>
> + void (*bg_color)(struct dpu_context *ctx, u32 color);<br>
> + void (*enhance_set)(struct dpu_context *ctx, u32 id, void *param);<br>
> + void (*enhance_get)(struct dpu_context *ctx, u32 id, void *param);<br>
> + int (*modeset)(struct dpu_context *ctx,<br>
> + struct drm_mode_modeinfo *mode);<br>
> + bool (*check_raw_int)(struct dpu_context *ctx, u32 mask);<br>
> +};<br>
> +<br>
> +struct dpu_clk_ops {<br>
> + int (*parse_dt)(struct dpu_context *ctx,<br>
> + struct device_node *np);<br>
> + int (*init)(struct dpu_context *ctx);<br>
> + int (*uinit)(struct dpu_context *ctx);<br>
> + int (*enable)(struct dpu_context *ctx);<br>
> + int (*disable)(struct dpu_context *ctx);<br>
> + int (*update)(struct dpu_context *ctx, int clk_id, int val);<br>
> +};<br>
> +<br>
> +struct dpu_glb_ops {<br>
> + int (*parse_dt)(struct dpu_context *ctx,<br>
> + struct device_node *np);<br>
> + void (*enable)(struct dpu_context *ctx);<br>
> + void (*disable)(struct dpu_context *ctx);<br>
> + void (*reset)(struct dpu_context *ctx);<br>
> + void (*power)(struct dpu_context *ctx, int enable);<br>
> +};<br>
> +<br>
Some of the above seem unused - parse_dt for example. Please drop the dead code.<br>
<br>
<br>
HTH<br>
Emil<br>
</blockquote></div></div>