vout: add dummy_lcd driver support [1/1]
authorEvoke Zhang <evoke.zhang@amlogic.com>
Thu, 6 Jun 2019 02:32:39 +0000 (10:32 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Wed, 19 Jun 2019 02:00:49 +0000 (19:00 -0700)
PD#TV-6485

Problem:
need add dummy_lcd for encp

Solution:
add dummy_lcd driver base on encp

Verify:
x301

Change-Id: Id6e289bb3fc95ff94455f31ae2dcd94985baf9ec
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
16 files changed:
MAINTAINERS
arch/arm/boot/dts/amlogic/tl1_t962x2_x301_1g.dts
arch/arm/boot/dts/amlogic/tl1_t962x2_x301_2g.dts
arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_1g.dts
arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_2g.dts
drivers/amlogic/media/vout/lcd/lcd_common.c
drivers/amlogic/media/vout/lcd/lcd_common.h
drivers/amlogic/media/vout/lcd/lcd_debug.c
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c
drivers/amlogic/media/vout/vout_serve/Makefile
drivers/amlogic/media/vout/vout_serve/dummy_lcd.c [new file with mode: 0644]
drivers/amlogic/media/vout/vout_serve/vout_func.c
drivers/amlogic/media/vout/vout_serve/vout_reg.h [new file with mode: 0644]
drivers/amlogic/media/vout/vout_serve/vout_serve.c
include/linux/amlogic/media/vout/vinfo.h

index b5cbd05..7594ecb 100644 (file)
@@ -14367,6 +14367,8 @@ F:      drivers/amlogic/media/vout/vout_serve/vout2_notify.c
 F:      drivers/amlogic/media/vout/vout_serve/vout2_serve.c
 F:      drivers/amlogic/media/vout/vout_serve/vout_func.c
 F:      drivers/amlogic/media/vout/vout_serve/vout_func.h
+F:     drivers/amlogic/media/vout/vout_serve/vout_reg.h
+F:     drivers/amlogic/media/vout/vout_serve/dummy_lcd.c
 
 AMLOGIC GPIO IRQ
 M: Xingyu Chen <xingyu.chen@amlogic.com>
index b07108b..a1a9b8d 100644 (file)
                fr_auto_policy = <0>;
        };
 
+       vout2 {
+               compatible = "amlogic, vout2";
+               dev_name = "vout";
+               status = "disabled";
+               clocks = <&clkc CLKID_VPU_CLKC_P0_COMP>,
+                       <&clkc CLKID_VPU_CLKC_MUX>;
+               clock-names = "vpu_clkc0",
+                       "vpu_clkc";
+       };
+
+       dummy_lcd {
+               compatible = "amlogic, dummy_lcd";
+               status = "disabled";
+               clocks = <&clkc CLKID_VCLK2_ENCP
+                       &clkc CLKID_VCLK2_VENCP0
+                       &clkc CLKID_VCLK2_VENCP1>;
+               clock-names = "encp_top_gate",
+                       "encp_int_gate0",
+                       "encp_int_gate1";
+       };
+
        /* Audio Related start */
        pdm_codec:dummy {
                #sound-dai-cells = <0>;
index 1fa6470..f3c1782 100644 (file)
                fr_auto_policy = <0>;
        };
 
+       vout2 {
+               compatible = "amlogic, vout2";
+               dev_name = "vout";
+               status = "disabled";
+               clocks = <&clkc CLKID_VPU_CLKC_P0_COMP>,
+                       <&clkc CLKID_VPU_CLKC_MUX>;
+               clock-names = "vpu_clkc0",
+                       "vpu_clkc";
+       };
+
+       dummy_lcd {
+               compatible = "amlogic, dummy_lcd";
+               status = "disabled";
+               clocks = <&clkc CLKID_VCLK2_ENCP
+                       &clkc CLKID_VCLK2_VENCP0
+                       &clkc CLKID_VCLK2_VENCP1>;
+               clock-names = "encp_top_gate",
+                       "encp_int_gate0",
+                       "encp_int_gate1";
+       };
+
        /* Audio Related start */
        pdm_codec:dummy {
                #sound-dai-cells = <0>;
index ec9f977..91ce75a 100644 (file)
                fr_auto_policy = <0>;
        };
 
+       vout2 {
+               compatible = "amlogic, vout2";
+               dev_name = "vout";
+               status = "disabled";
+               clocks = <&clkc CLKID_VPU_CLKC_P0_COMP>,
+                       <&clkc CLKID_VPU_CLKC_MUX>;
+               clock-names = "vpu_clkc0",
+                       "vpu_clkc";
+       };
+
+       dummy_lcd {
+               compatible = "amlogic, dummy_lcd";
+               status = "disabled";
+               clocks = <&clkc CLKID_VCLK2_ENCP
+                       &clkc CLKID_VCLK2_VENCP0
+                       &clkc CLKID_VCLK2_VENCP1>;
+               clock-names = "encp_top_gate",
+                       "encp_int_gate0",
+                       "encp_int_gate1";
+       };
+
        /* Audio Related start */
        pdm_codec:dummy {
                #sound-dai-cells = <0>;
index 679520e..4258a02 100644 (file)
                fr_auto_policy = <0>;
        };
 
+       vout2 {
+               compatible = "amlogic, vout2";
+               dev_name = "vout";
+               status = "disabled";
+               clocks = <&clkc CLKID_VPU_CLKC_P0_COMP>,
+                       <&clkc CLKID_VPU_CLKC_MUX>;
+               clock-names = "vpu_clkc0",
+                       "vpu_clkc";
+       };
+
+       dummy_lcd {
+               compatible = "amlogic, dummy_lcd";
+               status = "disabled";
+               clocks = <&clkc CLKID_VCLK2_ENCP
+                       &clkc CLKID_VCLK2_VENCP0
+                       &clkc CLKID_VCLK2_VENCP1>;
+               clock-names = "encp_top_gate",
+                       "encp_int_gate0",
+                       "encp_int_gate1";
+       };
+
        /* Audio Related start */
        pdm_codec:dummy {
                #sound-dai-cells = <0>;
index ca87abc..d6db171 100644 (file)
@@ -1065,3 +1065,32 @@ void lcd_if_enable_retry(struct lcd_config_s *pconf)
        pconf->retry_enable_cnt = 0;
 }
 
+void lcd_vout_notify_mode_change_pre(void)
+{
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+
+       if (lcd_drv->viu_sel == 1) {
+               vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE,
+                       &lcd_drv->lcd_info->mode);
+       } else if (lcd_drv->viu_sel == 2) {
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+               vout2_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE,
+                       &lcd_drv->lcd_info->mode);
+#endif
+       }
+}
+
+void lcd_vout_notify_mode_change(void)
+{
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+
+       if (lcd_drv->viu_sel == 1) {
+               vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,
+                       &lcd_drv->lcd_info->mode);
+       } else if (lcd_drv->viu_sel == 2) {
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+               vout2_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,
+                       &lcd_drv->lcd_info->mode);
+#endif
+       }
+}
index 32dc89c..1f1d392 100644 (file)
@@ -76,6 +76,8 @@ extern int lcd_vmode_change(struct lcd_config_s *pconf);
 extern void lcd_clk_change(struct lcd_config_s *pconf);
 extern void lcd_venc_change(struct lcd_config_s *pconf);
 extern void lcd_if_enable_retry(struct lcd_config_s *pconf);
+extern void lcd_vout_notify_mode_change_pre(void);
+extern void lcd_vout_notify_mode_change(void);
 
 /* lcd phy */
 extern void lcd_lvds_phy_set(struct lcd_config_s *pconf, int status);
index 734ace3..339f60d 100644 (file)
@@ -1539,8 +1539,7 @@ static void lcd_vinfo_update(void)
                vinfo->htotal = pconf->lcd_basic.h_period;
                vinfo->vtotal = pconf->lcd_basic.v_period;
        }
-       vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,
-               &lcd_drv->lcd_info->mode);
+       lcd_vout_notify_mode_change();
 }
 
 static void lcd_debug_config_update(void)
@@ -1558,8 +1557,8 @@ static void lcd_debug_clk_change(unsigned int pclk)
        struct lcd_config_s *pconf;
        unsigned int sync_duration;
 
-       vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE,
-               &lcd_drv->lcd_info->mode);
+       lcd_vout_notify_mode_change_pre();
+
        pconf = lcd_drv->lcd_config;
        sync_duration = pclk / pconf->lcd_basic.h_period;
        sync_duration = sync_duration * 100 / pconf->lcd_basic.v_period;
@@ -1589,8 +1588,7 @@ static void lcd_debug_clk_change(unsigned int pclk)
                break;
        }
 
-       vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,
-               &lcd_drv->lcd_info->mode);
+       lcd_vout_notify_mode_change();
 }
 
 static void lcd_power_interface_ctrl(int state)
index 424ca35..c62d124 100644 (file)
@@ -197,8 +197,7 @@ static int lcd_framerate_automation_set_mode(void)
        lcd_tablet_config_post_update(lcd_drv->lcd_config);
        lcd_venc_change(lcd_drv->lcd_config);
 
-       vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,
-               &lcd_drv->lcd_info->mode);
+       lcd_vout_notify_mode_change();
 
        return 0;
 }
@@ -1280,8 +1279,8 @@ static void lcd_set_vinfo(unsigned int sync_duration)
 
        LCDPR("%s: sync_duration=%d\n", __func__, sync_duration);
 
-       vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE,
-               &lcd_drv->lcd_info->mode);
+       lcd_vout_notify_mode_change_pre();
+
        /* update vinfo */
        lcd_drv->lcd_info->sync_duration_num = sync_duration;
        lcd_drv->lcd_info->sync_duration_den = 100;
@@ -1298,8 +1297,7 @@ static void lcd_set_vinfo(unsigned int sync_duration)
        lcd_tablet_config_post_update(lcd_drv->lcd_config);
        lcd_venc_change(lcd_drv->lcd_config);
 
-       vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,
-               &lcd_drv->lcd_info->mode);
+       lcd_vout_notify_mode_change();
 }
 
 static int lcd_frame_rate_adjust_notifier(struct notifier_block *nb,
index 0ce5c0d..02d152d 100644 (file)
@@ -464,8 +464,7 @@ static int lcd_framerate_automation_set_mode(void)
        if (lcd_drv->lcd_config->lcd_basic.lcd_type == LCD_VBYONE)
                lcd_vbyone_wait_stable();
 
-       vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,
-               &lcd_drv->lcd_info->mode);
+       lcd_vout_notify_mode_change();
 
        return 0;
 }
@@ -1493,8 +1492,8 @@ static void lcd_set_vinfo(unsigned int sync_duration)
 
        LCDPR("%s: sync_duration=%d\n", __func__, sync_duration);
 
-       vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE,
-               &lcd_drv->lcd_info->mode);
+       lcd_vout_notify_mode_change_pre();
+
        /* update vinfo */
        lcd_drv->lcd_info->sync_duration_num = sync_duration;
        lcd_drv->lcd_info->sync_duration_den = 100;
@@ -1514,8 +1513,7 @@ static void lcd_set_vinfo(unsigned int sync_duration)
        if (lcd_drv->lcd_config->lcd_basic.lcd_type == LCD_VBYONE)
                lcd_vbyone_wait_stable();
 
-       vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,
-               &lcd_drv->lcd_info->mode);
+       lcd_vout_notify_mode_change();
 }
 
 static int lcd_frame_rate_adjust_notifier(struct notifier_block *nb,
index a67378b..a8b4a89 100644 (file)
@@ -1,3 +1,3 @@
-obj-$(CONFIG_AMLOGIC_VOUT_SERVE)       += vout_notify.o vout_serve.o vout_func.o
+obj-$(CONFIG_AMLOGIC_VOUT_SERVE)       += vout_notify.o vout_serve.o vout_func.o dummy_lcd.o
 obj-$(CONFIG_AMLOGIC_VOUT2_SERVE)      += vout2_notify.o vout2_serve.o
 
diff --git a/drivers/amlogic/media/vout/vout_serve/dummy_lcd.c b/drivers/amlogic/media/vout/vout_serve/dummy_lcd.c
new file mode 100644 (file)
index 0000000..0c63725
--- /dev/null
@@ -0,0 +1,661 @@
+/*
+ * drivers/amlogic/media/vout/vout_serve/dummy_lcd.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+/* Linux Headers */
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/of.h>
+#include <linux/clk.h>
+#ifdef CONFIG_AMLOGIC_VPU
+#include <linux/amlogic/media/vpu/vpu.h>
+#endif
+#include <linux/amlogic/media/vout/vout_notify.h>
+
+/* Local Headers */
+#include "vout_func.h"
+#include "vout_reg.h"
+
+struct dummy_lcd_driver_s {
+       struct device *dev;
+       unsigned char status;
+       unsigned char viu_sel;
+
+       unsigned char clk_gate_state;
+
+       struct clk *encp_top_gate;
+       struct clk *encp_int_gate0;
+       struct clk *encp_int_gate1;
+};
+
+static struct dummy_lcd_driver_s *dummy_lcd_drv;
+
+/* **********************************************************
+ * dummy_lcd support
+ * **********************************************************
+ */
+static struct vinfo_s dummy_lcd_vinfo = {
+       .name              = "dummy_panel",
+       .mode              = VMODE_DUMMY_LCD,
+       .width             = 1920,
+       .height            = 1080,
+       .field_height      = 1080,
+       .aspect_ratio_num  = 16,
+       .aspect_ratio_den  = 9,
+       .sync_duration_num = 60,
+       .sync_duration_den = 1,
+       .video_clk         = 148500000,
+       .htotal            = 2200,
+       .vtotal            = 1125,
+       .fr_adj_type       = VOUT_FR_ADJ_NONE,
+       .viu_color_fmt     = COLOR_FMT_RGB444,
+       .viu_mux           = VIU_MUX_ENCP,
+       .vout_device       = NULL,
+};
+
+static void dummy_lcd_venc_set(void)
+{
+       unsigned int temp;
+
+       VOUTPR("%s\n", __func__);
+
+       vout_vcbus_write(ENCP_VIDEO_EN, 0);
+
+       vout_vcbus_write(ENCP_VIDEO_MODE, 0x8000);
+       vout_vcbus_write(ENCP_VIDEO_MODE_ADV, 0x0418);
+
+       temp = vout_vcbus_read(ENCL_VIDEO_MAX_PXCNT);
+       vout_vcbus_write(ENCP_VIDEO_MAX_PXCNT, temp);
+       temp = vout_vcbus_read(ENCL_VIDEO_MAX_LNCNT);
+       vout_vcbus_write(ENCP_VIDEO_MAX_LNCNT, temp);
+       temp = vout_vcbus_read(ENCL_VIDEO_HAVON_BEGIN);
+       vout_vcbus_write(ENCP_VIDEO_HAVON_BEGIN, temp);
+       temp = vout_vcbus_read(ENCL_VIDEO_HAVON_END);
+       vout_vcbus_write(ENCP_VIDEO_HAVON_END, temp);
+       temp = vout_vcbus_read(ENCL_VIDEO_VAVON_BLINE);
+       vout_vcbus_write(ENCP_VIDEO_VAVON_BLINE, temp);
+       temp = vout_vcbus_read(ENCL_VIDEO_VAVON_ELINE);
+       vout_vcbus_write(ENCP_VIDEO_VAVON_ELINE, temp);
+
+       temp = vout_vcbus_read(ENCL_VIDEO_HSO_BEGIN);
+       vout_vcbus_write(ENCP_VIDEO_HSO_BEGIN, temp);
+       temp = vout_vcbus_read(ENCL_VIDEO_HSO_END);
+       vout_vcbus_write(ENCP_VIDEO_HSO_END,   temp);
+       temp = vout_vcbus_read(ENCL_VIDEO_VSO_BEGIN);
+       vout_vcbus_write(ENCP_VIDEO_VSO_BEGIN, temp);
+       temp = vout_vcbus_read(ENCL_VIDEO_VSO_END);
+       vout_vcbus_write(ENCP_VIDEO_VSO_END,   temp);
+       temp = vout_vcbus_read(ENCL_VIDEO_VSO_BLINE);
+       vout_vcbus_write(ENCP_VIDEO_VSO_BLINE, temp);
+       temp = vout_vcbus_read(ENCL_VIDEO_VSO_ELINE);
+       vout_vcbus_write(ENCP_VIDEO_VSO_ELINE, temp);
+
+       temp = vout_vcbus_read(ENCL_VIDEO_VSO_ELINE);
+       vout_vcbus_write(ENCP_VIDEO_RGBIN_CTRL, temp);
+
+       vout_vcbus_write(ENCP_VIDEO_EN, 1);
+}
+
+static void dummy_lcd_clk_ctrl(int flag)
+{
+       unsigned int temp;
+
+       if (flag) {
+               temp = vout_hiu_getb(HHI_VIID_CLK_DIV, ENCL_CLK_SEL, 4);
+               vout_hiu_setb(HHI_VID_CLK_DIV, temp, ENCP_CLK_SEL, 4);
+
+               vout_hiu_setb(HHI_VID_CLK_CNTL2, 1, ENCP_GATE_VCLK, 1);
+       } else {
+               vout_hiu_setb(HHI_VID_CLK_CNTL2, 0, ENCP_GATE_VCLK, 1);
+       }
+}
+
+static void dummy_lcd_clk_gate_switch(int flag)
+{
+       if (flag) {
+               if (dummy_lcd_drv->clk_gate_state)
+                       return;
+               if (IS_ERR_OR_NULL(dummy_lcd_drv->encp_top_gate))
+                       VOUTERR("%s: encp_top_gate\n", __func__);
+               else
+                       clk_prepare_enable(dummy_lcd_drv->encp_top_gate);
+               if (IS_ERR_OR_NULL(dummy_lcd_drv->encp_int_gate0))
+                       VOUTERR("%s: encp_int_gate0\n", __func__);
+               else
+                       clk_prepare_enable(dummy_lcd_drv->encp_int_gate0);
+               if (IS_ERR_OR_NULL(dummy_lcd_drv->encp_int_gate1))
+                       VOUTERR("%s: encp_int_gate1\n", __func__);
+               else
+                       clk_prepare_enable(dummy_lcd_drv->encp_int_gate1);
+               dummy_lcd_drv->clk_gate_state = 1;
+       } else {
+               if (dummy_lcd_drv->clk_gate_state == 0)
+                       return;
+               dummy_lcd_drv->clk_gate_state = 0;
+               if (IS_ERR_OR_NULL(dummy_lcd_drv->encp_int_gate0))
+                       VOUTERR("%s: encp_int_gate0\n", __func__);
+               else
+                       clk_disable_unprepare(dummy_lcd_drv->encp_int_gate0);
+               if (IS_ERR_OR_NULL(dummy_lcd_drv->encp_int_gate1))
+                       VOUTERR("%s: encp_int_gate1\n", __func__);
+               else
+                       clk_disable_unprepare(dummy_lcd_drv->encp_int_gate1);
+               if (IS_ERR_OR_NULL(dummy_lcd_drv->encp_top_gate))
+                       VOUTERR("%s: encp_top_gate\n", __func__);
+               else
+                       clk_disable_unprepare(dummy_lcd_drv->encp_top_gate);
+       }
+}
+
+static void dummy_lcd_vinfo_update(void)
+{
+       unsigned int lcd_viu_sel = 0;
+       const struct vinfo_s *vinfo = NULL;
+
+       if (dummy_lcd_drv->viu_sel == 1) {
+               vinfo = get_current_vinfo2();
+               lcd_viu_sel = 2;
+       } else if (dummy_lcd_drv->viu_sel == 2) {
+               vinfo = get_current_vinfo();
+               lcd_viu_sel = 1;
+       }
+
+       if (vinfo) {
+               if (vinfo->mode != VMODE_LCD) {
+                       VOUTERR("display%d is not panel\n", lcd_viu_sel);
+                       vinfo = NULL;
+               }
+       }
+       if (!vinfo)
+               return;
+
+       dummy_lcd_vinfo.width = vinfo->width;
+       dummy_lcd_vinfo.height = vinfo->height;
+       dummy_lcd_vinfo.field_height = vinfo->field_height;
+       dummy_lcd_vinfo.aspect_ratio_num = vinfo->aspect_ratio_num;
+       dummy_lcd_vinfo.aspect_ratio_den = vinfo->aspect_ratio_den;
+       dummy_lcd_vinfo.sync_duration_num = vinfo->sync_duration_num;
+       dummy_lcd_vinfo.sync_duration_den = vinfo->sync_duration_den;
+       dummy_lcd_vinfo.video_clk = vinfo->video_clk;
+       dummy_lcd_vinfo.htotal = vinfo->htotal;
+       dummy_lcd_vinfo.vtotal = vinfo->vtotal;
+       dummy_lcd_vinfo.viu_color_fmt = vinfo->viu_color_fmt;
+}
+
+static struct vinfo_s *dummy_lcd_get_current_info(void)
+{
+       return &dummy_lcd_vinfo;
+}
+
+static int dummy_lcd_set_current_vmode(enum vmode_e mode)
+{
+       dummy_lcd_vinfo_update();
+
+#ifdef CONFIG_AMLOGIC_VPU
+       request_vpu_clk_vmod(dummy_lcd_vinfo.video_clk, VPU_VENCP);
+       switch_vpu_mem_pd_vmod(VPU_VENCP, VPU_MEM_POWER_ON);
+#endif
+       dummy_lcd_clk_gate_switch(1);
+
+       dummy_lcd_clk_ctrl(1);
+       dummy_lcd_venc_set();
+
+       dummy_lcd_drv->status = 1;
+       VOUTPR("%s finished\n", __func__);
+
+       return 0;
+}
+
+static enum vmode_e dummy_lcd_validate_vmode(char *name)
+{
+       enum vmode_e vmode = VMODE_MAX;
+
+       if (strcmp(dummy_lcd_vinfo.name, name) == 0)
+               vmode = dummy_lcd_vinfo.mode;
+
+       return vmode;
+}
+
+static int dummy_lcd_vmode_is_supported(enum vmode_e mode)
+{
+       if (dummy_lcd_vinfo.mode == (mode & VMODE_MODE_BIT_MASK))
+               return true;
+
+       return false;
+}
+
+static int dummy_lcd_disable(enum vmode_e cur_vmod)
+{
+       dummy_lcd_drv->status = 0;
+
+       vout_vcbus_write(ENCP_VIDEO_EN, 0); /* disable encp */
+       dummy_lcd_clk_ctrl(0);
+       dummy_lcd_clk_gate_switch(0);
+#ifdef CONFIG_AMLOGIC_VPU
+       switch_vpu_mem_pd_vmod(VPU_VENCP, VPU_MEM_POWER_DOWN);
+       release_vpu_clk_vmod(VPU_VENCP);
+#endif
+
+       VOUTPR("%s finished\n", __func__);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int dummy_lcd_lcd_suspend(void)
+{
+       dummy_lcd_disable(VMODE_DUMMY_LCD);
+       return 0;
+}
+
+static int dummy_lcd_lcd_resume(void)
+{
+       dummy_lcd_set_current_vmode(VMODE_DUMMY_LCD);
+       return 0;
+}
+
+#endif
+
+static int dummy_lcd_vout_state;
+static int dummy_lcd_vout_set_state(int bit)
+{
+       dummy_lcd_vout_state |= (1 << bit);
+       dummy_lcd_drv->viu_sel = bit;
+       return 0;
+}
+
+static int dummy_lcd_vout_clr_state(int bit)
+{
+       dummy_lcd_vout_state &= ~(1 << bit);
+       if (dummy_lcd_drv->viu_sel == bit)
+               dummy_lcd_drv->viu_sel = 0;
+       return 0;
+}
+
+static int dummy_lcd_vout_get_state(void)
+{
+       return dummy_lcd_vout_state;
+}
+
+static struct vout_server_s dummy_lcd_vout_server = {
+       .name = "dummy_lcd_vout_server",
+       .op = {
+               .get_vinfo          = dummy_lcd_get_current_info,
+               .set_vmode          = dummy_lcd_set_current_vmode,
+               .validate_vmode     = dummy_lcd_validate_vmode,
+               .vmode_is_supported = dummy_lcd_vmode_is_supported,
+               .disable            = dummy_lcd_disable,
+               .set_state          = dummy_lcd_vout_set_state,
+               .clr_state          = dummy_lcd_vout_clr_state,
+               .get_state          = dummy_lcd_vout_get_state,
+               .set_bist           = NULL,
+#ifdef CONFIG_PM
+               .vout_suspend       = dummy_lcd_lcd_suspend,
+               .vout_resume        = dummy_lcd_lcd_resume,
+#endif
+       },
+};
+
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+static struct vout_server_s dummy_lcd_vout2_server = {
+       .name = "dummy_lcd_vout2_server",
+       .op = {
+               .get_vinfo          = dummy_lcd_get_current_info,
+               .set_vmode          = dummy_lcd_set_current_vmode,
+               .validate_vmode     = dummy_lcd_validate_vmode,
+               .vmode_is_supported = dummy_lcd_vmode_is_supported,
+               .disable            = dummy_lcd_disable,
+               .set_state          = dummy_lcd_vout_set_state,
+               .clr_state          = dummy_lcd_vout_clr_state,
+               .get_state          = dummy_lcd_vout_get_state,
+               .set_bist           = NULL,
+#ifdef CONFIG_PM
+               .vout_suspend       = dummy_lcd_lcd_suspend,
+               .vout_resume        = dummy_lcd_lcd_resume,
+#endif
+       },
+};
+#endif
+
+static void dummy_lcd_vout_server_init(void)
+{
+       vout_register_server(&dummy_lcd_vout_server);
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+       vout2_register_server(&dummy_lcd_vout2_server);
+#endif
+}
+
+static void dummy_lcd_vout_server_remove(void)
+{
+       vout_unregister_server(&dummy_lcd_vout_server);
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+       vout2_unregister_server(&dummy_lcd_vout2_server);
+#endif
+}
+
+/* ********************************************************* */
+static int dummy_lcd_vout_mode_update(void)
+{
+       enum vmode_e mode = VMODE_DUMMY_LCD;
+
+       VOUTPR("%s\n", __func__);
+
+       if (dummy_lcd_drv->viu_sel == 1)
+               vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE, &mode);
+       else if (dummy_lcd_drv->viu_sel == 2)
+               vout2_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE, &mode);
+       dummy_lcd_set_current_vmode(mode);
+       if (dummy_lcd_drv->viu_sel == 1)
+               vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE, &mode);
+       else if (dummy_lcd_drv->viu_sel == 2)
+               vout2_notifier_call_chain(VOUT_EVENT_MODE_CHANGE, &mode);
+
+       return 0;
+}
+
+static int dummy_lcd_vout_notify_callback(struct notifier_block *block,
+               unsigned long cmd, void *para)
+{
+       const struct vinfo_s *vinfo;
+
+       switch (cmd) {
+       case VOUT_EVENT_MODE_CHANGE:
+               vinfo = get_current_vinfo();
+               if (!vinfo)
+                       break;
+               if (vinfo->mode != VMODE_LCD)
+                       break;
+               dummy_lcd_vout_mode_update();
+               break;
+       default:
+               break;
+       }
+       return 0;
+}
+
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+static int dummy_lcd_vout2_notify_callback(struct notifier_block *block,
+               unsigned long cmd, void *para)
+{
+       const struct vinfo_s *vinfo;
+
+       switch (cmd) {
+       case VOUT_EVENT_MODE_CHANGE:
+               vinfo = get_current_vinfo2();
+               if (!vinfo)
+                       break;
+               if (vinfo->mode != VMODE_LCD)
+                       break;
+               dummy_lcd_vout_mode_update();
+               break;
+       default:
+               break;
+       }
+       return 0;
+}
+#endif
+
+static struct notifier_block dummy_lcd_vout_notifier = {
+       .notifier_call = dummy_lcd_vout_notify_callback,
+};
+
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+static struct notifier_block dummy_lcd_vout2_notifier = {
+       .notifier_call = dummy_lcd_vout2_notify_callback,
+};
+#endif
+
+/* ********************************************************* */
+static const char *dummy_lcd_debug_usage_str = {
+"Usage:\n"
+"    echo test <index> > /sys/class/dummy_lcd/debug ; test pattern for encp\n"
+"    echo reg > /sys/class/dummy_lcd/debug ; dump regs for encp\n"
+};
+
+static ssize_t dummy_lcd_debug_show(struct class *class,
+               struct class_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%s\n", dummy_lcd_debug_usage_str);
+}
+
+static unsigned int dummy_lcd_reg_dump_encp[] = {
+       VPU_VIU_VENC_MUX_CTRL,
+       ENCP_VIDEO_EN,
+       ENCP_VIDEO_MODE,
+       ENCP_VIDEO_MODE_ADV,
+       ENCP_VIDEO_MAX_PXCNT,
+       ENCP_VIDEO_MAX_LNCNT,
+       ENCP_VIDEO_HAVON_BEGIN,
+       ENCP_VIDEO_HAVON_END,
+       ENCP_VIDEO_VAVON_BLINE,
+       ENCP_VIDEO_VAVON_ELINE,
+       ENCP_VIDEO_HSO_BEGIN,
+       ENCP_VIDEO_HSO_END,
+       ENCP_VIDEO_VSO_BEGIN,
+       ENCP_VIDEO_VSO_END,
+       ENCP_VIDEO_VSO_BLINE,
+       ENCP_VIDEO_VSO_ELINE,
+       ENCP_VIDEO_RGBIN_CTRL,
+       0xffff,
+};
+
+static ssize_t dummy_lcd_debug_store(struct class *class,
+               struct class_attribute *attr, const char *buf, size_t count)
+{
+       unsigned int ret;
+       unsigned int val, i;
+
+       switch (buf[0]) {
+       case 't':
+               ret = sscanf(buf, "test %d", &val);
+               if (ret == 1) {
+                       pr_info("todo bist pattern\n");
+               } else {
+                       pr_info("invalid data\n");
+                       return -EINVAL;
+               }
+               break;
+       case 'r':
+               pr_info("dummy_lcd register dump:\n");
+               i = 0;
+               while (i < ARRAY_SIZE(dummy_lcd_reg_dump_encp)) {
+                       if (dummy_lcd_reg_dump_encp[i] == 0xffff)
+                               break;
+                       pr_info("vcbus   [0x%04x] = 0x%08x\n",
+                               dummy_lcd_reg_dump_encp[i],
+                               vout_vcbus_read(dummy_lcd_reg_dump_encp[i]));
+                       i++;
+               }
+               break;
+       default:
+               pr_info("invalid data\n");
+               break;
+       }
+
+       return count;
+}
+
+static struct class_attribute dummy_lcd_class_attrs[] = {
+       __ATTR(debug, 0644,
+               dummy_lcd_debug_show, dummy_lcd_debug_store),
+};
+
+static struct class *debug_class;
+static int dummy_lcd_creat_class(void)
+{
+       int i;
+
+       debug_class = class_create(THIS_MODULE, "dummy_lcd");
+       if (IS_ERR(debug_class)) {
+               VOUTERR("create debug class failed\n");
+               return -1;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(dummy_lcd_class_attrs); i++) {
+               if (class_create_file(debug_class, &dummy_lcd_class_attrs[i])) {
+                       VOUTERR("create debug attribute %s failed\n",
+                               dummy_lcd_class_attrs[i].attr.name);
+               }
+       }
+
+       return 0;
+}
+
+static int dummy_lcd_remove_class(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(dummy_lcd_class_attrs); i++)
+               class_remove_file(debug_class, &dummy_lcd_class_attrs[i]);
+
+       class_destroy(debug_class);
+       debug_class = NULL;
+
+       return 0;
+}
+/* ********************************************************* */
+
+static void dummy_lcd_clktree_probe(void)
+{
+       dummy_lcd_drv->clk_gate_state = 0;
+
+       dummy_lcd_drv->encp_top_gate = devm_clk_get(dummy_lcd_drv->dev,
+                       "encp_top_gate");
+       if (IS_ERR_OR_NULL(dummy_lcd_drv->encp_top_gate))
+               VOUTERR("%s: get encp_top_gate error\n", __func__);
+
+       dummy_lcd_drv->encp_int_gate0 = devm_clk_get(dummy_lcd_drv->dev,
+                       "encp_int_gate0");
+       if (IS_ERR_OR_NULL(dummy_lcd_drv->encp_int_gate0))
+               VOUTERR("%s: get encp_int_gate0 error\n", __func__);
+
+       dummy_lcd_drv->encp_int_gate1 = devm_clk_get(dummy_lcd_drv->dev,
+                       "encp_int_gate1");
+       if (IS_ERR_OR_NULL(dummy_lcd_drv->encp_int_gate1))
+               VOUTERR("%s: get encp_int_gate1 error\n", __func__);
+}
+
+static void dummy_lcd_clktree_remove(void)
+{
+       if (!IS_ERR_OR_NULL(dummy_lcd_drv->encp_top_gate))
+               devm_clk_put(dummy_lcd_drv->dev, dummy_lcd_drv->encp_top_gate);
+       if (!IS_ERR_OR_NULL(dummy_lcd_drv->encp_int_gate0))
+               devm_clk_put(dummy_lcd_drv->dev, dummy_lcd_drv->encp_int_gate0);
+       if (!IS_ERR_OR_NULL(dummy_lcd_drv->encp_int_gate1))
+               devm_clk_put(dummy_lcd_drv->dev, dummy_lcd_drv->encp_int_gate1);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id dummy_lcd_dt_match_table[] = {
+       {
+               .compatible = "amlogic, dummy_lcd",
+       },
+       {},
+};
+#endif
+
+static int dummy_lcd_probe(struct platform_device *pdev)
+{
+       dummy_lcd_drv = kzalloc(sizeof(struct dummy_lcd_driver_s), GFP_KERNEL);
+       if (!dummy_lcd_drv) {
+               VOUTERR("%s: dummy_lcd driver no enough memory\n", __func__);
+               return -ENOMEM;
+       }
+       dummy_lcd_drv->dev = &pdev->dev;
+
+       dummy_lcd_clktree_probe();
+       dummy_lcd_vout_server_init();
+
+       vout_register_client(&dummy_lcd_vout_notifier);
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+       vout2_register_client(&dummy_lcd_vout2_notifier);
+#endif
+       dummy_lcd_creat_class();
+
+       VOUTPR("%s OK\n", __func__);
+
+       return 0;
+}
+
+static int dummy_lcd_remove(struct platform_device *pdev)
+{
+       if (dummy_lcd_drv == NULL)
+               return 0;
+
+       dummy_lcd_remove_class();
+       vout_unregister_client(&dummy_lcd_vout_notifier);
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+       vout2_unregister_client(&dummy_lcd_vout2_notifier);
+#endif
+       dummy_lcd_vout_server_remove();
+       dummy_lcd_clktree_remove();
+
+       kfree(dummy_lcd_drv);
+       dummy_lcd_drv = NULL;
+
+       VOUTPR("%s\n", __func__);
+       return 0;
+}
+
+static void dummy_lcd_shutdown(struct platform_device *pdev)
+{
+       if (dummy_lcd_drv == NULL)
+               return;
+       if (dummy_lcd_drv->status)
+               dummy_lcd_disable(VMODE_DUMMY_LCD);
+}
+
+static struct platform_driver dummy_lcd_platform_driver = {
+       .probe = dummy_lcd_probe,
+       .remove = dummy_lcd_remove,
+       .shutdown = dummy_lcd_shutdown,
+       .driver = {
+               .name = "dummy_lcd",
+               .owner = THIS_MODULE,
+#ifdef CONFIG_OF
+               .of_match_table = dummy_lcd_dt_match_table,
+#endif
+       },
+};
+
+static int __init dummy_lcd_init(void)
+{
+       if (platform_driver_register(&dummy_lcd_platform_driver)) {
+               VOUTERR("failed to register dummy_lcd driver module\n");
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static void __exit dummy_lcd_exit(void)
+{
+       platform_driver_unregister(&dummy_lcd_platform_driver);
+}
+
+subsys_initcall(dummy_lcd_init);
+module_exit(dummy_lcd_exit);
+
index 0ea80a6..eae6240 100644 (file)
 #include <linux/err.h>
 
 /* Amlogic Headers */
-#include <linux/amlogic/iomap.h>
 #include <linux/amlogic/media/vout/vout_notify.h>
 
 /* Local Headers */
 #include "vout_func.h"
+#include "vout_reg.h"
 
 static DEFINE_MUTEX(vout_mutex);
 
@@ -111,24 +111,6 @@ struct vout_module_s *vout_func_get_vout2_module(void)
 EXPORT_SYMBOL(vout_func_get_vout2_module);
 #endif
 
-static unsigned int vout_func_vcbus_read(unsigned int _reg)
-{
-       return aml_read_vcbus(_reg);
-};
-
-static void vout_func_vcbus_write(unsigned int _reg, unsigned int _value)
-{
-       aml_write_vcbus(_reg, _value);
-};
-
-static void vout_func_vcbus_setb(unsigned int _reg, unsigned int _value,
-               unsigned int _start, unsigned int _len)
-{
-       vout_func_vcbus_write(_reg, ((vout_func_vcbus_read(_reg) &
-                       ~(((1L << (_len))-1) << (_start))) |
-                       (((_value)&((1L<<(_len))-1)) << (_start))));
-}
-
 static inline int vout_func_check_state(int index, unsigned int state,
                struct vout_server_s *p_server)
 {
@@ -239,24 +221,11 @@ void vout_func_update_viu(int index)
        }
 
        if (mux_bit < 0xff) {
-               vout_func_vcbus_setb(VPU_VIU_VENC_MUX_CTRL,
+               vout_vcbus_setb(VPU_VIU_VENC_MUX_CTRL,
                                mux_sel, mux_bit, 2);
        }
        if (clk_bit < 0xff)
-               vout_func_vcbus_setb(VPU_VENCX_CLK_CTRL, clk_sel, clk_bit, 1);
-
-       /* special setting for dummy mode */
-       if (index == 1) {
-               if (vinfo->mode == VMODE_DUMMY_LCD) {
-                       /* viu1 use encl_vsync */
-                       vout_func_vcbus_setb(VPU_VIU_VENC_MUX_CTRL, 0, 4, 2);
-                       vout_func_vcbus_setb(VPU_VIU_VENC_MUX_CTRL, 1, 20, 1);
-                       vout_func_vcbus_setb(VPP_WRBAK_CTRL, 1, 11, 1);
-               } else {
-                       vout_func_vcbus_setb(VPU_VIU_VENC_MUX_CTRL, 0, 20, 1);
-                       vout_func_vcbus_setb(VPP_WRBAK_CTRL, 0, 11, 1);
-               }
-       }
+               vout_vcbus_setb(VPU_VENCX_CLK_CTRL, clk_sel, clk_bit, 1);
 
 #if 0
        VOUTPR("%s: %d, mux_sel=%d, clk_sel=%d\n",
diff --git a/drivers/amlogic/media/vout/vout_serve/vout_reg.h b/drivers/amlogic/media/vout/vout_serve/vout_reg.h
new file mode 100644 (file)
index 0000000..54c265f
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * drivers/amlogic/media/vout/vout_serve/vout_reg.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _VOUT_REG_H_
+#define _VOUT_REG_H_
+#include <linux/amlogic/iomap.h>
+
+/* [3: 2] cntl_viu2_sel_venc:
+ *         0=ENCL, 1=ENCI, 2=ENCP, 3=ENCT.
+ * [1: 0] cntl_viu1_sel_venc:
+ *         0=ENCL, 1=ENCI, 2=ENCP, 3=ENCT.
+ */
+#define VPU_VIU_VENC_MUX_CTRL                      0x271a
+/* [2] Enci_afifo_clk: 0: cts_vpu_clk_tm 1: cts_vpu_clkc_tm
+ * [1] Encl_afifo_clk: 0: cts_vpu_clk_tm 1: cts_vpu_clkc_tm
+ * [0] Encp_afifo_clk: 0: cts_vpu_clk_tm 1: cts_vpu_clkc_tm
+ */
+#define VPU_VENCX_CLK_CTRL                         0x2785
+
+#define VPP_POSTBLEND_H_SIZE                       0x1d21
+#define VPP2_POSTBLEND_H_SIZE                      0x1921
+#define VPP_WRBAK_CTRL                             0x1df9
+
+/* ENCL registers */
+#define ENCL_VIDEO_EN                              0x1ca0
+#define ENCL_VIDEO_Y_SCL                           0x1ca1
+#define ENCL_VIDEO_PB_SCL                          0x1ca2
+#define ENCL_VIDEO_PR_SCL                          0x1ca3
+#define ENCL_VIDEO_Y_OFFST                         0x1ca4
+#define ENCL_VIDEO_PB_OFFST                        0x1ca5
+#define ENCL_VIDEO_PR_OFFST                        0x1ca6
+/* ----- Video mode */
+#define ENCL_VIDEO_MODE                            0x1ca7
+#define ENCL_VIDEO_MODE_ADV                        0x1ca8
+/* --------------- Debug pins */
+#define ENCL_DBG_PX_RST                            0x1ca9
+#define ENCL_DBG_LN_RST                            0x1caa
+#define ENCL_DBG_PX_INT                            0x1cab
+#define ENCL_DBG_LN_INT                            0x1cac
+/* ----------- Video Advanced setting */
+#define ENCL_VIDEO_YFP1_HTIME                      0x1cad
+#define ENCL_VIDEO_YFP2_HTIME                      0x1cae
+#define ENCL_VIDEO_YC_DLY                          0x1caf
+#define ENCL_VIDEO_MAX_PXCNT                       0x1cb0
+#define ENCL_VIDEO_HAVON_END                       0x1cb1
+#define ENCL_VIDEO_HAVON_BEGIN                     0x1cb2
+#define ENCL_VIDEO_VAVON_ELINE                     0x1cb3
+#define ENCL_VIDEO_VAVON_BLINE                     0x1cb4
+#define ENCL_VIDEO_HSO_BEGIN                       0x1cb5
+#define ENCL_VIDEO_HSO_END                         0x1cb6
+#define ENCL_VIDEO_VSO_BEGIN                       0x1cb7
+#define ENCL_VIDEO_VSO_END                         0x1cb8
+#define ENCL_VIDEO_VSO_BLINE                       0x1cb9
+#define ENCL_VIDEO_VSO_ELINE                       0x1cba
+#define ENCL_VIDEO_MAX_LNCNT                       0x1cbb
+#define ENCL_VIDEO_BLANKY_VAL                      0x1cbc
+#define ENCL_VIDEO_BLANKPB_VAL                     0x1cbd
+#define ENCL_VIDEO_BLANKPR_VAL                     0x1cbe
+#define ENCL_VIDEO_HOFFST                          0x1cbf
+#define ENCL_VIDEO_VOFFST                          0x1cc0
+#define ENCL_VIDEO_RGB_CTRL                        0x1cc1
+#define ENCL_VIDEO_FILT_CTRL                       0x1cc2
+#define ENCL_VIDEO_OFLD_VPEQ_OFST                  0x1cc3
+#define ENCL_VIDEO_OFLD_VOAV_OFST                  0x1cc4
+#define ENCL_VIDEO_MATRIX_CB                       0x1cc5
+#define ENCL_VIDEO_MATRIX_CR                       0x1cc6
+#define ENCL_VIDEO_RGBIN_CTRL                      0x1cc7
+#define ENCL_MAX_LINE_SWITCH_POINT                 0x1cc8
+#define ENCL_DACSEL_0                              0x1cc9
+#define ENCL_DACSEL_1                              0x1cca
+
+/* ENCP registers */
+#define ENCP_VIDEO_EN                              0x1b80
+#define ENCP_VIDEO_SYNC_MODE                       0x1b81
+#define ENCP_MACV_EN                               0x1b82
+#define ENCP_VIDEO_Y_SCL                           0x1b83
+#define ENCP_VIDEO_PB_SCL                          0x1b84
+#define ENCP_VIDEO_PR_SCL                          0x1b85
+#define ENCP_VIDEO_SYNC_SCL                        0x1b86
+#define ENCP_VIDEO_MACV_SCL                        0x1b87
+#define ENCP_VIDEO_Y_OFFST                         0x1b88
+#define ENCP_VIDEO_PB_OFFST                        0x1b89
+#define ENCP_VIDEO_PR_OFFST                        0x1b8a
+#define ENCP_VIDEO_SYNC_OFFST                      0x1b8b
+#define ENCP_VIDEO_MACV_OFFST                      0x1b8c
+//----- Video mode
+#define ENCP_VIDEO_MODE                            0x1b8d
+#define ENCP_VIDEO_MODE_ADV                        0x1b8e
+//--------------- Debug pins
+#define ENCP_DBG_PX_RST                            0x1b90
+#define ENCP_DBG_LN_RST                            0x1b91
+#define ENCP_DBG_PX_INT                            0x1b92
+#define ENCP_DBG_LN_INT                            0x1b93
+//----------- Video Advanced setting
+#define ENCP_VIDEO_YFP1_HTIME                      0x1b94
+#define ENCP_VIDEO_YFP2_HTIME                      0x1b95
+#define ENCP_VIDEO_YC_DLY                          0x1b96
+#define ENCP_VIDEO_MAX_PXCNT                       0x1b97
+#define ENCP_VIDEO_HSPULS_BEGIN                    0x1b98
+#define ENCP_VIDEO_HSPULS_END                      0x1b99
+#define ENCP_VIDEO_HSPULS_SWITCH                   0x1b9a
+#define ENCP_VIDEO_VSPULS_BEGIN                    0x1b9b
+#define ENCP_VIDEO_VSPULS_END                      0x1b9c
+#define ENCP_VIDEO_VSPULS_BLINE                    0x1b9d
+#define ENCP_VIDEO_VSPULS_ELINE                    0x1b9e
+#define ENCP_VIDEO_EQPULS_BEGIN                    0x1b9f
+#define ENCP_VIDEO_EQPULS_END                      0x1ba0
+#define ENCP_VIDEO_EQPULS_BLINE                    0x1ba1
+#define ENCP_VIDEO_EQPULS_ELINE                    0x1ba2
+#define ENCP_VIDEO_HAVON_END                       0x1ba3
+#define ENCP_VIDEO_HAVON_BEGIN                     0x1ba4
+#define ENCP_VIDEO_VAVON_ELINE                     0x1baf
+#define ENCP_VIDEO_VAVON_BLINE                     0x1ba6
+#define ENCP_VIDEO_HSO_BEGIN                       0x1ba7
+#define ENCP_VIDEO_HSO_END                         0x1ba8
+#define ENCP_VIDEO_VSO_BEGIN                       0x1ba9
+#define ENCP_VIDEO_VSO_END                         0x1baa
+#define ENCP_VIDEO_VSO_BLINE                       0x1bab
+#define ENCP_VIDEO_VSO_ELINE                       0x1bac
+#define ENCP_VIDEO_SYNC_WAVE_CURVE                 0x1bad
+#define ENCP_VIDEO_MAX_LNCNT                       0x1bae
+#define ENCP_VIDEO_SY_VAL                          0x1bb0
+#define ENCP_VIDEO_SY2_VAL                         0x1bb1
+#define ENCP_VIDEO_BLANKY_VAL                      0x1bb2
+#define ENCP_VIDEO_BLANKPB_VAL                     0x1bb3
+#define ENCP_VIDEO_BLANKPR_VAL                     0x1bb4
+#define ENCP_VIDEO_HOFFST                          0x1bb5
+#define ENCP_VIDEO_VOFFST                          0x1bb6
+#define ENCP_VIDEO_RGB_CTRL                        0x1bb7
+#define ENCP_VIDEO_FILT_CTRL                       0x1bb8
+#define ENCP_VIDEO_OFLD_VPEQ_OFST                  0x1bb9
+#define ENCP_VIDEO_OFLD_VOAV_OFST                  0x1bba
+#define ENCP_VIDEO_MATRIX_CB                       0x1bbb
+#define ENCP_VIDEO_MATRIX_CR                       0x1bbc
+#define ENCP_VIDEO_RGBIN_CTRL                      0x1bbd
+
+/* HIU */
+#define HHI_VIID_CLK_DIV                           0x4a
+#define DAC0_CLK_SEL           28
+#define DAC1_CLK_SEL           24
+#define DAC2_CLK_SEL           20
+#define VCLK2_XD_RST           17
+#define VCLK2_XD_EN            16
+#define ENCL_CLK_SEL           12
+#define VCLK2_XD                0
+
+#define HHI_VID_CLK_DIV                            0x59
+#define ENCI_CLK_SEL           28
+#define ENCP_CLK_SEL           24
+#define ENCT_CLK_SEL           20
+#define VCLK_XD_RST            17
+#define VCLK_XD_EN             16
+#define ENCL_CLK_SEL           12
+#define VCLK_XD1                8
+#define VCLK_XD0                0
+
+#define HHI_VID_CLK_CNTL2                          0x65
+#define HDMI_TX_PIXEL_GATE_VCLK  5
+#define VDAC_GATE_VCLK           4
+#define ENCL_GATE_VCLK           3
+#define ENCP_GATE_VCLK           2
+#define ENCT_GATE_VCLK           1
+#define ENCI_GATE_VCLK           0
+
+static inline unsigned int vout_vcbus_read(unsigned int _reg)
+{
+       return aml_read_vcbus(_reg);
+};
+
+static inline void vout_vcbus_write(unsigned int _reg, unsigned int _value)
+{
+       aml_write_vcbus(_reg, _value);
+};
+
+static inline void vout_vcbus_setb(unsigned int _reg, unsigned int _value,
+               unsigned int _start, unsigned int _len)
+{
+       vout_vcbus_write(_reg, ((vout_vcbus_read(_reg) &
+                       ~(((1L << (_len)) - 1) << (_start))) |
+                       (((_value) & ((1L << (_len)) - 1)) << (_start))));
+}
+
+static inline unsigned int vout_vcbus_getb(unsigned int reg,
+               unsigned int _start, unsigned int _len)
+{
+       return (vout_vcbus_read(reg) >> _start) & ((1L << _len) - 1);
+}
+
+static inline unsigned int vout_hiu_read(unsigned int _reg)
+{
+       return aml_read_hiubus(_reg);
+};
+
+static inline void vout_hiu_write(unsigned int _reg, unsigned int _value)
+{
+       aml_write_hiubus(_reg, _value);
+};
+
+static inline void vout_hiu_setb(unsigned int _reg, unsigned int _value,
+               unsigned int _start, unsigned int _len)
+{
+       vout_hiu_write(_reg, ((vout_hiu_read(_reg) &
+                       ~(((1L << (_len)) - 1) << (_start))) |
+                       (((_value) & ((1L << (_len)) - 1)) << (_start))));
+}
+
+static inline unsigned int vout_hiu_getb(unsigned int _reg,
+               unsigned int _start, unsigned int _len)
+{
+       return (vout_hiu_read(_reg) >> (_start)) & ((1L << (_len)) - 1);
+}
+
+#endif
index bc4ddfc..8452350 100644 (file)
@@ -129,24 +129,6 @@ static struct vinfo_s nulldisp_vinfo[] = {
                .viu_mux           = VIU_MUX_MAX,
                .vout_device       = NULL,
        },
-       {
-               .name              = "dummy_panel",
-               .mode              = VMODE_DUMMY_LCD,
-               .width             = 1920,
-               .height            = 1080,
-               .field_height      = 1080,
-               .aspect_ratio_num  = 16,
-               .aspect_ratio_den  = 9,
-               .sync_duration_num = 60,
-               .sync_duration_den = 1,
-               .video_clk         = 148500000,
-               .htotal            = 2200,
-               .vtotal            = 1125,
-               .fr_adj_type       = VOUT_FR_ADJ_NONE,
-               .viu_color_fmt     = COLOR_FMT_RGB444,
-               .viu_mux           = VIU_MUX_MAX,
-               .vout_device       = NULL,
-       },
 };
 
 static struct vinfo_s *nulldisp_get_current_info(void)
@@ -397,43 +379,6 @@ static ssize_t vout_mode_store(struct class *class,
        return count;
 }
 
-static ssize_t vout_dummy_store(struct class *class,
-               struct class_attribute *attr, const char *buf, size_t count)
-{
-       unsigned int tmp[4], sync_duration;
-       enum vmode_e mode;
-       int ret;
-
-       mutex_lock(&vout_serve_mutex);
-       mode = VMODE_DUMMY_LCD;
-       ret = sscanf(buf, "%d %d %d %d", &tmp[0], &tmp[1], &tmp[2], &tmp[3]);
-       if (ret == 2) {
-               vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE, &mode);
-               nulldisp_vinfo[2].width = tmp[0];
-               nulldisp_vinfo[2].height = tmp[1];
-               nulldisp_vinfo[2].field_height = tmp[1];
-               VOUTPR("set dummy size: %d x %d\n", tmp[0], tmp[1]);
-               vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE, &mode);
-       } else if (ret == 4) {
-               vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE, &mode);
-               nulldisp_vinfo[2].width = tmp[0];
-               nulldisp_vinfo[2].height = tmp[1];
-               nulldisp_vinfo[2].field_height = tmp[1];
-               nulldisp_vinfo[2].sync_duration_num = tmp[2];
-               nulldisp_vinfo[2].sync_duration_den = tmp[3];
-               sync_duration = (tmp[2] * 100) / tmp[3];
-               VOUTPR("set dummy size: %d x %d, frame_rate: %d.%02dHz\n",
-                       tmp[0], tmp[1],
-                       (sync_duration / 100), (sync_duration % 100));
-               vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE, &mode);
-       } else {
-               VOUTERR("invalid data\n");
-       }
-       mutex_unlock(&vout_serve_mutex);
-
-       return count;
-}
-
 static ssize_t vout_axis_show(struct class *class,
                struct class_attribute *attr, char *buf)
 {
@@ -610,7 +555,6 @@ static ssize_t vout_vinfo_show(struct class *class,
 
 static struct class_attribute vout_class_attrs[] = {
        __ATTR(mode,      0644, vout_mode_show, vout_mode_store),
-       __ATTR(dummy,      0644, NULL, vout_dummy_store),
        __ATTR(axis,      0644, vout_axis_show, vout_axis_store),
        __ATTR(fr_policy, 0644,
                vout_fr_policy_show, vout_fr_policy_store),
index 6ef397b..ee462b0 100644 (file)
@@ -23,7 +23,7 @@
 /* the MSB is represent vmode set by vmode_init */
 #define        VMODE_INIT_BIT_MASK     0x8000
 #define        VMODE_MODE_BIT_MASK     0xff
-#define VMODE_NULL_DISP_MAX    3
+#define VMODE_NULL_DISP_MAX    2
 
 enum vmode_e {
        VMODE_HDMI = 0,