23 #include <linux/kernel.h>
24 #include <linux/module.h>
27 #include <linux/bitops.h>
34 #define DBG(format, ...) pr_debug("VRFB: " format, ## __VA_ARGS__)
36 #define DBG(format, ...)
39 #define SMS_ROT_VIRT_BASE(context, rot) \
40 (((context >= 4) ? 0xD0000000 : 0x70000000) \
41 + (0x4000000 * (context)) \
42 + (0x1000000 * (rot)))
44 #define OMAP_VRFB_SIZE (2048 * 2048 * 4)
46 #define VRFB_PAGE_WIDTH_EXP 5
47 #define VRFB_PAGE_HEIGHT_EXP 5
48 #define VRFB_PAGE_WIDTH (1 << VRFB_PAGE_WIDTH_EXP)
49 #define VRFB_PAGE_HEIGHT (1 << VRFB_PAGE_HEIGHT_EXP)
50 #define SMS_IMAGEHEIGHT_OFFSET 16
51 #define SMS_IMAGEWIDTH_OFFSET 0
52 #define SMS_PH_OFFSET 8
53 #define SMS_PW_OFFSET 4
54 #define SMS_PS_OFFSET 0
56 #define VRFB_NUM_CTXS 12
58 static unsigned long ctx_map;
74 static inline void restore_hw_context(
int ctx)
83 unsigned long stride = width * bytespp;
95 static inline u32 get_extra_physical_size(
u16 image_width_roundup,
u8 bytespp)
104 unsigned long map = ctx_map;
106 for (i =
ffs(map);
i; i =
ffs(map)) {
110 restore_hw_context(i);
124 unsigned long image_width_roundup = get_image_width_roundup(width,
130 return (width * height * bytespp) + get_extra_physical_size(
131 image_width_roundup, bytespp);
137 unsigned long image_width_roundup = get_image_width_roundup(width,
145 extra = get_extra_physical_size(image_width_roundup, bytespp);
147 if (phys_size < extra)
150 height = (phys_size -
extra) / (width * bytespp);
153 return min_t(
unsigned long, height, 2048);
159 unsigned bytespp,
bool yuv_mode)
161 unsigned pixel_size_exp;
168 DBG(
"omapfb_set_vrfb(%d, %lx, %dx%d, %d, %d)\n", ctx, paddr,
169 width, height, bytespp, yuv_mode);
180 else if (bytespp == 2)
190 DBG(
"vrfb w %u, h %u bytespp %d\n", vrfb_width, vrfb_height, bytespp);
199 vrfb_hw_context[
ctx].physical_ba =
paddr;
200 vrfb_hw_context[
ctx].size =
size;
207 DBG(
"vrfb offset pixels %d, %d\n",
208 vrfb_width - width, vrfb_height - height);
225 if (!vrfb->
vaddr[rot]) {
230 DBG(
"ioremapped vrfb area %d of size %lu into %p\n", rot, size,
245 DBG(
"release ctx %d\n", ctx);
249 BUG_ON(!(ctx_map & (1 << ctx)));
253 for (rot = 0; rot < 4; ++
rot) {
254 if (vrfb->
paddr[rot]) {
273 DBG(
"request ctx\n");
278 if ((ctx_map & (1 << ctx)) == 0)
281 if (ctx == VRFB_NUM_CTXS) {
282 pr_err(
"vrfb: no free contexts\n");
287 DBG(
"found free ctx %d\n", ctx);
291 memset(vrfb, 0,
sizeof(*vrfb));
295 for (rot = 0; rot < 4; ++
rot) {
298 pr_err(
"vrfb: failed to reserve VRFB "
299 "area for ctx %d, rotation %d\n",
308 DBG(
"VRFB %d/%d: %lx\n", ctx, rot*90, vrfb->
paddr[rot]);