CPU:RK3288 系统:Android 5.1
下面是官方文档中的信息。 1、rk3288 支持的显示接口可以任意组合。 2、双屏异显时,一个显示接口当主屏,另一个当副屏;主副屏由板级 dts 文件确定,启动后无法动态更改。 3、当两路显示接口显示不同分辨率时,rk3288 只能为一路显示接口提供精确时钟,另一路显示接口时钟会有微小频偏。
瑞芯微虽然提供了 Android 5.1 的补丁,但是本人在移植过程中出现一些问题(打补丁最好一行行核对,不要图方便直接使用指令)。 设备 eDP 为主屏,lvds 为副屏。
(1)首先修改两个屏参文件 lcd-xxx.dtsi。 eDP 屏参文件补丁 - diff --git a/kernel/arch/arm/boot/dts/lcd-NV116FH1.dtsi b/kernel/arch/arm/boot/dts/lcd-NV116FH1.dtsi
- index 3862b05..7bf992f 100755
- --- a/kernel/arch/arm/boot/dts/lcd-NV116FH1.dtsi
- +++ b/kernel/arch/arm/boot/dts/lcd-NV116FH1.dtsi
- @@ -3,11 +3,9 @@
- *
- */
-
- -/ {
- -
- - disp_timings: display-timings {
- - native-mode = <&timing0>;
- - timing0: timing0 {
- + display-timings {
- + native-mode = <&nv116fhm>;
- + nv116fhm: timing0 {
- screen-type = <SCREEN_EDP>;
- out-face = <OUT_P666>;
- clock-frequency = <205000000>;
- @@ -30,4 +30,3 @@
- swap-gb = <0>;
- };
- };
- -};
复制代码lvds 屏参文件补丁、 - diff --git a/kernel/arch/arm/boot/dts/lcd-ZJ080NA-08A.dtsi b/kernel/arch/arm/boot/dts/lcd-ZJ080NA-08A.dtsi
- old mode 100644
- new mode 100755
- index fc6385c..58f999be
- --- a/kernel/arch/arm/boot/dts/lcd-ZJ080NA-08A.dtsi
- +++ b/kernel/arch/arm/boot/dts/lcd-ZJ080NA-08A.dtsi
- @@ -3,11 +3,10 @@
- *
- */
-
- -/ {
-
- - disp_timings: display-timings {
- - native-mode = <&timing0>;
- - timing0: timing0 {
- + display-timings {
- + native-mode = <&zj080na>;
- + zj080na: timing0 {
- screen-type = <SCREEN_DUAL_LVDS>;
- lvds-format = <LVDS_8BIT_1>;
- out-face = <OUT_P888>;
- @@ -30,4 +30,3 @@
- swap-gb = <0>;
- };
- };
- -};
复制代码(2)根据官方提供,打上 kernel 补丁 - diff --git a/kernel/arch/arm/boot/dts/rk3288-tb_8846.dts b/kernel/arch/arm/boot/dts/rk3288-tb_8846.dts
- index 6a65163..fc48fc0 100755
- --- a/kernel/arch/arm/boot/dts/rk3288-tb_8846.dts
- +++ b/kernel/arch/arm/boot/dts/rk3288-tb_8846.dts
- @@ -565,12 +565,56 @@ clock-frequency = <50000000>;
- };
-
- &fb {
- - rockchip,disp-mode = <DUAL>;
- - rockchip,uboot-logo-on = <1>;
- + rockchip,disp-mode = <DUAL_LCD>;
- + rockchip,uboot-logo-on = <0>;
- };
-
- &rk_screen {
- - display-timings = <&disp_timings>;
- + status = "okay";
- + screen0 {
- + screen_prop = <PRMRY>;
- + native-mode = <DEFAULT_MODE>;
- + power_ctr {
- + lcd_en {
- + rockchip,power_type = <GPIO>;
- + gpios = <&gpio7 GPIO_A5 GPIO_ACTIVE_HIGH>;
- + rockchip,delay = <10>;
- + };
- + /*lcd_cs {
- + rockchip,power_type = <GPIO>;
- + gpios = <&gpio7 GPIO_A4 GPIO_ACTIVE_HIGH>;
- + rockchip,delay = <10>;
- + };*/
- + };
- + #include "lcd-NV156FH1.dtsi"
- + };
- + screen1 {
- + screen_prop = <EXTEND>;
- + native-mode = <DEFAULT_MODE>;
- + power_ctr {
- + lcd_en {
- + rockchip,power_type = <GPIO>;
- + gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>;
- + rockchip,delay = <10>;
- + };
- + /*lcd_cs {
- + rockchip,power_type = <GPIO>;
- + gpios = <&gpio7 GPIO_A4 GPIO_ACTIVE_HIGH>;
- + rockchip,delay = <10>;
- + };*/
- + };
- + #include "lcd-ZJ080NA-08A.dtsi"
- + };
- +};
- +
- +&edp {
- + status = "okay";
- + prop = <PRMRY>;
- +};
- +
- +&lvds {
- + status = "okay";
- + prop = <EXTEND>;
- };
-
- /*lcdc0 as PRMRY(LCD),lcdc1 as EXTEND(HDMI)*/
- @@ -587,18 +631,18 @@ clock-frequency = <50000000>;
- rockchip,delay = <5>;
- };*/
-
- - lcd_en:lcd_en {
- + /*lcd_en:lcd_en {
- rockchip,power_type = <GPIO>;
- gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>;
- rockchip,delay = <200>;
- };
-
- - /*lcd_cs:lcd_cs {
- + lcd_cs:lcd_cs {
- rockchip,power_type = <GPIO>;
- gpios = <&gpio7 GPIO_A4 GPIO_ACTIVE_HIGH>;
- rockchip,delay = <10>;
- - };*/
- -
- + };
- + */
- /*lcd_rst:lcd_rst {
- rockchip,power_type = <GPIO>;
- gpios = <&gpio3 GPIO_D6 GPIO_ACTIVE_HIGH>;
- @@ -615,7 +659,7 @@ clock-frequency = <50000000>;
- };
-
- &hdmi {
- - status = "okay";
- + status = "disabled";
- rockchip,hdmi_video_source = <DISPLAY_SOURCE_LCDC1>;
- };
-
- diff --git a/kernel/drivers/video/rockchip/rk_fb.c b/kernel/drivers/video/rockchip/rk_fb.c
- index 533ce2b..4037cfd 100755
- --- a/kernel/drivers/video/rockchip/rk_fb.c
- +++ b/kernel/drivers/video/rockchip/rk_fb.c
- @@ -112,9 +112,8 @@ 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;
- -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;
- +static struct rk_fb_trsm_ops *trsm_prmry_ops;
- +static struct rk_fb_trsm_ops *trsm_extend_ops;
- static int uboot_logo_on;
-
- static int rk_fb_debug_lvl;
- @@ -148,53 +147,24 @@ int rk_fb_get_display_policy(void)
-
- int rk_fb_trsm_ops_register(struct rk_fb_trsm_ops *ops, int type)
- {
- - switch (type) {
- - case SCREEN_RGB:
- - case SCREEN_LVDS:
- - case SCREEN_DUAL_LVDS:
- - case SCREEN_LVDS_10BIT:
- - case SCREEN_DUAL_LVDS_10BIT:
- - trsm_lvds_ops = ops;
- - break;
- - case SCREEN_EDP:
- - trsm_edp_ops = ops;
- - break;
- - case SCREEN_MIPI:
- - case SCREEN_DUAL_MIPI:
- - trsm_mipi_ops = ops;
- - break;
- - default:
- - printk(KERN_WARNING "%s:un supported transmitter:%d!\n",
- - __func__, type);
- - break;
- - }
- + if (type == PRMRY)
- + trsm_prmry_ops = ops;
- + else if (type == EXTEND)
- + trsm_extend_ops = ops;
- + else
- + pr_err("%s, type:%d\n", __func__, type);
- return 0;
- }
-
- struct rk_fb_trsm_ops *rk_fb_trsm_ops_get(int type)
- {
- struct rk_fb_trsm_ops *ops;
- - switch (type) {
- - case SCREEN_RGB:
- - case SCREEN_LVDS:
- - case SCREEN_DUAL_LVDS:
- - case SCREEN_LVDS_10BIT:
- - case SCREEN_DUAL_LVDS_10BIT:
- - ops = trsm_lvds_ops;
- - break;
- - case SCREEN_EDP:
- - ops = trsm_edp_ops;
- - break;
- - case SCREEN_MIPI:
- - case SCREEN_DUAL_MIPI:
- - ops = trsm_mipi_ops;
- - break;
- - default:
- - ops = NULL;
- - printk(KERN_WARNING "%s:un supported transmitter:%d!\n",
- - __func__, type);
- - break;
- - }
- + if (type == PRMRY)
- + ops = trsm_prmry_ops;
- + else if (type == EXTEND)
- + ops = trsm_extend_ops;
- + else
- + pr_err("%s, type:%d\n", __func__, type);
- return ops;
- }
-
- @@ -318,10 +288,10 @@ static int rk_fb_data_fmt(int data_format, int bits_per_pixel)
- /*
- * rk display power control parse from dts
- */
- -int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv)
- +int rk_disp_pwr_ctr_parse_dt(struct device_node *np,
- + struct rk_screen *rk_screen)
- {
- - struct device_node *root = of_get_child_by_name(dev_drv->dev->of_node,
- - "power_ctr");
- + struct device_node *root = of_get_child_by_name(np, "power_ctr");
- struct device_node *child;
- struct rk_disp_pwr_ctr_list *pwr_ctr;
- struct list_head *pos;
- @@ -330,10 +300,10 @@ int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv)
- u32 debug = 0;
- int ret;
-
- - INIT_LIST_HEAD(&dev_drv->pwrlist_head);
- + INIT_LIST_HEAD(rk_screen->pwrlist_head);
- if (!root) {
- - dev_err(dev_drv->dev, "can't find power_ctr node for lcdc%d\n",
- - dev_drv->id);
- + dev_err(rk_screen->dev, "can't find power_ctr node for lcdc%d\n",
- + rk_screen->lcdc_id);
- return -ENODEV;
- }
-
- @@ -346,7 +316,7 @@ 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)) {
- - dev_err(dev_drv->dev, "%s ivalid gpio\n",
- + dev_err(rk_screen->dev, "%s ivalid gpio\n",
- child->name);
- return -EINVAL;
- }
- @@ -354,7 +324,7 @@ int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv)
- ret = gpio_request(pwr_ctr->pwr_ctr.gpio,
- child->name);
- if (ret) {
- - dev_err(dev_drv->dev,
- + dev_err(rk_screen->dev,
- "request %s gpio fail:%d\n",
- child->name, ret);
- }
- @@ -365,7 +335,7 @@ 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))
- - dev_err(dev_drv->dev, "get regulator name failed!\n");
- + dev_err(rk_screen->dev, "get regulator name failed!\n");
- if (!of_property_read_u32(child, "rockchip,regulator_voltage", &val))
- pwr_ctr->pwr_ctr.volt = val;
- else
- @@ -377,13 +347,13 @@ 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;
- - list_add_tail(&pwr_ctr->list, &dev_drv->pwrlist_head);
- + list_add_tail(&pwr_ctr->list, rk_screen->pwrlist_head);
- }
-
- of_property_read_u32(root, "rockchip,debug", &debug);
-
- if (debug) {
- - list_for_each(pos, &dev_drv->pwrlist_head) {
- + list_for_each(pos, rk_screen->pwrlist_head) {
- pwr_ctr = list_entry(pos, struct rk_disp_pwr_ctr_list,
- list);
- printk(KERN_INFO "pwr_ctr_name:%s\n"
- @@ -411,9 +381,14 @@ int rk_disp_pwr_enable(struct rk_lcdc_driver *dev_drv)
- struct regulator *regulator_lcd = NULL;
- int count = 10;
-
- - if (list_empty(&dev_drv->pwrlist_head))
- + if (!dev_drv->cur_screen->pwrlist_head) {
- + pr_info("error: %s, lcdc%d screen pwrlist null\n",
- + __func__, dev_drv->id);
- + return 0;
- + }
- + if (list_empty(dev_drv->cur_screen->pwrlist_head))
- return 0;
- - list_for_each(pos, &dev_drv->pwrlist_head) {
- + list_for_each(pos, dev_drv->cur_screen->pwrlist_head) {
- pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list,
- list);
- pwr_ctr = &pwr_ctr_list->pwr_ctr;
- @@ -455,9 +430,14 @@ int rk_disp_pwr_disable(struct rk_lcdc_driver *dev_drv)
- struct regulator *regulator_lcd = NULL;
- int count = 10;
-
- - if (list_empty(&dev_drv->pwrlist_head))
- + if (!dev_drv->cur_screen->pwrlist_head) {
- + pr_info("error: %s, lcdc%d screen pwrlist null\n",
- + __func__, dev_drv->id);
- return 0;
- - list_for_each(pos, &dev_drv->pwrlist_head) {
- + }
- + if (list_empty(dev_drv->cur_screen->pwrlist_head))
- + return 0;
- + list_for_each(pos, dev_drv->cur_screen->pwrlist_head) {
- pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list,
- list);
- pwr_ctr = &pwr_ctr_list->pwr_ctr;
- @@ -586,7 +566,7 @@ int rk_fb_prase_timing_dt(struct device_node *np, struct rk_screen *screen)
- pr_err("parse display timing err\n");
- return -EINVAL;
- }
- - dt = display_timings_get(disp_timing, disp_timing->native_mode);
- + dt = display_timings_get(disp_timing, screen->native_mode);
- rk_fb_video_mode_from_timing(dt, screen);
- return 0;
-
- @@ -1676,6 +1656,7 @@ static void rk_fb_update_win(struct rk_lcdc_driver *dev_drv,
- 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;
- @@ -3852,7 +3833,8 @@ static int rk_fb_alloc_buffer(struct fb_info *fbi)
- win = dev_drv->win[win_id];
-
- if (!strcmp(fbi->fix.id, "fb0")) {
- - fb_mem_size = get_fb_size(dev_drv->reserved_fb);
- + fb_mem_size = get_fb_size(dev_drv->reserved_fb,
- + dev_drv->cur_screen);
- #if defined(CONFIG_ION_ROCKCHIP)
- if (rk_fb_alloc_buffer_by_ion(fbi, win, fb_mem_size) < 0)
- return -ENOMEM;
- @@ -3873,7 +3855,8 @@ 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;
- - fb_mem_size = get_fb_size(dev_drv->reserved_fb);
- + fb_mem_size = get_fb_size(dev_drv->reserved_fb,
- + dev_drv->cur_screen);
- #if defined(CONFIG_ION_ROCKCHIP)
- dev_drv_prmry = rk_get_prmry_lcdc_drv();
- if (dev_drv_prmry == NULL)
- @@ -4036,14 +4019,9 @@ static int init_lcdc_device_driver(struct rk_fb *rk_fb,
- dev_drv->area_support[i] = 1;
- if (dev_drv->ops->area_support_num)
- dev_drv->ops->area_support_num(dev_drv, dev_drv->area_support);
- - rk_disp_pwr_ctr_parse_dt(dev_drv);
- - if (dev_drv->prop == PRMRY) {
- - rk_fb_set_prmry_screen(screen);
- - rk_fb_get_prmry_screen(screen);
- - }
- - dev_drv->trsm_ops = rk_fb_trsm_ops_get(screen->type);
- - if (dev_drv->prop != PRMRY)
- - rk_fb_get_extern_screen(screen);
- + 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);
- dev_drv->output_color = screen->color_mode;
-
- return 0;
- @@ -4361,17 +4339,24 @@ 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[rk_fb->num_fb >> 1];
- - extend_fbi->var.pixclock = rk_fb->fb[0]->var.pixclock;
- + struct fb_info *extend_fbi = rk_fb->fb[rk_fb->num_fb >> 1];
- + extend_fbi->var.pixclock = rk_fb->fb[0]->var.pixclock;
- + extend_fbi->var.xres_virtual = rk_fb->fb[0]->var.xres_virtual;
- + extend_fbi->var.yres_virtual = rk_fb->fb[0]->var.yres_virtual;
- extend_fbi->fbops->fb_open(extend_fbi, 1);
- -#if defined(CONFIG_ROCKCHIP_IOMMU)
- if (dev_drv->iommu_enabled) {
- if (dev_drv->mmu_dev)
- rockchip_iovmm_set_fault_handler(dev_drv->dev,
- rk_fb_sysmmu_fault_handler);
- + if (dev_drv->ops->mmu_en)
- + dev_drv->ops->mmu_en(dev_drv);
- }
- -#endif
- rk_fb_alloc_buffer(extend_fbi);
- + 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
- return 0;
- diff --git a/kernel/drivers/video/rockchip/screen/rk_screen.c b/kernel/drivers/video/rockchip/screen/rk_screen.c
- index d5e3b15..87a82d9 100755
- --- a/kernel/drivers/video/rockchip/screen/rk_screen.c
- +++ b/kernel/drivers/video/rockchip/screen/rk_screen.c
- @@ -4,14 +4,23 @@
- #include "lcd.h"
- #include "../hdmi/rockchip-hdmi.h"
-
- -static struct rk_screen *rk_screen;
- +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<<<<<<<<<<<<<<<<<<<<\n");
- + pr_err(">>please init %s screen info in dtsi file<<\n",
- + (prop == PRMRY) ? "prmry" : "extend");
- + pr_err(">>>>>>>>>>>>>>>>>>>>error<<<<<<<<<<<<<<<<<<<<\n");
- +}
-
- int rk_fb_get_extern_screen(struct rk_screen *screen)
- {
- - if (unlikely(!rk_screen) || unlikely(!screen))
- + if (unlikely(!extend_screen) || unlikely(!screen))
- return -1;
-
- - memcpy(screen, rk_screen, sizeof(struct rk_screen));
- + memcpy(screen, extend_screen, sizeof(struct rk_screen));
- screen->dsp_lut = NULL;
- screen->cabc_lut = NULL;
- screen->type = SCREEN_NULL;
- @@ -19,42 +28,84 @@ int rk_fb_get_extern_screen(struct rk_screen *screen)
- return 0;
- }
-
- -int rk_fb_get_prmry_screen(struct rk_screen *screen)
- +int rk_fb_get_prmry_screen(struct rk_screen *screen)
- {
- - if (unlikely(!rk_screen) || unlikely(!screen))
- + if (unlikely(!prmry_screen) || unlikely(!screen))
- return -1;
-
- - memcpy(screen, rk_screen, sizeof(struct rk_screen));
- + memcpy(screen, prmry_screen, sizeof(struct rk_screen));
- return 0;
- }
-
- -int rk_fb_set_prmry_screen(struct rk_screen *screen)
- +int rk_fb_get_screen(struct rk_screen *screen, int prop)
- {
- - if (unlikely(!rk_screen) || unlikely(!screen))
- + struct rk_screen *cur_screen = NULL;
- +
- + if (unlikely(!screen))
- return -1;
-
- - rk_screen->lcdc_id = screen->lcdc_id;
- - rk_screen->screen_id = screen->screen_id;
- - rk_screen->x_mirror = screen->x_mirror;
- - rk_screen->y_mirror = screen->y_mirror;
- - rk_screen->overscan.left = screen->overscan.left;
- - rk_screen->overscan.top = screen->overscan.left;
- - rk_screen->overscan.right = screen->overscan.left;
- - rk_screen->overscan.bottom = screen->overscan.left;
- + 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;
- }
-
- -size_t get_fb_size(u8 reserved_fb)
- +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;
- +}
- +
- +size_t get_fb_size(u8 reserved_fb, struct rk_screen *screen)
- {
- size_t size = 0;
- u32 xres = 0;
- u32 yres = 0;
-
- - if (unlikely(!rk_screen))
- + if (unlikely(!screen))
- return 0;
-
- - xres = rk_screen->mode.xres;
- - yres = rk_screen->mode.yres;
- + xres = screen->mode.xres;
- + yres = screen->mode.yres;
-
- /* align as 64 bytes(16*4) in an odd number of times */
- xres = ALIGN_64BYTE_ODD_TIMES(xres, ALIGN_PIXEL_64BYTE_RGB8888);
- @@ -73,22 +124,51 @@ 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;
- + struct device_node *screen_np;
- + struct rk_screen *rk_screen;
- + int ret, screen_prop;
-
- if (!np) {
- dev_err(&pdev->dev, "Missing device tree node.\n");
- return -EINVAL;
- }
- - 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;
- +
- + 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: %d\n",
- + 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 %s\n",
- + (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 %s\n",
- + (screen_prop == PRMRY) ? "prmry" : "extend",
- + ret ? "failed" : "success");
- }
- - ret = rk_fb_prase_timing_dt(np, rk_screen);
- - dev_info(&pdev->dev, "rockchip screen probe %s\n",
- - ret ? "failed" : "success");
- - return ret;
- +
- + dev_info(&pdev->dev, "rockchip screen probe success\n");
- + return 0;
- }
-
- static const struct of_device_id rk_screen_dt_ids[] = {
- diff --git a/kernel/drivers/video/rockchip/transmitter/rk32_dp.c b/kernel/drivers/video/rockchip/transmitter/rk32_dp.c
- index 2b3457c..624089e 100755
- --- a/kernel/drivers/video/rockchip/transmitter/rk32_dp.c
- +++ b/kernel/drivers/video/rockchip/transmitter/rk32_dp.c
- @@ -119,7 +119,7 @@ static int rk32_edp_init_edp(struct rk32_edp *edp)
- struct rk_screen *screen = &edp->screen;
- u32 val = 0;
-
- - rk_fb_get_prmry_screen(screen);
- + rk_fb_get_screen(screen, edp->prop);
-
- if (cpu_is_rk3288()) {
- if (screen->lcdc_id == 1) /*select lcdc*/
- @@ -1712,17 +1712,21 @@ static int rk32_edp_probe(struct platform_device *pdev)
- struct resource *res;
- struct device_node *np = pdev->dev.of_node;
- int ret;
- + int prop;
-
- if (!np) {
- dev_err(&pdev->dev, "Missing device tree node.\n");
- return -EINVAL;
- }
- + of_property_read_u32(np, "prop", &prop);
- + pr_info("Use EDP as %s screen\n", (prop == PRMRY) ? "prmry" : "extend");
-
- edp = devm_kzalloc(&pdev->dev, sizeof(struct rk32_edp), GFP_KERNEL);
- if (!edp) {
- dev_err(&pdev->dev, "no memory for state\n");
- return -ENOMEM;
- }
- + edp->prop = prop;
- edp->dev = &pdev->dev;
- edp->video_info.h_sync_polarity = 0;
- edp->video_info.v_sync_polarity = 0;
- @@ -1734,7 +1738,7 @@ 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;
- - rk_fb_get_prmry_screen(&edp->screen);
- + rk_fb_get_screen(&edp->screen, prop);
- if (edp->screen.type != SCREEN_EDP) {
- dev_err(&pdev->dev, "screen is not edp!\n");
- return -EINVAL;
- @@ -1809,7 +1813,7 @@ static int rk32_edp_probe(struct platform_device *pdev)
- if (!support_uboot_display())
- rk32_edp_clk_disable(edp);
- rk32_edp = edp;
- - rk_fb_trsm_ops_register(&trsm_edp_ops, SCREEN_EDP);
- + rk_fb_trsm_ops_register(&trsm_edp_ops, prop);
- #if defined(CONFIG_DEBUG_FS)
- edp->debugfs_dir = debugfs_create_dir("edp", NULL);
- if (IS_ERR(edp->debugfs_dir)) {
- diff --git a/kernel/drivers/video/rockchip/transmitter/rk32_dp.h b/kernel/drivers/video/rockchip/transmitter/rk32_dp.h
- index 08347b5..8ec3e26 100755
- --- a/kernel/drivers/video/rockchip/transmitter/rk32_dp.h
- +++ b/kernel/drivers/video/rockchip/transmitter/rk32_dp.h
- @@ -566,6 +566,7 @@ struct rk32_edp {
- bool clk_on;
- bool edp_en;
- struct dentry *debugfs_dir;
- + int prop;
- };
-
-
- diff --git a/kernel/drivers/video/rockchip/transmitter/rk32_lvds.c b/kernel/drivers/video/rockchip/transmitter/rk32_lvds.c
- index 692e33e..6180504 100755
- --- a/kernel/drivers/video/rockchip/transmitter/rk32_lvds.c
- +++ b/kernel/drivers/video/rockchip/transmitter/rk32_lvds.c
- @@ -78,7 +78,7 @@ static int rk32_lvds_en(void)
- u32 val = 0;
- u32 delay_times = 20;
-
- - rk_fb_get_prmry_screen(screen);
- + rk_fb_get_screen(screen, lvds->prop);
-
- /* enable clk */
- rk32_lvds_clk_enable(lvds);
- @@ -169,19 +169,22 @@ static int rk32_lvds_probe(struct platform_device *pdev)
- struct rk32_lvds *lvds;
- struct resource *res;
- struct device_node *np = pdev->dev.of_node;
- + int prop;
-
- if (!np) {
- dev_err(&pdev->dev, "Missing device tree node.\n");
- return -EINVAL;
- }
-
- + of_property_read_u32(np, "prop", &prop);
- + pr_info("Use LVDS as %s screen\n", (prop == PRMRY) ? "prmry":"extend");
- lvds = devm_kzalloc(&pdev->dev, sizeof(struct rk32_lvds), GFP_KERNEL);
- if (!lvds) {
- dev_err(&pdev->dev, "no memory for state\n");
- return -ENOMEM;
- }
- lvds->dev = &pdev->dev;
- - rk_fb_get_prmry_screen(&lvds->screen);
- + rk_fb_get_screen(&lvds->screen, prop);
- if ((lvds->screen.type != SCREEN_RGB) &&
- (lvds->screen.type != SCREEN_LVDS) &&
- (lvds->screen.type != SCREEN_DUAL_LVDS) &&
- @@ -214,7 +217,8 @@ static int rk32_lvds_probe(struct platform_device *pdev)
- }
-
- rk32_lvds = lvds;
- - rk_fb_trsm_ops_register(&trsm_lvds_ops,SCREEN_LVDS);
- + lvds->prop = prop;
- + rk_fb_trsm_ops_register(&trsm_lvds_ops, prop);
- dev_info(&pdev->dev, "rk32 lvds driver probe success\n");
-
- return 0;
- diff --git a/kernel/drivers/video/rockchip/transmitter/rk32_lvds.h b/kernel/drivers/video/rockchip/transmitter/rk32_lvds.h
- index 198311a..0a8dd45 100755
- --- a/kernel/drivers/video/rockchip/transmitter/rk32_lvds.h
- +++ b/kernel/drivers/video/rockchip/transmitter/rk32_lvds.h
- @@ -34,6 +34,7 @@ struct rk32_lvds {
- struct clk *pd;
- struct rk_screen screen;
- bool clk_on;
- + int prop;
- };
-
- static int inline lvds_writel(struct rk32_lvds *lvds, u32 offset, u32 val)
- diff --git a/kernel/include/dt-bindings/rkfb/rk_fb.h b/kernel/include/dt-bindings/rkfb/rk_fb.h
- index b903f92..05f908f 100755
- --- a/kernel/include/dt-bindings/rkfb/rk_fb.h
- +++ b/kernel/include/dt-bindings/rkfb/rk_fb.h
- @@ -12,6 +12,7 @@
- #define NO_DUAL 0
- #define ONE_DUAL 1
- #define DUAL 2
- +#define DUAL_LCD 3
-
- #define OUT_P888 0 //24bit screen,connect to lcdc D0~D23
- #define OUT_P666 1 //18bit screen,connect to lcdc D0~D17
- @@ -74,6 +75,13 @@
- #define DISPLAY_POLICY_BOX 1
- #define DISPLAY_POLICY_BOX_TEMP 2
-
- +#define DEFAULT_MODE 0
- +#define HDMI_720P 0
- +#define HDMI_1080P 1
- +#define HDMI_2160P 2
- +#define NTSC_CVBS 3
- +#define PAL_CVBS 4
- +
- /* lvds connect config
- *
- * LVDS_8BIT_1 LVDS_8BIT_2 LVDS_8BIT_3 LVDS_6BIT
- diff --git a/kernel/include/linux/rk_fb.h b/kernel/include/linux/rk_fb.h
- index e17c49c..21beff7 100755
- --- a/kernel/include/linux/rk_fb.h
- +++ b/kernel/include/linux/rk_fb.h
- @@ -713,11 +713,12 @@ 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);
- -extern int rk_fb_get_extern_screen(struct rk_screen *screen);
- extern int rk_fb_get_prmry_screen( struct rk_screen *screen);
- -extern int rk_fb_set_prmry_screen(struct rk_screen *screen);
- +extern int rk_fb_get_screen(struct rk_screen *screen, int prop);
- +extern int rk_fb_set_screen(struct rk_screen *screen, int prop);
- extern u32 rk_fb_get_prmry_screen_pixclock(void);
- -extern int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv);
- +extern int rk_disp_pwr_ctr_parse_dt(struct device_node *np,
- + struct rk_screen *rk_screen);
- 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);
- diff --git a/kernel/include/linux/rk_screen.h b/kernel/include/linux/rk_screen.h
- index af0ffe7..9e57081 100755
- --- a/kernel/include/linux/rk_screen.h
- +++ b/kernel/include/linux/rk_screen.h
- @@ -61,12 +61,16 @@ struct overscan {
- *ft: the time need to display one frame time
- */
- struct rk_screen {
- + struct device *dev;
- + int prop;
- + struct list_head *pwrlist_head;
- u16 type;
- u16 lvds_format;
- u16 face;
- u16 color_mode;
- u8 lcdc_id;
- u8 screen_id;
- + int native_mode;
- struct fb_videomode mode;
- u32 post_dsp_stx;
- u32 post_dsp_sty;
- @@ -144,7 +148,7 @@ struct rk29fb_info {
- };
-
- extern void set_lcd_info(struct rk_screen *screen, struct rk29lcd_info *lcd_info);
- -extern size_t get_fb_size(u8 reserved_fb);
- +extern size_t get_fb_size(u8 reserved_fb, struct rk_screen *screen);
-
- extern void set_tv_info(struct rk_screen *screen);
- extern void set_hdmi_info(struct rk_screen *screen);
复制代码 (3)根据官方提供,打上 hardware 补丁
- diff --git a/hardware/rockchip/hwcomposer/rk_hwcomposer.cpp b/hardware/rockchip/hwcomposer/rk_hwcomposer.cpp
- index 9f4d7ce..a12bfca 100755
- --- a/hardware/rockchip/hwcomposer/rk_hwcomposer.cpp
- +++ b/hardware/rockchip/hwcomposer/rk_hwcomposer.cpp
- @@ -62,6 +62,7 @@ static int hwc_device_close(struct hw_device_t * dev);
-
- int hwc_sprite_replace(hwcContext * Context, hwc_display_contents_1_t * list);
- void* hwc_control_3dmode_thread(void *arg);
- +int hwc_parse_screen_info(int *outX, int *outY);
-
- void* hotplug_try_register(void *arg);
- void hotplug_get_resolution(int* w,int* h);
- @@ -9428,6 +9429,10 @@ int hotplug_get_config(int flag){
- int outX = 0;
- int outY = 0;
- hotplug_parse_mode(&outX, &outY);
- + if (hwc_get_int_property("ro.htg.force", "0"))
- + hwc_parse_screen_info(&outX, &outY);
- + else
- + hotplug_parse_mode(&outX, &outY);
- info.xres = outX;
- info.yres = outY;
- info.yres_virtual = info.yres * 3;
- @@ -9723,6 +9728,29 @@ OnError:
-
- }
-
- +int hwc_parse_screen_info(int *outX, int *outY)
- +{
- + char buf[100];
- + int width = 0;
- + int height = 0;
- + int fdExternal = -1;
- + fdExternal = open("/sys/class/graphics/fb4/screen_info", O_RDONLY);
- + if(fdExternal < 0){
- + ALOGE("hotplug_get_config:open fb screen_info error,cvbsfd=%d",fdExternal);
- + return -errno;
- + }
- + if(read(fdExternal,buf,sizeof(buf)) < 0){
- + ALOGE("error reading fb screen_info: %s", strerror(errno));
- + return -1;
- + }
- + close(fdExternal);
- + sscanf(buf,"xres:%d yres:%d",&width,&height);
- + ALOGD("hotplug_get_config:width=%d,height=%d",width,height);
- + *outX = width;
- + *outY = height;
- + return 0;
- +}
- +
- int hotplug_parse_mode(int *outX, int *outY)
- {
- int fd = open("/sys/class/display/HDMI/mode", O_RDONLY);
- @@ -9894,7 +9922,12 @@ void *hotplug_try_register(void *arg)
- if(getHdmiMode() == 1){
- handle_hotplug_event(1, 6);
- ALOGI("hotplug_try_register at line = %d",__LINE__);
- - }else{
- + } else if (hwc_get_int_property("ro.htg.force", "0")) {
- + hotplug_free_dimbuffer();
- + hotplug_get_config(0);
- + handle_hotplug_event(1, 6);
- + ALOGI("hotplug_try_register at line = %d",__LINE__);
- + } else {
- #if (defined(RK3368_BOX) || defined(RK3288_BOX))
- #if RK3288_BOX
- if(context->mLcdcNum == 1){
复制代码(4)根据官方提供,打上 framework 补丁
- diff --git a/frameworks/base/api/current.txt b/frameworks/base/api/current.txt
- index c537823..c1cc9a6 100755
- --- a/frameworks/base/api/current.txt
- +++ b/frameworks/base/api/current.txt
- @@ -3332,7 +3332,9 @@ package android.app {
- method public boolean isImmersive();
- method public boolean isTaskRoot();
- method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
- - method public boolean moveTaskToBack(boolean);
- + method public void moveAppToDisplay(int);
- + method public void moveExtendDisplay();
- + method public boolean moveTaskToBack(boolean);
- method public boolean navigateUpTo(android.content.Intent);
- method public boolean navigateUpToFromChild(android.app.Activity, android.content.Intent);
- method public void onActionModeFinished(android.view.ActionMode);
- @@ -3474,7 +3476,8 @@ package android.app {
- method public void startSearch(java.lang.String, boolean, android.os.Bundle, boolean);
- method public void stopLockTask();
- method public deprecated void stopManagingCursor(android.database.Cursor);
- - method public void takeKeyEvents(boolean);
- + method public void syncDualDisplay();
- + method public void takeKeyEvents(boolean);
- method public void triggerSearch(java.lang.String, android.os.Bundle);
- method public void unregisterForContextMenu(android.view.View);
- field public static final int DEFAULT_KEYS_DIALER = 1; // 0x1
- @@ -7206,7 +7209,8 @@ package android.content {
- method public abstract deprecated void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
- method public abstract deprecated void sendStickyOrderedBroadcast(android.content.Intent, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- method public abstract deprecated void sendStickyOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- - method public abstract void setTheme(int);
- + method public abstract void setDualScreen(boolean);
- + method public abstract void setTheme(int);
- method public abstract deprecated void setWallpaper(android.graphics.Bitmap) throws java.io.IOException;
- method public abstract deprecated void setWallpaper(java.io.InputStream) throws java.io.IOException;
- method public abstract void startActivities(android.content.Intent[]);
- @@ -7371,7 +7375,8 @@ package android.content {
- method public void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
- method public void sendStickyOrderedBroadcast(android.content.Intent, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- method public void sendStickyOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- - method public void setTheme(int);
- + method public void setDualScreen(boolean);
- + method public void setTheme(int);
- method public void setWallpaper(android.graphics.Bitmap) throws java.io.IOException;
- method public void setWallpaper(java.io.InputStream) throws java.io.IOException;
- method public void startActivities(android.content.Intent[]);
- @@ -29564,7 +29569,8 @@ package android.test.mock {
- method public void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
- method public void sendStickyOrderedBroadcast(android.content.Intent, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- method public void sendStickyOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- - method public void setTheme(int);
- + method public void setDualScreen(boolean);
- + method public void setTheme(int);
- method public void setWallpaper(android.graphics.Bitmap) throws java.io.IOException;
- method public void setWallpaper(java.io.InputStream) throws java.io.IOException;
- method public void startActivities(android.content.Intent[]);
- @@ -34808,7 +34814,9 @@ package android.view {
- method public abstract boolean isFloating();
- method public abstract boolean isShortcutKey(int, android.view.KeyEvent);
- method public final void makeActive();
- - method protected abstract void onActive();
- + method public abstract void moveAppToDisplay(int);
- + method public abstract void moveExtendDisplay();
- + method protected abstract void onActive();
- method public abstract void onConfigurationChanged(android.content.res.Configuration);
- method public abstract void openPanel(int, android.view.KeyEvent);
- method public abstract android.view.View peekDecorView();
- @@ -34875,7 +34883,8 @@ package android.view {
- method public abstract boolean superDispatchKeyShortcutEvent(android.view.KeyEvent);
- method public abstract boolean superDispatchTouchEvent(android.view.MotionEvent);
- method public abstract boolean superDispatchTrackballEvent(android.view.MotionEvent);
- - method public abstract void takeInputQueue(android.view.InputQueue.Callback);
- + method public abstract void syncDualDisplay();
- + method public abstract void takeInputQueue(android.view.InputQueue.Callback);
- method public abstract void takeKeyEvents(boolean);
- method public abstract void takeSurface(android.view.SurfaceHolder.Callback2);
- method public abstract void togglePanel(int, android.view.KeyEvent);
- diff --git a/frameworks/base/api/system-current.txt b/frameworks/base/api/system-current.txt
- index ef86f85..0a1feda 100755
- --- a/frameworks/base/api/system-current.txt
- +++ b/frameworks/base/api/system-current.txt
- @@ -3414,7 +3414,9 @@ package android.app {
- method public boolean isTaskRoot();
- method public boolean isVoiceInteraction();
- method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
- - method public boolean moveTaskToBack(boolean);
- + method public void moveAppToDisplay(int);
- + method public void moveExtendDisplay();
- + method public boolean moveTaskToBack(boolean);
- method public boolean navigateUpTo(android.content.Intent);
- method public boolean navigateUpToFromChild(android.app.Activity, android.content.Intent);
- method public void onActionModeFinished(android.view.ActionMode);
- @@ -3557,7 +3559,8 @@ package android.app {
- method public void startSearch(java.lang.String, boolean, android.os.Bundle, boolean);
- method public void stopLockTask();
- method public deprecated void stopManagingCursor(android.database.Cursor);
- - method public void takeKeyEvents(boolean);
- + method public void syncDualDisplay();
- + method public void takeKeyEvents(boolean);
- method public void triggerSearch(java.lang.String, android.os.Bundle);
- method public void unregisterForContextMenu(android.view.View);
- field public static final int DEFAULT_KEYS_DIALER = 1; // 0x1
- @@ -7444,7 +7447,8 @@ package android.content {
- method public abstract deprecated void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
- method public abstract deprecated void sendStickyOrderedBroadcast(android.content.Intent, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- method public abstract deprecated void sendStickyOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- - method public abstract void setTheme(int);
- + method public abstract void setDualScreen(boolean);
- + method public abstract void setTheme(int);
- method public abstract deprecated void setWallpaper(android.graphics.Bitmap) throws java.io.IOException;
- method public abstract deprecated void setWallpaper(java.io.InputStream) throws java.io.IOException;
- method public abstract void startActivities(android.content.Intent[]);
- @@ -7615,7 +7619,8 @@ package android.content {
- method public void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
- method public void sendStickyOrderedBroadcast(android.content.Intent, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- method public void sendStickyOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- - method public void setTheme(int);
- + method public void setDualScreen(boolean);
- + method public void setTheme(int);
- method public void setWallpaper(android.graphics.Bitmap) throws java.io.IOException;
- method public void setWallpaper(java.io.InputStream) throws java.io.IOException;
- method public void startActivities(android.content.Intent[]);
- @@ -31798,7 +31803,8 @@ package android.test.mock {
- method public void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
- method public void sendStickyOrderedBroadcast(android.content.Intent, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- method public void sendStickyOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
- - method public void setTheme(int);
- + method public void setDualScreen(boolean);
- + method public void setTheme(int);
- method public void setWallpaper(android.graphics.Bitmap) throws java.io.IOException;
- method public void setWallpaper(java.io.InputStream) throws java.io.IOException;
- method public void startActivities(android.content.Intent[]);
- @@ -37042,6 +37048,8 @@ package android.view {
- method public abstract boolean isFloating();
- method public abstract boolean isShortcutKey(int, android.view.KeyEvent);
- method public final void makeActive();
- + method public abstract void moveAppToDisplay(int);
- + method public abstract void moveExtendDisplay();
- method protected abstract void onActive();
- method public abstract void onConfigurationChanged(android.content.res.Configuration);
- method public abstract void openPanel(int, android.view.KeyEvent);
- @@ -37110,6 +37118,7 @@ package android.view {
- method public abstract boolean superDispatchKeyShortcutEvent(android.view.KeyEvent);
- method public abstract boolean superDispatchTouchEvent(android.view.MotionEvent);
- method public abstract boolean superDispatchTrackballEvent(android.view.MotionEvent);
- + method public abstract void syncDualDisplay();
- method public abstract void takeInputQueue(android.view.InputQueue.Callback);
- method public abstract void takeKeyEvents(boolean);
- method public abstract void takeSurface(android.view.SurfaceHolder.Callback2);
- diff --git a/frameworks/base/core/java/android/app/Activity.java b/frameworks/base/core/java/android/app/Activity.java
- index ce65cf3..5159661 100755
- --- a/frameworks/base/core/java/android/app/Activity.java
- +++ b/frameworks/base/core/java/android/app/Activity.java
- @@ -6495,4 +6495,22 @@ public class Activity extends ContextThemeWrapper
- */
- public void onTranslucentConversionComplete(boolean drawComplete);
- }
- +
- + public void moveAppToDisplay(int id) {
- + if (mWindow != null) {
- + mWindow.moveAppToDisplay(id);
- + }
- + }
- +
- + public void syncDualDisplay() {
- + if (mWindow != null) {
- + mWindow.syncDualDisplay();
- + }
- + }
- +
- + public void moveExtendDisplay() {
- + if (mWindow != null) {
- + mWindow.moveExtendDisplay();
- + }
- + }
- }
- diff --git a/frameworks/base/core/java/android/app/ContextImpl.java b/frameworks/base/core/java/android/app/ContextImpl.java
- index 6c9c804..ebee424 100755
- --- a/frameworks/base/core/java/android/app/ContextImpl.java
- +++ b/frameworks/base/core/java/android/app/ContextImpl.java
- @@ -122,6 +122,7 @@ import android.os.SystemVibrator;
- import android.os.UserManager;
- import android.os.storage.IMountService;
- import android.os.storage.StorageManager;
- +import android.provider.Settings;
- import android.print.IPrintManager;
- import android.print.PrintManager;
- import android.service.fingerprint.IFingerprintService;
- @@ -2224,6 +2225,32 @@ class ContextImpl extends Context {
- return mDisplayAdjustments;
- }
-
- + @Override
- + public void setDualScreen(boolean enable) {
- +
- + int value = 0;
- + if (enable) {
- + value = 1;
- + } else {
- + Settings.System.putInt(getContentResolver(), Settings.System.DUAL_SCREEN_ICON_USED, 0);
- + }
- + Settings.System.putInt(getContentResolver(), Settings.System.DUAL_SCREEN_MODE, value);
- +
- + try {
- + IActivityManager am = ActivityManagerNative.getDefault();
- + Configuration config = am.getConfiguration();
- +
- + // Will set userSetLocale to indicate this isn't some passing default - the user
- + // wants this remembered
- + config.setDualScreenFlag(enable);
- +
- + am.updateConfiguration(config);
- +
- + } catch (RemoteException e) {
- + // Intentionally left blank
- + }
- + }
- +
- private File getDataDirFile() {
- if (mPackageInfo != null) {
- return mPackageInfo.getDataDirFile();
- diff --git a/frameworks/base/core/java/android/content/Context.java b/frameworks/base/core/java/android/content/Context.java
- index 7028dfe..25268fc 100755
- --- a/frameworks/base/core/java/android/content/Context.java
- +++ b/frameworks/base/core/java/android/content/Context.java
- @@ -3460,4 +3460,6 @@ public abstract class Context {
- public boolean isRestricted() {
- return false;
- }
- +
- + public abstract void setDualScreen(boolean enable);
- }
- diff --git a/frameworks/base/core/java/android/content/ContextWrapper.java b/frameworks/base/core/java/android/content/ContextWrapper.java
- index cfae1cf..4ecbea6 100755
- --- a/frameworks/base/core/java/android/content/ContextWrapper.java
- +++ b/frameworks/base/core/java/android/content/ContextWrapper.java
- @@ -710,4 +710,9 @@ public class ContextWrapper extends Context {
- public DisplayAdjustments getDisplayAdjustments(int displayId) {
- return mBase.getDisplayAdjustments(displayId);
- }
- +
- + @Override
- + public void setDualScreen(boolean enable) {
- + mBase.setDualScreen(enable);
- + }
- }
- diff --git a/frameworks/base/core/java/android/view/IWindowSession.aidl b/frameworks/base/core/java/android/view/IWindowSession.aidl
- index 3fb19c2..3192265 100755
- --- a/frameworks/base/core/java/android/view/IWindowSession.aidl
- +++ b/frameworks/base/core/java/android/view/IWindowSession.aidl
- @@ -232,4 +232,7 @@ interface IWindowSession {
- void updatePositionAndSize(IWindow window,int x,int y,int widht,int height);
-
- void setOnlyShowInExtendDisplay(IWindow window,int transit);
- +
- + void moveAppToDisplay(IWindow window, int id);
- + void syncDualDisplay();
- }
- diff --git a/frameworks/base/core/java/android/view/Window.java b/frameworks/base/core/java/android/view/Window.java
- index f74d92c..03744d3 100755
- --- a/frameworks/base/core/java/android/view/Window.java
- +++ b/frameworks/base/core/java/android/view/Window.java
- @@ -1896,5 +1896,7 @@ public abstract class Window {
- */
- public abstract void setNavigationBarColor(int color);
-
- -
- + public abstract void moveAppToDisplay(int id);
- + public abstract void syncDualDisplay();
- + public abstract void moveExtendDisplay();
- }
- diff --git a/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java
- index 5333c35..c309cc3 100755
- --- a/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java
- +++ b/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java
- @@ -5136,5 +5136,24 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
- }
- }
-
- + @Override
- + public void moveAppToDisplay(int id) {
- + try {
- + mDecor.getRootWindowSession().moveAppToDisplay(mDecor.getWindow(), id);
- + } catch (RemoteException ex) {}
- + }
-
- + @Override
- + public void syncDualDisplay() {
- + try {
- + mDecor.getRootWindowSession().syncDualDisplay();
- + } catch (RemoteException ex) {}
- + }
- +
- + @Override
- + public void moveExtendDisplay() {
- + try {
- + mDecor.getRootWindowSession().setOnlyShowInExtendDisplay(mDecor.getWindow(),-1);
- + } catch (RemoteException ex) {}
- + }
- }
- diff --git a/frameworks/base/services/core/java/com/android/server/wm/Session.java b/frameworks/base/services/core/java/com/android/server/wm/Session.java
- index ec92751..0f70d64 100755
- --- a/frameworks/base/services/core/java/com/android/server/wm/Session.java
- +++ b/frameworks/base/services/core/java/com/android/server/wm/Session.java
- @@ -216,6 +216,14 @@ final class Session extends IWindowSession.Stub
- public void setOnlyShowInExtendDisplay(IWindow window,int transit){
- mService.setOnlyShowInExtendDisplay(this, window,transit);
- }
- +
- + public void moveAppToDisplay(IWindow window, int id) {
- + mService.moveAppToDisplay(this, window, id);
- + }
- +
- + public void syncDualDisplay() {
- + mService.syncDualDisplay();
- + }
-
- public void performDeferredDestroy(IWindow window) {
- mService.performDeferredDestroyWindow(this, window);
- diff --git a/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java b/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
- index 37281ca..433a161 100755
- --- a/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
- +++ b/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
- @@ -10050,6 +10050,7 @@ public class WindowManagerService extends IWindowManager.Stub
- public static final int SET_MULTIWINDOW_MODE_ACTION = 41;
- public static final int DO_TASK_DISPLAY_CHANGED = 42;
- public static final int MULTIWINDOW_MOVE_BACK_ACTION = 43;
- + public static final int MOVE_APP_TO_DISPLAY = 44;
- @Override
- public void handleMessage(Message msg) {
- if (DEBUG_WINDOW_TRACE) {
- @@ -10621,6 +10622,11 @@ public class WindowManagerService extends IWindowManager.Stub
- } catch (RemoteException e) {
- }
- break;
- + case MOVE_APP_TO_DISPLAY:
- + synchronized (mWindowMap) {
- + moveAppToIdDisplay(msg.arg1, msg.arg2, (int)msg.obj);
- + }
- + break;
- }
- if (DEBUG_WINDOW_TRACE) {
- Slog.v(TAG, "handleMessage: exit");
- @@ -14493,6 +14499,216 @@ if(mCurConfiguration.enableMultiWindow()&&false){
- }
- Binder.restoreCallingIdentity(origId);
- }
- +
- + public void moveAppToDisplay(Session session, IWindow client, int displayid) {
- + long origId = Binder.clearCallingIdentity();
- + synchronized(mWindowMap){
- + if(mDisplayContents == null || mDisplayContents.size() <= 1){
- + return;
- + }
- + final int displayCount = mDisplayContents.size();
- + DisplayContent defaultContent = getDefaultDisplayContentLocked();
- + int displayId = 0;
- + boolean hasTargetDisplay = false;
- + for(int i = 0; i < displayCount;i++){
- + final DisplayContent content = mDisplayContents.valueAt(i);
- + displayId = content.getDisplayId();
- + if (displayId == displayid) {
- + hasTargetDisplay = true;
- + break;
- + }
- + }
- + if(!hasTargetDisplay){
- + return;
- + }
- + if(!okToDisplay()){
- + return;
- + }
- + WindowState current = windowForClientLocked(session, client, false);
- + if(isHomeWindow(current)){
- + return;
- + }
- + AppWindowToken wtoken = current.mAppToken;
- + if(wtoken == null){
- + return;
- + }
- +
- + if(current.getDisplayId() == displayid) return;
- +
- + Settings.System.putInt(mContext.getContentResolver(),
- + Settings.System.DUAL_SCREEN_ICON_USED, 1);
- + int groupId = wtoken.groupId;
- + mH.sendMessage(mH.obtainMessage(H.MOVE_APP_TO_DISPLAY, groupId, displayid, current.getDisplayId()));
- + }
- + Binder.restoreCallingIdentity(origId);
- + }
- +
- + public void syncDualDisplay() {
- + updateDisplayShowSynchronization();
- + }
- +
- + // case as follow:
- + // 1. mast screen -> external screen
- + // 2. external screen -> mast screen
- + // 3. external screen -> external screen
- + private void moveAppToIdDisplay(int groupId, int displayid, int currentid) {
- + long origId = Binder.clearCallingIdentity();
- + int curMoveTaskId = -1;
- + synchronized(mWindowMap){
- + if(mDisplayContents == null || mDisplayContents.size() <= 1) {
- + return;
- + }
- + DisplayContent defaultContent = getDefaultDisplayContentLocked();
- + int defaultDisplayId = defaultContent.getDisplayId();
- + final int displayCount = mDisplayContents.size();
- + int displayId = 0;
- + DisplayContent currentContent = null;
- + DisplayContent targetContent = null;
- + for(int i = 0; i < displayCount;i++) {
- + final DisplayContent content = mDisplayContents.valueAt(i);
- + if (content.getDisplayId() == displayid) {
- + targetContent = content;
- + }
- + if (content.getDisplayId() == currentid) {
- + currentContent = content;
- + }
- + }
- +
- + if (targetContent == null) return;
- + if (currentContent == null) return;
- +
- + if(!okToDisplay()){
- + return;
- + }
- +
- + WindowState win = null;
- + WindowList windows = currentContent.getWindowList();
- + try {
- + SurfaceControl.openTransaction();
- + if (displayid == defaultDisplayId) {
- + int max = 1;
- + int countOfTwoScreen = 0;
- + WindowList defaultWindows = defaultContent.getWindowList();
- + HashMap<Integer,AppWindowToken> visibleAppsOfTwoScreen = new HashMap<Integer,AppWindowToken>();
- + ArrayList<AppWindowToken> pendingRemoveOfTwoScreen = new ArrayList<AppWindowToken>();
- + for(int j = 0; j < windows.size(); j++) {
- + win = windows.get(j);
- + if (win == null) continue;
- + if (ignoreWindow(win,false) || win.mAppToken == null) continue;
- + if(isHomeWindow(win)) break;
- + if(!win.isDefaultDisplay()) {
- + AppWindowToken tk = win.mAppToken;
- + if(!visibleAppsOfTwoScreen.containsKey(tk.groupId)){
- + visibleAppsOfTwoScreen.put(tk.groupId, tk);
- + if (tk.groupId == groupId) {
- + pendingRemoveOfTwoScreen.add(tk);
- + }
- + }
- + /*if(!visibleAppsOfTwoScreen.containsKey(tk.groupId)){
- + visibleAppsOfTwoScreen.put(tk.groupId, tk);
- + countOfTwoScreen++;
- + if(countOfTwoScreen > max){
- + pendingRemoveOfTwoScreen.add(tk);
- + }
- + }*/
- + }
- + }
- + if(pendingRemoveOfTwoScreen.size() > 0){
- + for(int k =0;k < pendingRemoveOfTwoScreen.size(); k++){
- + int removeTaskId = pendingRemoveOfTwoScreen.get(k).groupId;
- + for(int m = 0; m < windows.size(); m++){
- + WindowState ws = windows.get(m);
- + int mGroupId = ws.mAppToken.groupId;
- + if (mGroupId == removeTaskId) {
- + final ArrayList<TaskStack> stacks = defaultContent.getStacks();
- + final int numStacks = stacks.size();
- + int stackNdx = 1;
- + final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
- + final int numTasks = tasks.size();
- + for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
- + if (tasks.get(taskNdx).taskId != ws.taskId) continue;
- + final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
- + if (!tokens.contains(ws.mAppToken)) { // wrong happened
- + tasks.get(taskNdx).addAppToken(tokens.size(), ws.mAppToken);
- + }
- + //break;
- + }
- + windows.remove(ws);
- + ws.mDisplayContent = defaultContent;
- + if(ws.mWinAnimator != null){
- + int layerStack = defaultContent.getDisplay().getLayerStack();
- + if(ws.mWinAnimator.mSurfaceControl != null){
- + ws.mWinAnimator.mSurfaceControl.setLayerStack(layerStack);
- + }
- + }
- + defaultWindows.add(ws);
- + }
- + }
- + }
- + }
- + } else if (currentid == defaultDisplayId) {
- + WindowList targetDisplayAddList = new WindowList();
- + WindowList targetDisplayWindows = targetContent.getWindowList();
- + for(int i=windows.size()-1; i >= 0; i--){
- + win = windows.get(i);
- + if(win == null){
- + continue;
- + }
- + if (win.mAppToken == null){
- + continue;
- + }
- + int mGroupId = win.mAppToken.groupId;
- + if(mGroupId == groupId){
- +
- + final ArrayList<TaskStack> stacks = currentContent.getStacks();
- + final int numStacks = stacks.size();
- + int stackNdx = 1;
- + final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
- +
- + final int numTasks = tasks.size();
- + for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
- + if (tasks.get(taskNdx).taskId != win.taskId) continue;
- + final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
- + for (int n = 0; n<tokens.size();) {
- + AppWindowToken awt = tokens.get(n);
- + if (tokens.contains(awt) || awt.removed) { // no useful
- + tasks.get(taskNdx).removeAppToken(awt);
- + }
- + }
- + }
- + windows.remove(win);
- + win.mDisplayContent = targetContent;
- +
- + if(win.mWinAnimator != null){
- + int layerStack = targetContent.getDisplay().getLayerStack();
- + if(win.mWinAnimator.mSurfaceControl!= null){
- + win.mWinAnimator.mSurfaceControl.setLayerStack(layerStack);
- + }
- + }
- + targetDisplayAddList.add(0, win);
- + }
- + }
- + targetDisplayWindows.addAll(targetDisplayAddList);
- + } else {
- + // external screen -> external screen
- + }
- +
- + for (int i = 0; i < displayCount; i++) {
- + final DisplayContent content = mDisplayContents.valueAt(i);
- + assignLayersLocked(content.getWindowList());
- + content.layoutNeeded = true;
- + }
- + updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, false);
- + mAppTransition.setReady();
- + performLayoutAndPlaceSurfacesLocked();
- +
- + }finally {
- + SurfaceControl.closeTransaction();
- + }
- +
- + }
- + Binder.restoreCallingIdentity(origId);
- + }
-
- public void moveWindowToSecondDisplay() {
- int topId = -100;
- diff --git a/frameworks/base/test-runner/src/android/test/mock/MockContext.java b/frameworks/base/test-runner/src/android/test/mock/MockContext.java
- index 3378872..cd24654 100755
- --- a/frameworks/base/test-runner/src/android/test/mock/MockContext.java
- +++ b/frameworks/base/test-runner/src/android/test/mock/MockContext.java
- @@ -643,4 +643,9 @@ public class MockContext extends Context {
- public File[] getExternalMediaDirs() {
- throw new UnsupportedOperationException();
- }
- +
- + @Override
- + public void setDualScreen(boolean enable) {
- + throw new UnsupportedOperationException();
- + }
- }
复制代码 (5)官方提供的补丁打完了,但是此时编译可能会报错,如下:
- cts/tests/tests/view/src/android/view/cts/WindowTest.java:846: error: WindowTest.MockWindow is not abstract and does not override abstract method moveExtendDisplay() in Window
- public class MockWindow extends Window {
- ^
- Note: Some input files use or override a deprecated API.
- Note: Recompile with -Xlint:deprecation for details.
- 1 error
- make: *** [out/target/common/obj/APPS/CtsViewTestCases_intermediates/classes-full-debug.jar] Error 41
- make: *** Waiting for unfinished jobs....
- Note: Some input files use or override a deprecated API.
- Note: Recompile with -Xlint:deprecation for details.
- Note: Some input files use unchecked or unsafe operations.
- Note: Recompile with -Xlint:unchecked for details.
- Note: Some input files use or override a deprecated API.
- Note: Recompile with -Xlint:deprecation for details.
- Note: Some input files use unchecked or unsafe operations.
- Note: Recompile with -Xlint:unchecked for details.
- Warning: AndroidManifest.xml already defines minSdkVersion (in http://schemas.android.com/apk/res/android); using existing value in manifest.
- Warning: AndroidManifest.xml already defines targetSdkVersion (in http://schemas.android.com/apk/res/android); using existing value in manifest.
- #### make failed to build some targets (03:55 (mm:ss)) ####
复制代码 根据编译错误提示,需要修改 cts/tests/tests/view/src/android/view/cts/WindowTest.java 文件。
- diff --git a/cts/tests/tests/view/src/android/view/cts/WindowTest.java b/cts/tests/tests/view/src/android/view/cts/WindowTest.java
- index 3c5386d..8732ae7 100755
- --- a/cts/tests/tests/view/src/android/view/cts/WindowTest.java
- +++ b/cts/tests/tests/view/src/android/view/cts/WindowTest.java
- @@ -998,6 +998,19 @@ public class WindowTest extends ActivityInstrumentationTestCase2<WindowCtsActivi
- }
-
- @Override
- + public void moveAppToDisplay(int id) {
- + }
- +
- + @Override
- + public void syncDualDisplay() {
- + }
- +
- + @Override
- + public void moveExtendDisplay() {
- + }
- +
- +
- + @Override
- public void setDefaultWindowFormat(int format) {
- super.setDefaultWindowFormat(format);
- }
复制代码 (6)此时可以编译成功,在屏参正确的前提下,主屏显示正常,副屏出现花屏,需要在 system.prop 里添加属性 ro.htg.force=1。
- diff --git a/device/rockchip/rk3288/system.prop b/device/rockchip/rk3288/system.prop
- index 26a2b09..c4f2c3d 100755
- --- a/device/rockchip/rk3288/system.prop
- +++ b/device/rockchip/rk3288/system.prop
- @@ -12,6 +12,7 @@ rild.libpath=/system/lib/libril-rk29-dataonly.so
- rild.libargs=-d /dev/ttyACM0
- persist.tegra.nvmmlite = 1
- ro.audio.monitorOrientation=true
- +ro.htg.force=1
-
- #NFC
- debug.nfc.fw_download=false
复制代码此时大功告成,双屏可以正常显示,也可以实现双屏异显。
如果 lcd 出现重复性黑屏亮屏,找到对应的屏参文件,在正常范围内调节频率 clk 值即可。 - display-timings {
- native-mode = <&ee101ia>;
- ee101ia: timing0 {
- screen-type = <SCREEN_DUAL_LVDS>;
- lvds-format = <LVDS_8BIT_1>;
- out-face = <OUT_P888>;
- color-mode = <COLOR_RGB>;
- // 调节 lcd 频率
- clock-frequency = <148500000>;
- hactive = <1920>;
- vactive = <1080>;
复制代码
本文作者 LeeAaron 来源 博客园
|