video: ipufb: do not use bitfields
bitfields are not portable and one should make assumptions of the layout of bitfields. Replace them with the ipu_ch_param_write_field() which is already used in the mainline IPUv3 driver. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
68a6fedcd4
commit
497436eb58
|
@ -281,110 +281,96 @@ static struct imx_ipu_fb_rgb def_rgb_32 = {
|
|||
.transp = {.offset = 24, .length = 8,},
|
||||
};
|
||||
|
||||
struct chan_param_mem_planar {
|
||||
/* Word 0 */
|
||||
u32 xv:10;
|
||||
u32 yv:10;
|
||||
u32 xb:12;
|
||||
#define IPU_CPMEM_WORD(word, ofs, size) ((((word) * 160 + (ofs)) << 8) | (size))
|
||||
|
||||
u32 yb:12;
|
||||
u32 res1:2;
|
||||
u32 nsb:1;
|
||||
u32 lnpb:6;
|
||||
u32 ubo_l:11;
|
||||
#define IPU_FIELD_XV IPU_CPMEM_WORD(0, 0, 10)
|
||||
#define IPU_FIELD_YV IPU_CPMEM_WORD(0, 10, 10)
|
||||
#define IPU_FIELD_XB IPU_CPMEM_WORD(0, 20, 12)
|
||||
|
||||
u32 ubo_h:15;
|
||||
u32 vbo_l:17;
|
||||
#define IPU_FIELD_YB IPU_CPMEM_WORD(0, 32, 12)
|
||||
#define IPU_FIELD_SCE IPU_CPMEM_WORD(0, 44, 1)
|
||||
#define IPU_FIELD_RES1 IPU_CPMEM_WORD(0, 45, 1)
|
||||
#define IPU_FIELD_NSB IPU_CPMEM_WORD(0, 46, 1)
|
||||
#define IPU_FIELD_LNPB IPU_CPMEM_WORD(0, 47, 6)
|
||||
#define IPU_FIELD_SX IPU_CPMEM_WORD(0, 53, 10)
|
||||
#define IPU_FIELD_SY_L IPU_CPMEM_WORD(0, 63, 1)
|
||||
|
||||
u32 vbo_h:9;
|
||||
u32 res2:3;
|
||||
u32 fw:12;
|
||||
u32 fh_l:8;
|
||||
#define IPU_FIELD_SY_H IPU_CPMEM_WORD(0, 64, 9)
|
||||
#define IPU_FIELD_NS IPU_CPMEM_WORD(0, 73, 10)
|
||||
#define IPU_FIELD_SM IPU_CPMEM_WORD(0, 83, 10)
|
||||
#define IPU_FIELD_SDX_L IPU_CPMEM_WORD(0, 93, 3)
|
||||
|
||||
u32 fh_h:4;
|
||||
u32 res3:28;
|
||||
#define IPU_FIELD_SDX_H IPU_CPMEM_WORD(0, 96, 2)
|
||||
#define IPU_FIELD_SDY IPU_CPMEM_WORD(0, 98, 5)
|
||||
#define IPU_FIELD_SDRX IPU_CPMEM_WORD(0, 103, 1)
|
||||
#define IPU_FIELD_SDRY IPU_CPMEM_WORD(0, 104, 1)
|
||||
#define IPU_FIELD_SDR1 IPU_CPMEM_WORD(0, 105, 1)
|
||||
#define IPU_FIELD_RES2 IPU_CPMEM_WORD(0, 106, 2)
|
||||
#define IPU_FIELD_FW IPU_CPMEM_WORD(0, 108, 12)
|
||||
#define IPU_FIELD_FH_L IPU_CPMEM_WORD(0, 120, 8)
|
||||
|
||||
/* Word 1 */
|
||||
u32 eba0;
|
||||
#define IPU_FIELD_FH_H IPU_CPMEM_WORD(0, 128, 4)
|
||||
#define IPU_FIELD_RES3 IPU_CPMEM_WORD(0, 132, 28)
|
||||
|
||||
u32 eba1;
|
||||
#define IPU_FIELD_EBA0 IPU_CPMEM_WORD(1, 0, 32)
|
||||
|
||||
u32 bpp:3;
|
||||
u32 sl:14;
|
||||
u32 pfs:3;
|
||||
u32 bam:3;
|
||||
u32 res4:2;
|
||||
u32 npb:6;
|
||||
u32 res5:1;
|
||||
#define IPU_FIELD_EBA1 IPU_CPMEM_WORD(1, 32, 32)
|
||||
|
||||
u32 sat:2;
|
||||
u32 res6:30;
|
||||
} __attribute__ ((packed));
|
||||
#define IPU_FIELD_BPP IPU_CPMEM_WORD(1, 64, 3)
|
||||
#define IPU_FIELD_SL IPU_CPMEM_WORD(1, 67, 14)
|
||||
#define IPU_FIELD_PFS IPU_CPMEM_WORD(1, 81, 3)
|
||||
#define IPU_FIELD_BAM IPU_CPMEM_WORD(1, 84, 3)
|
||||
#define IPU_FIELD_RES4 IPU_CPMEM_WORD(1, 87, 2)
|
||||
#define IPU_FIELD_NPB IPU_CPMEM_WORD(1, 89, 6)
|
||||
#define IPU_FIELD_RES5 IPU_CPMEM_WORD(1, 95, 1)
|
||||
|
||||
struct chan_param_mem_interleaved {
|
||||
/* Word 0 */
|
||||
u32 xv:10;
|
||||
u32 yv:10;
|
||||
u32 xb:12;
|
||||
#define IPU_FIELD_SAT IPU_CPMEM_WORD(1, 96, 2)
|
||||
#define IPU_FIELD_SCC IPU_CPMEM_WORD(1, 98, 1)
|
||||
#define IPU_FIELD_OFS0 IPU_CPMEM_WORD(1, 99, 5)
|
||||
#define IPU_FIELD_OFS1 IPU_CPMEM_WORD(1, 104, 5)
|
||||
#define IPU_FIELD_OFS2 IPU_CPMEM_WORD(1, 109, 5)
|
||||
#define IPU_FIELD_OFS3 IPU_CPMEM_WORD(1, 114, 5)
|
||||
#define IPU_FIELD_WID0 IPU_CPMEM_WORD(1, 119, 3)
|
||||
#define IPU_FIELD_WID1 IPU_CPMEM_WORD(1, 122, 3)
|
||||
#define IPU_FIELD_WID2 IPU_CPMEM_WORD(1, 125, 3)
|
||||
|
||||
u32 yb:12;
|
||||
u32 sce:1;
|
||||
u32 res1:1;
|
||||
u32 nsb:1;
|
||||
u32 lnpb:6;
|
||||
u32 sx:10;
|
||||
u32 sy_l:1;
|
||||
#define IPU_FIELD_WID3 IPU_CPMEM_WORD(1, 128, 3)
|
||||
#define IPU_FIELD_DEC_SEL IPU_CPMEM_WORD(1, 131, 1)
|
||||
#define IPU_FIELD_RES6 IPU_CPMEM_WORD(1, 132, 28)
|
||||
|
||||
u32 sy_h:9;
|
||||
u32 ns:10;
|
||||
u32 sm:10;
|
||||
u32 sdx_l:3;
|
||||
|
||||
u32 sdx_h:2;
|
||||
u32 sdy:5;
|
||||
u32 sdrx:1;
|
||||
u32 sdry:1;
|
||||
u32 sdr1:1;
|
||||
u32 res2:2;
|
||||
u32 fw:12;
|
||||
u32 fh_l:8;
|
||||
|
||||
u32 fh_h:4;
|
||||
u32 res3:28;
|
||||
|
||||
/* Word 1 */
|
||||
u32 eba0;
|
||||
|
||||
u32 eba1;
|
||||
|
||||
u32 bpp:3;
|
||||
u32 sl:14;
|
||||
u32 pfs:3;
|
||||
u32 bam:3;
|
||||
u32 res4:2;
|
||||
u32 npb:6;
|
||||
u32 res5:1;
|
||||
|
||||
u32 sat:2;
|
||||
u32 scc:1;
|
||||
u32 ofs0:5;
|
||||
u32 ofs1:5;
|
||||
u32 ofs2:5;
|
||||
u32 ofs3:5;
|
||||
u32 wid0:3;
|
||||
u32 wid1:3;
|
||||
u32 wid2:3;
|
||||
|
||||
u32 wid3:3;
|
||||
u32 dec_sel:1;
|
||||
u32 res6:28;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
union chan_param_mem {
|
||||
struct chan_param_mem_planar pp;
|
||||
struct chan_param_mem_interleaved ip;
|
||||
struct ipu_cpmem_word {
|
||||
u32 data[5];
|
||||
};
|
||||
|
||||
struct ipu_ch_param {
|
||||
struct ipu_cpmem_word word[2];
|
||||
};
|
||||
|
||||
void ipu_ch_param_write_field(struct ipu_ch_param __iomem *base, u32 wbs, u32 v)
|
||||
{
|
||||
u32 bit = (wbs >> 8) % 160;
|
||||
u32 size = wbs & 0xff;
|
||||
u32 word = (wbs >> 8) / 160;
|
||||
u32 i = bit / 32;
|
||||
u32 ofs = bit % 32;
|
||||
u32 mask = (1 << size) - 1;
|
||||
u32 val;
|
||||
|
||||
pr_debug("%s %d %d %d\n", __func__, word, bit , size);
|
||||
|
||||
val = readl(&base->word[word].data[i]);
|
||||
val &= ~(mask << ofs);
|
||||
val |= v << ofs;
|
||||
writel(val, &base->word[word].data[i]);
|
||||
|
||||
if ((bit + size - 1) / 32 > i) {
|
||||
val = readl(&base->word[word].data[i + 1]);
|
||||
val &= ~(mask >> (ofs ? (32 - ofs) : 0));
|
||||
val |= v >> (ofs ? (32 - ofs) : 0);
|
||||
writel(val, &base->word[word].data[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline u32 reg_read(struct ipu_fb_info *fbi, unsigned long reg)
|
||||
{
|
||||
u32 val;
|
||||
|
@ -500,60 +486,61 @@ static int sdc_init_panel(struct fb_info *info, enum disp_data_mapping fmt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ipu_ch_param_set_size(union chan_param_mem *params,
|
||||
static void ipu_ch_param_set_size(struct ipu_ch_param *p,
|
||||
u32 pixel_fmt, uint16_t width,
|
||||
uint16_t height, uint16_t stride)
|
||||
{
|
||||
params->pp.fw = width - 1;
|
||||
params->pp.fh_l = height - 1;
|
||||
params->pp.fh_h = (height - 1) >> 8;
|
||||
params->pp.sl = stride - 1;
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_FW, width - 1);
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_FH_L, height - 1);
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_FH_H, (height - 1) >> 8);
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_SL, stride - 1);
|
||||
|
||||
/* See above, for further formats see the Linux driver */
|
||||
switch (pixel_fmt) {
|
||||
case IPU_PIX_FMT_RGB565:
|
||||
params->ip.bpp = 2;
|
||||
params->ip.pfs = 4;
|
||||
params->ip.npb = 7;
|
||||
params->ip.sat = 2; /* SAT = 32-bit access */
|
||||
params->ip.ofs0 = 0; /* Red bit offset */
|
||||
params->ip.ofs1 = 5; /* Green bit offset */
|
||||
params->ip.ofs2 = 11; /* Blue bit offset */
|
||||
params->ip.ofs3 = 16; /* Alpha bit offset */
|
||||
params->ip.wid0 = 4; /* Red bit width - 1 */
|
||||
params->ip.wid1 = 5; /* Green bit width - 1 */
|
||||
params->ip.wid2 = 4; /* Blue bit width - 1 */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_BPP, 2);
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_PFS, 4);
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_NPB, 7);
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_SAT, 2); /* SAT = 32-bit access */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_OFS0, 0); /* Red bit offset */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_OFS1, 5); /* Green bit offset */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_OFS2, 11); /* Blue bit offset */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_OFS3, 16); /* Alpha bit offset */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_WID0, 4); /* Red bit width - 1 */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_WID1, 5); /* Green bit width - 1 */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_WID2, 4); /* Blue bit width - 1 */
|
||||
break;
|
||||
case IPU_PIX_FMT_RGB24:
|
||||
params->ip.bpp = 1; /* 24 BPP & RGB PFS */
|
||||
params->ip.pfs = 4;
|
||||
params->ip.npb = 7;
|
||||
params->ip.sat = 2; /* SAT = 32-bit access */
|
||||
params->ip.ofs0 = 16; /* Red bit offset */
|
||||
params->ip.ofs1 = 8; /* Green bit offset */
|
||||
params->ip.ofs2 = 0; /* Blue bit offset */
|
||||
params->ip.ofs3 = 24; /* Alpha bit offset */
|
||||
params->ip.wid0 = 7; /* Red bit width - 1 */
|
||||
params->ip.wid1 = 7; /* Green bit width - 1 */
|
||||
params->ip.wid2 = 7; /* Blue bit width - 1 */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_BPP, 1); /* 24 BPP & RGB PFS */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_PFS, 4);
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_NPB, 7);
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_SAT, 2); /* SAT = 32-bit access */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_OFS0, 16); /* Red bit offset */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_OFS1, 8); /* Green bit offset */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_OFS2, 0); /* Blue bit offset */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_OFS3, 24); /* Alpha bit offset */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_WID0, 7); /* Red bit width - 1 */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_WID1, 7); /* Green bit width - 1 */
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_WID2, 7); /* Blue bit width - 1 */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
params->pp.nsb = 1;
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_NSB, 1);
|
||||
}
|
||||
|
||||
static void ipu_ch_param_set_buffer(union chan_param_mem *params,
|
||||
void *buf0, void *buf1)
|
||||
static void ipu_ch_param_set_buffer(struct ipu_ch_param *p, void *buf0, void *buf1)
|
||||
{
|
||||
params->pp.eba0 = (u32)buf0;
|
||||
params->pp.eba1 = (u32)buf1;
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_EBA0, (u32)buf0);
|
||||
ipu_ch_param_write_field(p, IPU_FIELD_EBA1, (u32)buf1);
|
||||
}
|
||||
|
||||
static void ipu_write_param_mem(struct ipu_fb_info *fbi, u32 addr,
|
||||
u32 *data, u32 num_words)
|
||||
struct ipu_ch_param *p, u32 num_words)
|
||||
{
|
||||
u32 *data = (void *)p;
|
||||
|
||||
for (; num_words > 0; num_words--) {
|
||||
reg_write(fbi, addr, IPU_IMA_ADDR);
|
||||
reg_write(fbi, *data++, IPU_IMA_DATA);
|
||||
|
@ -586,7 +573,7 @@ static u32 dma_param_addr(enum ipu_channel channel)
|
|||
static void ipu_init_channel_buffer(struct ipu_fb_info *fbi,
|
||||
enum ipu_channel channel, void *fbmem)
|
||||
{
|
||||
union chan_param_mem params = {};
|
||||
struct ipu_ch_param p = {};
|
||||
u32 reg;
|
||||
u32 stride_bytes;
|
||||
|
||||
|
@ -594,23 +581,23 @@ static void ipu_init_channel_buffer(struct ipu_fb_info *fbi,
|
|||
stride_bytes = (stride_bytes + 3) & ~3;
|
||||
|
||||
/* Build parameter memory data for DMA channel */
|
||||
ipu_ch_param_set_size(¶ms, bpp_to_pixfmt(fbi->info.bits_per_pixel),
|
||||
ipu_ch_param_set_size(&p, bpp_to_pixfmt(fbi->info.bits_per_pixel),
|
||||
fbi->info.xres, fbi->info.yres, stride_bytes);
|
||||
ipu_ch_param_set_buffer(¶ms, fbmem, NULL);
|
||||
params.pp.bam = 0;
|
||||
/* Some channels (rotation) have restriction on burst length */
|
||||
|
||||
ipu_ch_param_set_buffer(&p, fbmem, NULL);
|
||||
|
||||
/* Some channels (rotation) have restriction on burst length */
|
||||
switch (channel) {
|
||||
case IDMAC_SDC_0:
|
||||
case IDMAC_SDC_1:
|
||||
/* In original code only IPU_PIX_FMT_RGB565 was setting burst */
|
||||
params.pp.npb = 16 - 1;
|
||||
ipu_ch_param_write_field(&p, IPU_FIELD_NPB, 16 - 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ipu_write_param_mem(fbi, dma_param_addr(channel), (u32 *)¶ms, 10);
|
||||
ipu_write_param_mem(fbi, dma_param_addr(channel), &p, 10);
|
||||
|
||||
/* Disable double-buffering */
|
||||
reg = reg_read(fbi, IPU_CHA_DB_MODE_SEL);
|
||||
|
|
Loading…
Reference in New Issue