1
0
Fork 0

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
Liu Ying 2017-09-12 17:41:59 +08:00 committed by Jason Liu
parent 6336ced7ba
commit b4de1b03ce
4 changed files with 103 additions and 0 deletions

View File

@ -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;
}

View File

@ -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};

View File

@ -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;
}

View File

@ -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);