#include <linux/linux_logo.h>
#include <linux/dma-mapping.h>
#include <linux/regulator/consumer.h>
+#include <linux/of_address.h>
+#include <linux/memblock.h>
#include "bmp_helper.h"
case YUV444_A:
pixel_width = 8;
break;
+ case YUYV422:
+ case UYVY422:
+ case YUYV420:
+ case UYVY420:
+ pixel_width = 16;
+ break;
default:
pr_warn("%s: unsupported format: 0x%x\n",
__func__, data_format);
static int rk_fb_data_fmt(int data_format, int bits_per_pixel)
{
- int fb_data_fmt;
+ int fb_data_fmt = 0;
if (data_format) {
switch (data_format) {
case HAL_PIXEL_FORMAT_FBDC_U8U8U8: /* fbdc rgb888 */
fb_data_fmt = FBDC_RGBX_888;
break;
+ case HAL_PIXEL_FORMAT_YUYV422: /* yuyv422 */
+ fb_data_fmt = YUYV422;
+ break;
+ case HAL_PIXEL_FORMAT_YUYV420: /* yuyv420 */
+ fb_data_fmt = YUYV420;
+ break;
+ case HAL_PIXEL_FORMAT_UYVY422: /* uyvy422 */
+ fb_data_fmt = UYVY422;
+ break;
+ case HAL_PIXEL_FORMAT_UYVY420: /* uyvy420 */
+ fb_data_fmt = UYVY420;
+ break;
default:
pr_warn("%s: unsupported format: 0x%x\n",
__func__, data_format);
screen->lvds_format = dt->lvds_format;
screen->face = dt->face;
screen->color_mode = dt->color_mode;
+ screen->width = dt->screen_widt;
+ screen->height = dt->screen_hight;
screen->dsp_lut = dt->dsp_lut;
screen->cabc_lut = dt->cabc_lut;
screen->cabc_gamma_base = dt->cabc_gamma_base;
case FBDC_RGBX_888:
strcpy(fmt, "FBDC_RGBX_888");
break;
+ case YUYV422:
+ strcpy(fmt, "YUYV422");
+ break;
+ case YUYV420:
+ strcpy(fmt, "YUYV420");
+ break;
+ case UYVY422:
+ strcpy(fmt, "UYVY422");
+ break;
+ case UYVY420:
+ strcpy(fmt, "UYVY420");
+ break;
default:
strcpy(fmt, "invalid");
break;
win->area[i].smem_start =
reg_win_data->reg_area_data[i].smem_start;
if (inf->disp_mode == DUAL ||
+ inf->disp_mode == DUAL_LCD ||
inf->disp_mode == NO_DUAL) {
win->area[i].xpos =
reg_win_data->reg_area_data[i].xpos;
struct rk_screen *screen = dev_drv->cur_screen;/*screen0;*/
struct fb_info *fbi;
int i, ion_fd, acq_fence_fd;
- u32 xvir, yvir;
- u32 xoffset, yoffset;
+ u32 xvir = 0, yvir = 0;
+ u32 xoffset = 0, yoffset = 0;
struct ion_handle *hdl;
size_t len;
- int index_buf;
- u8 fb_data_fmt;
- u8 pixel_width;
- u32 vir_width_bit;
- u32 stride, uv_stride;
- u32 stride_32bit_1;
- u32 stride_32bit_2;
- u16 uv_x_off, uv_y_off, uv_y_act;
+ int index_buf = 0;
+ u8 fb_data_fmt = 0;
+ u8 pixel_width = 0;
+ u32 vir_width_bit = 0;
+ u32 stride = 0, uv_stride = 0;
+ u32 stride_32bit_1 = 0;
+ u32 stride_32bit_2 = 0;
+ u16 uv_x_off = 0, uv_y_off = 0, uv_y_act = 0;
u8 is_pic_yuv = 0;
u8 ppixel_a = 0, global_a = 0;
ion_phys_addr_t phy_addr;
int ret = 0;
- int buff_len;
+ int buff_len = 0;
reg_win_data->reg_area_data[0].smem_start = -1;
reg_win_data->area_num = 0;
ion_import_dma_buf(rk_fb->ion_client,
ion_fd);
if (IS_ERR(hdl)) {
- pr_info("%s: Could not import handle:"
- " %ld\n", __func__, (long)hdl);
+ pr_info("%s: win[%d]area[%d] can't import handle\n",
+ __func__, win_par->win_id, i);
+ pr_info("fd: %d, hdl: 0x%p, ion_client: 0x%p\n",
+ ion_fd, hdl, rk_fb->ion_client);
return -EINVAL;
break;
}
win_data->ret_fence_fd = -1;
pr_info("win num = %d,null frame\n", regs->win_num);
err2:
+ rk_fb_config_debug(dev_drv, win_data, regs, 0);
kfree(regs);
mutex_unlock(&dev_drv->output_lock);
u32 xvir = var->xres_virtual;
u8 data_format = var->nonstd & 0xff;
u8 fb_data_fmt;
- u8 pixel_width;
+ u8 pixel_width = 0;
u32 vir_width_bit;
- u32 stride, uv_stride;
+ u32 stride, uv_stride = 0;
u32 stride_32bit_1;
u32 stride_32bit_2;
u16 uv_x_off, uv_y_off, uv_y_act;
}
}
- envp[0] = "switch screen";
+ envp[0] = "switch vop screen";
memset(envplcdc, 0, sizeof(envplcdc));
memset(envpfbdev, 0, sizeof(envpfbdev));
- sprintf(envplcdc, "SCREEN=%d,ENABLE=%d", screen->type, enable);
+ sprintf(envplcdc, "SCREEN=%d,ENABLE=%d,VOPID=%d", screen->type, enable, dev_drv->id);
sprintf(envpfbdev, "FBDEV=%d", dev_drv->fb_index_base);
envp[1] = envplcdc;
envp[2] = envpfbdev;
/* If there is more than one lcdc device, we disable
* the layer which attached to this device
*/
- dev_drv->suspend_flag = 1;
flush_kthread_worker(&dev_drv->update_regs_worker);
for (i = 0; i < dev_drv->lcdc_win_num; i++) {
if (dev_drv->win[i] && dev_drv->win[i]->state)
mutex_unlock(&dev_drv->switch_screen);
return 0;
} else {
+ if (load_screen || (rk_fb->disp_policy != DISPLAY_POLICY_BOX)) {
+ for (i = 0; i < dev_drv->lcdc_win_num; i++) {
+ if (dev_drv->win[i] && dev_drv->win[i]->state &&
+ dev_drv->ops->win_direct_en)
+ dev_drv->ops->win_direct_en(dev_drv, i, 0);
+ }
+ }
if (dev_drv->uboot_logo) {
if (dev_drv->cur_screen->mode.xres !=
screen->mode.xres ||
dev_drv->cur_screen->x_mirror = dev_drv->rotate_mode & X_MIRROR;
dev_drv->cur_screen->y_mirror = dev_drv->rotate_mode & Y_MIRROR;
}
+
if (!dev_drv->uboot_logo || load_screen ||
(rk_fb->disp_policy != DISPLAY_POLICY_BOX)) {
for (i = 0; i < dev_drv->lcdc_win_num; i++) {
dev_drv->ops->cfg_done(dev_drv);
} else if (!dev_drv->win[win_id]->state) {
dev_drv->ops->open(dev_drv, win_id, 1);
- dev_drv->suspend_flag = 0;
- mutex_lock(&dev_drv->win_config);
- info->var.xoffset = 0;
- info->var.yoffset = 0;
- info->fbops->fb_set_par(info);
- info->fbops->fb_pan_display(&info->var,
- info);
- mutex_unlock(&dev_drv->win_config);
+ /* dev_drv->suspend_flag = 0; */
+ /* mutex_lock(&dev_drv->win_config);
+ * info->var.xoffset = 0;
+ * info->var.yoffset = 0;
+ * info->fbops->fb_set_par(info);
+ * info->fbops->fb_pan_display(&info->var,
+ * info);
+ * mutex_unlock(&dev_drv->win_config);
+ */
}
}
}
return false;
}
-__weak phys_addr_t uboot_logo_base;
-__weak phys_addr_t uboot_logo_size;
-__weak phys_addr_t uboot_logo_offset;
+phys_addr_t uboot_logo_base;
+phys_addr_t uboot_logo_size;
+phys_addr_t uboot_logo_offset;
+
+static int __init rockchip_uboot_mem_late_init(void)
+{
+ int err;
+
+ if (uboot_logo_size) {
+ void *start = phys_to_virt(uboot_logo_base);
+ void *end = phys_to_virt(uboot_logo_base + uboot_logo_size);
+
+ err = memblock_free(uboot_logo_base, uboot_logo_size);
+ if (err < 0)
+ pr_err("%s: freeing memblock failed: %d\n",
+ __func__, err);
+ free_reserved_area(start, end, -1, "logo");
+ }
+ return 0;
+}
+
+late_initcall(rockchip_uboot_mem_late_init);
int rk_fb_register(struct rk_lcdc_driver *dev_drv,
struct rk_lcdc_win *win, int id)
fbi->fix = def_fix;
sprintf(fbi->fix.id, "fb%d", rk_fb->num_fb);
fb_videomode_to_var(&fbi->var, &dev_drv->cur_screen->mode);
+ fbi->var.width = dev_drv->cur_screen->width;
+ fbi->var.height = dev_drv->cur_screen->height;
fbi->var.grayscale |=
(fbi->var.xres << 8) + (fbi->var.yres << 20);
#if defined(CONFIG_LOGO_LINUX_BMP)
start += PAGE_SIZE;
i++;
}
- vaddr = vmap(pages, nr_pages, VM_MAP,
- pgprot_writecombine(PAGE_KERNEL));
+ vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
if (!vaddr) {
pr_err("failed to vmap phy addr 0x%lx\n",
(long)(uboot_logo_base +
start += PAGE_SIZE;
i++;
}
- vaddr = vmap(pages, nr_pages, VM_MAP,
- pgprot_writecombine(PAGE_KERNEL));
+ vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
if (!vaddr) {
pr_err("failed to vmap phy addr 0x%x\n",
start);
struct fb_info *extend_fbi = rk_fb->fb[dev_drv->fb_index_base];
extend_fbi->var.pixclock = rk_fb->fb[0]->var.pixclock;
- extend_fbi->fbops->fb_open(extend_fbi, 1);
- if (dev_drv->iommu_enabled) {
- if (dev_drv->mmu_dev)
- rockchip_iovmm_set_fault_handler(dev_drv->dev,
- rk_fb_sysmmu_fault_handler);
+ if (rk_fb->disp_mode == DUAL_LCD) {
+ extend_fbi->fbops->fb_open(extend_fbi, 1);
+ if (dev_drv->iommu_enabled) {
+ if (dev_drv->mmu_dev)
+ rockchip_iovmm_set_fault_handler(dev_drv->dev,
+ rk_fb_sysmmu_fault_handler);
+ }
+ rk_fb_alloc_buffer(extend_fbi);
}
- rk_fb_alloc_buffer(extend_fbi);
}
#endif
return 0;
{
struct rk_fb *rk_fb = NULL;
struct device_node *np = pdev->dev.of_node;
- u32 mode;
+ u32 mode, ret;
+ struct device_node *node;
if (!np) {
dev_err(&pdev->dev, "Missing device tree node.\n");
}
#endif
+ node = of_parse_phandle(np, "memory-region", 0);
+ if (node) {
+ struct resource r;
+
+ ret = of_address_to_resource(node, 0, &r);
+ if (ret)
+ return ret;
+
+ if (uboot_logo_on) {
+ uboot_logo_base = r.start;
+ uboot_logo_size = resource_size(&r);
+
+ if (uboot_logo_size > SZ_16M)
+ uboot_logo_offset = SZ_16M;
+ else
+ uboot_logo_offset = 0;
+ }
+ pr_info("logo: base=0x%llx, size=0x%llx, offset=0x%llx\n",
+ uboot_logo_base, uboot_logo_size, uboot_logo_offset);
+ }
+
fb_pdev = pdev;
dev_info(&pdev->dev, "rockchip framebuffer driver probe\n");
return 0;