1
0
Fork 0

MLK-19152-1 gpu: imx: lcdif: realize fb horizontal crop via Pigeon Mode

According to the LCDIF specification, the Legacy Mode does not
support cropping function in the horizontal direction, so add
Pigeon Mode which can support this kind of function. And when
enable this mode, the legacy horizontal timings configuration
should use stride value but not the active width, and related
pigeon configuration should use the active width but not the
stride value.

Signed-off-by: Fancy Fang <chen.fang@nxp.com>
(cherry picked from commit e6da9542693dd585972897f62748a101f5726a74)
pull/10/head
Fancy Fang 2018-08-07 18:04:54 +08:00 committed by Jason Liu
parent d69b387eb2
commit bd770efe10
3 changed files with 76 additions and 0 deletions

View File

@ -377,6 +377,64 @@ void lcdif_set_fb_addr(struct lcdif_soc *lcdif, int id, u32 addr)
}
EXPORT_SYMBOL(lcdif_set_fb_addr);
void lcdif_set_fb_hcrop(struct lcdif_soc *lcdif, u32 src_w,
u32 fb_w, bool crop)
{
u32 mask_cnt, htotal, hcount;
u32 vdctrl2, vdctrl3, vdctrl4, transfer_count;
u32 pigeon_12_0, pigeon_12_1, pigeon_12_2;
if (!crop) {
writel(0x0, lcdif->base + HW_EPDC_PIGEON_12_0);
writel(0x0, lcdif->base + HW_EPDC_PIGEON_12_1);
return;
}
/* transfer_count's hcount, vdctrl2's htotal and vdctrl4's
* H_VALID_DATA_CNT should use fb width instead of hactive
* when requires cropping.
* */
transfer_count = readl(lcdif->base + LCDIF_TRANSFER_COUNT);
hcount = TRANSFER_COUNT_GET_HCOUNT(transfer_count);
transfer_count &= ~TRANSFER_COUNT_SET_HCOUNT(0xffff);
transfer_count |= TRANSFER_COUNT_SET_HCOUNT(fb_w);
writel(transfer_count, lcdif->base + LCDIF_TRANSFER_COUNT);
vdctrl2 = readl(lcdif->base + LCDIF_VDCTRL2);
htotal = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2);
htotal += fb_w - hcount;
vdctrl2 &= ~VDCTRL2_SET_HSYNC_PERIOD(0x3ffff);
vdctrl2 |= VDCTRL2_SET_HSYNC_PERIOD(htotal);
writel(vdctrl2, lcdif->base + LCDIF_VDCTRL2);
vdctrl4 = readl(lcdif->base + LCDIF_VDCTRL4);
vdctrl4 &= ~SET_DOTCLK_H_VALID_DATA_CNT(0x3ffff);
vdctrl4 |= SET_DOTCLK_H_VALID_DATA_CNT(fb_w);
writel(vdctrl4, lcdif->base + LCDIF_VDCTRL4);
/* configure related pigeon registers */
vdctrl3 = readl(lcdif->base + LCDIF_VDCTRL3);
mask_cnt = GET_HOR_WAIT_CNT(vdctrl3) - 5;
pigeon_12_0 = PIGEON_12_0_SET_STATE_MASK(0x24) |
PIGEON_12_0_SET_MASK_CNT(mask_cnt) |
PIGEON_12_0_SET_MASK_CNT_SEL(0x6) |
PIGEON_12_0_POL_ACTIVE_LOW |
PIGEON_12_0_EN;
writel(pigeon_12_0, lcdif->base + HW_EPDC_PIGEON_12_0);
pigeon_12_1 = PIGEON_12_1_SET_CLR_CNT(src_w) |
PIGEON_12_1_SET_SET_CNT(0x0);
writel(pigeon_12_1, lcdif->base + HW_EPDC_PIGEON_12_1);
pigeon_12_2 = 0x0;
writel(pigeon_12_2, lcdif->base + HW_EPDC_PIGEON_12_2);
}
EXPORT_SYMBOL(lcdif_set_fb_hcrop);
void lcdif_set_mode(struct lcdif_soc *lcdif, struct videomode *vmode)
{
const struct of_device_id *of_id =

View File

@ -32,6 +32,11 @@
#define LCDIF_VDCTRL3 0xa0
#define LCDIF_VDCTRL4 0xb0
/* pigeon registers for crop */
#define HW_EPDC_PIGEON_12_0 0xb00
#define HW_EPDC_PIGEON_12_1 0xb10
#define HW_EPDC_PIGEON_12_2 0xb20
/* reg bit manipulation */
#define REG_MASK(e, s) (((1 << ((e) - (s) + 1)) - 1) << (s))
#define REG_PUT(x, e, s) (((x) << (s)) & REG_MASK(e, s))
@ -115,6 +120,17 @@
#define VDCTRL4_SYNC_SIGNALS_ON BIT(18)
#define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
#define PIGEON_12_0_SET_STATE_MASK(x) REG_PUT((x), 31, 24)
#define PIGEON_12_0_SET_MASK_CNT(x) REG_PUT((x), 23, 12)
#define PIGEON_12_0_SET_MASK_CNT_SEL(x) REG_PUT((x), 11, 8)
#define PIGEON_12_0_SET_OFFSET(x) REG_PUT((x), 7, 4)
#define PIGEON_12_0_SET_INC_SEL(x) REG_PUT((x), 3, 2)
#define PIGEON_12_0_POL_ACTIVE_LOW BIT(1)
#define PIGEON_12_0_EN BIT(0)
#define PIGEON_12_1_SET_CLR_CNT(x) REG_PUT((x), 31, 16)
#define PIGEON_12_1_SET_SET_CNT(x) REG_PUT((x), 15, 0)
#define STMLCDIF_8BIT 1 /* pixel data bus to the display is of 8 bit width */
#define STMLCDIF_16BIT 0 /* pixel data bus to the display is of 16 bit width */
#define STMLCDIF_18BIT 2 /* pixel data bus to the display is of 18 bit width */

View File

@ -32,6 +32,8 @@ int lcdif_get_bus_fmt_from_pix_fmt(struct lcdif_soc *lcdif,
int lcdif_set_pix_fmt(struct lcdif_soc *lcdif, u32 format);
void lcdif_set_fb_addr(struct lcdif_soc *lcdif, int id, u32 addr);
void lcdif_set_mode(struct lcdif_soc *lcdif, struct videomode *vmode);
void lcdif_set_fb_hcrop(struct lcdif_soc *lcdif, u32 src_w,
u32 fb_w, bool crop);
void lcdif_enable_controller(struct lcdif_soc *lcdif);
void lcdif_disable_controller(struct lcdif_soc *lcdif);
void lcdif_dump_registers(struct lcdif_soc *lcdif);