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>pull/10/head
parent
6336ced7ba
commit
b4de1b03ce
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -674,6 +674,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);
|
||||
|
@ -704,6 +708,10 @@ 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);
|
||||
|
||||
bool dpu_has_pc(struct dpu_soc *dpu);
|
||||
unsigned int dpu_get_syncmode_min_prate(struct dpu_soc *dpu);
|
||||
unsigned int dpu_get_singlemode_max_width(struct dpu_soc *dpu);
|
||||
|
||||
bool dpu_vproc_has_fetcheco_cap(u32 cap_mask);
|
||||
bool dpu_vproc_has_hscale_cap(u32 cap_mask);
|
||||
bool dpu_vproc_has_vscale_cap(u32 cap_mask);
|
||||
|
|
Loading…
Reference in New Issue