完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
根据5.1的双屏显示patch,在android6.0上修改了下,因为没硬件环境,所以未经验证,仅供参考。edp是主屏,lvds是副屏。
edp屏: lcd-LM133LFL01-EDP1920x1080_dual.dtsi /* * RockChip. DisplayPort screen LM133LFL01 * */ disp_timings: display-timings { native-mode = <&lm133lfl01>; lm133lfl01: timing0 { screen-type = out-face = clock-frequency = <43200000>; hactive = <1920>; vactive = <1080>; hback-porch = <148>; hfront-porch = <88>; vback-porch = <36>; vfront-porch = <4>; hsync-len = <44>; vsync-len = <5>; hsync-active = <1>; vsync-active = <1>; de-active = <0>; pixelclk-active = <0>; swap-rb = <0>; swap-rg = <0>; swap-gb = <0>; }; }; lvds屏: arch/arm/boot/dts/lcd-b101ew05_dual.dtsi display-timings { native-mode = <&b101ew05>; b101ew05: timing0 { screen-type = lvds-format = out-face = color-mode = clock-frequency = <71000000>; hactive = <1024>; vactive = <600>; hback-porch = <100>; hfront-porch = <18>; vback-porch = <8>; vfront-porch = <6>; hsync-len = <10>; vsync-len = <2>; hsync-active = <0>; vsync-active = <0>; de-active = <0>; pixelclk-active = <0>; swap-rb = <0>; swap-rg = <0>; swap-gb = <0>; }; }; 其余部分: diff --git a/arch/arm/boot/dts/rk3288-tb_8846.dts b/arch/arm/boot/dts/rk3288-tb_8846.dts index f80578e..ec71f93 100755 --- a/arch/arm/boot/dts/rk3288-tb_8846.dts +++ b/arch/arm/boot/dts/rk3288-tb_8846.dts @@ -1,9 +1,11 @@ /dts-v1/; #include "rk3288.dtsi" -//#include "lcd-b101ew05.dtsi" -#include "lcd-F402.dtsi" -#include "vtl_ts_sdk8846.dtsi" + +//#include "lcd-F402.dtsi" +//#include "vtl_ts_sdk8846.dtsi" + #include "rk3288-cif-sensor.dtsi" / { fiq-debugger { @@ -607,14 +609,60 @@ }; &fb { - rockchip,disp-mode = - rockchip,uboot-logo-on = <1>; + rockchip,disp-mode = + rockchip,uboot-logo-on = <0>; }; &rk_screen { - display-timings = <&disp_timings>; + status = "okay"; + screen0 { + screen_prop = + native-mode = + power_ctr { + lcd_en { + rockchip,power_type = + gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>; + rockchip,delay = <10>; + }; + lcd_cs { + rockchip,power_type = + gpios = <&gpio7 GPIO_A4 GPIO_ACTIVE_HIGH>; + rockchip,delay = <10>; + }; + }; + #include "lcd-LM133LFL01-EDP1920x1080_dual.dtsi" + }; + screen1 { + screen_prop = + native-mode = + power_ctr { + lcd_en { + rockchip,power_type = + gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>; + rockchip,delay = <10>; + }; + lcd_cs { + rockchip,power_type = + gpios = <&gpio7 GPIO_A4 GPIO_ACTIVE_HIGH>; + rockchip,delay = <10>; + }; + }; + #include "lcd-b101ew05_dual.dtsi" + }; }; + +&lvds { + status = "okay"; + prop = +}; + +&edp { + status = "okay"; + prop = +}; + + /*lcdc0 as PRMRY(LCD),lcdc1 as EXTEND(HDMI)*/ &lcdc0 { status = "okay"; @@ -629,7 +677,7 @@ rockchip,delay = <5>; };*/ - lcd_en:lcd_en { + /* lcd_en:lcd_en { rockchip,power_type = gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>; rockchip,delay = <10>; @@ -639,7 +687,7 @@ rockchip,power_type = gpios = <&gpio7 GPIO_A4 GPIO_ACTIVE_HIGH>; rockchip,delay = <10>; - }; + }; */ /*lcd_rst:lcd_rst { rockchip,power_type = @@ -657,7 +705,7 @@ }; &hdmi { - status = "okay"; + status = "disabled"; rockchip,hdmi_video_source = }; diff --git a/arch/arm/configs/rockchip_defconfig b/arch/arm/configs/rockchip_defconfig index 40edcbf..78a3f27 100644 --- a/arch/arm/configs/rockchip_defconfig +++ b/arch/arm/configs/rockchip_defconfig @@ -433,6 +433,7 @@ CONFIG_DP_ANX6345=y CONFIG_RK32_DP=y CONFIG_MIPI_DSI=y CONFIG_RK32_MIPI_DSI=y +CONFIG_SMART_DUAL_LCD=y CONFIG_RK_HDMI=y CONFIG_RK_TVENCODER=y CONFIG_RK1000_TVOUT=y diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig index 6034139..39543bc 100755 --- a/drivers/video/rockchip/Kconfig +++ b/drivers/video/rockchip/Kconfig @@ -58,6 +58,9 @@ config THREE_FB_BUFFER help select y if android support three buffer,like Jelly Bean +config SMART_DUAL_LCD + bool"smart dual lcd support" + default n source "drivers/video/rockchip/lcdc/Kconfig" source "drivers/video/rockchip/screen/Kconfig" diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index c45387c..8c5eb98 100755 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -71,9 +71,16 @@ EXPORT_SYMBOL(video_data_to_mirroring); extern phys_addr_t uboot_logo_base; extern phys_addr_t uboot_logo_size; extern phys_addr_t uboot_logo_offset; + +#ifndef CONFIG_SMART_DUAL_LCD static struct rk_fb_trsm_ops *trsm_lvds_ops; static struct rk_fb_trsm_ops *trsm_edp_ops; static struct rk_fb_trsm_ops *trsm_mipi_ops; +#else +static struct rk_fb_trsm_ops *trsm_prmry_ops; +static struct rk_fb_trsm_ops *trsm_extend_ops; +#endif + static int uboot_logo_on; static int rk_fb_debug_lvl; @@ -107,6 +114,7 @@ int rk_fb_get_display_policy(void) int rk_fb_trsm_ops_register(struct rk_fb_trsm_ops *ops, int type) { +#ifndef CONFIG_SMART_DUAL_LCD switch (type) { case SCREEN_RGB: case SCREEN_LVDS: @@ -127,13 +135,23 @@ int rk_fb_trsm_ops_register(struct rk_fb_trsm_ops *ops, int type) __func__, type); break; } +#else + if (type == PRMRY) + trsm_prmry_ops = ops; + else if (type == EXTEND) + trsm_extend_ops = ops; + else + pr_err("%s, type:%dn", __func__, type); +#endif + return 0; } struct rk_fb_trsm_ops *rk_fb_trsm_ops_get(int type) { - struct rk_fb_trsm_ops *ops; + struct rk_fb_trsm_ops *ops; +#ifndef CONFIG_SMART_DUAL_LCD switch (type) { case SCREEN_RGB: case SCREEN_LVDS: @@ -155,6 +173,15 @@ struct rk_fb_trsm_ops *rk_fb_trsm_ops_get(int type) __func__, type); break; } +#else + if (type == PRMRY) + ops = trsm_prmry_ops; + else if (type == EXTEND) + ops = trsm_extend_ops; + else + pr_err("%s, type:%dn", __func__, type); +#endif + return ops; } @@ -309,10 +336,19 @@ static int rk_fb_data_fmt(int data_format, int bits_per_pixel) /* * rk display power control parse from dts */ +#ifndef CONFIG_SMART_DUAL_LCD int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv) +#else +int rk_disp_pwr_ctr_parse_dt(struct device_node *np, struct rk_screen *rk_screen) +#endif { +#ifndef CONFIG_SMART_DUAL_LCD struct device_node *root = of_get_child_by_name(dev_drv->dev->of_node, "power_ctr"); +#else + struct device_node *root = of_get_child_by_name(np, "power_ctr"); +#endif + struct device_node *child; struct rk_disp_pwr_ctr_list *pwr_ctr; struct list_head *pos; @@ -321,10 +357,20 @@ int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv) u32 debug = 0; int ret; +#ifndef CONFIG_SMART_DUAL_LCD INIT_LIST_HEAD(&dev_drv->pwrlist_head); +#else + INIT_LIST_HEAD(rk_screen->pwrlist_head); +#endif + if (!root) { +#ifndef CONFIG_SMART_DUAL_LCD dev_err(dev_drv->dev, "can't find power_ctr node for lcdc%dn", dev_drv->id); +#else + dev_err(rk_screen->dev, "can't find power_ctr node for lcdc%dn", + rk_screen->lcdc_id); +#endif return -ENODEV; } @@ -337,17 +383,29 @@ int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv) pwr_ctr->pwr_ctr.type = GPIO; pwr_ctr->pwr_ctr.gpio = of_get_gpio_flags(child, 0, &flags); if (!gpio_is_valid(pwr_ctr->pwr_ctr.gpio)) { +#ifndef CONFIG_SMART_DUAL_LCD dev_err(dev_drv->dev, "%s ivalid gpion", child->name); +#else + dev_err(rk_screen->dev, "%s ivalid gpion", + child->name); +#endif + return -EINVAL; } pwr_ctr->pwr_ctr.atv_val = !(flags & OF_GPIO_ACTIVE_LOW); ret = gpio_request(pwr_ctr->pwr_ctr.gpio, child->name); if (ret) { +#ifndef CONFIG_SMART_DUAL_LCD dev_err(dev_drv->dev, "request %s gpio fail:%dn", child->name, ret); +#else + dev_err(rk_screen->dev, + "request %s gpio fail:%dn", + child->name, ret); +#endif } } else { @@ -356,7 +414,11 @@ int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv) ret = of_property_read_string(child, "rockchip,regulator_name", &(pwr_ctr->pwr_ctr.rgl_name)); if (ret || IS_ERR_OR_NULL(pwr_ctr->pwr_ctr.rgl_name)) +#ifndef CONFIG_SMART_DUAL_LCD dev_err(dev_drv->dev, "get regulator name failed!n"); +#else + dev_err(rk_screen->dev, "get regulator name failed!n"); +#endif if (!of_property_read_u32(child, "rockchip,regulator_voltage", &val)) pwr_ctr->pwr_ctr.volt = val; else @@ -368,13 +430,21 @@ int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv) pwr_ctr->pwr_ctr.delay = val; else pwr_ctr->pwr_ctr.delay = 0; +#ifndef CONFIG_SMART_DUAL_LCD list_add_tail(&pwr_ctr->list, &dev_drv->pwrlist_head); +#else + list_add_tail(&pwr_ctr->list, rk_screen->pwrlist_head); +#endif } of_property_read_u32(root, "rockchip,debug", &debug); if (debug) { +#ifndef CONFIG_SMART_DUAL_LCD list_for_each(pos, &dev_drv->pwrlist_head) { +#else + list_for_each(pos, rk_screen->pwrlist_head) { +#endif pwr_ctr = list_entry(pos, struct rk_disp_pwr_ctr_list, list); pr_info("pwr_ctr_name:%sn" @@ -400,10 +470,25 @@ int rk_disp_pwr_enable(struct rk_lcdc_driver *dev_drv) struct pwr_ctr *pwr_ctr; struct regulator *regulator_lcd = NULL; int count = 10; - +#ifndef CONFIG_SMART_DUAL_LCD if (list_empty(&dev_drv->pwrlist_head)) return 0; - list_for_each(pos, &dev_drv->pwrlist_head) { +#else + if (!dev_drv->cur_screen->pwrlist_head) { + pr_info("error: %s, lcdc%d screen pwrlist nulln", + __func__, dev_drv->id); + return 0; + } + if (list_empty(dev_drv->cur_screen->pwrlist_head)) + return 0; +#endif + +#ifndef CONFIG_SMART_DUAL_LCD + list_for_each(pos, &dev_drv->pwrlist_head) +#else + list_for_each(pos, dev_drv->cur_screen->pwrlist_head) +#endif + { pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, list); pwr_ctr = &pwr_ctr_list->pwr_ctr; @@ -446,9 +531,25 @@ int rk_disp_pwr_disable(struct rk_lcdc_driver *dev_drv) struct regulator *regulator_lcd = NULL; int count = 10; +#ifndef CONFIG_SMART_DUAL_LCD if (list_empty(&dev_drv->pwrlist_head)) return 0; - list_for_each(pos, &dev_drv->pwrlist_head) { +#else + if (!dev_drv->cur_screen->pwrlist_head) { + pr_info("error: %s, lcdc%d screen pwrlist nulln", + __func__, dev_drv->id); + return 0; + } + if (list_empty(dev_drv->cur_screen->pwrlist_head)) + return 0; +#endif + +#ifndef CONFIG_SMART_DUAL_LCD + list_for_each(pos, &dev_drv->pwrlist_head) +#else + list_for_each(pos, dev_drv->cur_screen->pwrlist_head) +#endif + { pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, list); pwr_ctr = &pwr_ctr_list->pwr_ctr; @@ -478,7 +579,7 @@ int rk_disp_pwr_disable(struct rk_lcdc_driver *dev_drv) } return 0; } - + int rk_fb_video_mode_from_timing(const struct display_timing *dt, struct rk_screen *screen) { @@ -533,7 +634,11 @@ int rk_fb_prase_timing_dt(struct device_node *np, struct rk_screen *screen) pr_err("parse display timing errn"); return -EINVAL; } +#ifndef CONFIG_SMART_DUAL_LCD dt = display_timings_get(disp_timing, disp_timing->native_mode); +#else + dt = display_timings_get(disp_timing, screen->native_mode); +#endif rk_fb_video_mode_from_timing(dt, screen); return 0; @@ -792,6 +897,7 @@ u64 rk_fb_get_prmry_screen_framedone_t(void) int rk_fb_set_prmry_screen_status(int status) { struct rk_lcdc_driver *dev_drv = rk_get_prmry_lcdc_drv(); + struct rk_screen *screen; if (unlikely(!dev_drv)) @@ -1657,8 +1763,14 @@ static void rk_fb_update_win(struct rk_lcdc_driver *dev_drv, reg_win_data->reg_area_data.ion_handle; win->area.smem_start = reg_win_data->reg_area_data.smem_start; +#ifndef CONFIG_SMART_DUAL_LCD + if (inf->disp_mode == DUAL || + inf->disp_mode == NO_DUAL) { +#else if (inf->disp_mode == DUAL || + inf->disp_mode == DUAL_LCD || inf->disp_mode == NO_DUAL) { +#endif win->area.xpos = reg_win_data->reg_area_data.xpos; win->area.ypos = @@ -3884,7 +3996,12 @@ static int rk_fb_alloc_buffer(struct fb_info *fbi) win = dev_drv->win[win_id]; if (!strcmp(fbi->fix.id, "fb0")) { +#ifndef CONFIG_SMART_DUAL_LCD fb_mem_size = get_fb_size(dev_drv->reserved_fb); +#else + fb_mem_size = get_fb_size(dev_drv->reserved_fb, dev_drv->cur_screen); +#endif + #if defined(CONFIG_ION_ROCKCHIP) if (rk_fb_alloc_buffer_by_ion(fbi, win, fb_mem_size) < 0) return -ENOMEM; @@ -3905,8 +4022,11 @@ static int rk_fb_alloc_buffer(struct fb_info *fbi) if (dev_drv->prop == EXTEND && dev_drv->iommu_enabled) { struct rk_lcdc_driver *dev_drv_prmry; int win_id_prmry; - +#ifndef CONFIG_SMART_DUAL_LCD fb_mem_size = get_fb_size(dev_drv->reserved_fb); +#else + fb_mem_size = get_fb_size(dev_drv->reserved_fb, dev_drv->cur_screen); +#endif #if defined(CONFIG_ION_ROCKCHIP) dev_drv_prmry = rk_get_prmry_lcdc_drv(); if (dev_drv_prmry == NULL) @@ -4071,6 +4191,7 @@ static int init_lcdc_device_driver(struct rk_fb *rk_fb, dev_drv->area_support = 1; if (dev_drv->ops->area_support_num) dev_drv->ops->area_support_num(dev_drv, dev_drv->area_support); +#ifndef CONFIG_SMART_DUAL_LCD rk_disp_pwr_ctr_parse_dt(dev_drv); if (dev_drv->prop == PRMRY) { rk_fb_set_prmry_screen(screen); @@ -4079,6 +4200,11 @@ static int init_lcdc_device_driver(struct rk_fb *rk_fb, dev_drv->trsm_ops = rk_fb_trsm_ops_get(screen->type); if (dev_drv->prop != PRMRY) rk_fb_get_extern_screen(screen); +#else + rk_fb_set_screen(screen, dev_drv->prop); + rk_fb_get_screen(screen, dev_drv->prop); + dev_drv->trsm_ops = rk_fb_trsm_ops_get(dev_drv->prop); +#endif dev_drv->output_color = screen->color_mode; return 0; @@ -4416,16 +4542,32 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv, main_fbi->fbops->fb_pan_display(&main_fbi->var, main_fbi); #endif } else { + struct fb_info *extend_fbi = rk_fb->fb[dev_drv->fb_index_base]; extend_fbi->var.pixclock = rk_fb->fb[0]->var.pixclock; +#ifdef CONFIG_SMART_DUAL_LCD + extend_fbi->var.xres_virtual = rk_fb->fb[0]->var.xres_virtual; + extend_fbi->var.yres_virtual = rk_fb->fb[0]->var.yres_virtual; +#endif 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); +#ifdef CONFIG_SMART_DUAL_LCD + if (dev_drv->ops->mmu_en) + dev_drv->ops->mmu_en(dev_drv); +#endif } + rk_fb_alloc_buffer(extend_fbi); +#ifdef CONFIG_SMART_DUAL_LCD + if (rk_fb->disp_mode == DUAL_LCD) { + extend_fbi->fbops->fb_set_par(extend_fbi); + extend_fbi->fbops->fb_pan_display(&extend_fbi->var, extend_fbi); + } +#endif } #endif return 0; diff --git a/drivers/video/rockchip/screen/rk_screen.c b/drivers/video/rockchip/screen/rk_screen.c index 11ff587..23e5fbe 100755 --- a/drivers/video/rockchip/screen/rk_screen.c +++ b/drivers/video/rockchip/screen/rk_screen.c @@ -4,14 +4,33 @@ #include "lcd.h" #include "../hdmi/rockchip-hdmi.h" +#ifndef CONFIG_SMART_DUAL_LCD static struct rk_screen *rk_screen; +#else +static struct rk_screen *prmry_screen; +static struct rk_screen *extend_screen; + +static void rk_screen_info_error(struct rk_screen *screen, int prop) +{ + pr_err(">>>>>>>>>>>>>>>>>>>>error<<<<<<<<<<<<<<<<<<< + pr_err(">>>>>>>>>>>>>>>>>>>>error<<<<<<<<<<<<<<<<<<< +#endif int rk_fb_get_extern_screen(struct rk_screen *screen) { +#ifndef CONFIG_SMART_DUAL_LCD if (unlikely(!rk_screen) || unlikely(!screen)) return -1; - memcpy(screen, rk_screen, sizeof(struct rk_screen)); +#else + if (unlikely(!extend_screen) || unlikely(!screen)) + return -1; + memcpy(screen, extend_screen, sizeof(struct rk_screen)); +#endif + screen->dsp_lut = NULL; screen->cabc_lut = NULL; screen->type = SCREEN_NULL; @@ -21,13 +40,21 @@ int rk_fb_get_extern_screen(struct rk_screen *screen) int rk_fb_get_prmry_screen(struct rk_screen *screen) { +#ifndef CONFIG_SMART_DUAL_LCD if (unlikely(!rk_screen) || unlikely(!screen)) return -1; memcpy(screen, rk_screen, sizeof(struct rk_screen)); +#else + if (unlikely(!prmry_screen) || unlikely(!screen)) + return -1; + memcpy(screen, prmry_screen, sizeof(struct rk_screen)); + +#endif return 0; } +#ifndef CONFIG_SMART_DUAL_LCD int rk_fb_set_prmry_screen(struct rk_screen *screen) { if (unlikely(!rk_screen) || unlikely(!screen)) @@ -43,19 +70,87 @@ int rk_fb_set_prmry_screen(struct rk_screen *screen) rk_screen->overscan.bottom = screen->overscan.left; return 0; } +#else +int rk_fb_get_screen(struct rk_screen *screen, int prop) +{ + struct rk_screen *cur_screen = NULL; + + if (unlikely(!screen)) + return -1; + if (prop == PRMRY) { + if (unlikely(!prmry_screen)) { + rk_screen_info_error(screen, prop); + return -1; + } + cur_screen = prmry_screen; + } else { + if (unlikely(!extend_screen)) { + rk_screen_info_error(screen, prop); + return -1; + } + cur_screen = extend_screen; + } + + memcpy(screen, cur_screen, sizeof(struct rk_screen)); + + return 0; + +} +int rk_fb_set_screen(struct rk_screen *screen, int prop) +{ + struct rk_screen *cur_screen = NULL; + if (unlikely(!screen)) + return -1; + if (prop == PRMRY) { + if (unlikely(!prmry_screen)) { + rk_screen_info_error(screen, prop); + return -1; + } + cur_screen = prmry_screen; + } else { + if (unlikely(!extend_screen)) { + rk_screen_info_error(screen, prop); + return -1; + } + cur_screen = extend_screen; + } + + cur_screen->lcdc_id = screen->lcdc_id; + cur_screen->screen_id = screen->screen_id; + cur_screen->x_mirror = screen->x_mirror; + cur_screen->y_mirror = screen->y_mirror; + cur_screen->overscan.left = screen->overscan.left; + cur_screen->overscan.top = screen->overscan.left; + cur_screen->overscan.right = screen->overscan.left; + cur_screen->overscan.bottom = screen->overscan.left; + + return 0; +} + +#endif + +#ifndef CONFIG_SMART_DUAL_LCD size_t get_fb_size(u8 reserved_fb) +#else +size_t get_fb_size(u8 reserved_fb, struct rk_screen *screen) +#endif { size_t size = 0; u32 xres = 0; u32 yres = 0; +#ifndef CONFIG_SMART_DUAL_LCD if (unlikely(!rk_screen)) return 0; - xres = rk_screen->mode.xres; yres = rk_screen->mode.yres; - +#else + if (unlikely(!screen)) + return 0; + xres = screen->mode.xres; + yres = screen->mode.yres; +#endif /* align as 64 bytes(16*4) in an odd number of times */ xres = ALIGN_64BYTE_ODD_TIMES(xres, ALIGN_PIXEL_64BYTE_RGB8888); if (reserved_fb == ONE_FB_BUFFER) @@ -75,12 +170,19 @@ size_t get_fb_size(u8 reserved_fb) static int rk_screen_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - int ret; +#ifndef CONFIG_SMART_DUAL_LCD + int ret; +#else + struct device_node *screen_np; + struct rk_screen *rk_screen; + int ret, screen_prop; +#endif if (!np) { dev_err(&pdev->dev, "Missing device tree node.n"); return -EINVAL; } +#ifndef CONFIG_SMART_DUAL_LCD rk_screen = devm_kzalloc(&pdev->dev, sizeof(struct rk_screen), GFP_KERNEL); if (!rk_screen) { @@ -90,7 +192,44 @@ static int rk_screen_probe(struct platform_device *pdev) ret = rk_fb_prase_timing_dt(np, rk_screen); dev_info(&pdev->dev, "rockchip screen probe %sn", ret ? "failed" : "success"); - return ret; + return ret; +#else + for_each_child_of_node(np, screen_np) { + rk_screen = devm_kzalloc(&pdev->dev, + sizeof(struct rk_screen), GFP_KERNEL); + if (!rk_screen) { + dev_err(&pdev->dev, "kmalloc for rk screen fail!"); + return -ENOMEM; + } + rk_screen->pwrlist_head = devm_kzalloc(&pdev->dev, + sizeof(struct list_head), GFP_KERNEL); + if (!rk_screen->pwrlist_head) { + dev_err(&pdev->dev, "kmalloc for rk_screen pwrlist_head fail!"); + return -ENOMEM; + } + of_property_read_u32(screen_np, "screen_prop", &screen_prop); + if (screen_prop == PRMRY) + prmry_screen = rk_screen; + else if (screen_prop == EXTEND) + extend_screen = rk_screen; + else + dev_err(&pdev->dev, "unknow screen prop: %dn", + screen_prop); + rk_screen->prop = screen_prop; + of_property_read_u32(screen_np, "native-mode", &rk_screen->native_mode); + rk_screen->dev = &pdev->dev; + ret = rk_fb_prase_timing_dt(screen_np, rk_screen); + pr_info("%s screen timing parse %sn", + (screen_prop == PRMRY) ? "prmry" : "extend", + ret ? "failed" : "success"); + ret = rk_disp_pwr_ctr_parse_dt(screen_np, rk_screen); + pr_info("%s screen power ctrl parse %sn", + (screen_prop == PRMRY) ? "prmry" : "extend", + ret ? "failed" : "success"); + } + dev_info(&pdev->dev, "rockchip screen probe successn"); + return 0; +#endif } static const struct of_device_id rk_screen_dt_ids[] = { diff --git a/drivers/video/rockchip/transmitter/rk32_dp.c b/drivers/video/rockchip/transmitter/rk32_dp.c index 2b3457c..976dc8a 100755 --- a/drivers/video/rockchip/transmitter/rk32_dp.c +++ b/drivers/video/rockchip/transmitter/rk32_dp.c @@ -119,8 +119,11 @@ static int rk32_edp_init_edp(struct rk32_edp *edp) struct rk_screen *screen = &edp->screen; u32 val = 0; +#ifndef CONFIG_SMART_DUAL_LCD rk_fb_get_prmry_screen(screen); - +#else + rk_fb_get_screen(screen, edp->prop); +#endif if (cpu_is_rk3288()) { if (screen->lcdc_id == 1) /*select lcdc*/ val = EDP_SEL_VOP_LIT | (EDP_SEL_VOP_LIT << 16); @@ -1712,17 +1715,25 @@ static int rk32_edp_probe(struct platform_device *pdev) struct resource *res; struct device_node *np = pdev->dev.of_node; int ret; - +#ifdef CONFIG_SMART_DUAL_LCD + int prop; +#endif if (!np) { dev_err(&pdev->dev, "Missing device tree node.n"); return -EINVAL; } - +#ifdef CONFIG_SMART_DUAL_LCD + of_property_read_u32(np, "prop", &prop); + pr_info("Use EDP as %s screenn", (prop == PRMRY) ? "primary" : "extend"); +#endif edp = devm_kzalloc(&pdev->dev, sizeof(struct rk32_edp), GFP_KERNEL); if (!edp) { dev_err(&pdev->dev, "no memory for staten"); return -ENOMEM; } +#ifdef CONFIG_SMART_DUAL_LCD + edp->prop = prop; +#endif edp->dev = &pdev->dev; edp->video_info.h_sync_polarity = 0; edp->video_info.v_sync_polarity = 0; @@ -1734,7 +1745,11 @@ static int rk32_edp_probe(struct platform_device *pdev) edp->video_info.link_rate = LINK_RATE_1_62GBPS; edp->video_info.lane_count = LANE_CNT4; +#ifndef CONFIG_SMART_DUAL_LCD rk_fb_get_prmry_screen(&edp->screen); +#else + rk_fb_get_screen(&edp->screen, prop); +#endif if (edp->screen.type != SCREEN_EDP) { dev_err(&pdev->dev, "screen is not edp!n"); return -EINVAL; @@ -1809,7 +1824,11 @@ static int rk32_edp_probe(struct platform_device *pdev) if (!support_uboot_display()) rk32_edp_clk_disable(edp); rk32_edp = edp; +#ifndef CONFIG_SMART_DUAL_LCD rk_fb_trsm_ops_register(&trsm_edp_ops, SCREEN_EDP); +#else + rk_fb_trsm_ops_register(&trsm_edp_ops, prop); +#endif #if defined(CONFIG_DEBUG_FS) edp->debugfs_dir = debugfs_create_dir("edp", NULL); if (IS_ERR(edp->debugfs_dir)) { diff --git a/drivers/video/rockchip/transmitter/rk32_dp.h b/drivers/video/rockchip/transmitter/rk32_dp.h index 08347b5..f58d266 100755 --- a/drivers/video/rockchip/transmitter/rk32_dp.h +++ b/drivers/video/rockchip/transmitter/rk32_dp.h @@ -566,6 +566,9 @@ struct rk32_edp { bool clk_on; bool edp_en; struct dentry *debugfs_dir; +#ifdef CONFIG_SMART_DUAL_LCD + int prop; +#endif }; diff --git a/drivers/video/rockchip/transmitter/rk32_lvds.c b/drivers/video/rockchip/transmitter/rk32_lvds.c index 3e8394f..df46f46 100755 --- a/drivers/video/rockchip/transmitter/rk32_lvds.c +++ b/drivers/video/rockchip/transmitter/rk32_lvds.c @@ -59,8 +59,11 @@ static int rk32_lvds_en(void) u32 h_bp = 0; u32 val = 0; +#ifndef CONFIG_SMART_DUAL_LCD rk_fb_get_prmry_screen(screen); - +#else + rk_fb_get_screen(screen, lvds->prop); +#endif /* enable clk */ rk32_lvds_clk_enable(lvds); @@ -141,18 +144,29 @@ static int rk32_lvds_probe(struct platform_device *pdev) struct resource *res; struct device_node *np = pdev->dev.of_node; +#ifdef CONFIG_SMART_DUAL_LCD + int prop; +#endif + if (!np) { dev_err(&pdev->dev, "Missing device tree node.n"); return -EINVAL; } - +#ifdef CONFIG_SMART_DUAL_LCD + of_property_read_u32(np, "prop", &prop); + pr_info("Use LVDS as %s screenn", (prop == PRMRY) ? "prmry":"extend"); +#endif lvds = devm_kzalloc(&pdev->dev, sizeof(struct rk32_lvds), GFP_KERNEL); if (!lvds) { dev_err(&pdev->dev, "no memory for staten"); return -ENOMEM; } lvds->dev = &pdev->dev; +#ifndef CONFIG_SMART_DUAL_LCD rk_fb_get_prmry_screen(&lvds->screen); +#else + rk_fb_get_screen(&lvds->screen, prop); +#endif if ((lvds->screen.type != SCREEN_RGB) && (lvds->screen.type != SCREEN_LVDS) && (lvds->screen.type != SCREEN_DUAL_LVDS) && @@ -185,7 +199,12 @@ static int rk32_lvds_probe(struct platform_device *pdev) } rk32_lvds = lvds; +#ifndef CONFIG_SMART_DUAL_LCD rk_fb_trsm_ops_register(&trsm_lvds_ops,SCREEN_LVDS); +#else + lvds->prop = prop; + rk_fb_trsm_ops_register(&trsm_lvds_ops, prop); +#endif dev_info(&pdev->dev, "rk32 lvds driver probe successn"); return 0; diff --git a/drivers/video/rockchip/transmitter/rk32_lvds.h b/drivers/video/rockchip/transmitter/rk32_lvds.h index ca424a7..9a1d1a0 100755 --- a/drivers/video/rockchip/transmitter/rk32_lvds.h +++ b/drivers/video/rockchip/transmitter/rk32_lvds.h @@ -34,6 +34,9 @@ struct rk32_lvds { struct clk *pd; struct rk_screen screen; bool clk_on; +#ifdef CONFIG_SMART_DUAL_LCD + int prop; +#endif }; static int inline lvds_writel(struct rk32_lvds *lvds, u32 offset, u32 val) diff --git a/include/dt-bindings/rkfb/rk_fb.h b/include/dt-bindings/rkfb/rk_fb.h index 6d75770..e4e909b 100755 --- a/include/dt-bindings/rkfb/rk_fb.h +++ b/include/dt-bindings/rkfb/rk_fb.h @@ -12,6 +12,10 @@ #define NO_DUAL 0 #define ONE_DUAL 1 #define DUAL 2 + +#define DUAL_LCD 3 +#define DEFAULT_MODE 0 + /******************************************************************** ** display output interface supported by rockchip ** ********************************************************************/ diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 62647a9..b8eb90f 100755 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -808,11 +808,25 @@ extern int rk_fb_register(struct rk_lcdc_driver *dev_drv, struct rk_lcdc_win *win, int id); extern int rk_fb_unregister(struct rk_lcdc_driver *dev_drv); extern struct rk_lcdc_driver *rk_get_lcdc_drv(char *name); +#ifndef CONFIG_SMART_DUAL_LCD extern int rk_fb_get_extern_screen(struct rk_screen *screen); +#endif extern int rk_fb_get_prmry_screen( struct rk_screen *screen); +#ifndef CONFIG_SMART_DUAL_LCD extern int rk_fb_set_prmry_screen(struct rk_screen *screen); +#endif + +#ifdef CONFIG_SMART_DUAL_LCD +extern int rk_fb_get_screen(struct rk_screen *screen, int prop); +extern int rk_fb_set_screen(struct rk_screen *screen, int prop); +#endif + extern u32 rk_fb_get_prmry_screen_pixclock(void); +#ifndef CONFIG_SMART_DUAL_LCD extern int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv); +#else +extern int rk_disp_pwr_ctr_parse_dt(struct device_node *np, struct rk_screen *rk_screen); +#endif extern int rk_disp_pwr_enable(struct rk_lcdc_driver *dev_drv); extern int rk_disp_pwr_disable(struct rk_lcdc_driver *dev_drv); extern bool is_prmry_rk_lcdc_registered(void); @@ -839,4 +853,5 @@ int rk_fb_pixel_width(int data_format); void trace_buffer_dump(struct device *dev, struct rk_lcdc_driver *dev_drv); extern int rockchip_get_screen_type(void); + #endif diff --git a/include/linux/rk_screen.h b/include/linux/rk_screen.h index af0ffe7..5419623 100644 --- a/include/linux/rk_screen.h +++ b/include/linux/rk_screen.h @@ -61,6 +61,13 @@ struct overscan { *ft: the time need to display one frame time */ struct rk_screen { +#ifdef CONFIG_SMART_DUAL_LCD + struct device *dev; + int prop; + struct list_head *pwrlist_head; + int native_mode; +#endif + u16 type; u16 lvds_format; u16 face; @@ -144,8 +151,12 @@ struct rk29fb_info { }; extern void set_lcd_info(struct rk_screen *screen, struct rk29lcd_info *lcd_info); +#ifndef CONFIG_SMART_DUAL_LCD extern size_t get_fb_size(u8 reserved_fb); - +#else +extern size_t get_fb_size(u8 reserved_fb, struct rk_screen *screen); +extern size_t get_rotate_fb_size(struct rk_screen *screen); +#endif extern void set_tv_info(struct rk_screen *screen); extern void set_hdmi_info(struct rk_screen *screen); |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
678 浏览 0 评论
920 浏览 1 评论
814 浏览 1 评论
2030 浏览 1 评论
3275 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 07:49 , Processed in 0.461436 second(s), Total 42, Slave 34 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号