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:
Pengcheng Chen
2018-12-11 12:55:59 +08:00
committed by Dongjin Kim
parent a8766cd067
commit a96bf74964
5 changed files with 567 additions and 109 deletions

View File

@@ -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;

View File

@@ -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)

View File

@@ -1028,7 +1028,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,
@@ -1418,8 +1418,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);
@@ -1557,6 +1559,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)
{
@@ -1578,21 +1849,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)
{
@@ -1657,6 +1913,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,
@@ -2411,6 +2669,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)

View File

@@ -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
@@ -3544,9 +3546,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,
@@ -3554,13 +3553,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;
@@ -3625,14 +3621,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,
@@ -3640,11 +3630,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 =
@@ -3665,10 +3653,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;
@@ -4090,9 +4076,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)
@@ -4162,10 +4145,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
@@ -4176,11 +4155,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 ==
@@ -4207,11 +4184,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 =
@@ -4219,11 +4194,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 */
@@ -4304,7 +4277,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;
@@ -8545,7 +8518,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;
@@ -9198,28 +9170,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)
@@ -9268,23 +9467,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,
@@ -9522,29 +9708,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,

View File

@@ -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);