summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLiu Ying <victor.liu@nxp.com>2017-09-12 17:41:59 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:33:43 +0800
commit2192e34d671698e73bfabb536faa8a5b1ec9c377 (patch)
tree4ae2843c76d52f19f3fa1b276539abf6ae978744 /drivers
parentd84dd1e1a23ea659e73888a09b6e2f71daad7474 (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.c50
-rw-r--r--drivers/gpu/imx/dpu/dpu-prv.h7
-rw-r--r--drivers/gpu/imx/dpu/dpu-tcon.c38
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;
+}