aboutsummaryrefslogtreecommitdiff
path: root/drivers/mxc/ipu3/ipu_param_mem.h
diff options
context:
space:
mode:
authorJason Chen <b02280@freescale.com>2011-09-06 14:06:09 +0800
committerEric Miao <eric.miao@linaro.org>2011-11-15 16:28:23 +0800
commite3890c94e871bbf10aa331cb28763f4c6cd05ed0 (patch)
treea547d3a0c26f26787fae61d1780e6cdd1f1267e2 /drivers/mxc/ipu3/ipu_param_mem.h
parent3e61b0c69bced2cc1d7359fa770e4b426de24827 (diff)
downloadlinux-linaro-e3890c94e871bbf10aa331cb28763f4c6cd05ed0.tar.gz
ENGR00155146 ipuv3: use mutex instead of spin lock
keep spin lock for irq function, but use mutex replace other splin lock to provide better sync method. Add _ipu_get/put function to check clock enable. Signed-off-by: Jason Chen <b02280@freescale.com>
Diffstat (limited to 'drivers/mxc/ipu3/ipu_param_mem.h')
-rw-r--r--drivers/mxc/ipu3/ipu_param_mem.h154
1 files changed, 107 insertions, 47 deletions
diff --git a/drivers/mxc/ipu3/ipu_param_mem.h b/drivers/mxc/ipu3/ipu_param_mem.h
index d7167f7831e..d2ad2695b68 100644
--- a/drivers/mxc/ipu3/ipu_param_mem.h
+++ b/drivers/mxc/ipu3/ipu_param_mem.h
@@ -41,6 +41,24 @@ struct ipu_ch_param {
} \
}
+#define ipu_ch_param_set_field_io(base, w, bit, size, v) { \
+ int i = (bit) / 32; \
+ int off = (bit) % 32; \
+ unsigned reg_offset; \
+ u32 temp; \
+ reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
+ reg_offset += i; \
+ temp = readl((u32 *)base + reg_offset); \
+ temp |= (v) << off; \
+ writel(temp, (u32 *)base + reg_offset); \
+ if (((bit)+(size)-1)/32 > i) { \
+ reg_offset++; \
+ temp = readl((u32 *)base + reg_offset); \
+ temp |= (v) >> (off ? (32 - off) : 0); \
+ writel(temp, (u32 *)base + reg_offset); \
+ } \
+}
+
#define ipu_ch_param_mod_field(base, w, bit, size, v) { \
int i = (bit) / 32; \
int off = (bit) % 32; \
@@ -56,6 +74,27 @@ struct ipu_ch_param {
} \
}
+#define ipu_ch_param_mod_field_io(base, w, bit, size, v) { \
+ int i = (bit) / 32; \
+ int off = (bit) % 32; \
+ u32 mask = (1UL << size) - 1; \
+ unsigned reg_offset; \
+ u32 temp; \
+ reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
+ reg_offset += i; \
+ temp = readl((u32 *)base + reg_offset); \
+ temp &= ~(mask << off); \
+ temp |= (v) << off; \
+ writel(temp, (u32 *)base + reg_offset); \
+ if (((bit)+(size)-1)/32 > i) { \
+ reg_offset++; \
+ temp = readl((u32 *)base + reg_offset); \
+ temp &= ~(mask >> (32 - off)); \
+ temp |= ((v) >> (off ? (32 - off) : 0)); \
+ writel(temp, (u32 *)base + reg_offset); \
+ } \
+}
+
#define ipu_ch_param_read_field(base, w, bit, size) ({ \
u32 temp2; \
int i = (bit) / 32; \
@@ -71,6 +110,25 @@ struct ipu_ch_param {
temp1; \
})
+#define ipu_ch_param_read_field_io(base, w, bit, size) ({ \
+ u32 temp1, temp2; \
+ int i = (bit) / 32; \
+ int off = (bit) % 32; \
+ u32 mask = (1UL << size) - 1; \
+ unsigned reg_offset; \
+ reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
+ reg_offset += i; \
+ temp1 = readl((u32 *)base + reg_offset); \
+ temp1 = mask & (temp1 >> off); \
+ if (((bit)+(size)-1)/32 > i) { \
+ reg_offset++; \
+ temp2 = readl((u32 *)base + reg_offset); \
+ temp2 &= mask >> (off ? (32 - off) : 0); \
+ temp1 |= temp2 << (off ? (32 - off) : 0); \
+ } \
+ temp1; \
+})
+
static inline int __ipu_ch_get_third_buf_cpmem_num(int ch)
{
switch (ch) {
@@ -126,35 +184,35 @@ static inline void _ipu_ch_param_dump(struct ipu_soc *ipu, int ch)
p->word[1].data[0], p->word[1].data[1], p->word[1].data[2],
p->word[1].data[3], p->word[1].data[4]);
dev_dbg(ipu->dev, "PFS 0x%x, ",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 85, 4));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 85, 4));
dev_dbg(ipu->dev, "BPP 0x%x, ",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 0, 107, 3));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 107, 3));
dev_dbg(ipu->dev, "NPB 0x%x\n",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 78, 7));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7));
dev_dbg(ipu->dev, "FW %d, ",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 0, 125, 13));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 125, 13));
dev_dbg(ipu->dev, "FH %d, ",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 0, 138, 12));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 138, 12));
dev_dbg(ipu->dev, "Stride %d\n",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 102, 14));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14));
dev_dbg(ipu->dev, "Width0 %d+1, ",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 116, 3));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 116, 3));
dev_dbg(ipu->dev, "Width1 %d+1, ",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 119, 3));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 119, 3));
dev_dbg(ipu->dev, "Width2 %d+1, ",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 122, 3));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 122, 3));
dev_dbg(ipu->dev, "Width3 %d+1, ",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 125, 3));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 125, 3));
dev_dbg(ipu->dev, "Offset0 %d, ",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 128, 5));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 128, 5));
dev_dbg(ipu->dev, "Offset1 %d, ",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 133, 5));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 133, 5));
dev_dbg(ipu->dev, "Offset2 %d, ",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 138, 5));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 138, 5));
dev_dbg(ipu->dev, "Offset3 %d\n",
- ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 143, 5));
+ ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 143, 5));
}
static inline void _ipu_ch_param_init(struct ipu_soc *ipu, int ch,
@@ -392,24 +450,24 @@ static inline void _ipu_ch_param_set_burst_size(struct ipu_soc *ipu,
{
int32_t sub_ch = 0;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 78, 7,
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7,
burst_pixels - 1);
sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
if (sub_ch <= 0)
return;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 78, 7,
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 78, 7,
burst_pixels - 1);
};
static inline int _ipu_ch_param_get_burst_size(struct ipu_soc *ipu, uint32_t ch)
{
- return ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 78, 7) + 1;
+ return ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7) + 1;
};
static inline int _ipu_ch_param_get_bpp(struct ipu_soc *ipu, uint32_t ch)
{
- return ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 0, 107, 3);
+ return ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 107, 3);
};
static inline void _ipu_ch_param_set_buffer(struct ipu_soc *ipu, uint32_t ch,
@@ -422,7 +480,7 @@ static inline void _ipu_ch_param_set_buffer(struct ipu_soc *ipu, uint32_t ch,
bufNum = 0;
}
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 29 * bufNum, 29,
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 29 * bufNum, 29,
phyaddr / 8);
};
@@ -432,24 +490,24 @@ static inline void _ipu_ch_param_set_rotation(struct ipu_soc *ipu, uint32_t ch,
u32 temp_rot = bitrev8(rot) >> 5;
int32_t sub_ch = 0;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 0, 119, 3, temp_rot);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 119, 3, temp_rot);
sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
if (sub_ch <= 0)
return;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 0, 119, 3, temp_rot);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 119, 3, temp_rot);
};
static inline void _ipu_ch_param_set_block_mode(struct ipu_soc *ipu, uint32_t ch)
{
int32_t sub_ch = 0;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 0, 117, 2, 1);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 117, 2, 1);
sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
if (sub_ch <= 0)
return;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 0, 117, 2, 1);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 117, 2, 1);
};
static inline void _ipu_ch_param_set_alpha_use_separate_channel(struct ipu_soc *ipu,
@@ -459,9 +517,9 @@ static inline void _ipu_ch_param_set_alpha_use_separate_channel(struct ipu_soc *
int32_t sub_ch = 0;
if (option) {
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 1);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 1);
} else {
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 0);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 0);
}
sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
@@ -469,9 +527,9 @@ static inline void _ipu_ch_param_set_alpha_use_separate_channel(struct ipu_soc *
return;
if (option) {
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 1);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 1);
} else {
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 0);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 0);
}
};
@@ -479,12 +537,12 @@ static inline void _ipu_ch_param_set_alpha_condition_read(struct ipu_soc *ipu, u
{
int32_t sub_ch = 0;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 149, 1, 1);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 149, 1, 1);
sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
if (sub_ch <= 0)
return;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 149, 1, 1);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 149, 1, 1);
};
static inline void _ipu_ch_param_set_alpha_buffer_memory(struct ipu_soc *ipu, uint32_t ch)
@@ -511,12 +569,12 @@ static inline void _ipu_ch_param_set_alpha_buffer_memory(struct ipu_soc *ipu, ui
return;
}
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 90, 3, alp_mem_idx);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 90, 3, alp_mem_idx);
sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
if (sub_ch <= 0)
return;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 90, 3, alp_mem_idx);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 90, 3, alp_mem_idx);
};
static inline void _ipu_ch_param_set_interlaced_scan(struct ipu_soc *ipu, uint32_t ch)
@@ -526,10 +584,10 @@ static inline void _ipu_ch_param_set_interlaced_scan(struct ipu_soc *ipu, uint32
sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
- ipu_ch_param_set_field(ipu_ch_param_addr(ipu, ch), 0, 113, 1, 1);
+ ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch), 0, 113, 1, 1);
if (sub_ch > 0)
- ipu_ch_param_set_field(ipu_ch_param_addr(ipu, sub_ch), 0, 113, 1, 1);
- stride = ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 102, 14) + 1;
+ ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 113, 1, 1);
+ stride = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14) + 1;
/* ILO is 20-bit and 8-byte aligned */
if (stride/8 > 0xfffff)
dev_warn(ipu->dev,
@@ -537,27 +595,29 @@ static inline void _ipu_ch_param_set_interlaced_scan(struct ipu_soc *ipu, uint32
if (stride%8)
dev_warn(ipu->dev,
"IDMAC%d's ILO is not 8-byte aligned\n", ch);
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 58, 20, stride / 8);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 58, 20, stride / 8);
if (sub_ch > 0)
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 58, 20,
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 58, 20,
stride / 8);
stride *= 2;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 102, 14, stride - 1);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14, stride - 1);
if (sub_ch > 0)
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 102, 14,
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 102, 14,
stride - 1);
};
-static inline void _ipu_ch_param_set_high_priority(struct ipu_soc *ipu, uint32_t ch)
+static inline void _ipu_ch_param_set_axi_id(struct ipu_soc *ipu, uint32_t ch, uint32_t id)
{
int32_t sub_ch = 0;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 93, 2, 1);
+ id %= 4;
+
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 93, 2, id);
sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
if (sub_ch <= 0)
return;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 93, 2, 1);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 93, 2, id);
};
/* IDMAC U/V offset changing support */
@@ -713,26 +773,26 @@ static inline void _ipu_ch_offset_update(struct ipu_soc *ipu,
dev_warn(ipu->dev,
"IDMAC%d's V offset is not 8-byte aligned\n", ch);
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 0, 46, 22, u_offset / 8);
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 0, 68, 22, v_offset / 8);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22, u_offset / 8);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22, v_offset / 8);
sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
if (sub_ch <= 0)
return;
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22, u_offset / 8);
- ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22, v_offset / 8);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22, u_offset / 8);
+ ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22, v_offset / 8);
};
static inline void _ipu_ch_params_set_alpha_width(struct ipu_soc *ipu, uint32_t ch, int alpha_width)
{
int32_t sub_ch = 0;
- ipu_ch_param_set_field(ipu_ch_param_addr(ipu, ch), 1, 125, 3, alpha_width - 1);
+ ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch), 1, 125, 3, alpha_width - 1);
sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
if (sub_ch <= 0)
return;
- ipu_ch_param_set_field(ipu_ch_param_addr(ipu, sub_ch), 1, 125, 3, alpha_width - 1);
+ ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 125, 3, alpha_width - 1);
};
#endif