mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
osd: add dd functions used phys_to_page and vmap [1/1]
PD#SWPL-3153 Problem: remove phys_to_vir caused dd functions disable. Solution: add dd functions used phys_to_page and vmap Verify: franklin Change-Id: Ic28ac0107adfee58933d0b19a2a7c2893c06b789 Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
This commit is contained in:
committed by
Jianxin Pan
parent
73536ef3f3
commit
2d82eff6fe
@@ -733,11 +733,10 @@ struct hw_para_s {
|
||||
u32 osd_fps;
|
||||
u32 osd_fps_start;
|
||||
u32 osd_display_debug;
|
||||
char __iomem *screen_base[HW_OSD_COUNT];
|
||||
u32 screen_size[HW_OSD_COUNT];
|
||||
char __iomem *screen_base_backup[HW_OSD_COUNT];
|
||||
u32 screen_size_backup[HW_OSD_COUNT];
|
||||
u32 osd_clear[HW_OSD_COUNT];
|
||||
ulong screen_base[HW_OSD_COUNT];
|
||||
ulong screen_size[HW_OSD_COUNT];
|
||||
ulong screen_base_backup[HW_OSD_COUNT];
|
||||
ulong screen_size_backup[HW_OSD_COUNT];
|
||||
u32 vinfo_width;
|
||||
u32 vinfo_height;
|
||||
u32 fb_drvier_probe;
|
||||
|
||||
@@ -133,10 +133,12 @@ static ssize_t logmodule_write_file(
|
||||
char buf[128];
|
||||
int ret = 0;
|
||||
|
||||
count = min_t(size_t, count, (sizeof(buf)-1));
|
||||
if (count > sizeof(buf) || count <= 0)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(buf, userbuf, count))
|
||||
return -EFAULT;
|
||||
buf[count] = 0;
|
||||
if (buf[count - 1] == '\n')
|
||||
buf[count - 1] = '\0';
|
||||
ret = kstrtoint(buf, 0, &log_module);
|
||||
osd_log_info("log_level: %d->%d\n", osd_log_module, log_module);
|
||||
osd_log_module = log_module;
|
||||
@@ -470,7 +472,8 @@ static ssize_t osd_clear_write_file(struct file *file,
|
||||
return -EFAULT;
|
||||
buf[count] = 0;
|
||||
ret = kstrtoint(buf, 0, &osd_clear);
|
||||
osd_set_clear(osd_id, osd_clear);
|
||||
if (osd_clear)
|
||||
osd_set_clear(osd_id);
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -478,12 +481,12 @@ static ssize_t osd_dump_read_file(struct file *file,
|
||||
char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char __iomem *buf;
|
||||
u8 __iomem *buf = NULL;
|
||||
struct seq_file *s = file->private_data;
|
||||
int osd_id = *(int *)s;
|
||||
unsigned long len;
|
||||
unsigned long len = 0;
|
||||
|
||||
osd_restore_screen_info(osd_id, &buf, &len);
|
||||
len = get_vmap_addr(osd_id, &buf);
|
||||
if (buf && len)
|
||||
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
|
||||
else
|
||||
@@ -494,7 +497,14 @@ static ssize_t osd_dump_write_file(struct file *file,
|
||||
const char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
#if 1
|
||||
return 0;
|
||||
#else
|
||||
struct seq_file *s = file->private_data;
|
||||
int osd_id = *(int *)s;
|
||||
|
||||
return dd_vmap_write(osd_id, userbuf, count, ppos);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void parse_param(char *buf_orig, char **parm)
|
||||
|
||||
@@ -1010,7 +1010,7 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
|
||||
osd_sync_request_render(info->node,
|
||||
info->var.yres,
|
||||
sync_request_render, phys_addr, len);
|
||||
osd_restore_screen_info(info->node,
|
||||
osd_get_screen_info(info->node,
|
||||
&info->screen_base, &info->screen_size);
|
||||
ret = copy_to_user(argp,
|
||||
&sync_request,
|
||||
@@ -1400,8 +1400,10 @@ static int malloc_osd_memory(struct fb_info *info)
|
||||
fix->smem_len = fbdev->fb_len;
|
||||
info->screen_base = (char __iomem *)fbdev->fb_mem_vaddr;
|
||||
info->screen_size = fix->smem_len;
|
||||
osd_hw.screen_base[fb_index] = fbdev->fb_mem_paddr;
|
||||
osd_hw.screen_size[fb_index] = fix->smem_len;
|
||||
osd_backup_screen_info(fb_index,
|
||||
info->screen_base, info->screen_size);
|
||||
osd_hw.screen_base[fb_index], osd_hw.screen_size[fb_index]);
|
||||
logo_index = osd_get_logo_index();
|
||||
osd_log_info("logo_index=%x,fb_index=%d\n",
|
||||
logo_index, fb_index);
|
||||
@@ -1539,6 +1541,275 @@ static int osd_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
||||
return vm_iomap_memory(vma, start, len);
|
||||
}
|
||||
|
||||
static int is_new_page(unsigned long addr, unsigned long pos)
|
||||
{
|
||||
static ulong pre_addr;
|
||||
u32 offset;
|
||||
int ret = 0;
|
||||
|
||||
/* ret == 0 : in same page*/
|
||||
if (pos == 0)
|
||||
ret = 1;
|
||||
else {
|
||||
offset = pre_addr & ~PAGE_MASK;
|
||||
if ((offset + addr - pre_addr) >= PAGE_SIZE)
|
||||
ret = 1;
|
||||
}
|
||||
pre_addr = addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t osd_read(struct fb_info *info, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
u32 fb_index;
|
||||
struct osd_fb_dev_s *fbdev;
|
||||
unsigned long p = *ppos;
|
||||
unsigned long total_size;
|
||||
static u8 *vaddr;
|
||||
ulong phys;
|
||||
u32 offset, npages;
|
||||
struct page **pages = NULL;
|
||||
struct page *pages_array[2] = {};
|
||||
pgprot_t pgprot;
|
||||
u8 *buffer, *dst;
|
||||
u8 __iomem *src;
|
||||
int i, c, cnt = 0, err = 0;
|
||||
|
||||
fbdev = (struct osd_fb_dev_s *)info->par;
|
||||
fb_index = fbdev->fb_index;
|
||||
total_size = osd_hw.screen_size[fb_index];
|
||||
if (total_size == 0)
|
||||
total_size = info->fix.smem_len;
|
||||
|
||||
if (p >= total_size)
|
||||
return 0;
|
||||
|
||||
if (count >= total_size)
|
||||
count = total_size;
|
||||
|
||||
if (count + p > total_size)
|
||||
count = total_size - p;
|
||||
if (count <= PAGE_SIZE) {
|
||||
/* small than one page, need not vmalloc */
|
||||
npages = PAGE_ALIGN(count) / PAGE_SIZE;
|
||||
phys = osd_hw.screen_base[fb_index] + p;
|
||||
if (is_new_page(phys, p)) {
|
||||
/* new page, need call vmap*/
|
||||
offset = phys & ~PAGE_MASK;
|
||||
if ((offset + count) > PAGE_SIZE)
|
||||
npages++;
|
||||
for (i = 0; i < npages; i++) {
|
||||
pages_array[i] = phys_to_page(phys);
|
||||
phys += PAGE_SIZE;
|
||||
}
|
||||
/*nocache*/
|
||||
pgprot = pgprot_writecombine(PAGE_KERNEL);
|
||||
if (vaddr) {
|
||||
/* unmap prevois vaddr */
|
||||
vunmap(vaddr);
|
||||
vaddr = NULL;
|
||||
}
|
||||
vaddr = vmap(pages_array, npages, VM_MAP, pgprot);
|
||||
if (!vaddr) {
|
||||
pr_err("the phy(%lx) vmaped fail, size: %d\n",
|
||||
phys, npages << PAGE_SHIFT);
|
||||
return -ENOMEM;
|
||||
}
|
||||
src = (u8 __iomem *) (vaddr);
|
||||
} else {
|
||||
/* in same page just get vaddr + p*/
|
||||
src = (u8 __iomem *) (vaddr + (p & ~PAGE_MASK));
|
||||
}
|
||||
} else {
|
||||
npages = PAGE_ALIGN(count) / PAGE_SIZE;
|
||||
phys = osd_hw.screen_base[fb_index] + p;
|
||||
offset = phys & ~PAGE_MASK;
|
||||
if ((offset + count) > PAGE_SIZE)
|
||||
npages++;
|
||||
pages = vmalloc(sizeof(struct page *) * npages);
|
||||
if (!pages)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < npages; i++) {
|
||||
pages[i] = phys_to_page(phys);
|
||||
phys += PAGE_SIZE;
|
||||
}
|
||||
/*nocache*/
|
||||
pgprot = pgprot_writecombine(PAGE_KERNEL);
|
||||
if (vaddr) {
|
||||
/*unmap prevois vaddr */
|
||||
vunmap(vaddr);
|
||||
vaddr = NULL;
|
||||
}
|
||||
vaddr = vmap(pages, npages, VM_MAP, pgprot);
|
||||
if (!vaddr) {
|
||||
pr_err("the phy(%lx) vmaped fail, size: %d\n",
|
||||
phys, npages << PAGE_SHIFT);
|
||||
vfree(pages);
|
||||
return -ENOMEM;
|
||||
}
|
||||
vfree(pages);
|
||||
src = (u8 __iomem *) (vaddr);
|
||||
}
|
||||
|
||||
buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
|
||||
GFP_KERNEL);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
/* osd_sync(info); */
|
||||
|
||||
while (count) {
|
||||
c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
|
||||
dst = buffer;
|
||||
fb_memcpy_fromfb(dst, src, c);
|
||||
dst += c;
|
||||
src += c;
|
||||
|
||||
if (copy_to_user(buf, buffer, c)) {
|
||||
err = -EFAULT;
|
||||
break;
|
||||
}
|
||||
*ppos += c;
|
||||
buf += c;
|
||||
cnt += c;
|
||||
count -= c;
|
||||
}
|
||||
|
||||
kfree(buffer);
|
||||
|
||||
return (err) ? err : cnt;
|
||||
|
||||
}
|
||||
|
||||
static ssize_t osd_write(struct fb_info *info, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
u32 fb_index;
|
||||
struct osd_fb_dev_s *fbdev;
|
||||
unsigned long p = *ppos;
|
||||
unsigned long total_size;
|
||||
static u8 *vaddr;
|
||||
ulong phys;
|
||||
u32 offset, npages;
|
||||
struct page **pages = NULL;
|
||||
struct page *pages_array[2] = {};
|
||||
pgprot_t pgprot;
|
||||
u8 *buffer, *src;
|
||||
u8 __iomem *dst;
|
||||
int i, c, cnt = 0, err = 0;
|
||||
|
||||
fbdev = (struct osd_fb_dev_s *)info->par;
|
||||
fb_index = fbdev->fb_index;
|
||||
total_size = osd_hw.screen_size[fb_index];
|
||||
|
||||
if (total_size == 0)
|
||||
total_size = info->fix.smem_len;
|
||||
|
||||
if (p > total_size)
|
||||
return -EFBIG;
|
||||
|
||||
if (count > total_size) {
|
||||
err = -EFBIG;
|
||||
count = total_size;
|
||||
}
|
||||
|
||||
if (count + p > total_size) {
|
||||
if (!err)
|
||||
err = -ENOSPC;
|
||||
|
||||
count = total_size - p;
|
||||
}
|
||||
if (count <= PAGE_SIZE) {
|
||||
/* small than one page, need not vmalloc */
|
||||
npages = PAGE_ALIGN(count) / PAGE_SIZE;
|
||||
phys = osd_hw.screen_base[fb_index] + p;
|
||||
if (is_new_page(phys, p)) {
|
||||
/* new page, need call vmap*/
|
||||
offset = phys & ~PAGE_MASK;
|
||||
if ((offset + count) > PAGE_SIZE)
|
||||
npages++;
|
||||
for (i = 0; i < npages; i++) {
|
||||
pages_array[i] = phys_to_page(phys);
|
||||
phys += PAGE_SIZE;
|
||||
}
|
||||
/*nocache*/
|
||||
pgprot = pgprot_writecombine(PAGE_KERNEL);
|
||||
if (vaddr) {
|
||||
/* unmap prevois vaddr */
|
||||
vunmap(vaddr);
|
||||
vaddr = NULL;
|
||||
}
|
||||
vaddr = vmap(pages_array, npages, VM_MAP, pgprot);
|
||||
if (!vaddr) {
|
||||
pr_err("the phy(%lx) vmaped fail, size: %d\n",
|
||||
phys, npages << PAGE_SHIFT);
|
||||
return -ENOMEM;
|
||||
}
|
||||
dst = (u8 __iomem *) (vaddr);
|
||||
} else {
|
||||
/* in same page just get vaddr + p*/
|
||||
dst = (u8 __iomem *) (vaddr + (p & ~PAGE_MASK));
|
||||
}
|
||||
} else {
|
||||
npages = PAGE_ALIGN(count) / PAGE_SIZE;
|
||||
phys = osd_hw.screen_base[fb_index] + p;
|
||||
offset = phys & ~PAGE_MASK;
|
||||
if ((offset + count) > PAGE_SIZE)
|
||||
npages++;
|
||||
pages = vmalloc(sizeof(struct page *) * npages);
|
||||
if (!pages)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < npages; i++) {
|
||||
pages[i] = phys_to_page(phys);
|
||||
phys += PAGE_SIZE;
|
||||
}
|
||||
/*nocache*/
|
||||
pgprot = pgprot_writecombine(PAGE_KERNEL);
|
||||
if (vaddr) {
|
||||
/* unmap prevois vaddr */
|
||||
vunmap(vaddr);
|
||||
vaddr = NULL;
|
||||
}
|
||||
vaddr = vmap(pages, npages, VM_MAP, pgprot);
|
||||
if (!vaddr) {
|
||||
pr_err("the phy(%lx) vmaped fail, size: %d\n",
|
||||
phys, npages << PAGE_SHIFT);
|
||||
vfree(pages);
|
||||
return -ENOMEM;
|
||||
}
|
||||
vfree(pages);
|
||||
dst = (u8 __iomem *) (vaddr);
|
||||
|
||||
}
|
||||
buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
|
||||
GFP_KERNEL);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
/* osd_sync() */
|
||||
|
||||
while (count) {
|
||||
c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
|
||||
src = buffer;
|
||||
|
||||
if (copy_from_user(src, buf, c)) {
|
||||
err = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
fb_memcpy_tofb(dst, src, c);
|
||||
dst += c;
|
||||
*ppos += c;
|
||||
buf += c;
|
||||
cnt += c;
|
||||
count -= c;
|
||||
}
|
||||
|
||||
kfree(buffer);
|
||||
|
||||
return (cnt) ? cnt : err;
|
||||
|
||||
}
|
||||
|
||||
static int osd_release(struct fb_info *info, int arg)
|
||||
{
|
||||
@@ -1560,21 +1831,6 @@ static int osd_release(struct fb_info *info, int arg)
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
static ssize_t osd_clear(struct device *device, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
u32 res = 0;
|
||||
int ret = 0;
|
||||
|
||||
ret = kstrtoint(buf, 0, &res);
|
||||
osd_log_info("clear: osd %d\n", res);
|
||||
|
||||
memset(fb_rmem_vaddr[res],
|
||||
0x0,
|
||||
fb_rmem_size[res]);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int osd_blank(int blank_mode, struct fb_info *info)
|
||||
{
|
||||
@@ -1639,6 +1895,8 @@ static struct fb_ops osd_ops = {
|
||||
#endif
|
||||
.fb_open = osd_open,
|
||||
.fb_mmap = osd_mmap,
|
||||
.fb_read = osd_read,
|
||||
.fb_write = osd_write,
|
||||
.fb_blank = osd_blank,
|
||||
.fb_pan_display = osd_pan_display,
|
||||
.fb_sync = osd_sync,
|
||||
@@ -2393,6 +2651,22 @@ static ssize_t store_afbcd(struct device *device, struct device_attribute *attr,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t osd_clear(struct device *device, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
u32 res = 0;
|
||||
int ret = 0;
|
||||
struct fb_info *fb_info = dev_get_drvdata(device);
|
||||
|
||||
ret = kstrtoint(buf, 0, &res);
|
||||
osd_log_info("clear: osd %d\n", fb_info->node);
|
||||
|
||||
if (res)
|
||||
osd_set_clear(fb_info->node);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_log_level(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
/* Android Headers */
|
||||
|
||||
@@ -72,7 +75,6 @@
|
||||
#include "osd_fb.h"
|
||||
|
||||
#define OSD_BLEND_SHIFT_WORKAROUND
|
||||
#define REMOVE_PHYS_TO_VIRT
|
||||
#ifdef CONFIG_AMLOGIC_VSYNC_FIQ_ENABLE
|
||||
#define FIQ_VSYNC
|
||||
#endif
|
||||
@@ -3736,9 +3738,6 @@ static bool osd_ge2d_compose_pan_display(struct osd_fence_map_s *fence_map)
|
||||
{
|
||||
u32 index = fence_map->fb_index;
|
||||
bool free_scale_set = false;
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
void *vaddr = NULL;
|
||||
#endif
|
||||
|
||||
canvas_config(osd_hw.fb_gem[index].canvas_idx,
|
||||
fence_map->ext_addr,
|
||||
@@ -3746,13 +3745,10 @@ static bool osd_ge2d_compose_pan_display(struct osd_fence_map_s *fence_map)
|
||||
(osd_hw.color_info[index]->bpp >> 3)),
|
||||
fence_map->height,
|
||||
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
vaddr = phys_to_virt(fence_map->ext_addr);
|
||||
osd_hw.screen_base[index] = vaddr;
|
||||
osd_hw.screen_base[index] = fence_map->ext_addr;
|
||||
osd_hw.screen_size[index] =
|
||||
CANVAS_ALIGNED(fence_map->width *
|
||||
osd_hw.color_info[index]->bpp) * fence_map->height;
|
||||
#endif
|
||||
osd_hw.pandata[index].x_start = 0;
|
||||
osd_hw.pandata[index].x_end = fence_map->width - 1;
|
||||
osd_hw.pandata[index].y_start = 0;
|
||||
@@ -3817,14 +3813,8 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map)
|
||||
u32 x_start, x_end, y_start, y_end;
|
||||
bool freescale_update = false;
|
||||
struct pandata_s freescale_dst[HW_OSD_COUNT];
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
void *vaddr = NULL;
|
||||
#endif
|
||||
|
||||
ext_addr = ext_addr + fence_map->byte_stride * fence_map->yoffset;
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
vaddr = phys_to_virt(ext_addr);
|
||||
#endif
|
||||
|
||||
if (!osd_hw.osd_afbcd[index].enable) {
|
||||
canvas_config(osd_hw.fb_gem[index].canvas_idx,
|
||||
@@ -3832,11 +3822,9 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map)
|
||||
fence_map->byte_stride,
|
||||
fence_map->height,
|
||||
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
osd_hw.screen_base[index] = vaddr;
|
||||
osd_hw.screen_base[index] = ext_addr;
|
||||
osd_hw.screen_size[index] =
|
||||
fence_map->byte_stride * fence_map->height;
|
||||
#endif
|
||||
} else {
|
||||
osd_hw.osd_afbcd[index].phy_addr = ext_addr;
|
||||
osd_hw.osd_afbcd[index].frame_width =
|
||||
@@ -3857,10 +3845,8 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map)
|
||||
else
|
||||
osd_hw.osd_afbcd[index].conv_lbuf_len = 1024;
|
||||
}
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
osd_hw.screen_base[index] = vaddr;
|
||||
osd_hw.screen_base[index] = ext_addr;
|
||||
osd_hw.screen_size[index] = fence_map->afbc_len;
|
||||
#endif
|
||||
}
|
||||
width_dst = osd_hw.free_dst_data_backup[index].x_end -
|
||||
osd_hw.free_dst_data_backup[index].x_start + 1;
|
||||
@@ -4282,9 +4268,6 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map)
|
||||
u32 index = layer_map->fb_index;
|
||||
const struct color_bit_define_s *color = NULL;
|
||||
u32 ext_addr = 0;
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
void *vaddr = NULL;
|
||||
#endif
|
||||
u32 format = 0;
|
||||
|
||||
if (index > OSD_MAX)
|
||||
@@ -4354,10 +4337,6 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map)
|
||||
layer_map->byte_stride *
|
||||
layer_map->src_y;
|
||||
#endif
|
||||
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
vaddr = phys_to_virt(ext_addr);
|
||||
#endif
|
||||
if (!osd_hw.osd_afbcd[index].enable) {
|
||||
/*ext_addr is no crop, so height =
|
||||
* layer_map->src_h + layer_map->src_y
|
||||
@@ -4368,11 +4347,9 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map)
|
||||
layer_map->src_h + layer_map->src_y,
|
||||
CANVAS_ADDR_NOWRAP,
|
||||
CANVAS_BLKMODE_LINEAR);
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
osd_hw.screen_base[index] = vaddr;
|
||||
osd_hw.screen_base[index] = ext_addr;
|
||||
osd_hw.screen_size[index] =
|
||||
layer_map->byte_stride * layer_map->src_h;
|
||||
#endif
|
||||
} else {
|
||||
osd_hw.osd_afbcd[index].phy_addr = ext_addr;
|
||||
if (osd_hw.osd_meson_dev.afbc_type ==
|
||||
@@ -4399,11 +4376,9 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map)
|
||||
else
|
||||
osd_hw.osd_afbcd[index]
|
||||
.conv_lbuf_len = 1024;
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
osd_hw.screen_base[index] = vaddr;
|
||||
osd_hw.screen_base[index] = ext_addr;
|
||||
osd_hw.screen_size[index] =
|
||||
layer_map->afbc_len;
|
||||
#endif
|
||||
} else if (osd_hw.osd_meson_dev
|
||||
.afbc_type == MALI_AFBC) {
|
||||
osd_hw.osd_afbcd[index].frame_width =
|
||||
@@ -4411,11 +4386,9 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map)
|
||||
//BYTE_32_ALIGNED(layer_map->src_w);
|
||||
osd_hw.osd_afbcd[index].frame_height =
|
||||
BYTE_8_ALIGNED(layer_map->src_h);
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
osd_hw.screen_base[index] = vaddr;
|
||||
osd_hw.screen_base[index] = ext_addr;
|
||||
osd_hw.screen_size[index] =
|
||||
layer_map->afbc_len;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* just get para, need update via do_hwc */
|
||||
@@ -4496,7 +4469,7 @@ static void osd_pan_display_layers_fence(
|
||||
layer_map = &fence_map->layer_map[i];
|
||||
index = layer_map->fb_index;
|
||||
if (i != layer_map->fb_index) {
|
||||
osd_hw.screen_base[i] = NULL;
|
||||
osd_hw.screen_base[i] = 0;
|
||||
osd_hw.screen_size[i] = 0;
|
||||
osd_hw.enable[i] = 0;
|
||||
continue;
|
||||
@@ -8756,7 +8729,6 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe,
|
||||
osd_hw.free_src_data_backup[idx].y_end = 0;
|
||||
osd_hw.free_scale_mode[idx] = 0;
|
||||
osd_hw.buffer_alloc[idx] = 0;
|
||||
osd_hw.osd_clear[idx] = 0;
|
||||
osd_hw.osd_afbcd[idx].enable = 0;
|
||||
osd_hw.use_h_filter_mode[idx] = -1;
|
||||
osd_hw.use_v_filter_mode[idx] = -1;
|
||||
@@ -9410,28 +9382,255 @@ void osd_get_blending_para(struct hw_osd_blending_s **para)
|
||||
}
|
||||
void osd_backup_screen_info(
|
||||
u32 index,
|
||||
char __iomem *screen_base,
|
||||
u32 screen_size)
|
||||
unsigned long screen_base,
|
||||
unsigned long screen_size)
|
||||
{
|
||||
osd_hw.screen_base_backup[index] = screen_base;
|
||||
osd_hw.screen_size_backup[index] = screen_size;
|
||||
osd_hw.screen_base[index] = screen_base;
|
||||
osd_hw.screen_size[index] = screen_size;
|
||||
}
|
||||
|
||||
void osd_restore_screen_info(
|
||||
void osd_get_screen_info(
|
||||
u32 index,
|
||||
char __iomem **screen_base,
|
||||
unsigned long *screen_size)
|
||||
{
|
||||
*screen_base = osd_hw.screen_base[index];
|
||||
*screen_size = (unsigned long)osd_hw.screen_size[index];
|
||||
|
||||
*screen_base = (char __iomem *)osd_hw.screen_base[index];
|
||||
*screen_size = osd_hw.screen_size[index];
|
||||
}
|
||||
|
||||
void osd_set_clear(u32 index, u32 osd_clear)
|
||||
int get_vmap_addr(u32 index, u8 __iomem **buf)
|
||||
{
|
||||
osd_hw.osd_clear[index] = osd_clear;
|
||||
unsigned long total_size;
|
||||
ulong phys;
|
||||
u32 offset, npages;
|
||||
struct page **pages = NULL;
|
||||
pgprot_t pgprot;
|
||||
static u8 *vaddr;
|
||||
int i;
|
||||
|
||||
total_size = osd_hw.screen_size[index];
|
||||
|
||||
npages = PAGE_ALIGN(total_size) / PAGE_SIZE;
|
||||
phys = osd_hw.screen_base[index];
|
||||
offset = phys & ~PAGE_MASK;
|
||||
if (offset)
|
||||
npages++;
|
||||
pages = vmalloc(sizeof(struct page *) * npages);
|
||||
if (!pages)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < npages; i++) {
|
||||
pages[i] = phys_to_page(phys);
|
||||
phys += PAGE_SIZE;
|
||||
}
|
||||
/*nocache*/
|
||||
pgprot = pgprot_writecombine(PAGE_KERNEL);
|
||||
if (vaddr) {
|
||||
/* unmap prevois vaddr */
|
||||
vunmap(vaddr);
|
||||
vaddr = NULL;
|
||||
}
|
||||
vaddr = vmap(pages, npages, VM_MAP, pgprot);
|
||||
if (!vaddr) {
|
||||
pr_err("the phy(%lx) vmaped fail, size: %d\n",
|
||||
phys, npages << PAGE_SHIFT);
|
||||
vfree(pages);
|
||||
return -ENOMEM;
|
||||
}
|
||||
vfree(pages);
|
||||
*buf = (u8 __iomem *) (vaddr);
|
||||
|
||||
return osd_hw.screen_size[index];
|
||||
}
|
||||
#if 0
|
||||
static int is_new_page(unsigned long addr, unsigned long pos)
|
||||
{
|
||||
static ulong pre_addr;
|
||||
u32 offset;
|
||||
int ret = 0;
|
||||
|
||||
/* ret == 0 : in same page*/
|
||||
if (pos == 0)
|
||||
ret = 1;
|
||||
else {
|
||||
offset = pre_addr & ~PAGE_MASK;
|
||||
if ((offset + addr - pre_addr) >= PAGE_SIZE)
|
||||
ret = 1;
|
||||
}
|
||||
pre_addr = addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t dd_vmap_write(u32 index, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
unsigned long p = *ppos;
|
||||
unsigned long total_size;
|
||||
static u8 *vaddr;
|
||||
ulong phys;
|
||||
u32 offset, npages;
|
||||
struct page **pages = NULL;
|
||||
struct page *pages_array[2] = {};
|
||||
pgprot_t pgprot;
|
||||
u8 *buffer, *src;
|
||||
u8 __iomem *dst;
|
||||
int i, c, cnt = 0, err = 0;
|
||||
|
||||
total_size = osd_hw.screen_size[index];
|
||||
if (p > total_size)
|
||||
return -EFBIG;
|
||||
|
||||
if (count > total_size) {
|
||||
err = -EFBIG;
|
||||
count = total_size;
|
||||
}
|
||||
|
||||
if (count + p > total_size) {
|
||||
if (!err)
|
||||
err = -ENOSPC;
|
||||
|
||||
count = total_size - p;
|
||||
}
|
||||
if (count < PAGE_SIZE) {
|
||||
/* small than one page, need not vmalloc */
|
||||
npages = PAGE_ALIGN(count) / PAGE_SIZE;
|
||||
phys = osd_hw.screen_base[index] + p;
|
||||
if (is_new_page(phys, p)) {
|
||||
/* new page, need call vmap*/
|
||||
offset = phys & ~PAGE_MASK;
|
||||
if ((offset + count) > PAGE_SIZE)
|
||||
npages++;
|
||||
for (i = 0; i < npages; i++) {
|
||||
pages_array[i] = phys_to_page(phys);
|
||||
phys += PAGE_SIZE;
|
||||
}
|
||||
/*nocache*/
|
||||
pgprot = pgprot_writecombine(PAGE_KERNEL);
|
||||
if (vaddr) {
|
||||
/* unmap prevois vaddr */
|
||||
vunmap(vaddr);
|
||||
vaddr = NULL;
|
||||
}
|
||||
vaddr = vmap(pages_array, npages, VM_MAP, pgprot);
|
||||
if (!vaddr) {
|
||||
pr_err("the phy(%lx) vmaped fail, size: %d\n",
|
||||
phys, npages << PAGE_SHIFT);
|
||||
return -ENOMEM;
|
||||
}
|
||||
dst = (u8 __iomem *) (vaddr);
|
||||
} else {
|
||||
/* in same page just get vaddr + p*/
|
||||
dst = (u8 __iomem *) (vaddr + (p & ~PAGE_MASK));
|
||||
}
|
||||
} else {
|
||||
npages = PAGE_ALIGN(count) / PAGE_SIZE;
|
||||
phys = osd_hw.screen_base[index] + p;
|
||||
offset = phys & ~PAGE_MASK;
|
||||
if ((offset + count) > PAGE_SIZE)
|
||||
npages++;
|
||||
pages = vmalloc(sizeof(struct page *) * npages);
|
||||
if (!pages)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < npages; i++) {
|
||||
pages[i] = phys_to_page(phys);
|
||||
phys += PAGE_SIZE;
|
||||
}
|
||||
/*nocache*/
|
||||
pgprot = pgprot_writecombine(PAGE_KERNEL);
|
||||
//pgprot = PAGE_KERNEL;
|
||||
if (vaddr) {
|
||||
/* unmap prevois vaddr */
|
||||
vunmap(vaddr);
|
||||
vaddr = NULL;
|
||||
}
|
||||
vaddr = vmap(pages, npages, VM_MAP, pgprot);
|
||||
if (!vaddr) {
|
||||
pr_err("the phy(%lx) vmaped fail, size: %d\n",
|
||||
phys, npages << PAGE_SHIFT);
|
||||
vfree(pages);
|
||||
return -ENOMEM;
|
||||
}
|
||||
vfree(pages);
|
||||
dst = (u8 __iomem *) (vaddr);
|
||||
}
|
||||
buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
|
||||
GFP_KERNEL);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
/* osd_sync() */
|
||||
|
||||
while (count) {
|
||||
c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
|
||||
src = buffer;
|
||||
|
||||
if (copy_from_user(src, buf, c)) {
|
||||
err = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
fb_memcpy_tofb(dst, src, c);
|
||||
dst += c;
|
||||
*ppos += c;
|
||||
buf += c;
|
||||
cnt += c;
|
||||
count -= c;
|
||||
}
|
||||
kfree(buffer);
|
||||
return (cnt) ? cnt : err;
|
||||
}
|
||||
#endif
|
||||
int osd_set_clear(u32 index)
|
||||
{
|
||||
unsigned long total_size;
|
||||
ulong phys;
|
||||
u32 offset, npages;
|
||||
struct page **pages = NULL;
|
||||
pgprot_t pgprot;
|
||||
static u8 *vaddr;
|
||||
u8 __iomem *dst;
|
||||
int i, c, count, cnt = 0;
|
||||
|
||||
total_size = osd_hw.screen_size[index];
|
||||
npages = PAGE_ALIGN(total_size) / PAGE_SIZE;
|
||||
phys = osd_hw.screen_base[index];
|
||||
offset = phys & (~PAGE_MASK);
|
||||
if (offset)
|
||||
npages++;
|
||||
pages = vmalloc(sizeof(struct page *) * npages);
|
||||
if (!pages)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < npages; i++) {
|
||||
pages[i] = phys_to_page(phys);
|
||||
phys += PAGE_SIZE;
|
||||
}
|
||||
/*nocache*/
|
||||
pgprot = pgprot_writecombine(PAGE_KERNEL);
|
||||
|
||||
vaddr = vmap(pages, npages, VM_MAP, pgprot);
|
||||
if (!vaddr) {
|
||||
pr_err("the phy(%lx) vmaped fail, size: %d\n",
|
||||
phys, npages << PAGE_SHIFT);
|
||||
vfree(pages);
|
||||
return -ENOMEM;
|
||||
}
|
||||
vfree(pages);
|
||||
dst = (u8 __iomem *) (vaddr);
|
||||
|
||||
count = total_size;
|
||||
while (count) {
|
||||
c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
|
||||
memset(dst, 0, c);
|
||||
dst += c;
|
||||
cnt += c;
|
||||
count -= c;
|
||||
}
|
||||
if (vaddr) {
|
||||
/* unmap prevois vaddr */
|
||||
vunmap(vaddr);
|
||||
vaddr = NULL;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static const struct color_bit_define_s *convert_panel_format(u32 format)
|
||||
@@ -9480,23 +9679,10 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map)
|
||||
bool freescale_update = false;
|
||||
struct pandata_s freescale_dst[HW_OSD_COUNT];
|
||||
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
void *vaddr = NULL;
|
||||
#endif
|
||||
|
||||
phy_addr = phy_addr + plane_map->byte_stride * plane_map->src_y;
|
||||
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
vaddr = phys_to_virt(phy_addr);
|
||||
osd_hw.screen_base[index] = vaddr;
|
||||
osd_hw.screen_base[index] = phy_addr;
|
||||
osd_hw.screen_size[index] =
|
||||
plane_map->byte_stride * plane_map->src_h;
|
||||
if (osd_hw.osd_clear[index]) {
|
||||
if (vaddr)
|
||||
memset(vaddr, 0x0,
|
||||
plane_map->byte_stride*plane_map->src_h);
|
||||
}
|
||||
#endif
|
||||
osd_log_dbg(MODULE_RENDER, "canvas_id=%x, phy_addr=%x\n",
|
||||
osd_hw.fb_gem[index].canvas_idx, phy_addr);
|
||||
canvas_config(osd_hw.fb_gem[index].canvas_idx,
|
||||
@@ -9734,29 +9920,15 @@ static void osd_cursor_move(struct osd_plane_map_s *plane_map)
|
||||
u32 phy_addr = plane_map->phy_addr;
|
||||
u32 x_start, x_end, y_start, y_end;
|
||||
u32 x, y;
|
||||
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
void *vaddr = NULL;
|
||||
#endif
|
||||
|
||||
struct pandata_s disp_tmp;
|
||||
struct pandata_s free_dst_data_backup;
|
||||
|
||||
if (index != OSD2)
|
||||
return;
|
||||
phy_addr = phy_addr + plane_map->byte_stride * plane_map->src_y;
|
||||
|
||||
#ifndef REMOVE_PHYS_TO_VIRT
|
||||
vaddr = phys_to_virt(phy_addr);
|
||||
osd_hw.screen_base[index] = vaddr;
|
||||
osd_hw.screen_base[index] = phy_addr;
|
||||
osd_hw.screen_size[index] =
|
||||
plane_map->byte_stride * plane_map->src_h;
|
||||
if (osd_hw.osd_clear[index]) {
|
||||
if (vaddr)
|
||||
memset(vaddr, 0x0,
|
||||
plane_map->byte_stride*plane_map->src_h);
|
||||
}
|
||||
#endif
|
||||
canvas_config(osd_hw.fb_gem[index].canvas_idx,
|
||||
phy_addr,
|
||||
plane_map->byte_stride,
|
||||
|
||||
@@ -191,13 +191,16 @@ void osd_do_hwc(void);
|
||||
int osd_get_capbility(u32 index);
|
||||
void osd_backup_screen_info(
|
||||
u32 index,
|
||||
char __iomem *screen_base,
|
||||
u32 screen_size);
|
||||
void osd_restore_screen_info(
|
||||
unsigned long screen_base,
|
||||
unsigned long screen_size);
|
||||
void osd_get_screen_info(
|
||||
u32 index,
|
||||
char __iomem **screen_base,
|
||||
unsigned long *screen_size);
|
||||
void osd_set_clear(u32 index, u32 osd_clear);
|
||||
int get_vmap_addr(u32 index, u8 __iomem **buf);
|
||||
ssize_t dd_vmap_write(u32 index, const char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
int osd_set_clear(u32 index);
|
||||
void osd_page_flip(struct osd_plane_map_s *plane_map);
|
||||
void walk_through_update_list(void);
|
||||
int osd_setting_blend(void);
|
||||
|
||||
Reference in New Issue
Block a user