diff options
author | Liu Ying <victor.liu@nxp.com> | 2017-09-12 17:41:59 +0800 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:33:43 +0800 |
commit | 2192e34d671698e73bfabb536faa8a5b1ec9c377 (patch) | |
tree | 4ae2843c76d52f19f3fa1b276539abf6ae978744 /drivers | |
parent | d84dd1e1a23ea659e73888a09b6e2f71daad7474 (diff) |
MLK-19413-22 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 pixel combiner is available for
a particular DPU variant via the dpu_has_pc() helper and 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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-common.c | 50 | ||||
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-prv.h | 7 | ||||
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-tcon.c | 38 |
3 files changed, 95 insertions, 0 deletions
diff --git a/drivers/gpu/imx/dpu/dpu-common.c b/drivers/gpu/imx/dpu/dpu-common.c index a2d35f86b845..468acf8cc82a 100644 --- a/drivers/gpu/imx/dpu/dpu-common.c +++ b/drivers/gpu/imx/dpu/dpu-common.c @@ -27,6 +27,7 @@ #include <linux/regmap.h> #include <soc/imx8/sc/sci.h> #include <video/dpu.h> +#include <video/imx8-pc.h> #include <video/imx8-prefetch.h> #include "dpu-prv.h" @@ -544,6 +545,7 @@ static const struct dpu_devtype dpu_type_v1 = { .has_prefetch = false, .has_disp_sel_clk = false, .has_dual_ldb = false, + .has_pc = false, .has_syncmode_fixup = false, .pixel_link_quirks = false, .pixel_link_nhvsync = false, @@ -575,7 +577,10 @@ static const struct dpu_devtype dpu_type_v2_qm = { .has_prefetch = true, .has_disp_sel_clk = true, .has_dual_ldb = false, + .has_pc = true, .has_syncmode_fixup = true, + .syncmode_min_prate = 300000, + .singlemode_max_width = 1920, .pixel_link_quirks = true, .pixel_link_nhvsync = true, .version = DPU_V2, @@ -606,7 +611,10 @@ static const struct dpu_devtype dpu_type_v2_qxp = { .has_prefetch = true, .has_disp_sel_clk = false, .has_dual_ldb = true, + .has_pc = true, .has_syncmode_fixup = false, + .syncmode_min_prate = UINT_MAX, /* pc is unused */ + .singlemode_max_width = UINT_MAX, /* pc is unused */ .pixel_link_quirks = true, .pixel_link_nhvsync = true, .version = DPU_V2, @@ -625,6 +633,30 @@ static const struct of_device_id dpu_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, dpu_dt_ids); +bool dpu_has_pc(struct dpu_soc *dpu) +{ + return dpu->devtype->has_pc; +} +EXPORT_SYMBOL_GPL(dpu_has_pc); + +unsigned int dpu_get_syncmode_min_prate(struct dpu_soc *dpu) +{ + if (dpu->devtype->has_pc) + return dpu->devtype->syncmode_min_prate; + else + return UINT_MAX; +} +EXPORT_SYMBOL_GPL(dpu_get_syncmode_min_prate); + +unsigned int dpu_get_singlemode_max_width(struct dpu_soc *dpu) +{ + if (dpu->devtype->has_pc) + return dpu->devtype->singlemode_max_width; + else + return UINT_MAX; +} +EXPORT_SYMBOL_GPL(dpu_get_singlemode_max_width); + bool dpu_vproc_has_fetcheco_cap(u32 cap_mask) { return !!(cap_mask & DPU_VPROC_CAP_FETCHECO); @@ -794,6 +826,7 @@ static int dpu_submodules_init(struct dpu_soc *dpu, const struct dpu_unit *fds = devtype->fds; const struct dpu_unit *fls = devtype->fls; const struct dpu_unit *fws = devtype->fws; + const struct dpu_unit *tcons = devtype->tcons; DPU_UNITS_INIT(cf); DPU_UNITS_INIT(dec); @@ -851,6 +884,23 @@ static int dpu_submodules_init(struct dpu_soc *dpu, } } + /* get pixel combiner */ + if (devtype->has_pc) { + struct dpu_tcon *tcon; + struct pc *pc = + pc_lookup_by_phandle(dpu->dev, "fsl,pixel-combiner"); + int i; + + 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 e53b529e4b56..7bae7709d6ef 100644 --- a/drivers/gpu/imx/dpu/dpu-prv.h +++ b/drivers/gpu/imx/dpu/dpu-prv.h @@ -200,6 +200,10 @@ struct dpu_devtype { const unsigned long *unused_irq; const unsigned int *sw2hw_irq_map; /* NULL means linear */ const unsigned int *sw2hw_block_id_map; /* NULL means linear */ + + const unsigned int syncmode_min_prate; /* need pixel combiner, KHz */ + const unsigned int singlemode_max_width; + /* * index: 0 1 2 3 4 5 6 * source: fl0(sub0) fl1(sub0) fw2(sub0) fd0 fd1 fd2 fd3 @@ -209,6 +213,7 @@ struct dpu_devtype { bool has_prefetch; bool has_disp_sel_clk; bool has_dual_ldb; + bool has_pc; bool has_syncmode_fixup; bool pixel_link_quirks; bool pixel_link_nhvsync; /* HSYNC and VSYNC high active */ @@ -323,6 +328,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 bac0c47c7ed0..60b7a574ab41 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) @@ -223,6 +225,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; @@ -292,3 +322,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; +} |