author | Evoke Zhang <evoke.zhang@amlogic.com> | 2019-06-06 02:32:39 (GMT) |
---|---|---|
committer | Tao Zeng <tao.zeng@amlogic.com> | 2019-06-19 02:00:49 (GMT) |
commit | a425e81dcf70dee0523880efd159c4b144e4d876 (patch) | |
tree | ec2112842cfddce369bbd3ef839c42ff8f062bec | |
parent | 775fc0ac6feacb0261a543bbda35456b7bcd3ed1 (diff) | |
download | common-a425e81dcf70dee0523880efd159c4b144e4d876.zip common-a425e81dcf70dee0523880efd159c4b144e4d876.tar.gz common-a425e81dcf70dee0523880efd159c4b144e4d876.tar.bz2 |
vout: add dummy_lcd driver support [1/1]
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>
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | arch/arm/boot/dts/amlogic/tl1_t962x2_x301_1g.dts | 21 | ||||
-rw-r--r-- | arch/arm/boot/dts/amlogic/tl1_t962x2_x301_2g.dts | 21 | ||||
-rw-r--r-- | arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_1g.dts | 21 | ||||
-rw-r--r-- | arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_2g.dts | 21 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/lcd/lcd_common.c | 29 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/lcd/lcd_common.h | 2 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/lcd/lcd_debug.c | 10 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c | 10 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c | 10 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/vout_serve/Makefile | 2 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/vout_serve/dummy_lcd.c | 661 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/vout_serve/vout_func.c | 37 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/vout_serve/vout_reg.h | 227 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/vout_serve/vout_serve.c | 56 | ||||
-rw-r--r-- | include/linux/amlogic/media/vout/vinfo.h | 2 |
16 files changed, 1022 insertions, 110 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index b5cbd05..7594ecb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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> diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_1g.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_1g.dts index b07108b..a1a9b8d 100644 --- a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_1g.dts +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_1g.dts @@ -247,6 +247,27 @@ 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>; diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_2g.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_2g.dts index 1fa6470..f3c1782 100644 --- a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_2g.dts +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_2g.dts @@ -242,6 +242,27 @@ 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>; diff --git a/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_1g.dts b/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_1g.dts index ec9f977..91ce75a 100644 --- a/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_1g.dts +++ b/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_1g.dts @@ -244,6 +244,27 @@ 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>; diff --git a/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_2g.dts b/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_2g.dts index 679520e..4258a02 100644 --- a/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_2g.dts +++ b/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_2g.dts @@ -238,6 +238,27 @@ 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>; diff --git a/drivers/amlogic/media/vout/lcd/lcd_common.c b/drivers/amlogic/media/vout/lcd/lcd_common.c index ca87abc..d6db171 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_common.c +++ b/drivers/amlogic/media/vout/lcd/lcd_common.c @@ -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 + } +} diff --git a/drivers/amlogic/media/vout/lcd/lcd_common.h b/drivers/amlogic/media/vout/lcd/lcd_common.h index 32dc89c..1f1d392 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_common.h +++ b/drivers/amlogic/media/vout/lcd/lcd_common.h @@ -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); diff --git a/drivers/amlogic/media/vout/lcd/lcd_debug.c b/drivers/amlogic/media/vout/lcd/lcd_debug.c index 734ace3..339f60dd 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_debug.c +++ b/drivers/amlogic/media/vout/lcd/lcd_debug.c @@ -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) diff --git a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c index 424ca35..c62d124 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c @@ -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, diff --git a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c index 0ce5c0d..02d152d 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c @@ -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, diff --git a/drivers/amlogic/media/vout/vout_serve/Makefile b/drivers/amlogic/media/vout/vout_serve/Makefile index a67378b..a8b4a89 100644 --- a/drivers/amlogic/media/vout/vout_serve/Makefile +++ b/drivers/amlogic/media/vout/vout_serve/Makefile @@ -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 index 0000000..0c63725 --- a/dev/null +++ b/drivers/amlogic/media/vout/vout_serve/dummy_lcd.c @@ -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); + diff --git a/drivers/amlogic/media/vout/vout_serve/vout_func.c b/drivers/amlogic/media/vout/vout_serve/vout_func.c index 0ea80a6..eae6240 100644 --- a/drivers/amlogic/media/vout/vout_serve/vout_func.c +++ b/drivers/amlogic/media/vout/vout_serve/vout_func.c @@ -22,11 +22,11 @@ #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 index 0000000..54c265f --- a/dev/null +++ b/drivers/amlogic/media/vout/vout_serve/vout_reg.h @@ -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 diff --git a/drivers/amlogic/media/vout/vout_serve/vout_serve.c b/drivers/amlogic/media/vout/vout_serve/vout_serve.c index bc4ddfc..8452350 100644 --- a/drivers/amlogic/media/vout/vout_serve/vout_serve.c +++ b/drivers/amlogic/media/vout/vout_serve/vout_serve.c @@ -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), diff --git a/include/linux/amlogic/media/vout/vinfo.h b/include/linux/amlogic/media/vout/vinfo.h index 6ef397b..ee462b0 100644 --- a/include/linux/amlogic/media/vout/vinfo.h +++ b/include/linux/amlogic/media/vout/vinfo.h @@ -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, |