diff options
author | Liu Ying <victor.liu@nxp.com> | 2019-11-12 13:56:45 +0800 |
---|---|---|
committer | Dong Aisheng <aisheng.dong@nxp.com> | 2019-11-25 15:58:23 +0800 |
commit | a1ab21d2fc621a8b6ee4691cbc9c909b8ce7d383 (patch) | |
tree | 2d5643255c2ccf70cf0c9d3d85a62c01256fbd54 | |
parent | 15952eb997ea126b615878f9ceae359597f4fdff (diff) |
gpu: imx: dpu: Add pixel combiner support
This patch adds pixel combiner support in the DPU core driver.
Users may get and enable/disable/control a pixel combiner instant
via tcon functions and may tell if it is needed in a specific usecase
via the dpu_get_syncmode_min_prate() and dpu_get_singlemode_max_width()
helpers.
Signed-off-by: Liu Ying <victor.liu@nxp.com>
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-common.c | 56 | ||||
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-prv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-tcon.c | 38 | ||||
-rw-r--r-- | include/video/dpu.h | 6 |
4 files changed, 101 insertions, 3 deletions
diff --git a/drivers/gpu/imx/dpu/dpu-common.c b/drivers/gpu/imx/dpu/dpu-common.c index 7c2a3b8f6cd5..deea323d4359 100644 --- a/drivers/gpu/imx/dpu/dpu-common.c +++ b/drivers/gpu/imx/dpu/dpu-common.c @@ -26,6 +26,7 @@ #include <linux/platform_device.h> #include <linux/pm_domain.h> #include <video/dpu.h> +#include <video/imx8-pc.h> #include <video/imx8-prefetch.h> #include "dpu-prv.h" @@ -235,7 +236,7 @@ static const struct cm_reg_ofs _cm_reg_ofs = { static const unsigned long unused_irq[] = {0x00000000, 0xfffe0008}; -static const struct dpu_data dpu_data = { +static const struct dpu_data dpu_data_qxp = { .cm_ofs = 0x0, .cfs = &_cfs, .decs = &_decs, @@ -253,21 +254,57 @@ static const struct dpu_data dpu_data = { .unused_irq = unused_irq, .plane_src_mask = DPU_PLANE_SRC_FL0_ID | DPU_PLANE_SRC_FW2_ID | DPU_PLANE_SRC_FD0_ID | DPU_PLANE_SRC_FD1_ID, + .syncmode_min_prate = UINT_MAX, /* pc is unused */ + .singlemode_max_width = UINT_MAX, /* pc is unused */ +}; + +static const struct dpu_data dpu_data_qm = { + .cm_ofs = 0x0, + .cfs = &_cfs, + .decs = &_decs, + .eds = &_eds, + .fds = &_fds, + .fes = &_fes, + .fgs = &_fgs, + .fls = &_fls, + .fws = &_fws, + .hss = &_hss, + .lbs = &_lbs, + .tcons = &_tcons, + .vss = &_vss, + .cm_reg_ofs = &_cm_reg_ofs, + .unused_irq = unused_irq, + .plane_src_mask = DPU_PLANE_SRC_FL0_ID | DPU_PLANE_SRC_FW2_ID | + DPU_PLANE_SRC_FD0_ID | DPU_PLANE_SRC_FD1_ID, + .syncmode_min_prate = 300000, + .singlemode_max_width = 1920, }; static const struct of_device_id dpu_dt_ids[] = { { .compatible = "fsl,imx8qxp-dpu", - .data = &dpu_data, + .data = &dpu_data_qxp, }, { .compatible = "fsl,imx8qm-dpu", - .data = &dpu_data, + .data = &dpu_data_qm, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, dpu_dt_ids); +unsigned int dpu_get_syncmode_min_prate(struct dpu_soc *dpu) +{ + return dpu->data->syncmode_min_prate; +} +EXPORT_SYMBOL_GPL(dpu_get_syncmode_min_prate); + +unsigned int dpu_get_singlemode_max_width(struct dpu_soc *dpu) +{ + return dpu->data->singlemode_max_width; +} +EXPORT_SYMBOL_GPL(dpu_get_singlemode_max_width); + unsigned int dpu_get_master_stream_id(struct dpu_soc *dpu) { return dpu->data->master_stream_id; @@ -720,8 +757,11 @@ static int dpu_submodules_init(struct dpu_soc *dpu, const struct dpu_unit *fds = data->fds; const struct dpu_unit *fls = data->fls; const struct dpu_unit *fws = data->fws; + const struct dpu_unit *tcons = data->tcons; struct dpu_fetchunit *fu; struct dprc *dprc; + struct dpu_tcon *tcon; + struct pc *pc; int i; DPU_UNITS_INIT(cf); @@ -770,6 +810,16 @@ static int dpu_submodules_init(struct dpu_soc *dpu, dpu_fw_put(fu); } + pc = pc_lookup_by_phandle(dpu->dev, "fsl,pixel-combiner"); + if (!pc) + return -EPROBE_DEFER; + + for (i = 0; i < tcons->num; i++) { + tcon = dpu_tcon_get(dpu, i); + tcon_get_pc(tcon, pc); + dpu_tcon_put(tcon); + } + return 0; } diff --git a/drivers/gpu/imx/dpu/dpu-prv.h b/drivers/gpu/imx/dpu/dpu-prv.h index dcbfcd4e00b5..9bdd71f613b6 100644 --- a/drivers/gpu/imx/dpu/dpu-prv.h +++ b/drivers/gpu/imx/dpu/dpu-prv.h @@ -192,6 +192,8 @@ struct dpu_data { const struct cm_reg_ofs *cm_reg_ofs; const unsigned long *unused_irq; + unsigned int syncmode_min_prate; /* need pixel combiner, KHz */ + unsigned int singlemode_max_width; unsigned int master_stream_id; u32 plane_src_mask; @@ -315,6 +317,8 @@ static inline u32 yuv_color(u8 y, u8 u, u8 v) return (y << 24) | (u << 16) | (v << 8); } +void tcon_get_pc(struct dpu_tcon *tcon, void *data); + static const unsigned int cf_ids[] = {0, 1, 4, 5}; static const unsigned int dec_ids[] = {0, 1}; static const unsigned int ed_ids[] = {0, 1, 4, 5}; diff --git a/drivers/gpu/imx/dpu/dpu-tcon.c b/drivers/gpu/imx/dpu/dpu-tcon.c index aa5f45115bc2..fe046520b13a 100644 --- a/drivers/gpu/imx/dpu/dpu-tcon.c +++ b/drivers/gpu/imx/dpu/dpu-tcon.c @@ -20,6 +20,7 @@ #include <linux/platform_device.h> #include <linux/types.h> #include <video/dpu.h> +#include <video/imx8-pc.h> #include "dpu-prv.h" #define SSQCNTS 0 @@ -63,6 +64,7 @@ struct dpu_tcon { int id; bool inuse; struct dpu_soc *dpu; + struct pc *pc; }; static inline u32 dpu_tcon_read(struct dpu_tcon *tcon, unsigned int offset) @@ -220,6 +222,34 @@ bool tcon_is_slave(struct dpu_tcon *tcon) } EXPORT_SYMBOL_GPL(tcon_is_slave); +void tcon_configure_pc(struct dpu_tcon *tcon, unsigned int di, + unsigned int frame_width, u32 mode, u32 format) +{ + if (WARN_ON(!tcon || !tcon->pc)) + return; + + pc_configure(tcon->pc, di, frame_width, mode, format); +} +EXPORT_SYMBOL_GPL(tcon_configure_pc); + +void tcon_enable_pc(struct dpu_tcon *tcon) +{ + if (WARN_ON(!tcon || !tcon->pc)) + return; + + pc_enable(tcon->pc); +} +EXPORT_SYMBOL_GPL(tcon_enable_pc); + +void tcon_disable_pc(struct dpu_tcon *tcon) +{ + if (WARN_ON(!tcon || !tcon->pc)) + return; + + pc_disable(tcon->pc); +} +EXPORT_SYMBOL_GPL(tcon_disable_pc); + struct dpu_tcon *dpu_tcon_get(struct dpu_soc *dpu, int id) { struct dpu_tcon *tcon; @@ -289,3 +319,11 @@ int dpu_tcon_init(struct dpu_soc *dpu, unsigned int id, return 0; } + +void tcon_get_pc(struct dpu_tcon *tcon, void *data) +{ + if (WARN_ON(!tcon)) + return; + + tcon->pc = data; +} diff --git a/include/video/dpu.h b/include/video/dpu.h index ed9b65cacde7..1cc5c8c5ccaf 100644 --- a/include/video/dpu.h +++ b/include/video/dpu.h @@ -557,6 +557,10 @@ void tcon_cfg_videomode(struct dpu_tcon *tcon, struct drm_display_mode *m, bool side_by_side); bool tcon_is_master(struct dpu_tcon *tcon); bool tcon_is_slave(struct dpu_tcon *tcon); +void tcon_configure_pc(struct dpu_tcon *tcon, unsigned int di, + unsigned int frame_width, u32 mode, u32 format); +void tcon_enable_pc(struct dpu_tcon *tcon); +void tcon_disable_pc(struct dpu_tcon *tcon); struct dpu_tcon *dpu_tcon_get(struct dpu_soc *dpu, int id); void dpu_tcon_put(struct dpu_tcon *tcon); struct dpu_tcon *dpu_aux_tcon_peek(struct dpu_tcon *tcon); @@ -587,6 +591,8 @@ struct dpu_fetchunit *fetchdecode_get_fetcheco(struct dpu_fetchunit *fu); struct dpu_hscaler *fetchdecode_get_hscaler(struct dpu_fetchunit *fu); struct dpu_vscaler *fetchdecode_get_vscaler(struct dpu_fetchunit *fu); +unsigned int dpu_get_syncmode_min_prate(struct dpu_soc *dpu); +unsigned int dpu_get_singlemode_max_width(struct dpu_soc *dpu); unsigned int dpu_get_master_stream_id(struct dpu_soc *dpu); bool dpu_vproc_has_fetcheco_cap(u32 cap_mask); |