diff options
Diffstat (limited to 'drivers/video')
72 files changed, 9518 insertions, 7486 deletions
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index a8d900d0..5671093c 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -1,14 +1,21 @@ -/* - * linux/drivers/video/backlight/pwm_bl.c - * - * simple PWM based backlight control, board code has to setup - * 1) pin configuration so PWM waveforms can output - * 2) platform_data being correctly configured - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ +/*++ + linux/drivers/video/backlight/pwm_bl.c + + Copyright (c) 2013 WonderMedia Technologies, Inc. + + 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. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ #include <linux/module.h> #include <linux/kernel.h> @@ -20,18 +27,9 @@ #include <linux/pwm.h> #include <linux/pwm_backlight.h> #include <linux/slab.h> -#include <linux/irq.h> #include <mach/hardware.h> -#include <linux/delay.h> -#include <linux/gpio.h> -#include <mach/wmt_iomux.h> - -int pwm_or_gpio=1; -extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); - - struct pwm_bl_data { struct pwm_device *pwm; struct device *dev; @@ -58,85 +56,6 @@ static inline void __pwm0_gpio_setup(void) REG32_VAL(PIN_SHARING_SEL_4BYTE_ADDR) &= ~0x1000; } -static int pre_brightness_value; -void sgm3727_bl_brightness(int brightness_value) -{ - int i = 0; - int pulse_num = 0; - brightness_value= (brightness_value-10)*31/245; - brightness_value = 31 - brightness_value; - - if (brightness_value >= 32) - { - brightness_value = 31; - } - if (brightness_value < 0) - { - brightness_value = 0; - } - //printk("%s,brightness_value=%d,%d\n",__FUNCTION__,pre_brightness_value,brightness_value); - if(pre_brightness_value == brightness_value) - { - return; - } - else if(pre_brightness_value == 0xFF) - { - pulse_num = brightness_value; - } - else if(brightness_value>pre_brightness_value) - { - pulse_num = brightness_value - pre_brightness_value; - } - else - { - pulse_num = (brightness_value + 32 ) - pre_brightness_value; - } - - //printk("%s,pulse_num=%d\n",__FUNCTION__,pulse_num); - if (pulse_num < 32) - { - local_irq_disable(); - if(pre_brightness_value == 0xFF) - { - gpio_direction_output(WMT_PIN_GP0_GPIO0,0); - mdelay(5);//5 - gpio_direction_output(WMT_PIN_GP0_GPIO0,1); - udelay(50); - } - for (i=0; i < pulse_num; i++) - { - gpio_direction_output(WMT_PIN_GP0_GPIO0,0); - udelay(10);//50 - gpio_direction_output(WMT_PIN_GP0_GPIO0,1); - udelay(10);//50 - } - local_irq_enable(); - } - - pre_brightness_value = brightness_value; -} - -static int cw500_backlight_update_status(struct backlight_device *bl) -{ - struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); - int brightness = bl->props.brightness; - int max = bl->props.max_brightness; - - if(!brightness) - { - gpio_direction_output(WMT_PIN_GP0_GPIO0,0); - pre_brightness_value = 0xFF; - mdelay(10); - return; - } - else - { - sgm3727_bl_brightness(brightness); - } - - return 0; -} - static int pwm_backlight_update_status(struct backlight_device *bl) { struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); @@ -187,31 +106,12 @@ static int pwm_backlight_check_fb(struct backlight_device *bl, return !pb->check_fb || pb->check_fb(pb->dev, info); } -backlight_update_status_select(struct backlight_device *bl) -{ - if(pwm_or_gpio){ - //printk("pwm branch\n"); - pwm_backlight_update_status(bl); - }else{ - printk("gpio branch\n"); - cw500_backlight_update_status(bl); - } - -} - static const struct backlight_ops pwm_backlight_ops = { - //.update_status = pwm_backlight_update_status,//TODO: add uboot control rubbit - //.update_status = cw500_backlight_update_status, - .update_status = backlight_update_status_select, + .update_status = pwm_backlight_update_status, .get_brightness = pwm_backlight_get_brightness, .check_fb = pwm_backlight_check_fb, }; -/* -* wmt.bl_select: -* 0----->gpio control back light -* 1----->pwm control back light -* default pwm control back light -*/ + static int pwm_backlight_probe(struct platform_device *pdev) { struct backlight_properties props; @@ -219,18 +119,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) struct backlight_device *bl; struct pwm_bl_data *pb; int ret; - unsigned char buf[64]; - int varlen = sizeof(buf); - memset(buf, 0x0, sizeof(buf)); - ret = wmt_getsyspara("wmt.bl_select", buf, &varlen); - if (ret == 0) { - sscanf(buf, "%d", &pwm_or_gpio); - } - else { - pwm_or_gpio = 1; - printk("default use pwm to control backlight,pwm_or_gpio:%d\n",pwm_or_gpio); - } if (!data) { dev_err(&pdev->dev, "failed to find platform data\n"); return -EINVAL; @@ -248,16 +137,9 @@ static int pwm_backlight_probe(struct platform_device *pdev) ret = -ENOMEM; goto err_alloc; } - if(pwm_or_gpio){ - __pwm0_gpio_setup(); - }else{ - pre_brightness_value = 0; - //ret = gpio_request(WMT_PIN_GP0_GPIO0,"gpio lcd back light"); - //if (ret){ - // printk("gpio_request gpio lcd back light failed\n"); - // goto err_alloc; - //} - } + + __pwm0_gpio_setup(); + pb->invert = data->invert; pb->period = data->pwm_period_ns; pb->notify = data->notify; @@ -313,53 +195,36 @@ static int pwm_backlight_remove(struct platform_device *pdev) pwm_free(pb->pwm); if (data->exit) data->exit(&pdev->dev); - if(!pwm_or_gpio) - gpio_free(WMT_PIN_GP0_GPIO0); return 0; } #ifdef CONFIG_PM static int pwm_backlight_suspend(struct device *dev) { - int ret=0; struct backlight_device *bl = dev_get_drvdata(dev); struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); - printk("%s\n",__func__); + if (pb->notify) pb->notify(pb->dev, 0); - if(pwm_or_gpio){ - if (pb->invert) { - pwm_config(pb->pwm, pb->period, pb->period); - } else { - pwm_config(pb->pwm, 0, pb->period); - pwm_disable(pb->pwm); - } - }else{ + if (pb->invert) { + pwm_config(pb->pwm, pb->period, pb->period); + } else { + pwm_config(pb->pwm, 0, pb->period); + pwm_disable(pb->pwm); } if (pb->notify_after) pb->notify_after(pb->dev, 0); - if(!pwm_or_gpio){ - gpio_free(WMT_PIN_GP0_GPIO0); - } return 0; } static int pwm_backlight_resume(struct device *dev) { - int ret=0; - printk("%s\n",__func__); - if(pwm_or_gpio){ - __pwm0_gpio_setup(); - }else{ - ret = gpio_request(WMT_PIN_GP0_GPIO0,"gpio lcd back light"); - if (ret){ - printk("gpio_request gpio lcd back light failed\n"); - return -1; - } - gpio_direction_output(WMT_PIN_GP0_GPIO0,0); - } + //struct backlight_device *bl = dev_get_drvdata(dev); + //backlight_update_status(bl); + + __pwm0_gpio_setup(); return 0; } diff --git a/drivers/video/backlight/wmt_bl.c b/drivers/video/backlight/wmt_bl.c index 97087216..66d02ca7 100755..100644 --- a/drivers/video/backlight/wmt_bl.c +++ b/drivers/video/backlight/wmt_bl.c @@ -1,6 +1,21 @@ -/* - * for backlight control on wmt platform, base on pwm_bl.c - */ +/*++ + linux/drivers/video/backlight/wmt_bl.c + + Copyright (c) 2013 WonderMedia Technologies, Inc. + + 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. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ #include <linux/module.h> #include <linux/kernel.h> @@ -24,7 +39,7 @@ static struct { static int backlight_delay = 0; -static struct led_trigger *logo_led; +static struct led_trigger *genesis_led; static BLOCKING_NOTIFIER_HEAD(bl_chain_head); int register_bl_notifier(struct notifier_block *nb) @@ -61,17 +76,9 @@ static void backlight_on(bool on) msleep(backlight_delay); } gpio_direction_output(power.gpio, on ? power.active : !power.active); - led_trigger_event(logo_led, on ? LED_FULL : LED_OFF); - - if (!on) { - /* - * delay 100 ms between 'backlight power off' and 'lcd power off' - * at suspend sequence to avoid to lcd flicker - */ - msleep(100); - } - + led_trigger_event(genesis_led, on ? LED_FULL : LED_OFF); old_state = on; + bl_notifier_call_chain(on ? BL_OPEN : BL_CLOSE); } } @@ -175,14 +182,14 @@ static int __init wmt_bl_init(void) if (rc) return rc; - led_trigger_register_simple("logoled", &logo_led); + led_trigger_register_simple("genesis", &genesis_led); return platform_device_register(&wm8880_device_pwmbl); } static void __exit wmt_bl_exit(void) { - led_trigger_unregister_simple(logo_led); + led_trigger_unregister_simple(genesis_led); platform_device_unregister(&wm8880_device_pwmbl); } diff --git a/drivers/video/backlight/wmt_bl.h b/drivers/video/backlight/wmt_bl.h index a25117b9..a5d5dfde 100755..100644 --- a/drivers/video/backlight/wmt_bl.h +++ b/drivers/video/backlight/wmt_bl.h @@ -1,3 +1,22 @@ +/*++
+ linux/drivers/video/backlight/wmt_bl.h
+
+ Copyright (c) 2013 WonderMedia Technologies, Inc.
+
+ 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.
+ You should have received a copy of the GNU General Public License along with
+ this program. If not, see <http://www.gnu.org/licenses/>.
+
+ WonderMedia Technologies, Inc.
+ 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
#ifndef _LINUX_WMT_BL_H
#define _LINUX_WMT_BL_H
diff --git a/drivers/video/wmt/Makefile b/drivers/video/wmt/Makefile index 1847d587..9603160c 100755..100644 --- a/drivers/video/wmt/Makefile +++ b/drivers/video/wmt/Makefile @@ -11,8 +11,8 @@ obj-$(CONFIG_FB_WMT) += vout-wmt.o # wmt vpp obj-$(CONFIG_FB_WMT) += vout.o vpp.o govrh.o scl.o vppm.o lvds.o -obj-$(CONFIG_WMT_HDMI) += hdmi.o -obj-$(CONFIG_FB_WMT) += vpp-osif.o wmt-vpp.o wmt-sync.o +obj-$(CONFIG_WMT_HDMI) += hdmi.o hdmi_cp.o +obj-$(CONFIG_FB_WMT) += vpp-osif.o wmt-sync.o obj-$(CONFIG_WMT_CEC) += cec.o dev-cec.o obj-$(CONFIG_FB_WMT) += mali.o diff --git a/drivers/video/wmt/bootanimation/LzmaDec.c b/drivers/video/wmt/bootanimation/LzmaDec.c index 10f6cda6..b8be701d 100755..100644 --- a/drivers/video/wmt/bootanimation/LzmaDec.c +++ b/drivers/video/wmt/bootanimation/LzmaDec.c @@ -1,5 +1,21 @@ -/* LzmaDec.c -- LZMA Decoder -2008-11-06 : Igor Pavlov : Public domain */ +/*++ + linux/drivers/video/wmt/LzmaDec.c + + Copyright (c) 2013 WonderMedia Technologies, Inc. + + 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. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ #include "LzmaDec.h" diff --git a/drivers/video/wmt/bootanimation/LzmaDec.h b/drivers/video/wmt/bootanimation/LzmaDec.h index 98cdbe94..232ec65e 100755..100644 --- a/drivers/video/wmt/bootanimation/LzmaDec.h +++ b/drivers/video/wmt/bootanimation/LzmaDec.h @@ -1,5 +1,21 @@ -/* LzmaDec.h -- LZMA Decoder -2008-10-04 : Igor Pavlov : Public domain */ +/*++ + linux/drivers/video/wmt/LzmaDec.h + + Copyright (c) 2013 WonderMedia Technologies, Inc. + + 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. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ #ifndef __LZMADEC_H #define __LZMADEC_H diff --git a/drivers/video/wmt/bootanimation/Makefile b/drivers/video/wmt/bootanimation/Makefile index f0d021a8..f0d021a8 100755..100644 --- a/drivers/video/wmt/bootanimation/Makefile +++ b/drivers/video/wmt/bootanimation/Makefile diff --git a/drivers/video/wmt/bootanimation/Types.h b/drivers/video/wmt/bootanimation/Types.h index 60cfe05e..1b74ece9 100755..100644 --- a/drivers/video/wmt/bootanimation/Types.h +++ b/drivers/video/wmt/bootanimation/Types.h @@ -1,5 +1,21 @@ -/* Types.h -- Basic types -2010-03-11 : Igor Pavlov : Public domain */ +/*++ + linux/drivers/video/wmt/Types.h + + Copyright (c) 2013 WonderMedia Technologies, Inc. + + 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. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ #ifndef __7Z_TYPES_H #define __7Z_TYPES_H diff --git a/drivers/video/wmt/bootanimation/anim_data.h b/drivers/video/wmt/bootanimation/anim_data.h index 1932ee0d..079528f6 100755..100644 --- a/drivers/video/wmt/bootanimation/anim_data.h +++ b/drivers/video/wmt/bootanimation/anim_data.h @@ -1,3 +1,22 @@ +/*++ + linux/drivers/video/wmt/anim_data.h + + Copyright (c) 2013 WonderMedia Technologies, Inc. + + 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. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ + static const unsigned char __initdata anim_data[] = { 0x21,0x43,0x34,0x12,0x01,0x01,0x01,0x00,0xAA,0x38,0x00,0x00,0x05,0x01,0x00,0x00, diff --git a/drivers/video/wmt/bootanimation/animation.c b/drivers/video/wmt/bootanimation/animation.c index de803ccd..ce37c44d 100755..100644 --- a/drivers/video/wmt/bootanimation/animation.c +++ b/drivers/video/wmt/bootanimation/animation.c @@ -1,10 +1,21 @@ -/** - * Author: Aimar Ma <AimarMa@wondermedia.com.cn> - * - * Show animation during kernel boot stage - * - * - **/ +/*++ + linux/drivers/video/wmt/animation.c + + Copyright (c) 2013 WonderMedia Technologies, Inc. + + 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. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ #include <linux/mm.h> #include <linux/timer.h> diff --git a/drivers/video/wmt/bootanimation/animation.h b/drivers/video/wmt/bootanimation/animation.h index e63686ec..f3d316df 100755..100644 --- a/drivers/video/wmt/bootanimation/animation.h +++ b/drivers/video/wmt/bootanimation/animation.h @@ -1,3 +1,22 @@ +/*++ + linux/drivers/video/wmt/animation.h + + Copyright (c) 2013 WonderMedia Technologies, Inc. + + 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. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ + #ifndef _BOOTANIMATION_H_ #define _BOOTANIMATION_H_ diff --git a/drivers/video/wmt/bootanimation/buffer.c b/drivers/video/wmt/bootanimation/buffer.c index 6b6f1b89..5e6f1fe7 100755..100644 --- a/drivers/video/wmt/bootanimation/buffer.c +++ b/drivers/video/wmt/bootanimation/buffer.c @@ -1,4 +1,21 @@ +/*++ + linux/drivers/video/wmt/buffer.c + Copyright (c) 2013 WonderMedia Technologies, Inc. + + 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. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ #include "buffer.h" #define assert(int ) diff --git a/drivers/video/wmt/bootanimation/buffer.h b/drivers/video/wmt/bootanimation/buffer.h index 3ac79aa5..0203ad80 100755..100644 --- a/drivers/video/wmt/bootanimation/buffer.h +++ b/drivers/video/wmt/bootanimation/buffer.h @@ -1,3 +1,22 @@ +/*++ + linux/drivers/video/wmt/buffer.h + + Copyright (c) 2013 WonderMedia Technologies, Inc. + + 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. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ + #ifndef ANIMATION_BUFFER_H_INCLUDED #define ANIMATION_BUFFER_H_INCLUDED diff --git a/drivers/video/wmt/cec.c b/drivers/video/wmt/cec.c index 5f80c334..8d2115fb 100755..100644 --- a/drivers/video/wmt/cec.c +++ b/drivers/video/wmt/cec.c @@ -47,13 +47,11 @@ int cec_physical_addr; /*---------------------------- CEC COMMON API -------------------------------*/ #ifdef WMT_FTBLK_CEC - -struct cec_base_regs *cec_regs = (void *) CEC_BASE_ADDR; /*---------------------------- CEC HAL --------------------------------------*/ void wmt_cec_tx_data(char *buf, int size) { int i; - unsigned int reg; + unsigned int addr, reg; int wait_idle; #ifdef DEBUG @@ -69,7 +67,7 @@ void wmt_cec_tx_data(char *buf, int size) } wait_idle = 0; - while (cec_regs->enable.b.wr_start) { + while (vppif_reg32_read(CEC_WR_START)) { /* wait idle */ if (wait_idle >= 10) { DPRINT("[CEC] wait idle timeout\n"); return; @@ -79,30 +77,37 @@ void wmt_cec_tx_data(char *buf, int size) return; } + addr = REG_CEC_ENCODE_HEADER; for (i = 0; i < size; i++) { reg = (buf[i] << 4) + 0x1; if (i == (size - 1)) reg |= BIT1; - cec_regs->encode_data[i].val = reg; + vppif_reg32_out(addr, reg); +#ifdef DEBUG + DPRINT("[CEC] wr 0x%x = 0x%x\n", addr, reg); +#endif + addr += 4; } - cec_regs->encode_number.b.wr_num = (size * 10) + 0x1; - cec_regs->enable.b.wr_start = 1; + vppif_reg32_write(CEC_WR_NUM, (size * 10) + 0x1); + vppif_reg32_write(CEC_WR_START, 1); } int wmt_cec_rx_data(char *buf) { int i, size; - unsigned int reg; + unsigned int addr, reg; + addr = REG_CEC_DECODE_HEADER; for (i = 0; i < 16; i++) { - reg = cec_regs->decode_data[i].val; + reg = vppif_reg32_in(addr); buf[i] = (reg & 0xFF0) >> 4; if (reg & BIT1) /* EOM */ break; + addr += 4; } - cec_regs->decode_reset.b.finish_reset = 1; + vppif_reg32_write(CEC_FINISH_RESET, 1); mdelay(1); - cec_regs->decode_reset.b.finish_reset = 0; + vppif_reg32_write(CEC_FINISH_RESET, 0); size = i + 1; #ifdef DEBUG DPRINT("[CEC] rx data(%d):\n", size); @@ -117,114 +122,98 @@ void wmt_cec_set_clock(void) { #define CEC_CLOCK (1000000 / 7984) - cec_regs->wr_start_set0 = (370 * CEC_CLOCK); /* 3.7 ms */ - cec_regs->wr_start_set1 = (450 * CEC_CLOCK); /* 4.5 ms */ - cec_regs->wr_logic0_set0 = (150 * CEC_CLOCK); /* 1.5 ms */ - cec_regs->wr_logic0_set1 = (240 * CEC_CLOCK); /* 2.4 ms */ - cec_regs->wr_logic1_set0 = (60 * CEC_CLOCK); /* 0.6 ms */ - cec_regs->wr_logic1_set1 = (240 * CEC_CLOCK); /* 2.4 ms */ - cec_regs->rd_start_l_set0 = (350 * CEC_CLOCK); /* 3.5 ms */ - cec_regs->rd_start_r_set0 = (390 * CEC_CLOCK); /* 3.9 ms */ - cec_regs->rd_start_l_set1 = (430 * CEC_CLOCK); /* 4.3 ms */ - cec_regs->rd_start_r_set1 = (470 * CEC_CLOCK); /* 4.7 ms */ - cec_regs->rd_logic0_l_set0 = (130 * CEC_CLOCK); /* 1.3 ms */ - cec_regs->rd_logic0_r_set0 = (170 * CEC_CLOCK); /* 1.7 ms */ - cec_regs->rd_logic0_l_set1 = (205 * CEC_CLOCK); /* 2.05 ms*/ - cec_regs->rd_logic0_r_set1 = (275 * CEC_CLOCK); /* 2.75 ms*/ - cec_regs->rd_logic1_l_set0 = (40 * CEC_CLOCK); /* 0.4 ms */ - cec_regs->rd_logic1_r_set0 = (80 * CEC_CLOCK); /* 0.8 ms */ - cec_regs->rd_logic1_l_set1 = (205 * CEC_CLOCK); /* 2.05 ms*/ - cec_regs->rd_logic1_r_set1 = (275 * CEC_CLOCK); /* 2.75 ms*/ - cec_regs->rd_l_set0_error = (182 * CEC_CLOCK); /* 1.82 ms */ - cec_regs->rd_r_set1_error = (238 * CEC_CLOCK); /* 2.38 ms */ - cec_regs->rd_l_error = (287 * CEC_CLOCK); /* 2.87 ms */ - cec_regs->rx_sample_l_range = (85 * CEC_CLOCK); /* 0.85 ms*/ - cec_regs->rx_sample_r_range = (125 * CEC_CLOCK); /*1.25 ms*/ - cec_regs->wr_set0_error = (225 * CEC_CLOCK); /* 2.25 ms */ - cec_regs->wr_set1_error = (225 * CEC_CLOCK); /* 2.25 ms ?*/ + vppif_reg32_out(REG_CEC_WR_START_SET0, 370 * CEC_CLOCK); /* 3.7 ms */ + vppif_reg32_out(REG_CEC_WR_START_SET1, 450 * CEC_CLOCK); /* 4.5 ms */ + vppif_reg32_out(REG_CEC_WR_LOGIC0_SET0, 150 * CEC_CLOCK); /* 1.5 ms */ + vppif_reg32_out(REG_CEC_WR_LOGIC0_SET1, 240 * CEC_CLOCK); /* 2.4 ms */ + vppif_reg32_out(REG_CEC_WR_LOGIC1_SET0, 60 * CEC_CLOCK); /* 0.6 ms */ + vppif_reg32_out(REG_CEC_WR_LOGIC1_SET1, 240 * CEC_CLOCK); /* 2.4 ms */ + vppif_reg32_out(REG_CEC_RD_START_L_SET0, 350 * CEC_CLOCK); /* 3.5 ms */ + vppif_reg32_out(REG_CEC_RD_START_R_SET0, 390 * CEC_CLOCK); /* 3.9 ms */ + vppif_reg32_out(REG_CEC_RD_START_L_SET1, 430 * CEC_CLOCK); /* 4.3 ms */ + vppif_reg32_out(REG_CEC_RD_START_R_SET1, 470 * CEC_CLOCK); /* 4.7 ms */ + vppif_reg32_out(REG_CEC_RD_LOGIC0_L_SET0, 130 * CEC_CLOCK); /* 1.3 ms */ + vppif_reg32_out(REG_CEC_RD_LOGIC0_R_SET0, 170 * CEC_CLOCK); /* 1.7 ms */ + vppif_reg32_out(REG_CEC_RD_LOGIC0_L_SET1, 205 * CEC_CLOCK); /* 2.05 ms*/ + vppif_reg32_out(REG_CEC_RD_LOGIC0_R_SET1, 275 * CEC_CLOCK); /* 2.75 ms*/ + vppif_reg32_out(REG_CEC_RD_LOGIC1_L_SET0, 40 * CEC_CLOCK); /* 0.4 ms */ + vppif_reg32_out(REG_CEC_RD_LOGIC1_R_SET0, 80 * CEC_CLOCK); /* 0.8 ms */ + vppif_reg32_out(REG_CEC_RD_LOGIC1_L_SET1, 205 * CEC_CLOCK); /* 2.05 ms*/ + vppif_reg32_out(REG_CEC_RD_LOGIC1_R_SET1, 275 * CEC_CLOCK); /* 2.75 ms*/ + vppif_reg32_out(REG_CEC_RD_L_SET0_ERROR, 182 * CEC_CLOCK); /* 1.82 ms */ + vppif_reg32_out(REG_CEC_RD_R_SET1_ERROR, 238 * CEC_CLOCK); /* 2.38 ms */ + vppif_reg32_out(REG_CEC_RD_L_ERROR, 287 * CEC_CLOCK); /* 2.87 ms */ + vppif_reg32_out(REG_CEC_RX_SAMPLE_L_RANGE, 85 * CEC_CLOCK); /* 0.85 ms*/ + vppif_reg32_out(REG_CEC_RX_SAMPLE_R_RANGE, 125 * CEC_CLOCK); /*1.25 ms*/ + vppif_reg32_out(REG_CEC_WR_SET0_ERROR, 225 * CEC_CLOCK); /* 2.25 ms */ + vppif_reg32_out(REG_CEC_WR_SET1_ERROR, 225 * CEC_CLOCK); /* 2.25 ms ?*/ } void wmt_cec_set_logical_addr(int no, char addr, int enable) { - switch (no) { - case 0: - cec_regs->logical_addr.b.addr1 = addr; - cec_regs->logical_addr.b.valid1 = addr; - break; - case 1: - cec_regs->logical_addr.b.addr2 = addr; - cec_regs->logical_addr.b.valid2 = addr; - break; - case 2: - cec_regs->logical_addr.b.addr3 = addr; - cec_regs->logical_addr.b.valid3 = addr; - break; - case 3: - cec_regs->logical_addr.b.addr4 = addr; - cec_regs->logical_addr.b.valid4 = addr; - break; - case 4: - cec_regs->logical_addr.b.addr5 = addr; - cec_regs->logical_addr.b.valid5 = addr; - break; - default: - DPRINT("[CEC] *W* invalid %d\n", no); - break; + unsigned int mask; + + if (no > 5) { + DPRINT("[CEC] *W* max 5\n"); + return; } + mask = 0xF << (4 * no); + vppif_reg32_write(REG_CEC_LOGICAL_ADDR, mask, 4 * no, addr); + mask = BIT24 << no; + vppif_reg32_write(REG_CEC_LOGICAL_ADDR, mask, 24 + no, enable); DBGMSG("[CEC] set logical addr %d,0x%x\n", no, addr); } void wmt_cec_rx_enable(int enable) { - cec_regs->reject.b.next_decode = (enable) ? 0 : 1; + vppif_reg32_write(CEC_REJECT_NEXT_DECODE, (enable) ? 0 : 1); /* GPIO4 disable GPIO function */ vppif_reg32_write(GPIO_BASE_ADDR + 0x40, BIT4, 4, (enable) ? 0 : 1); } void wmt_cec_enable_int(int no, int enable) { - if (enable) - cec_regs->int_enable |= (0x1 << no); - else - cec_regs->int_enable &= ~(0x1 << no); + vppif_reg32_write(REG_CEC_INT_ENABLE, 0x1 << no, no, enable); } void wmt_cec_clr_int(int sts) { - cec_regs->status.val = sts; + vppif_reg32_out(REG_CEC_STATUS, sts); } int wmt_cec_get_int(void) { int reg; - reg = cec_regs->status.val; + + reg = vppif_reg32_in(REG_CEC_STATUS); return reg; } void wmt_cec_enable_loopback(int enable) { /* 1 : read self write and all dest data */ - cec_regs->rd_encode.b.enable = enable; + vppif_reg32_write(CEC_RD_ENCODE_ENABLE, enable); } void wmt_cec_init_hw(void) { wmt_cec_set_clock(); - cec_regs->wr_retry.b.retry = 3; - cec_regs->rx_trig_range = 2; - - cec_regs->free_3x.b.free_3x = 3; - cec_regs->free_3x.b.free_5x = 5; - cec_regs->free_3x.b.free_7x = 7; - - cec_regs->comp.b.disable = 1; - cec_regs->handle_disable.b.err = 0; - cec_regs->handle_disable.b.no_ack = 0; - cec_regs->decode_full.b.disable = 0; - cec_regs->status4_disable.b.start = 1; - cec_regs->status4_disable.b.logic0 = 1; - cec_regs->status4_disable.b.logic1 = 1; - cec_regs->rd_encode.b.enable = 0; + vppif_reg32_write(CEC_WR_RETRY, 3); + vppif_reg32_out(REG_CEC_RX_TRIG_RANGE, 2); + + vppif_reg32_write(CEC_FREE_3X, 3); + vppif_reg32_write(CEC_FREE_5X, 5); + vppif_reg32_write(CEC_FREE_7X, 7); + + vppif_reg32_write(CEC_COMP_DISABLE, 1); + vppif_reg32_write(CEC_ERR_HANDLE_DISABLE, 0); + vppif_reg32_write(CEC_NO_ACK_DISABLE, 0); + vppif_reg32_write(CEC_DECODE_FULL_DISABLE, 0); + vppif_reg32_write(CEC_STATUS4_START_DISABLE, 1); + vppif_reg32_write(CEC_STATUS4_LOGIC0_DISABLE, 1); + vppif_reg32_write(CEC_STATUS4_LOGIC1_DISABLE, 1); + /* 1 : read self write and all dest data */ + vppif_reg32_write(CEC_RD_ENCODE_ENABLE, 0); } /*---------------------------- CEC API --------------------------------------*/ @@ -235,68 +224,69 @@ void wmt_cec_reg_dump(void) DPRINT("---------- CEC Tx ----------\n"); DPRINT("wr start %d,wr num %d\n", - cec_regs->enable.b.wr_start, cec_regs->encode_number.b.wr_num); + vppif_reg32_read(CEC_WR_START), + vppif_reg32_read(CEC_WR_NUM)); DPRINT("wr header ack %d,EOM %d,data 0x%x\n", - cec_regs->encode_data[0].b.wr_data_ack, - cec_regs->encode_data[0].b.wr_data_eom, - cec_regs->encode_data[0].b.wr_data); + vppif_reg32_read(CEC_WR_HEADER_ACK), + vppif_reg32_read(CEC_WR_HEADER_EOM), + vppif_reg32_read(CEC_WR_HEADER_DATA)); DPRINT("wr data ack %d,EOM %d,data 0x%x\n", - cec_regs->encode_data[1].b.wr_data_ack, - cec_regs->encode_data[1].b.wr_data_eom, - cec_regs->encode_data[1].b.wr_data); + vppif_reg32_read(CEC_WR_DATA_ACK), + vppif_reg32_read(CEC_WR_DATA_EOM), + vppif_reg32_read(CEC_WR_DATA)); DPRINT("finish reset %d,wr retry %d\n", - cec_regs->decode_reset.b.finish_reset, - cec_regs->wr_retry.b.retry); + vppif_reg32_read(CEC_FINISH_RESET), + vppif_reg32_read(CEC_WR_RETRY)); DPRINT("---------- CEC Rx ----------\n"); DPRINT("rd start %d,all ack %d,finish %d\n", - cec_regs->decode_start.b.rd_start, - cec_regs->decode_start.b.rd_all_ack, - cec_regs->decode_start.b.rd_finish); + vppif_reg32_read(CEC_RD_START), + vppif_reg32_read(CEC_RD_ALL_ACK), + vppif_reg32_read(CEC_RD_FINISH)); DPRINT("rd header ack %d,EOM %d,data 0x%x\n", - cec_regs->decode_data[0].b.rd_data_ack, - cec_regs->decode_data[0].b.rd_data_eom, - cec_regs->decode_data[0].b.rd_data); + vppif_reg32_read(CEC_RD_HEADER_ACK), + vppif_reg32_read(CEC_RD_HEADER_ACK), + vppif_reg32_read(CEC_RD_HEADER_DATA)); DPRINT("rd data ack %d,EOM %d,data 0x%x\n", - cec_regs->decode_data[1].b.rd_data_ack, - cec_regs->decode_data[1].b.rd_data_eom, - cec_regs->decode_data[1].b.rd_data); + vppif_reg32_read(CEC_RD_DATA_ACK), + vppif_reg32_read(CEC_RD_DATA_EOM), + vppif_reg32_read(CEC_RD_DATA)); DPRINT("---------- Logical addr ----------\n"); DPRINT("addr1 0x%x,valid %d\n", - cec_regs->logical_addr.b.addr1, - cec_regs->logical_addr.b.valid1); + vppif_reg32_read(CEC_LOGICAL_ADDR1), + vppif_reg32_read(CEC_ADDR_VALID1)); DPRINT("addr2 0x%x,valid %d\n", - cec_regs->logical_addr.b.addr2, - cec_regs->logical_addr.b.valid2); + vppif_reg32_read(CEC_LOGICAL_ADDR2), + vppif_reg32_read(CEC_ADDR_VALID2)); DPRINT("addr3 0x%x,valid %d\n", - cec_regs->logical_addr.b.addr3, - cec_regs->logical_addr.b.valid3); + vppif_reg32_read(CEC_LOGICAL_ADDR3), + vppif_reg32_read(CEC_ADDR_VALID3)); DPRINT("addr4 0x%x,valid %d\n", - cec_regs->logical_addr.b.addr4, - cec_regs->logical_addr.b.valid4); + vppif_reg32_read(CEC_LOGICAL_ADDR4), + vppif_reg32_read(CEC_ADDR_VALID4)); DPRINT("addr5 0x%x,valid %d\n", - cec_regs->logical_addr.b.addr5, - cec_regs->logical_addr.b.valid5); + vppif_reg32_read(CEC_LOGICAL_ADDR5), + vppif_reg32_read(CEC_ADDR_VALID5)); DPRINT("---------- Misc ----------\n"); - DPRINT("free 3x %d,5x %d,7x %d\n", - cec_regs->free_3x.b.free_3x, cec_regs->free_3x.b.free_5x, - cec_regs->free_3x.b.free_7x); + DPRINT("free 3x %d,5x %d,7x %d\n", vppif_reg32_read(CEC_FREE_3X), + vppif_reg32_read(CEC_FREE_5X), vppif_reg32_read(CEC_FREE_7X)); DPRINT("reject next decode %d,comp disable %d\n", - cec_regs->reject.b.next_decode, cec_regs->comp.b.disable); + vppif_reg32_read(CEC_REJECT_NEXT_DECODE), + vppif_reg32_read(CEC_COMP_DISABLE)); DPRINT("err handle disable %d,no ack disable %d\n", - cec_regs->handle_disable.b.err, - cec_regs->handle_disable.b.no_ack); + vppif_reg32_read(CEC_ERR_HANDLE_DISABLE), + vppif_reg32_read(CEC_NO_ACK_DISABLE)); DPRINT("r1 enc ok %d,r1 dec ok %d,r1 err %d\n", - cec_regs->status.b.r1_encode_ok, - cec_regs->status.b.r1_decode_ok, - cec_regs->status.b.r1_error); + vppif_reg32_read(CEC_R1_ENCODE_OK), + vppif_reg32_read(CEC_R1_DECODE_OK), + vppif_reg32_read(CEC_R1_ERROR)); DPRINT("r1 arb fail %d,r1 no ack %d\n", - cec_regs->status.b.r1_arb_fail, - cec_regs->status.b.r1_no_ack); + vppif_reg32_read(CEC_R1_ARB_FAIL), + vppif_reg32_read(CEC_R1_NO_ACK)); DPRINT("dec full disable %d,self rd enable %d\n", - cec_regs->decode_full.b.disable, - cec_regs->rd_encode.b.enable); + vppif_reg32_read(CEC_DECODE_FULL_DISABLE), + vppif_reg32_read(CEC_RD_ENCODE_ENABLE)); } #ifdef CONFIG_PM @@ -311,7 +301,7 @@ void wmt_cec_do_suspend(void) void wmt_cec_do_resume(void) { - vppm_regs->sw_reset2.val = 0x1011111; + vppif_reg32_out(REG_VPP_SWRST2_SEL, 0x1011111); /* disable GPIO function */ vppif_reg32_write(GPIO_BASE_ADDR + 0x40, BIT4, 4, 0); /* GPIO4 disable GPIO out */ diff --git a/drivers/video/wmt/cec.h b/drivers/video/wmt/cec.h index 887be767..d11d27b3 100755..100644 --- a/drivers/video/wmt/cec.h +++ b/drivers/video/wmt/cec.h @@ -23,7 +23,8 @@ #include "vpp-osif.h" #include "./hw/wmt-vpp-hw.h" -#include "hw/wmt-cec-reg.h" +#include "vpp.h" +#include "com-cec.h" #ifdef WMT_FTBLK_CEC diff --git a/drivers/video/wmt/com-cec.h b/drivers/video/wmt/com-cec.h index 8020aec5..80f1ce16 100755..100644 --- a/drivers/video/wmt/com-cec.h +++ b/drivers/video/wmt/com-cec.h @@ -42,16 +42,14 @@ extern "C" { #define MAX_MSG_BYTE 16 #define MSG_ABORT 0xff -struct wmt_cec_msg { +typedef struct wmt_cec_msg { char msglen; char msgdata[MAX_MSG_BYTE]; -}; -#define wmt_cec_msg_t struct wmt_cec_msg +} wmt_cec_msg_t; -struct wmt_phy_addr { +typedef struct wmt_phy_addr { unsigned int phy_addr; -}; -#define wmt_phy_addr_t struct wmt_phy_addr +} wmt_phy_addr_t; #define WMT_CEC_IOC_MAGIC 'c' #define WMT_CEC_IOC_MAXNR 3 diff --git a/drivers/video/wmt/com-mb.h b/drivers/video/wmt/com-mb.h index 1b1380b5..2045a8ea 100755..100644 --- a/drivers/video/wmt/com-mb.h +++ b/drivers/video/wmt/com-mb.h @@ -1,19 +1,19 @@ -/*++ - * WonderMedia Memory Block driver +/*++ + * WonderMedia Memory Block driver * * Copyright c 2010 WonderMedia Technologies, Inc. * - * 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 + * 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. + * 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. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * WonderMedia Technologies, Inc. @@ -31,7 +31,7 @@ /*------------------------------------------------------------------------------ Macros below are used for driver in IOCTL ------------------------------------------------------------------------------*/ -#define MB_IOC_MAGIC 'M' +#define MB_IOC_MAGIC 'M' /* O: physical address I: size */ #define MBIO_MALLOC _IOWR(MB_IOC_MAGIC, 0, unsigned long) @@ -58,7 +58,7 @@ #define MBIO_STATIC_SIZE _IOR(MB_IOC_MAGIC, 10, unsigned long) /* O: use counter I: physical address */ #define MBIO_MB_USER_COUNT _IOWR(MB_IOC_MAGIC, 11, unsigned long) -#define MBIO_FORCE_RESET _IO(MB_IOC_MAGIC, 12) +#define MBIO_FORCE_RESET _IO (MB_IOC_MAGIC,12) /* I: phys address */ #define MBIO_GET_BY_PHYS _IOW(MB_IOC_MAGIC, 13, unsigned long) /* I: phys address */ @@ -71,20 +71,6 @@ #define MBIO_SET_CACHABLE _IOW(MB_IOC_MAGIC, 17, unsigned long) /* O: property of MB */ #define MBIO_CLR_CACHABLE _IOW(MB_IOC_MAGIC, 18, unsigned long) -/* I: phys address */ -#define MBIO_STATIC_GET _IOW(MB_IOC_MAGIC, 19, unsigned long) -/* I: phys address */ -#define MBIO_STATIC_PUT _IOW(MB_IOC_MAGIC, 20, unsigned long) -/* I: user address O: physical address */ -#define MBIO_TEST_USER2PHYS _IOWR(MB_IOC_MAGIC, 100, unsigned long) -/* I: user address, size, prdt addr, and prdt size */ -#define MBIO_TEST_USER2PRDT _IOWR(MB_IOC_MAGIC, 101, unsigned long) -/* I: user address, size, mmu addr, and mmu size O: mmu physical addr */ -#define MBIO_TEST_USER2MMUT _IOWR(MB_IOC_MAGIC, 102, unsigned long) -/* I: user address, size, prdt addr, and prdt size */ -#define MBIO_TEST_MB2PRDT _IOWR(MB_IOC_MAGIC, 103, unsigned long) -/* I: user address, size, mmu addr, and mmu size O: mmu physical addr */ -#define MBIO_TEST_MB2MMUT _IOWR(MB_IOC_MAGIC, 104, unsigned long) #endif /* ifndef COM_MB_H */ diff --git a/drivers/video/wmt/com-vpp.h b/drivers/video/wmt/com-vpp.h index 4076c4ae..52447ffb 100755..100644 --- a/drivers/video/wmt/com-vpp.h +++ b/drivers/video/wmt/com-vpp.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/com-vpp.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -25,18 +25,18 @@ #define COM_VPP_H #ifdef __KERNEL__ -#include <linux/types.h> -#include <linux/fb.h> -#include <asm/io.h> -#include <mach/common_def.h> -#include <mach/com-video.h> + #include <linux/types.h> + #include <linux/fb.h> + #include <asm/io.h> + #include <mach/common_def.h> + #include <mach/com-video.h> #else -#include "com-video.h" -#ifdef CFG_LOADER -#include "com-fb.h" -#endif + #include "com-video.h" + #include "com-fb.h" #endif +#define VPP_OLD_API + #define VPP_NEW_FBUF_MANAGER #define VPP_AHB_CLK 250000000 @@ -106,12 +106,12 @@ #define BIT30 0x40000000 #define BIT31 0x80000000 -#define VPP_YUV_BLACK 0x008080 /* Y, Cr, Cb */ -#define VPP_YUV_WHITE 0xff8080 -#define VPP_YUV_RED 0x51f05a -#define VPP_YUV_GREEN 0x902235 -#define VPP_YUV_BLUE 0x286df0 -#define VPP_RGB32_BLACK 0x00000000 +#define VPP_YUV_BLACK 0x00, 0x80, 0x80 /* Y, Cr, Cb */ +#define VPP_YUV_WHITE 0xff, 0x80, 0x80 +#define VPP_YUV_RED 0x51, 0xf0, 0x5a +#define VPP_YUV_GREEN 0x90, 0x22, 0x35 +#define VPP_YUV_BLUE 0x28, 0x6d, 0xf0 +#define VPP_RGB32_BLACK 0x00, 0x00, 0x00, 0x00 #define VPP_COL_RGB32_BLACK 0x000000 #define VPP_COL_RGB32_WHITE 0xFFFFFF @@ -129,16 +129,15 @@ #define WMT_FB_COLFMT(a) (a & 0xFF) -enum vpp_fbuf_s { +typedef enum { VPP_FBUF_GOVR_1, VPP_FBUF_GOVR_2, VPP_FBUF_SCLR_1, VPP_FBUF_SCLR_2, VPP_FBUF_MAX -}; -#define vpp_fbuf_t enum vpp_fbuf_s +} vpp_fbuf_t; -enum vpp_flag_s { +typedef enum { VPP_FLAG_NULL = 0, VPP_FLAG_ENABLE = 1, VPP_FLAG_DISABLE = 0, @@ -150,10 +149,9 @@ enum vpp_flag_s { VPP_FLAG_ERROR = 0, VPP_FLAG_RD = 1, VPP_FLAG_WR = 0, -}; -#define vpp_flag_t enum vpp_flag_s +} vpp_flag_t; -enum vpp_mod_s { +typedef enum { VPP_MOD_GOVRH2, VPP_MOD_GOVRH, VPP_MOD_DISP, @@ -168,12 +166,11 @@ enum vpp_mod_s { VPP_MOD_LCDC, VPP_MOD_CURSOR, VPP_MOD_MAX -}; -#define vpp_mod_t enum vpp_mod_s +} vpp_mod_t; -enum vpp_vout_s { - VPP_VOUT_NONE = 0, - VPP_VOUT_SDA = 1, +typedef enum { + VPP_VOUT_SDA = 0, + VPP_VOUT_SDD = 1, VPP_VOUT_LCD = 2, VPP_VOUT_DVI = 3, VPP_VOUT_HDMI = 4, @@ -181,26 +178,50 @@ enum vpp_vout_s { VPP_VOUT_LVDS = 6, VPP_VOUT_VGA = 7, VPP_VOUT_FBDEV = 8, - VPP_VOUT_VIRDISP = 9, VPP_VOUT_MAX -}; -#define vpp_vout_t enum vpp_vout_s - -enum vpp_display_format_s { +} vpp_vout_t; + +typedef enum { + VPP_OUTDEV_TV_NORMAL, /* NTSC 720x480 or PAL 720x576 */ + VPP_OUTDEV_VGA, + VPP_OUTDEV_DVO, + VPP_OUTDEV_MAX +} vpp_output_device_t; + +typedef enum { + VPP_ALPHA_VIDEO, + VPP_ALPHA_GE, + VPP_ALPHA_MAX, +} vpp_alpha_t; + +typedef enum { VPP_DISP_FMT_FRAME, /* Progressive */ VPP_DISP_FMT_FIELD, /* Interlace */ VPP_DISP_FMT_MAX, -}; -#define vpp_display_format_t enum vpp_display_format_s +} vpp_display_format_t; -enum vpp_media_format_s { +typedef enum { VPP_MEDIA_FMT_MPEG, VPP_MEDIA_FMT_H264, VPP_MEDIA_FMT_MAX, -}; -#define vpp_media_format_t enum vpp_media_format_s - -enum vpp_csc_s { /* don't change this order */ +} vpp_media_format_t; + +typedef enum { + VPP_PATH_NULL = 0, + VPP_PATH_ALL = 0xffffffff, + /* in */ + VPP_PATH_GOVM_IN_VPU = BIT0, + VPP_PATH_GOVM_IN_SCL = BIT1, + VPP_PATH_GOVM_IN_GE = BIT2, + VPP_PATH_GOVM_IN_PIP = BIT3, + VPP_PATH_GOVM_IN_SPU = BIT4, + VPP_PATH_GOVM_IN_CUR = BIT5, + /* out */ + VPP_PATH_SCL_OUT_REALTIME = BIT10, + VPP_PATH_SCL_OUT_RECURSIVE = BIT11, +} vpp_path_t; + +typedef enum { /* don't change this order */ VPP_CSC_YUV2RGB2_MIN, VPP_CSC_YUV2RGB_SDTV_0_255 = VPP_CSC_YUV2RGB2_MIN, VPP_CSC_YUV2RGB_SDTV_16_235, @@ -217,27 +238,75 @@ enum vpp_csc_s { /* don't change this order */ VPP_CSC_RGB2YUV_JFIF_0_255, VPP_CSC_RGB2YUV_SMPTE170M, VPP_CSC_RGB2YUV_SMPTE240M, - VPP_CSC_RGB2YUV_JFIF_VT1625, VPP_CSC_MAX, VPP_CSC_BYPASS -}; -#define vpp_csc_t enum vpp_csc_s +} vpp_csc_t; -enum vpp_reglevel_s { +typedef enum { VPP_REG_LEVEL_1, VPP_REG_LEVEL_2, VPP_REG_LEVEL_MAX, -}; -#define vpp_reglevel_t enum vpp_reglevel_s - -enum vpp_datawidht_s { +} vpp_reglevel_t; + +typedef enum { + VPP_BPP_1, + VPP_BPP_2, + VPP_BPP_4, + VPP_BPP_8, + VPP_BPP_12, + VPP_BPP_16_565, + VPP_BPP_16_555 = VPP_BPP_16_565, + VPP_BPP_18, + VPP_BPP_24, + VPP_BPP_MAX, +} vpp_bpp_t; + +typedef enum { + VPP_GAMMA_DISABLE, + VPP_GAMMA_22, + VPP_GAMMA_24, + VPP_GAMMA_28, + VPP_GAMMA_MAX, +} vpp_gamma_t; + +typedef enum { VPP_DATAWIDHT_12, VPP_DATAWIDHT_24, VPP_DATAWIDHT_MAX, -}; -#define vpp_datawidht_t enum vpp_datawidht_s - -enum vpp_tvsys_s { +} vpp_datawidht_t; + +typedef enum { + VPP_ADDR_NORMAL, + VPP_ADDR_BURST, + VPP_ADDR_MAX, +} vpp_addr_mode_t; + +typedef enum { + VPP_DEI_WEAVE, + VPP_DEI_BOB, + VPP_DEI_ADAPTIVE_ONE, + VPP_DEI_ADAPTIVE_THREE, + VPP_DEI_FIELD, + VPP_DEI_MOTION_VECTOR, + VPP_DEI_MAX, + VPP_DEI_DYNAMIC, +} vpp_deinterlace_t; + +typedef enum { + VPP_DIR_THERE, + VPP_DIR_TWO, + VPP_DIR_FOUR, + VPP_DIR_FIVE, + VPP_DIR_MAX, +} vpp_direction_t; + +typedef enum { + VPP_FIELD_TOP, + VPP_FIELD_BOTTOM, + VPP_FIELD_MAX, +} vpp_field_t; + +typedef enum { VPP_TVSYS_NTSC, VPP_TVSYS_NTSCJ, VPP_TVSYS_NTSC443, @@ -250,10 +319,9 @@ enum vpp_tvsys_s { VPP_TVSYS_1080I, VPP_TVSYS_1080P, VPP_TVSYS_MAX -}; -#define vpp_tvsys_t enum vpp_tvsys_s +} vpp_tvsys_t; -enum vpp_tvconn_s { +typedef enum { VPP_TVCONN_YCBCR, VPP_TVCONN_SCART, VPP_TVCONN_YPBPR, @@ -261,14 +329,28 @@ enum vpp_tvconn_s { VPP_TVCONN_SVIDEO, VPP_TVCONN_CVBS, VPP_TVCONN_MAX -}; -#define vpp_tvconn_t enum vpp_tvconn_s +} vpp_tvconn_t; #define VPP_OPT_INTERLACE 0x01 #define VPP_DVO_SYNC_POLAR_HI 0x08 #define VPP_DVO_VSYNC_POLAR_HI 0x10 -struct vpp_clock_s { +typedef struct { + unsigned int pixel_clock; + unsigned int option; + + unsigned int hsync; + unsigned int hbp; + unsigned int hpixel; + unsigned int hfp; + + unsigned int vsync; + unsigned int vbp; + unsigned int vpixel; + unsigned int vfp; +} vpp_timing_t; + +typedef struct { int read_cycle; unsigned int total_pixel_of_line; @@ -283,24 +365,27 @@ struct vpp_clock_s { unsigned int vsync; unsigned int line_number_between_VBIS_VBIE; unsigned int line_number_between_PVBI_VBIS; -}; -#define vpp_clock_t struct vpp_clock_s +} vpp_clock_t; + +typedef struct _vpp_image_t { + U32 y_addr; + U32 c_addr; + vdo_color_fmt src_col_fmt; +} vpp_image_t; -struct vpp_scale_s { +typedef struct { vdo_framebuf_t src_fb; vdo_framebuf_t dst_fb; -}; -#define vpp_scale_t struct vpp_scale_s +} vpp_scale_t; -struct vpp_scale_overlap_s { +typedef struct { int mode; vdo_framebuf_t src_fb; vdo_framebuf_t src2_fb; vdo_framebuf_t dst_fb; -}; -#define vpp_scale_overlap_t struct vpp_scale_overlap_s +} vpp_scale_overlap_t; -struct vpp_overlap_s { +typedef struct { unsigned int alpha_src_type:2; /* 0-mif1,1-mif2,2-fix */ unsigned int alpha_src:8; unsigned int alpha_dst_type:2; /* 0-mif1,1-mif2,2-fix */ @@ -313,8 +398,7 @@ struct vpp_overlap_s { 5-(pix2,alpha),6-(pix1,pix2),7-(pix2,pix1) */ unsigned int reserved:4; unsigned int color_key; /* ARGB */ -}; -#define vpp_overlap_t struct vpp_overlap_s +} vpp_overlap_t; #define VPP_VOUT_STS_REGISTER 0x01 #define VPP_VOUT_STS_ACTIVE 0x02 @@ -323,24 +407,67 @@ struct vpp_overlap_s { #define VPP_VOUT_STS_BLANK 0x10 #define VPP_VOUT_STS_POWERDN 0x20 #define VPP_VOUT_STS_CONTENT_PROTECT 0x40 -#define VPP_VOUT_STS_FB 0xF00 -#define VPP_VOUT_ARG_NUM 5 -struct vpp_vout_info_s { - enum vpp_vout_s mode[VPP_VOUT_ARG_NUM]; - unsigned int status[VPP_VOUT_ARG_NUM]; -}; -#define vpp_vout_info_t struct vpp_vout_info_s - -struct vpp_vout_parm_s { +typedef struct { int num; - int arg; -}; -#define vpp_vout_parm_t struct vpp_vout_parm_s + unsigned int status; + char name[10]; +} vpp_vout_info_t; +typedef struct { + int num; + int arg; +} vpp_vout_parm_t; + +/* ============================================================================= + vout option + ============================================================================= + vout id option1 option2 - b8(1:blank) + SDA 0 tvsys tvconn + SDD 1 tvsys tvconn + LCD 2 lcd id bit per pixel(bit0-7), + b8(1:blank),b9-11(igs mode), + bit12-13(swap) + DVI 3 colfmt b0(0:12bit,1:24bit), + b1(1:interlace),b8(1:blank), + b9-11(igs mode),bit12-13(swap) + HDMI 4 colfmt b0(0:12bit,1:24bit), + b1(1:interlace),b8(1:blank) + DVO2HDMI 5 colfmt b0(0:12bit,1:24bit), + b1(1:interlace),b8(1:blank) + LVDS 6 lcd id bit per pixel(bit0-7), + b8(1:blank),b9-11(igs mode), + bit12-13(swap) + VGA 7 + FBDEV 8 + ============================================================================= + tvsys : 0-NTSC,3-PAL,8-720p,9-1080i,10-1080p + tvconn: 0-YCbCr,1-SCART,2-YPbPr,3-VGA,4-SVideo,5-CVBS + colfmt: 0-420,1-422H,3-444,6-ARGB,8-RGB24,9-RGB18,10-RGB16 + lcdid : 0-OEM(VGA 1024x768),1-Chilin(7"800x480), + 2-Innolux(7"800x480),3-AUO(800x600), + 4-Eking(800x600),5-Hannstar(10"1024x600) + ========================================================================== */ +#define VOUT_OPT_DWIDTH24 BIT(0) +#define VOUT_OPT_INTERLACE BIT(1) #define VOUT_OPT_BLANK BIT(8) +typedef struct { + int num; + unsigned int option[3]; +} vpp_vout_option_t; + +typedef struct { + int num; + vpp_timing_t tmr; +} vpp_vout_tmr_t; + +typedef struct { + unsigned int yaddr; + unsigned int caddr; +} vpp_fbaddr_t; + #define VPP_CAP_DUAL_DISPLAY BIT(0) -struct vpp_cap_s { +typedef struct { unsigned int chip_id; unsigned int version; unsigned int resx_max; @@ -348,63 +475,120 @@ struct vpp_cap_s { unsigned int pixel_clk; unsigned int module; unsigned int option; -}; -#define vpp_cap_t struct vpp_cap_s - -struct vpp_i2c_s { +} vpp_cap_t; + +typedef struct { + vpp_flag_t enable; + vpp_alpha_t mode; + int A; + int B; +} vpp_alpha_parm_t; + +typedef struct { + vpp_path_t src_path; + vpp_flag_t enable; +} vpp_src_path_t; + +typedef struct { + vpp_flag_t enable; + vpp_flag_t sync_polar; + vpp_flag_t vsync_polar; + vdo_color_fmt color_fmt; + vpp_datawidht_t data_w; + int clk_inv; + int clk_delay; +} vdo_dvo_parm_t; + +typedef struct { unsigned int addr; unsigned int index; unsigned int val; -}; -#define vpp_i2c_t struct vpp_i2c_s +} vpp_i2c_t; + +#define VPP_FLAG_DISPFB_ADDR BIT(0) +#define VPP_FLAG_DISPFB_INFO BIT(1) +#define VPP_FLAG_DISPFB_VIEW BIT(2) +#define VPP_FLAG_DISPFB_PIP BIT(3) +#define VPP_FLAG_DISPFB_MB_ONE BIT(4) +#define VPP_FLAG_DISPFB_MB_NO BIT(6) +typedef struct { + unsigned int yaddr; + unsigned int caddr; + vdo_framebuf_t info; + vdo_view_t view; + + unsigned int flag; +} vpp_dispfb_t; + +typedef struct { + vpp_mod_t mod; + int read; + unsigned int arg1; + unsigned int arg2; +} vpp_mod_arg_t; -struct vpp_mod_fbinfo_s { +typedef struct { + vpp_mod_t mod; + int read; + vpp_timing_t tmr; +} vpp_mod_timing_t; + +typedef struct { vpp_mod_t mod; int read; vdo_framebuf_t fb; -}; -#define vpp_mod_fbinfo_t struct vpp_mod_fbinfo_s +} vpp_mod_fbinfo_t; + +typedef struct { + vpp_mod_t mod; + int read; + vdo_view_t view; +} vpp_mod_view_t; -struct vpp_vmode_parm_s { +typedef struct { unsigned int resx; unsigned int resy; unsigned int fps; unsigned int option; -}; -#define vpp_vmode_parm_t struct vpp_vmode_parm_s +} vpp_vmode_parm_t; #define VPP_VOUT_VMODE_NUM 20 -struct vpp_vout_vmode_s { +typedef struct { vpp_vout_t mode; int num; vpp_vmode_parm_t parm[VPP_VOUT_VMODE_NUM]; -}; -#define vpp_vout_vmode_t struct vpp_vout_vmode_s - -struct vpp_vout_edid_s { +} vpp_vout_vmode_t; + +typedef struct { + int queue_cnt; + int cur_cnt; + int isr_cnt; + int disp_cnt; + int skip_cnt; + int full_cnt; + int reserved[2]; +} vpp_dispfb_info_t; + +typedef struct { vpp_vout_t mode; int size; char *buf; -}; -#define vpp_vout_edid_t struct vpp_vout_edid_s +} vpp_vout_edid_t; -struct vpp_vout_cp_info_s { +typedef struct { int num; unsigned int bksv[2]; -}; -#define vpp_vout_cp_info_t struct vpp_vout_cp_info_s +} vpp_vout_cp_info_t; #define VPP_VOUT_CP_NUM 336 -struct vpp_vout_cp_key_s { +typedef struct { char key[VPP_VOUT_CP_NUM]; -}; -#define vpp_vout_cp_key_t struct vpp_vout_cp_key_s +} vpp_vout_cp_key_t; -struct vpp_mod_parm_t { - vpp_mod_t mod; - int read; - unsigned int parm; -}; +typedef struct { + vpp_deinterlace_t mode; + int level; +} vpp_deinterlace_parm_t; #define VPPIO_MAGIC 'f' @@ -414,22 +598,52 @@ struct vpp_mod_parm_t { #define VPPIO_VPPSET_INFO _IOW(VPPIO_MAGIC, VPPIO_VPP_BASE + 0, vpp_cap_t) #define VPPIO_I2CSET_BYTE _IOW(VPPIO_MAGIC, VPPIO_VPP_BASE + 1, vpp_i2c_t) #define VPPIO_I2CGET_BYTE _IOR(VPPIO_MAGIC, VPPIO_VPP_BASE + 1, vpp_i2c_t) -#define VPPIO_MODSET_CSC \ - _IOW(VPPIO_MAGIC, VPPIO_VPP_BASE + 2, struct vpp_mod_parm_t) +#define VPPIO_MODULE_FRAMERATE \ + _IOWR(VPPIO_MAGIC, VPPIO_VPP_BASE + 2, vpp_mod_arg_t) +#define VPPIO_MODULE_ENABLE \ + _IOWR(VPPIO_MAGIC, VPPIO_VPP_BASE + 3, vpp_mod_arg_t) +#define VPPIO_MODULE_TIMING \ + _IOWR(VPPIO_MAGIC, VPPIO_VPP_BASE + 4, vpp_mod_timing_t) +#define VPPIO_MODULE_FBADDR \ + _IOWR(VPPIO_MAGIC, VPPIO_VPP_BASE + 5, vpp_mod_arg_t) #define VPPIO_MODULE_FBINFO \ _IOWR(VPPIO_MAGIC, VPPIO_VPP_BASE + 6, vpp_mod_fbinfo_t) +/* #define VPPIO_VPPSET_DIRECTPATH _IO(VPPIO_MAGIC,VPPIO_VPP_BASE + 7) */ +#define VPPIO_VPPSET_FBDISP _IOW(VPPIO_MAGIC, VPPIO_VPP_BASE + 8, vpp_dispfb_t) +#define VPPIO_VPPGET_FBDISP \ + _IOW(VPPIO_MAGIC, VPPIO_VPP_BASE + 8, vpp_dispfb_info_t) +#define VPPIO_WAIT_FRAME _IO(VPPIO_MAGIC, VPPIO_VPP_BASE + 9) +#define VPPIO_MODULE_VIEW \ + _IOWR(VPPIO_MAGIC, VPPIO_VPP_BASE + 10, vpp_mod_view_t) #define VPPIO_STREAM_ENABLE _IO(VPPIO_MAGIC, VPPIO_VPP_BASE + 12) #define VPPIO_STREAM_GETFB \ _IOR(VPPIO_MAGIC, VPPIO_VPP_BASE + 13, vdo_framebuf_t) #define VPPIO_STREAM_PUTFB \ _IOW(VPPIO_MAGIC, VPPIO_VPP_BASE + 13, vdo_framebuf_t) +#define VPPIO_MODULE_CSC _IOWR(VPPIO_MAGIC, VPPIO_VPP_BASE + 14, vpp_mod_arg_t) #define VPPIO_MULTIVD_ENABLE _IO(VPPIO_MAGIC, VPPIO_VPP_BASE + 15) /* VOUT ioctl command */ #define VPPIO_VOUT_BASE 0x10 #define VPPIO_VOGET_INFO _IOR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 0, vpp_vout_info_t) -#define VPPIO_VOGET_HDMI_3D \ - _IOR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 1, struct vpp_vout_parm_s) +#define VPPIO_VOSET_MODE \ + _IOW(VPPIO_MAGIC, VPPIO_VOUT_BASE + 1, vpp_vout_parm_t) +#define VPPIO_VOSET_BLANK \ + _IOW(VPPIO_MAGIC, VPPIO_VOUT_BASE + 2, vpp_vout_parm_t) +/* #define VPPIO_VOSET_DACSENSE \ + _IOW(VPPIO_MAGIC, VPPIO_VOUT_BASE + 3, vpp_vout_parm_t) */ +#define VPPIO_VOSET_BRIGHTNESS \ + _IOW(VPPIO_MAGIC, VPPIO_VOUT_BASE + 4, vpp_vout_parm_t) +#define VPPIO_VOGET_BRIGHTNESS \ + _IOR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 4, vpp_vout_parm_t) +#define VPPIO_VOSET_CONTRAST \ + _IOW(VPPIO_MAGIC, VPPIO_VOUT_BASE + 5, vpp_vout_parm_t) +#define VPPIO_VOGET_CONTRAST \ + _IOR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 5, vpp_vout_parm_t) +#define VPPIO_VOSET_OPTION \ + _IOW(VPPIO_MAGIC, VPPIO_VOUT_BASE + 6, vpp_vout_option_t) +#define VPPIO_VOGET_OPTION \ + _IOR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 6, vpp_vout_option_t) #define VPPIO_VOUT_VMODE \ _IOWR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 7, vpp_vout_vmode_t) #define VPPIO_VOGET_EDID _IOR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 8, vpp_vout_edid_t) @@ -438,11 +652,22 @@ struct vpp_mod_parm_t { #define VPPIO_VOSET_CP_KEY \ _IOW(VPPIO_MAGIC, VPPIO_VOUT_BASE + 10, vpp_vout_cp_key_t) #define VPPIO_VOSET_AUDIO_PASSTHRU _IO(VPPIO_MAGIC, VPPIO_VOUT_BASE + 11) +/* #define VPPIO_VOSET_OVERSCAN_OFFSET \ + _IOW(VPPIO_MAGIC, VPPIO_VOUT_BASE + 12, vpp_vout_overscan_offset_t) */ #define VPPIO_VOSET_VIRTUAL_FBDEV _IO(VPPIO_MAGIC, VPPIO_VOUT_BASE + 13) +/* GOVR ioctl command */ +#define VPPIO_GOVR_BASE 0x20 +#define VPPIO_GOVRSET_DVO _IOW(VPPIO_MAGIC, VPPIO_GOVR_BASE + 0, vdo_dvo_parm_t) +#define VPPIO_GOVRSET_CUR_COLKEY \ + _IOW(VPPIO_MAGIC, VPPIO_GOVR_BASE + 1, vpp_mod_arg_t) +#define VPPIO_GOVRSET_CUR_HOTSPOT \ + _IOW(VPPIO_MAGIC, VPPIO_GOVR_BASE + 2, vpp_mod_arg_t) + /* SCL ioctl command */ #define VPPIO_SCL_BASE 0x60 #define VPPIO_SCL_SCALE _IOWR(VPPIO_MAGIC, VPPIO_SCL_BASE + 0, vpp_scale_t) +#define VPPIO_SCL_DROP_LINE_ENABLE _IO(VPPIO_MAGIC, VPPIO_SCL_BASE + 1) #define VPPIO_SCL_SCALE_ASYNC \ _IOWR(VPPIO_MAGIC, VPPIO_SCL_BASE + 2, vpp_scale_t) #define VPPIO_SCL_SCALE_FINISH _IO(VPPIO_MAGIC, VPPIO_SCL_BASE + 3) diff --git a/drivers/video/wmt/dev-cec.c b/drivers/video/wmt/dev-cec.c index 84105bd0..f03b202b 100755..100644 --- a/drivers/video/wmt/dev-cec.c +++ b/drivers/video/wmt/dev-cec.c @@ -30,7 +30,6 @@ #include <linux/netlink.h> #include <net/sock.h> #include "cec.h" -#include "vpp.h" #define DRIVER_NAME "wmt-cec" @@ -320,7 +319,7 @@ static ssize_t wmt_cec_write( return ret; } /* End of videodecoder_write() */ -const struct file_operations wmt_cec_fops = { +struct file_operations wmt_cec_fops = { .owner = THIS_MODULE, .open = wmt_cec_open, .release = wmt_cec_release, @@ -370,7 +369,8 @@ static int __init wmt_cec_probe if (vpp_request_irq(IRQ_VPP_IRQ20, wmt_cec_do_irq, SA_INTERRUPT, "cec", (void *) 0)) DPRINT("*E* request CEC ISR fail\n"); - cec_regs->int_enable = 0x1f; + vppif_reg32_out(REG_CEC_INT_ENABLE, 0x1f); + DBGMSG("[CEC] Exit wmt_cec_probe(0x%x)\n", dev_no); return 0; } /* End of wmt_cec_probe */ diff --git a/drivers/video/wmt/devices/Makefile b/drivers/video/wmt/devices/Makefile index da55ae48..955c31ec 100755..100644 --- a/drivers/video/wmt/devices/Makefile +++ b/drivers/video/wmt/devices/Makefile @@ -10,17 +10,11 @@ obj-$(CONFIG_LCD_AUO_A080SN01) += lcd-AUO-A080SN01.o obj-$(CONFIG_LCD_EKING_EK08009) += lcd-EKING-EK08009-70135.o obj-$(CONFIG_LCD_HANNSTAR_HSD101PFW2) += lcd-HANNSTAR-HSD101PFW2.o obj-y += lcd-lvds-1024x600.o -obj-y += lcd-gl5001w.o -#obj-y += cs8556.o -#obj-y += lcd-b079xan01.o -obj-y += lcd-spi.o -obj-y += lcd-setup.o +obj-y += cs8556.o +obj-y += lcd-b079xan01.o obj-$(CONFIG_LCD_WMT) += lcd.o -#obj-$(CONFIG_HDMI_SIL902X_WMT) += sil902x.o -#obj-$(CONFIG_HDCP_SIL902X_WMT) += sil9024/ -obj-$(CONFIG_DVI_VT1632_WMT) += vt1632.o -obj-$(CONFIG_TV_VT1625_WMT) += vt1625.o +obj-$(CONFIG_DVI_VT1632_WMT) += vt1632.o vt1625.o #obj-$(CONFIG_HDMI_CAT6610_WMT) += cat6612.o cat6610/ #obj-$(CONFIG_HDMI_AD9389_WMT) += ad9389.o #obj-$(CONFIG_EXTTV_ADV7393_WMT) += ad7393.o diff --git a/drivers/video/wmt/devices/cs8556.c b/drivers/video/wmt/devices/cs8556.c index 72097685..c44fb336 100755..100644 --- a/drivers/video/wmt/devices/cs8556.c +++ b/drivers/video/wmt/devices/cs8556.c @@ -1,627 +1,617 @@ -/*++ - * linux/drivers/video/wmt/cs8556.c - * WonderMedia video post processor (VPP) driver - * - * Copyright c 2013 WonderMedia Technologies, Inc. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ -/********************************************************************* -* REVISON HISTORY -* -* VERSION | DATE | AUTHORS | DESCRIPTION -* 1.0 | 2013/08/24 | Howay Huo | First Release -**********************************************************************/ - -#define CS8556_C -/* #define DEBUG */ -/*----------------------- DEPENDENCE -----------------------------------------*/ -#include <linux/i2c.h> -#include <mach/hardware.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/gpio.h> -#include <mach/wmt_iomux.h> -#include "../vout.h" - -/*----------------------- PRIVATE MACRO --------------------------------------*/ -/* #define VT1632_XXXX xxxx *//*Example*/ - - -/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ -/* #define VT1632_XXXX 1 *//*Example*/ -#define CS8556_ADDR 0x3d -#define CS8556_NAME "CS8556" - -/*----------------------- PRIVATE TYPE --------------------------------------*/ -/* typedef xxxx vt1632_xxx_t; *//*Example*/ -struct avdetect_gpio_t { - unsigned int flag; - unsigned int gpiono; - unsigned int act; -}; - -/*----------EXPORTED PRIVATE VARIABLES are defined in vt1632.h -------------*/ -/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ -/* int vt1632_xxx; *//*Example*/ -static int s_cs8556_ready; -static int s_cs8556_init; -static struct i2c_client *s_cs8556_client; -static enum vout_tvformat_t s_tvformat = TV_MAX; -static int s_irq_init; -static struct avdetect_gpio_t s_avdetect_gpio = {0, WMT_PIN_GP0_GPIO5, 1}; - -static unsigned char s_CS8556_Original_Offset0[] = { - 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, - 0x80, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static unsigned char s_RGB888_To_PAL_Offset0[] = { - 0x01, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5F, 0x03, 0x3F, 0x00, 0x7D, 0x00, 0x53, 0x03, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x02, 0x04, 0x00, 0x2E, 0x00, 0x62, 0x02, - 0x00, 0x00, 0x84, 0x00, 0x2B, 0x00, 0x36, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBF, 0x06, 0x7F, 0x00, 0xFE, 0x00, 0xA4, 0x06, - 0x00, 0x00, 0x2D, 0x11, 0x3C, 0x01, 0x3A, 0x01, - 0x70, 0x02, 0x04, 0x00, 0x12, 0x00, 0x34, 0x01, - 0x00, 0x00, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x41, 0x18, 0x09, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x24, 0x1A, 0x00, 0x01, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x01, 0xA4, 0x06, 0x0B, 0x00, 0x07, 0x01, - 0xF0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x01 -}; - -static unsigned char s_RGB888_To_NTSC_Offset0[] = { - 0x01, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x59, 0x03, 0x3D, 0x00, 0x7E, 0x00, 0x49, 0x03, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x0C, 0x02, 0x05, 0x00, 0x21, 0x00, 0x03, 0x02, - 0x00, 0x00, 0x7A, 0x00, 0x23, 0x00, 0x16, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xB3, 0x06, 0x7F, 0x00, 0x00, 0x01, 0xA4, 0x06, - 0x00, 0x00, 0x05, 0x50, 0x00, 0x01, 0x07, 0x01, - 0x0C, 0x02, 0x02, 0x00, 0x12, 0x00, 0x07, 0x01, - 0x00, 0x00, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x41, 0x18, 0x09, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x24, 0x1A, 0x00, 0x01, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x01, 0xA4, 0x06, 0x0B, 0x00, 0x07, 0x01, - 0xF0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 -}; - -/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ -/* void vt1632_xxx(void); *//*Example*/ -static int I2CMultiPageRead(unsigned char maddr, unsigned char page, - unsigned char saddr, int number, unsigned char *value) -{ - int ret; - unsigned char wbuf[2]; - struct i2c_msg rd[2]; - - wbuf[0] = page; - wbuf[1] = saddr; - - rd[0].addr = maddr; - rd[0].flags = 0; - rd[0].len = 2; - rd[0].buf = wbuf; - - rd[1].addr = maddr; - rd[1].flags = I2C_M_RD; - rd[1].len = number; - rd[1].buf = value; - - ret = i2c_transfer(s_cs8556_client->adapter, rd, ARRAY_SIZE(rd)); - - if (ret != ARRAY_SIZE(rd)) { - DBG_ERR("fail\n"); - return -1; - } - - return 0; -} - -static int I2CMultiPageWrite(unsigned char maddr, unsigned char page, - unsigned char saddr, int number, unsigned char *value) -{ - int ret; - unsigned char *pbuf; - struct i2c_msg wr[1]; - - pbuf = kmalloc(number + 2, GFP_KERNEL); - if (!pbuf) { - DBG_ERR("alloc memory fail\n"); - return -1; - } - - *pbuf = page; - *(pbuf + 1) = saddr; - - memcpy(pbuf + 2, value, number); - - wr[0].addr = maddr; - wr[0].flags = 0; - wr[0].len = number + 2; - wr[0].buf = pbuf; - - ret = i2c_transfer(s_cs8556_client->adapter, wr, ARRAY_SIZE(wr)); - - if (ret != ARRAY_SIZE(wr)) { - DBG_ERR("fail\n"); - kfree(pbuf); - return -1; - } - - kfree(pbuf); - return 0 ; -} - -/************************ i2c device struct definition ************************/ -static int __devinit cs8556_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - DBGMSG("cs8556_i2c_probe\n"); - - return 0; -} - -static int __devexit cs8556_i2c_remove(struct i2c_client *client) -{ - DBGMSG("cs8556_i2c_remove\n"); - - return 0; -} - - -static const struct i2c_device_id cs8556_i2c_id[] = { - {CS8556_NAME, 0}, - { }, -}; -MODULE_DEVICE_TABLE(i2c, cs8556_i2c_id); - -static struct i2c_board_info __initdata cs8556_i2c_board_info[] = { - { - I2C_BOARD_INFO(CS8556_NAME, CS8556_ADDR), - }, -}; - -static struct i2c_driver cs8556_i2c_driver = { - .driver = { - .name = CS8556_NAME, - .owner = THIS_MODULE, - }, - .probe = cs8556_i2c_probe, - .remove = __devexit_p(cs8556_i2c_remove), - .id_table = cs8556_i2c_id, -}; - -/*----------------------- Function Body --------------------------------------*/ -static void avdetect_irq_enable(void) -{ - wmt_gpio_unmask_irq(s_avdetect_gpio.gpiono); -} - -static void avdetect_irq_disable(void) -{ - wmt_gpio_mask_irq(s_avdetect_gpio.gpiono); -} - -int avdetect_irq_hw_init(int resume) -{ - int ret; - - if (!resume) { - ret = gpio_request(s_avdetect_gpio.gpiono, - "avdetect irq"); /* enable gpio */ - if (ret < 0) { - DBG_ERR("gpio(%d) request fail for avdetect irq\n", - s_avdetect_gpio.gpiono); - return ret; - } - } else - gpio_re_enabled(s_avdetect_gpio.gpiono); /* re-enable gpio */ - - gpio_direction_input(s_avdetect_gpio.gpiono); /* gpio input */ - - /* enable pull and pull-up */ - wmt_gpio_setpull(s_avdetect_gpio.gpiono, WMT_GPIO_PULL_UP); - - /* disable interrupt */ - wmt_gpio_mask_irq(s_avdetect_gpio.gpiono); - - /* rise edge and clear interrupt */ - wmt_gpio_set_irq_type(s_avdetect_gpio.gpiono, IRQ_TYPE_EDGE_BOTH); - - return 0; -} - -/* -static void avdetect_irq_hw_free(void) -{ - gpio_free(AVDETECT_IRQ_PIN); - -} -*/ - -static irqreturn_t avdetect_irq_handler(int irq, void *dev_id) -{ - /* DPRINT("avdetect_irq_handler\n"); */ - - if (!gpio_irqstatus(s_avdetect_gpio.gpiono)) - return IRQ_NONE; - - wmt_gpio_ack_irq(s_avdetect_gpio.gpiono); /* clear interrupt */ - - /* DPRINT("cvbs hotplug interrupt\n"); */ - if (!is_gpio_irqenable(s_avdetect_gpio.gpiono)) { - /* pr_err("avdetect irq is disabled\n"); */ - return IRQ_HANDLED; - } else - return IRQ_WAKE_THREAD; -} - -static irqreturn_t avdetect_irq_thread(int irq, void *dev) -{ - /* DPRINT(cvbs_hotplug_irq_thread\n"); */ - - if (s_avdetect_gpio.act == 1) { - if (gpio_get_value(s_avdetect_gpio.gpiono)) - DPRINT("av plug in\n"); - else - DPRINT("av plug out\n"); - } else { - if (gpio_get_value(s_avdetect_gpio.gpiono)) - DPRINT("av plug out\n"); - else - DPRINT("av plug in\n"); - } - - return IRQ_HANDLED; -} - -int cs8556_check_plugin(int hotplug) -{ - return 1; -} - -int cs8556_init(struct vout_t *vo) -{ - int ret; - char buf[40] = {0}; - int varlen = 40; - int no = 1; /* default i2c1 */ - int num; - unsigned char rbuf[256] = {0}; - struct i2c_adapter *adapter = NULL; - - DPRINT("cs8556_init\n"); - - if (s_tvformat == TV_MAX) { - if (wmt_getsyspara("wmt.display.tvformat", buf, &varlen) == 0) { - if (!strnicmp(buf, "PAL", 3)) - s_tvformat = TV_PAL; - else if (!strnicmp(buf, "NTSC", 4)) - s_tvformat = TV_NTSC; - else - s_tvformat = TV_UNDEFINED; - } else - s_tvformat = TV_UNDEFINED; - } - - if (s_tvformat == TV_UNDEFINED) - goto err0; - - if (!s_cs8556_init) { - if (wmt_getsyspara("wmt.cs8556.i2c", buf, &varlen) == 0) { - if (strlen(buf) > 0) - no = buf[0] - '0'; - } - - adapter = i2c_get_adapter(no); - if (adapter == NULL) { - DBG_ERR("Can't get i2c adapter,client address error\n"); - goto err0; - } - - s_cs8556_client = - i2c_new_device(adapter, cs8556_i2c_board_info); - if (s_cs8556_client == NULL) { - DBG_ERR("allocate i2c client failed\n"); - goto err0; - } - - i2c_put_adapter(adapter); - - ret = i2c_add_driver(&cs8556_i2c_driver); - if (ret != 0) { - DBG_ERR("Failed register CS8556 I2C driver: %d\n", ret); - goto err1; - } - - if (wmt_getsyspara("wmt.io.avdetect", buf, &varlen) == 0) { - num = sscanf(buf, "%d:%d:%d", &s_avdetect_gpio.flag, - &s_avdetect_gpio.gpiono, &s_avdetect_gpio.act); - - if (num != 3) - DBG_ERR("wmt.io.avdetect err. num = %d\n", num); - else { - if (s_avdetect_gpio.gpiono > 19) - DBG_ERR("invalid avdetect gpio : %d\n", - s_avdetect_gpio.gpiono); - else { - ret = avdetect_irq_hw_init(0); - if (!ret) { - ret = request_threaded_irq( - IRQ_GPIO, - avdetect_irq_handler, - avdetect_irq_thread, - IRQF_SHARED, - CS8556_NAME, - s_cs8556_client); - - if (ret) - DBG_ERR("irq req %d\n", - ret); - else { - s_irq_init = 1; - DPRINT("avdetect irq"); - DPRINT("req success\n"); - } - } - } - } - } - - s_cs8556_init = 1; - } else { - if (s_irq_init) - avdetect_irq_hw_init(1); - } - - ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf); - if (ret) { - DBG_ERR("I2C address 0x%02X is not found\n", CS8556_ADDR); - goto err0; - } - - switch (s_tvformat) { - case TV_PAL: - ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, - s_RGB888_To_PAL_Offset0); - if (ret) { - DBG_ERR("PAL init fail\n"); - goto err0; - } - break; - case TV_NTSC: - ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, - s_RGB888_To_NTSC_Offset0); - if (ret) { - DBG_ERR("NTSC init fail\n"); - goto err0; - } - break; - default: - goto err0; - break; - } - - if (s_irq_init) - avdetect_irq_enable(); - - s_cs8556_ready = 1; - - return 0; -#if 0 -err3: - cvbs_hotplug_irq_disable(); - free_irq(IRQ_GPIO, s_cs8556_client); - cvbs_hotplug_irq_hw_free(); -err2: - i2c_del_driver(&cs8556_i2c_driver); -#endif -err1: - i2c_unregister_device(s_cs8556_client); -err0: - s_cs8556_ready = 0; - return -1; -} - -static int cs8556_set_mode(unsigned int *option) -{ - if (!s_cs8556_ready) - return -1; - - return 0; -} - -static void cs8556_set_power_down(int enable) -{ - int ret; - unsigned char rbuf[256] = {0}; - - if (!s_cs8556_ready) - return; - - DBGMSG("cs8556_set_power_down(%d)\n", enable); - - if (enable) { - ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 5, - s_CS8556_Original_Offset0); - if (ret) - DBG_ERR("I2C write Original_Offset0 fail\n"); - else { - if (s_irq_init) - avdetect_irq_disable(); - } - } else { - ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf); - if (ret) { - DBG_ERR("I2C read Offset0 fail\n"); - return; - } - - switch (s_tvformat) { - case TV_PAL: - if (memcmp(rbuf, s_RGB888_To_PAL_Offset0, 0x50) != 0) { - ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, - 0x00, 256, s_RGB888_To_PAL_Offset0); - if (ret) - DBG_ERR("I2C write PAL_Offset0 fail\n"); - } - break; - case TV_NTSC: - if (memcmp(rbuf, s_RGB888_To_NTSC_Offset0, 0x50) != 0) { - ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, - 0x00, 256, s_RGB888_To_NTSC_Offset0); - if (ret) - DBG_ERR("I2C wr NTSC_Offset0 fail\n"); - } - break; - default: - break; - } - } -} - -static int cs8556_config(struct vout_info_t *info) -{ - return 0; -} - -static int cs8556_get_edid(char *buf) -{ - return -1; -} - -/* -static int cs8556_interrupt(void) -{ - return cs8556_check_plugin(1); -} -*/ - -void cs8556_read(void) -{ - int i, ret; - unsigned char rbuf[256] = {0}; - - ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf); - if (!ret) { - DPRINT("CS8556 Read offset0 data as follows:\n"); - for (i = 0; i < 256;) { - DPRINT("0x%02X,", rbuf[i]); - if ((++i) % 16 == 0) - DPRINT("\n"); - } - } -} - -int cvbs_is_ready(void) -{ - return s_cs8556_ready; -} - -/*----------------------- vout device plugin ---------------------------------*/ -struct vout_dev_t cs8556_vout_dev_ops = { - .name = CS8556_NAME, - .mode = VOUT_INF_DVI, - - .init = cs8556_init, - .set_power_down = cs8556_set_power_down, - .set_mode = cs8556_set_mode, - .config = cs8556_config, - .check_plugin = cs8556_check_plugin, - .get_edid = cs8556_get_edid, -/* .interrupt = cs8556_interrupt, */ -}; - -int cs8556_module_init(void) -{ - vout_device_register(&cs8556_vout_dev_ops); - return 0; -} /* End of cs8556_module_init */ -module_init(cs8556_module_init); -/*--------------------End of Function Body -----------------------------------*/ -#undef CS8556_C +/*++
+ * linux/drivers/video/wmt/cs8556.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2013 WonderMedia Technologies, Inc.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+/********************************************************************************
+* REVISON HISTORY
+*
+* VERSION | DATE | AUTHORS | DESCRIPTION
+* 1.0 | 2013/08/24 | Howay Huo | First Release
+*******************************************************************************/
+
+#define CS8556_C
+// #define DEBUG
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include <linux/i2c.h>
+#include <mach/hardware.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <mach/wmt_iomux.h>
+#include "../vout.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define VT1632_XXXX xxxx *//*Example*/
+//#define CONFIG_CS8556_INTERRUPT
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define VT1632_XXXX 1 *//*Example*/
+#define CS8556_ADDR 0x3d
+#define CS8556_NAME "CS8556"
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx vt1632_xxx_t; *//*Example*/
+typedef struct {
+ unsigned int flag;
+ unsigned int gpiono;
+ unsigned int act;
+}avdetect_gpio_t;
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in vt1632.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int vt1632_xxx; *//*Example*/
+static int s_cs8556_ready;
+static int s_cs8556_init;
+static struct i2c_client *s_cs8556_client;
+static int s_irq_init;
+static avdetect_gpio_t s_avdetect_gpio = {0, WMT_PIN_GP0_GPIO5, 1};
+
+static unsigned char s_CS8556_Original_Offset0[]={
+ 0xF0,0x7F,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x02,0x01,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+};
+
+static unsigned char s_RGB888_To_PAL_Offset0[]={
+ 0x01,0x80,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x00,
+ 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x5F,0x03,0x3F,0x00,0x7D,0x00,0x53,0x03,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,
+ 0x70,0x02,0x04,0x00,0x2E,0x00,0x62,0x02,0x00,0x00,0x84,0x00,0x2B,0x00,0x36,0x00,
+ 0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xBF,0x06,0x7F,0x00,0xFE,0x00,0xA4,0x06,0x00,0x00,0x2D,0x11,0x3C,0x01,0x3A,0x01,
+ 0x70,0x02,0x04,0x00,0x12,0x00,0x34,0x01,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,
+ 0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x04,0x41,0x18,0x09,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,
+ 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x24,0x1A,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x04,0x01,0xA4,0x06,0x0B,0x00,0x07,0x01,0xF0,0x00,0x00,0x00,0x00,0x04,0x40,0x01
+};
+
+static unsigned char s_RGB888_To_NTSC_Offset0[]={
+ 0x01,0x80,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x00,
+ 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x59,0x03,0x3D,0x00,0x7E,0x00,0x49,0x03,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,
+ 0x0C,0x02,0x05,0x00,0x21,0x00,0x03,0x02,0x00,0x00,0x7A,0x00,0x23,0x00,0x16,0x00,
+ 0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xB3,0x06,0x7F,0x00,0x00,0x01,0xA4,0x06,0x00,0x00,0x05,0x50,0x00,0x01,0x07,0x01,
+ 0x0C,0x02,0x02,0x00,0x12,0x00,0x07,0x01,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,
+ 0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x04,0x41,0x18,0x09,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,
+ 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x24,0x1A,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x04,0x01,0xA4,0x06,0x0B,0x00,0x07,0x01,0xF0,0x00,0x00,0x00,0x00,0x04,0x00,0x00
+};
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void vt1632_xxx(void); *//*Example*/
+static int I2CMultiPageRead(unsigned char maddr, unsigned char page, unsigned char saddr, int number, unsigned char *value)
+{
+ int ret;
+ unsigned char wbuf[2];
+ struct i2c_msg rd[2];
+
+ wbuf[0] = page;
+ wbuf[1] = saddr;
+
+ rd[0].addr = maddr;
+ rd[0].flags = 0;
+ rd[0].len = 2;
+ rd[0].buf = wbuf;
+
+ rd[1].addr = maddr;
+ rd[1].flags = I2C_M_RD;
+ rd[1].len = number;
+ rd[1].buf = value;
+
+ ret = i2c_transfer(s_cs8556_client->adapter, rd, ARRAY_SIZE(rd));
+
+ if (ret != ARRAY_SIZE(rd)) {
+ DBG_ERR("fail\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int I2CMultiPageWrite(unsigned char maddr, unsigned char page, unsigned char saddr, int number, unsigned char *value)
+{
+ int ret;
+ unsigned char *pbuf;
+ struct i2c_msg wr[1];
+
+ pbuf = kmalloc(number + 2, GFP_KERNEL);
+ if(!pbuf) {
+ DBG_ERR("alloc memory fail\n");
+ return -1;
+ }
+
+ *pbuf = page;
+ *(pbuf + 1) = saddr;
+
+ memcpy(pbuf + 2, value, number);
+
+ wr[0].addr = maddr;
+ wr[0].flags = 0;
+ wr[0].len = number + 2;
+ wr[0].buf = pbuf;
+
+ ret = i2c_transfer(s_cs8556_client->adapter, wr, ARRAY_SIZE(wr));
+
+ if (ret != ARRAY_SIZE(wr)) {
+ DBG_ERR("fail\n");
+ kfree(pbuf);
+ return -1;
+ }
+
+ kfree(pbuf);
+ return 0 ;
+}
+
+/************************** i2c device struct definition **************************/
+static int __devinit cs8556_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ DBGMSG("cs8556_i2c_probe\n");
+
+ return 0;
+}
+
+static int __devexit cs8556_i2c_remove(struct i2c_client *client)
+{
+ DBGMSG("cs8556_i2c_remove\n");
+
+ return 0;
+}
+
+
+static const struct i2c_device_id cs8556_i2c_id[] = {
+ {CS8556_NAME, 0},
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, cs8556_i2c_id);
+
+static struct i2c_board_info __initdata cs8556_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO(CS8556_NAME, CS8556_ADDR),
+ },
+};
+
+static struct i2c_driver cs8556_i2c_driver = {
+ .driver = {
+ .name = CS8556_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = cs8556_i2c_probe,
+ .remove = __devexit_p(cs8556_i2c_remove),
+ .id_table = cs8556_i2c_id,
+};
+
+/*----------------------- Function Body --------------------------------------*/
+static void avdetect_irq_enable(void)
+{
+ wmt_gpio_unmask_irq(s_avdetect_gpio.gpiono);
+}
+
+static void avdetect_irq_disable(void)
+{
+ wmt_gpio_mask_irq(s_avdetect_gpio.gpiono);
+}
+
+int avdetect_irq_hw_init(int resume)
+{
+ int ret;
+
+ if(!resume) {
+ ret = gpio_request(s_avdetect_gpio.gpiono, "avdetect irq"); //enable gpio
+ if(ret < 0) {
+ DBG_ERR("gpio(%d) request fail for avdetect irq\n", s_avdetect_gpio.gpiono);
+ return ret;
+ }
+ }else
+ gpio_re_enabled(s_avdetect_gpio.gpiono); //re-enable gpio
+
+ gpio_direction_input(s_avdetect_gpio.gpiono); //gpio input
+
+ wmt_gpio_setpull(s_avdetect_gpio.gpiono, WMT_GPIO_PULL_UP); //enable pull and pull-up
+
+ wmt_gpio_mask_irq(s_avdetect_gpio.gpiono); //disable interrupt
+
+ wmt_gpio_set_irq_type(s_avdetect_gpio.gpiono, IRQ_TYPE_EDGE_BOTH); //rise edge and clear interrupt
+
+ return 0;
+}
+
+/*
+static void avdetect_irq_hw_free(void)
+{
+ gpio_free(AVDETECT_IRQ_PIN);
+
+}
+*/
+
+static irqreturn_t avdetect_irq_handler(int irq, void *dev_id)
+{
+ //printk("avdetect_irq_handler\n");
+
+ if(!gpio_irqstatus(s_avdetect_gpio.gpiono))
+ return IRQ_NONE;
+
+ wmt_gpio_ack_irq(s_avdetect_gpio.gpiono); //clear interrupt
+
+ //printk("cvbs hotplug interrupt\n");
+ if(!is_gpio_irqenable(s_avdetect_gpio.gpiono)) {
+ //pr_err("avdetect irq is disabled\n");
+ return IRQ_HANDLED;
+ }else
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t avdetect_irq_thread(int irq, void *dev)
+{
+ //printk(cvbs_hotplug_irq_thread\n");
+
+ if(s_avdetect_gpio.act == 1) {
+ if(gpio_get_value(s_avdetect_gpio.gpiono))
+ printk("av plug in\n");
+ else
+ printk("av plug out\n");
+ }
+ else {
+ if(gpio_get_value(s_avdetect_gpio.gpiono))
+ printk("av plug out\n");
+ else
+ printk("av plug in\n");
+ }
+
+ return IRQ_HANDLED;
+}
+
+void cs8556_set_tv_mode(int ntsc)
+{
+ int ret;
+ unsigned char rbuf[256] = {0};
+
+ if( !s_cs8556_ready )
+ return;
+
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf);
+ if(ret) {
+ DBG_ERR("I2C read Offset0 fail\n");
+ return;
+ }
+
+ if(ntsc < 0) {
+ if(memcmp(rbuf, s_CS8556_Original_Offset0, 0x11) != 0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, s_CS8556_Original_Offset0);
+ if(ret)
+ DBG_ERR("I2C write Original_Offset0 fail\n");
+ else {
+ if(s_irq_init)
+ avdetect_irq_disable();
+ }
+ }
+
+ return;
+ }
+
+ if(ntsc) {
+ if(memcmp(rbuf, s_RGB888_To_NTSC_Offset0, 0x50) !=0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, s_RGB888_To_NTSC_Offset0);
+ if(ret)
+ DBG_ERR("I2C write NTSC_Offset0 fail\n");
+ }
+ } else {
+ if(memcmp(rbuf, s_RGB888_To_PAL_Offset0, 0x50) != 0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, s_RGB888_To_PAL_Offset0);
+ if(ret)
+ DBG_ERR("I2C write PAL_Offset0 fail\n");
+ }
+ }
+
+}
+
+int cs8556_check_plugin(int hotplug)
+{
+ return 1;
+}
+
+int cs8556_init(struct vout_s *vo)
+{
+ int ret;
+ char buf[40] = {0};
+ int varlen = 40;
+ int no = 1; //default i2c1
+ int num;
+ unsigned char rbuf[256] = {0};
+ struct i2c_adapter *adapter = NULL;
+ vout_tvformat_t tvformat = TV_MAX;
+
+ DPRINT("cs8556_init\n");
+
+ if(wmt_getsyspara("wmt.display.tvformat", buf, &varlen) == 0) {
+ if(!strnicmp(buf, "PAL", 3))
+ tvformat = TV_PAL;
+ else if(!strnicmp(buf, "NTSC", 4))
+ tvformat = TV_NTSC;
+ else
+ tvformat = TV_UNDEFINED;
+ } else
+ tvformat = TV_UNDEFINED;
+
+
+ if(tvformat == TV_UNDEFINED)
+ goto err0;
+
+ if(!s_cs8556_init) {
+ if(wmt_getsyspara("wmt.cs8556.i2c", buf, &varlen) == 0) {
+ if(strlen(buf) > 0)
+ no = buf[0] - '0';
+ }
+
+ adapter = i2c_get_adapter(no);
+ if (adapter == NULL) {
+ DBG_ERR("Can not get i2c adapter, client address error\n");
+ goto err0;
+ }
+
+ s_cs8556_client = i2c_new_device(adapter, cs8556_i2c_board_info);
+ if (s_cs8556_client == NULL) {
+ DBG_ERR("allocate i2c client failed\n");
+ goto err0;
+ }
+
+ i2c_put_adapter(adapter);
+
+ ret = i2c_add_driver(&cs8556_i2c_driver);
+ if (ret != 0) {
+ DBG_ERR("Failed to register CS8556 I2C driver: %d\n", ret);
+ goto err1;
+ }
+
+ if(wmt_getsyspara("wmt.io.avdetect", buf, &varlen) == 0) {
+ num = sscanf(buf, "%d:%d:%d", &s_avdetect_gpio.flag, &s_avdetect_gpio.gpiono,
+ &s_avdetect_gpio.act);
+
+ if(num != 3)
+ DBG_ERR("wmt.io.avdetect is error. param num = %d\n", num);
+ else {
+ if(s_avdetect_gpio.gpiono > 19)
+ DBG_ERR("invalid avdetect gpio no: %d\n", s_avdetect_gpio.gpiono);
+ else {
+ ret = avdetect_irq_hw_init(0);
+ if(!ret) {
+ ret = request_threaded_irq(IRQ_GPIO, avdetect_irq_handler,
+ avdetect_irq_thread, IRQF_SHARED, CS8556_NAME, s_cs8556_client);
+
+ if(ret)
+ DBG_ERR("%s: irq request failed: %d\n", __func__, ret);
+ else {
+ s_irq_init = 1;
+ DPRINT("avdetect irq request success\n");
+ }
+ }
+ }
+ }
+ }
+
+ s_cs8556_init = 1;
+ }
+ else {
+ if(s_irq_init)
+ avdetect_irq_hw_init(1);
+ }
+
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf);
+ if(ret) {
+ DBG_ERR("I2C address 0x%02X is not found\n", CS8556_ADDR);
+ goto err0;
+ }
+
+ //if(s_cs8556_ready) {
+ // DPRINT("cs8556_reinit");
+ switch(tvformat) {
+ case TV_PAL:
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, s_RGB888_To_PAL_Offset0);
+ if(ret) {
+ DBG_ERR("PAL init fail\n");
+ goto err0;
+ }
+ break;
+
+ case TV_NTSC:
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, s_RGB888_To_NTSC_Offset0);
+ if(ret) {
+ DBG_ERR("NTSC init fail\n");
+ goto err0;
+ }
+ break;
+
+ default:
+ goto err0;
+ break;
+ }
+ //}
+
+ if(s_irq_init)
+ avdetect_irq_enable();
+
+ s_cs8556_ready = 1;
+
+ return 0;
+//err3:
+// cvbs_hotplug_irq_disable();
+// free_irq(IRQ_GPIO, s_cs8556_client);
+// cvbs_hotplug_irq_hw_free();
+//err2:
+// i2c_del_driver(&cs8556_i2c_driver);
+err1:
+ i2c_unregister_device(s_cs8556_client);
+err0:
+ s_cs8556_ready = 0;
+ return -1;
+}
+
+static int cs8556_set_mode(unsigned int *option)
+{
+ if(!s_cs8556_ready)
+ return -1;
+
+ return 0;
+}
+
+static void cs8556_set_power_down(int enable)
+{
+ int ret;
+ vout_t *vo;
+ unsigned char rbuf[256] = {0};
+
+ if( !s_cs8556_ready )
+ return;
+
+ vo = vout_get_entry(VPP_VOUT_NUM_DVI);
+ if (vo->status & (VPP_VOUT_STS_BLANK + VPP_VOUT_STS_POWERDN)) {
+ enable = 1;
+ }
+
+ DPRINT("cs8556_set_power_down(%d)\n",enable);
+
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 0x11, rbuf);
+ if(ret) {
+ DBG_ERR("I2C read Offset0 fail\n");
+ return;
+ }
+
+ if( enable ){
+ if(memcmp(rbuf, s_CS8556_Original_Offset0, 0x11) != 0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 0x11, s_CS8556_Original_Offset0);
+ if(ret)
+ DBG_ERR("I2C write Offset0 to power down CS8556 fail\n");
+ else {
+ if(s_irq_init)
+ avdetect_irq_disable();
+ }
+ }
+ } else {
+ if(memcmp(rbuf, s_RGB888_To_PAL_Offset0, 0x11) != 0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 0x11, s_RGB888_To_PAL_Offset0);
+ if(ret)
+ DBG_ERR("I2C write offset0 to power up CS8556 fail\n");
+ }
+ }
+}
+
+static int cs8556_config(vout_info_t *info)
+{
+ int ntsc;
+
+ if(!s_cs8556_ready)
+ return -1;
+
+ if(info->resx == 720 && (info->resy == 576 || info->resy == 480)) {
+ ntsc = (info->resy == 480) ? 1 : 0;
+
+ DPRINT("cs8556_config (%dx%d@%d) %s\n", info->resx, info->resy, info->fps, ntsc ? "NTSC" : "PAL");
+
+ cs8556_set_tv_mode(ntsc);
+ } else {
+
+ DPRINT("cs8556_config (%dx%d@%d)\n", info->resx, info->resy, info->fps);
+ cs8556_set_tv_mode(-1);
+ }
+
+ return 0;
+}
+
+static int cs8556_get_edid(char *buf)
+{
+ return -1;
+}
+
+#ifdef CONFIG_CS8556_INTERRUPT
+static int cs8556_interrupt(void)
+{
+ return cs8556_check_plugin(1);
+}
+#endif
+
+void cs8556_read(void)
+{
+ int i, ret;
+ unsigned char rbuf[256] = {0};
+
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf);
+ if(!ret) {
+ printk("CS8556 Read offset0 data as follows:\n");
+ for(i = 0; i < 256;) {
+ printk("0x%02X,", rbuf[i]);
+ if((++i) % 16 == 0)
+ printk("\n");
+ }
+
+ }
+}
+
+/*----------------------- vout device plugin --------------------------------------*/
+vout_dev_t cs8556_vout_dev_ops = {
+ .name = CS8556_NAME,
+ .mode = VOUT_INF_DVI,
+
+ .init = cs8556_init,
+ .set_power_down = cs8556_set_power_down,
+ .set_mode = cs8556_set_mode,
+ .config = cs8556_config,
+ .check_plugin = cs8556_check_plugin,
+ .get_edid = cs8556_get_edid,
+#ifdef CONFIG_CS8556_INTERRUPT
+ .interrupt = cs8556_interrupt,
+#endif
+};
+
+int cs8556_module_init(void)
+{
+ vout_device_register(&cs8556_vout_dev_ops);
+ return 0;
+} /* End of cs8556_module_init */
+module_init(cs8556_module_init);
+/*--------------------End of Function Body -----------------------------------*/
+#undef CS8556_C
+
diff --git a/drivers/video/wmt/devices/lcd-AUO-A080SN01.c b/drivers/video/wmt/devices/lcd-AUO-A080SN01.c index f4602a16..113438d8 100755..100644 --- a/drivers/video/wmt/devices/lcd-AUO-A080SN01.c +++ b/drivers/video/wmt/devices/lcd-AUO-A080SN01.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-AUO-A080SN01.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -40,7 +40,7 @@ static void lcd_a080sn01_initial(void); /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_a080sn01_parm = { +lcd_parm_t lcd_a080sn01_parm = { .bits_per_pixel = 24, .capability = 0, .vmode = { @@ -59,8 +59,6 @@ struct lcd_parm_t lcd_a080sn01_parm = { .vmode = 0, .flag = 0, }, - .width = 162, - .height = 121, .initial = lcd_a080sn01_initial, }; @@ -75,7 +73,7 @@ static void lcd_a080sn01_initial(void) /* TODO */ } -struct lcd_parm_t *lcd_a080sn01_get_parm(int arg) +lcd_parm_t *lcd_a080sn01_get_parm(int arg) { return &lcd_a080sn01_parm; } diff --git a/drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c b/drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c index af9752b3..a9508f0b 100755..100644 --- a/drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c +++ b/drivers/video/wmt/devices/lcd-CHILIN-LW700at9003.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-CHILIN-LW700at9003.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -42,7 +42,7 @@ static void lcd_lw700at9003_power_off(void); /*----------------------- INTERNAL PRIVATE VARIABLES ------------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_lw700at9003_parm = { +lcd_parm_t lcd_lw700at9003_parm = { .bits_per_pixel = 18, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -61,8 +61,6 @@ struct lcd_parm_t lcd_lw700at9003_parm = { .vmode = 0, .flag = 0, }, - .width = 152, - .height = 91, .initial = lcd_lw700at9003_power_on, .uninitial = lcd_lw700at9003_power_off, }; @@ -84,7 +82,7 @@ static void lcd_lw700at9003_power_off(void) /* TODO */ } -struct lcd_parm_t *lcd_lw700at9003_get_parm(int arg) +lcd_parm_t *lcd_lw700at9003_get_parm(int arg) { lcd_lw700at9003_parm.bits_per_pixel = arg; return &lcd_lw700at9003_parm; diff --git a/drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c b/drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c index 1d401886..45ed2c2c 100755..100644 --- a/drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c +++ b/drivers/video/wmt/devices/lcd-EKING-EK08009-70135.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-EKING_EK08009-70135.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -41,7 +41,7 @@ static void lcd_ek08009_power_off(void); /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_ek08009_parm = { +lcd_parm_t lcd_ek08009_parm = { .bits_per_pixel = 18, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -60,8 +60,6 @@ struct lcd_parm_t lcd_ek08009_parm = { .vmode = 0, .flag = 0, }, - .width = 162, - .height = 162, .initial = lcd_ek08009_power_on, .uninitial = lcd_ek08009_power_off, }; @@ -84,7 +82,7 @@ static void lcd_ek08009_power_off(void) /* TODO */ } -struct lcd_parm_t *lcd_ek08009_get_parm(int arg) +lcd_parm_t *lcd_ek08009_get_parm(int arg) { return &lcd_ek08009_parm; } diff --git a/drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c b/drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c index 438e3fee..6c1acfc9 100755..100644 --- a/drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c +++ b/drivers/video/wmt/devices/lcd-HANNSTAR-HSD101PFW2.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-HANNSTAR-HSD101PFW2.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -41,7 +41,7 @@ static void lcd_HSD101PFW2_power_off(void); /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_HSD101PFW2_parm = { +lcd_parm_t lcd_HSD101PFW2_parm = { .bits_per_pixel = 18, .capability = 0, .vmode = { @@ -60,8 +60,6 @@ struct lcd_parm_t lcd_HSD101PFW2_parm = { .vmode = 0, .flag = 0, }, - .width = 222, - .height = 125, .initial = lcd_HSD101PFW2_power_on, .uninitial = lcd_HSD101PFW2_power_off, }; @@ -84,7 +82,7 @@ static void lcd_HSD101PFW2_power_off(void) /* TODO */ } -struct lcd_parm_t *lcd_HSD101PFW2_get_parm(int arg) +lcd_parm_t *lcd_HSD101PFW2_get_parm(int arg) { return &lcd_HSD101PFW2_parm; } diff --git a/drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c b/drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c index 7c1da494..a6db70e1 100755..100644 --- a/drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c +++ b/drivers/video/wmt/devices/lcd-INNOLUX-AT070TN83.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-INNOLUX-AT070TN83.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -36,12 +36,12 @@ /* typedef xxxx lcd_xxx_t; *//*Example*/ /*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ -static void lcd_at070tn83_initial(void); -static void lcd_at070tn83_uninitial(void); +static void lcd_at070tn83_power_on(void); +static void lcd_at070tn83_power_off(void); /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_at070tn83_parm = { +lcd_parm_t lcd_at070tn83_parm = { .bits_per_pixel = 18, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -60,46 +60,50 @@ struct lcd_parm_t lcd_at070tn83_parm = { .vmode = 0, .flag = 0, }, - .width = 154, - .height = 85, - .initial = lcd_at070tn83_initial, - .uninitial = lcd_at070tn83_uninitial, + .initial = lcd_at070tn83_power_on, + .uninitial = lcd_at070tn83_power_off, }; /*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ /* void lcd_xxx(void); *//*Example*/ /*----------------------- Function Body --------------------------------------*/ -static void lcd_at070tn83_initial(void) +static void lcd_at070tn83_power_on(void) { -#if 0 - outl(inl(GPIO_BASE_ADDR + 0x80) | BIT0, GPIO_BASE_ADDR + 0x80); - outl(inl(GPIO_BASE_ADDR + 0x4C) | BIT28, GPIO_BASE_ADDR + 0x4C); - outl(inl(GPIO_BASE_ADDR + 0x8C) | BIT28, GPIO_BASE_ADDR + 0x8C); - /* DVDD */ - /* T2 > 0ms */ /* AVDD/VCOM(NANDQS) */ - outl(inl(GPIO_BASE_ADDR + 0xCC) | BIT28, GPIO_BASE_ADDR + 0xCC); - /* T4 > 0ms */ - /* VGH */ - /* 0 < T6 <= 10ms */ - lcd_enable_signal(1); /* signal, DVO enable */ - lcd_oem_enable_backlight(200); /* T12 > 200ms, BL(bit0) */ +/* DPRINT("lcd_at070tn83_power_on\n"); */ + + /* TODO */ +#if (WMT_CUR_PID == WMT_PID_8425) + vppif_reg32_write(GPIO_BASE_ADDR + 0x24, 0x7, 0, 0x7); /* gpio enable */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x54, 0x7, 0, 0x7); /* output mode */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x7, 0, 0x0); /* output mode */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x640, 0x707, 0, 0x707); /*pull en*/ + + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x2, 1, 0x1); /* VGL lo */ + mdelay(8); /* delay 5ms */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x1, 0, 0x1); /* AVDD hi */ + mdelay(6); /* delay 5ms */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x4, 2, 0x1); /* VGH hi */ + mdelay(10); /* delay 10ms */ #endif } -static void lcd_at070tn83_uninitial(void) +static void lcd_at070tn83_power_off(void) { -#if 0 - /* BL(bit0) */ - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~BIT0, GPIO_BASE_ADDR + 0xC0); - mdelay(200); /* T12 > 200ms */ - lcd_enable_signal(0); /* singal, DVO enable */ - /* AVDD/VCOM(NANDQS) */ - outl(inl(GPIO_BASE_ADDR + 0xCC) & ~BIT28, GPIO_BASE_ADDR + 0xCC); +/* DPRINT("lcd_at070tn83_power_off\n"); */ + + /* TODO */ +#if (WMT_CUR_PID == WMT_PID_8425) + mdelay(10); /* delay 10ms */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x4, 2, 0x0); /* VGH lo */ + mdelay(6); /* delay 5ms */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x1, 0, 0x0); /* AVDD lo */ + mdelay(8); /* delay 5ms */ + vppif_reg32_write(GPIO_BASE_ADDR + 0x84, 0x2, 1, 0x0); /* VGL lo */ #endif } -struct lcd_parm_t *lcd_at070tn83_get_parm(int arg) +lcd_parm_t *lcd_at070tn83_get_parm(int arg) { return &lcd_at070tn83_parm; } diff --git a/drivers/video/wmt/devices/lcd-b079xan01.c b/drivers/video/wmt/devices/lcd-b079xan01.c index 05a6e957..54e5921e 100755..100644 --- a/drivers/video/wmt/devices/lcd-b079xan01.c +++ b/drivers/video/wmt/devices/lcd-b079xan01.c @@ -1,82 +1,209 @@ -/*++
- * linux/drivers/video/wmt/lcd-b079xan01.c
- * WonderMedia video post processor (VPP) driver
- *
- * Copyright c 2014 WonderMedia Technologies, Inc.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-#include <linux/delay.h> +/*++ + linux/drivers/video/wmt/devices/lcd-b079xan01.c -#include <mach/hardware.h> + Copyright (c) 2013 WonderMedia Technologies, Inc. + + 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. + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ + +#include <linux/delay.h> #include <linux/spi/spi.h> +#include <mach/hardware.h> #include <mach/wmt-spi.h> - #include <linux/gpio.h> #include <mach/wmt_iomux.h> - #include "../lcd.h" #define DRIVERNAME "ssd2828" +#define DELAY_MASK 0xff000000 + +#undef pr_err +#undef pr_info +#undef pr_warning +#define pr_err(fmt, args...) printk("[" DRIVERNAME "] " fmt, ##args) +#define pr_info(fmt, args...) printk("[" DRIVERNAME "] " fmt, ##args) +#define pr_warning(fmt, args...) printk("[" DRIVERNAME "] " fmt, ##args) + +extern void lcd_power_on(bool on); + +struct ssd2828_chip { + struct spi_device *spi; + int id; + int gpio_reset; +}; + +static int wmt_lcd_panel_id(void) +{ + char buf[96]; + int len = sizeof(buf); + int type, id = 0; + + if (wmt_getsyspara("wmt.display.param", buf, &len)) { + return -ENODEV; + } -static struct lcd_parm_t lcd_b079xan01_parm = { - .bits_per_pixel = 24, - .capability = 0, + sscanf(buf, "%d:%d", &type, &id); + return id; +} + +// B079XAN01 + +static const uint32_t b079xan01_init_sequence[] = { + 0x7000B1, 0x723240, //VSA=50, HAS=64 + 0x7000B2, 0x725078, //VBP=30+50, HBP=56+64 + 0x7000B3, 0x72243C, //VFP=36, HFP=60 + 0x7000B4, 0x720300, //HACT=768 + 0x7000B5, 0x720400, //VACT=1024 + 0x7000B6, 0x72000b, //burst mode, 24bpp loosely packed + 0x7000DE, 0x720003, //no of lane=4 + 0x7000D6, 0x720005, //RGB order and packet number in blanking period + 0x7000B9, 0x720000, //disable PLL + + //lane speed=576 (24MHz * 24 = 576) + //may modify according to requirement, 500Mbps to 560Mbps + //LP clock : 576 / 9 / 8 = 8 MHz + 0x7000BA, 0x728018, + 0x7000BB, 0x720008, + + 0x7000B9, 0x720001, //enable PPL + 0x7000C4, 0x720001, //enable BTA + 0x7000B7, 0x720342, //enter LP mode + 0x7000B8, 0x720000, //VC + 0x7000BC, 0x720000, //set packet size + + 0x700011, //sleep out cmd + + DELAY_MASK + 200, + + 0x700029, //display on + + DELAY_MASK + 200, + + 0x7000B7, 0x72030b, //video mode on +}; + +static lcd_parm_t lcd_b079xan01_parm = { + .bits_per_pixel = 24, + .capability = 0, .vmode = { - .name = "B079XAN01", - .refresh = 60, - .xres = 768, - .yres = 1024, - .pixclock = KHZ2PICOS(64800), - .left_margin = 56, - .right_margin = 60, - .upper_margin = 30, - .lower_margin = 36, - .hsync_len = 64, - .vsync_len = 50, - .sync = 0, /* FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, */ - .vmode = 0, - .flag = 0, + .name = "B079XAN01", + .refresh = 60, + .xres = 768, + .yres = 1024, + .pixclock = KHZ2PICOS(64800), + .left_margin = 56, + .right_margin = 60, + .upper_margin = 30, + .lower_margin = 36, + .hsync_len = 64, + .vsync_len = 50, + .sync = 0, + .vmode = 0, + .flag = 0, }, - .width = 120, - .height = 160, -#if 0 - .initial = lcd_power_on, - .uninitial = lcd_power_off, -#endif }; -static struct lcd_parm_t *lcd_b079xan01_get_parm(int arg) +static lcd_parm_t *lcd_b079xan01_get_parm(int arg) { return &lcd_b079xan01_parm; } -static int lcd_b079xan01_init(void) -{ - return lcd_panel_register(LCD_B079XAN01, - (void *) lcd_b079xan01_get_parm); -} +// BP080WX7 -struct ssd2828_chip { - struct spi_device *spi; - int gpio_reset; +static const uint32_t bp080wx7_init_sequence[] = { + 0x7000B1, 0x720202, // VSA=02 , HSA=02 + 0x7000B2, 0x720828, // VBP+VSA=8, HBP+HSA=40 + 0x7000B3, 0x72040A, // VFP=04 , HFP=10 + 0x7000B4, 0x720500, // HACT=1280 + 0x7000B5, 0x720320, // vACT=800 + 0x7000B6, 0x720007, // Non burst mode with sync event 24bpp + + //DELAY_MASK + 10, + + 0x7000DE, 0x720003, // 4lanes + 0x7000D6, 0x720005, // BGR + 0x7000B9, 0x720000, + + //DELAY_MASK + 10, + + 0x7000BA, 0x72C012, // PLL=24*16 = 384MHz + 0x7000BB, 0x720008, // LP CLK=8.3MHz + 0x7000B9, 0x720001, + + //DELAY_MASK + 200, + + 0x7000B8, 0x720000, // Virtual Channel 0 + 0x7000B7, 0x720342, // LP Mode + + //DELAY_MASK + 10, + + 0x7000BC, 0x720000, + 0x700011, //sleep out + + DELAY_MASK + 200, + + 0x7000BC, 0x720000, + 0x700029, //display on + + //DELAY_MASK + 50, + + 0x7000B7, 0x72034B, //Video Mode + + DELAY_MASK + 200, + + 0x7000BC, 0x720000, + 0x700029, //display on }; +//Timing parameter for 3.0" QVGA LCD +#define VBPD (6) +#define VFPD (4) +#define VSPW (2) + +#define HBPD (38) +#define HFPD (10) +#define HSPW (2) + +// setenv wmt.display.tmr 64800:0:8:47:1280:45:4:16:800:16 + +static lcd_parm_t lcd_bp080wx7_parm = { + .bits_per_pixel = 24, + .capability = 0, + .vmode = { + .name = "BP080WX7", + .refresh = 60, + .xres = 1280, + .yres = 800, + .pixclock = KHZ2PICOS(64800), + .left_margin = HBPD, + .right_margin = HFPD, + .upper_margin = VBPD, + .lower_margin = VFPD, + .hsync_len = HSPW, + .vsync_len = VSPW, + .sync = 0, + .vmode = 0, + .flag = 0, + }, +}; + +static lcd_parm_t *lcd_bp080wx7_get_parm(int arg) +{ + return &lcd_bp080wx7_parm; +} + +// SSD2828 api static int ssd2828_read(struct spi_device *spi, uint8_t reg) { int ret; @@ -88,13 +215,12 @@ static int ssd2828_read(struct spi_device *spi, uint8_t reg) ret = spi_write(spi, buf1, 3); if (ret) { pr_err("spi_write ret=%d\n", ret); - return -EIO; + return ret; } ret = spi_w8r16(spi, buf2[0]); if (ret < 0) { pr_err("spi_write ret=%d\n", ret); - return ret; } return ret; @@ -142,35 +268,7 @@ static inline int spi_write_24bit(struct spi_device *spi, uint32_t data) return ret; } -static const uint32_t ssd2828_init_sequence[] = { - 0x7000B1, 0x723240, /* VSA=50, HAS=64 */ - 0x7000B2, 0x725078, /* VBP=30+50, HBP=56+64 */ - 0x7000B3, 0x72243C, /* VFP=36, HFP=60 */ - 0x7000B4, 0x720300, /* HACT=768 */ - 0x7000B5, 0x720400, /* VACT=1024 */ - 0x7000B6, 0x72000b, /* burst mode, 24bpp loosely packed */ - 0x7000DE, 0x720003, /* no of lane=4 */ - 0x7000D6, 0x720005, /* RGB order and packet number in blanking period */ - 0x7000B9, 0x720000, /* disable PLL */ - - /* lane speed=576 (24MHz * 24 = 576) */ - /* may modify according to requirement, 500Mbps to 560Mbps */ - /* LP clock : 576 / 9 / 8 = 8 MHz */ - 0x7000BA, 0x728018, - 0x7000BB, 0x720008, - - 0x7000B9, 0x720001, /* enable PPL */ - 0x7000C4, 0x720001, /* enable BTA */ - 0x7000B7, 0x720342, /* enter LP mode */ - 0x7000B8, 0x720000, /* VC */ - 0x7000BC, 0x720000, /* set packet size */ - - 0x700011, 0xff0000 + 200, /* sleep out cmd */ - 0x700029, 0xff0000 + 200, /* display on */ - 0x7000B7, 0x72030b, /* video mode on */ -}; - -static int ssd2828_hw_reset(struct ssd2828_chip *chip) +static inline void ssd2828_hw_reset(struct ssd2828_chip *chip) { lcd_power_on(1); msleep(10); @@ -178,16 +276,16 @@ static int ssd2828_hw_reset(struct ssd2828_chip *chip) gpio_direction_output(chip->gpio_reset, 1); msleep(10); gpio_direction_output(chip->gpio_reset, 0); - msleep(20); + msleep(200); gpio_direction_output(chip->gpio_reset, 1); - msleep(20); - return 0; + msleep(200); } static int ssd2828_hw_init(struct ssd2828_chip *chip) { - int ret = 0; - int i; + const uint32_t *init_sequence; + size_t n; + int i, ret = 0; ssd2828_hw_reset(chip); @@ -197,14 +295,27 @@ static int ssd2828_hw_init(struct ssd2828_chip *chip) return -ENODEV; } - for (i = 0; i < ARRAY_SIZE(ssd2828_init_sequence); i++) { - if (ssd2828_init_sequence[i] & 0xff000000) { - msleep(ssd2828_init_sequence[i] & 0xff); - continue; + switch (chip->id) { + case LCD_B079XAN01: + init_sequence = b079xan01_init_sequence; + n = ARRAY_SIZE(b079xan01_init_sequence); + break; + case LCD_BP080WX7: + init_sequence = bp080wx7_init_sequence; + n = ARRAY_SIZE(bp080wx7_init_sequence); + break; + default: + return -EINVAL; + } + + for (i = 0; i < n; i++) { + if ((init_sequence[i] & DELAY_MASK) == DELAY_MASK) { + msleep(init_sequence[i] & 0xff); + } else { + ret = spi_write_24bit(chip->spi, init_sequence[i]); + if (ret) + break; } - ret = spi_write_24bit(chip->spi, ssd2828_init_sequence[i]); - if (ret) - break; } return ret; @@ -232,7 +343,7 @@ static ssize_t option_port_testmode_show(struct device *dev, s += sprintf(s, "=========\n"); out: - return s - buf; + return (s - buf); } static ssize_t option_port_testmode_store(struct device *dev, @@ -246,7 +357,7 @@ static DEVICE_ATTR(testmode, S_IRUGO, option_port_testmode_show, option_port_testmode_store); -static int __devinit ssd2828_probe(struct spi_device *spi) +static int __devinit ssd2828_spi_probe(struct spi_device *spi) { struct ssd2828_chip *chip; int gpio = WMT_PIN_GP0_GPIO0; @@ -269,12 +380,14 @@ static int __devinit ssd2828_probe(struct spi_device *spi) return -ENOMEM; chip->spi = spi; + chip->id = wmt_lcd_panel_id(); chip->gpio_reset = gpio; spi_set_drvdata(spi, chip); ret = sysfs_create_file(&spi->dev.kobj, &dev_attr_testmode.attr); - if (unlikely(ret)) + if (unlikely(ret)) { pr_err("ssd2828 sysfs_create_file failed\n"); + } return ret; } @@ -287,15 +400,11 @@ static int ssd2828_spi_resume(struct spi_device *spi) static struct spi_driver ssd2828_driver = { .driver = { - .name = DRIVERNAME, - .owner = THIS_MODULE, + .name = DRIVERNAME, + .owner = THIS_MODULE, }, - .probe = ssd2828_probe, - .resume = ssd2828_spi_resume, -#if 0 - .remove = __devexit_p(ssd2828_remove), - .shutdown = ssd2828_shutdown, -#endif + .probe = ssd2828_spi_probe, + .resume = ssd2828_spi_resume, }; static struct spi_board_info ssd2828_spi_info[] __initdata = { @@ -309,25 +418,16 @@ static struct spi_board_info ssd2828_spi_info[] __initdata = { }, }; -static int wmt_lcd_panel(void) -{ - char buf[96]; - int len = sizeof(buf); - int type, id = 0; - - if (wmt_getsyspara("wmt.display.param", buf, &len)) - return -ENODEV; - - sscanf(buf, "%d:%d", &type, &id); - return id; -} - -static int __init b079xan01_init(void) +static int __init ssd2828_init(void) { int ret; - if (wmt_lcd_panel() != LCD_B079XAN01) { - pr_err("LCD B079XAN01 not found\n"); + switch (wmt_lcd_panel_id()) { + case LCD_B079XAN01: + case LCD_BP080WX7: + break; + default: + pr_warning("lcd for ssd2828 not found\n"); return -EINVAL; } @@ -341,23 +441,25 @@ static int __init b079xan01_init(void) ret = spi_register_driver(&ssd2828_driver); if (ret) { pr_err("spi_register_driver failed\n"); - return -EIO; + return ret; } - if (lcd_b079xan01_init()) { - spi_unregister_driver(&ssd2828_driver); - return -ENODEV; - } + lcd_panel_register(LCD_B079XAN01, (void *)lcd_b079xan01_get_parm); + lcd_panel_register(LCD_BP080WX7, (void *)lcd_bp080wx7_get_parm); pr_info("spi %s register success\n", DRIVERNAME); - return 0; } -static void b079xan01_exit(void) +static void ssd2828_exit(void) { spi_unregister_driver(&ssd2828_driver); } -module_init(b079xan01_init); -module_exit(b079xan01_exit); +module_init(ssd2828_init); +module_exit(ssd2828_exit); + +MODULE_AUTHOR("Sam Mei"); +MODULE_DESCRIPTION("WonderMedia Mipi LCD Driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/video/wmt/devices/lcd-lvds-1024x600.c b/drivers/video/wmt/devices/lcd-lvds-1024x600.c index 952a2761..f491cce4 100755..100644 --- a/drivers/video/wmt/devices/lcd-lvds-1024x600.c +++ b/drivers/video/wmt/devices/lcd-lvds-1024x600.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-lvds-1024x600.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -40,7 +40,7 @@ static void lcd_LVDS_1024x600_initial(void); /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int lcd_xxx; *//*Example*/ -struct lcd_parm_t lcd_LVDS_1024x600_parm = { +lcd_parm_t lcd_LVDS_1024x600_parm = { .bits_per_pixel = 24, .capability = LCD_CAP_VSYNC_HI, .vmode = { @@ -59,8 +59,6 @@ struct lcd_parm_t lcd_LVDS_1024x600_parm = { .vmode = 0, .flag = 0, }, - .width = 222, - .height = 125, .initial = lcd_LVDS_1024x600_initial, }; @@ -75,7 +73,7 @@ static void lcd_LVDS_1024x600_initial(void) /* TODO */ } -struct lcd_parm_t *lcd_LVDS_1024x600_get_parm(int arg) +lcd_parm_t *lcd_LVDS_1024x600_get_parm(int arg) { return &lcd_LVDS_1024x600_parm; } diff --git a/drivers/video/wmt/devices/lcd-oem.c b/drivers/video/wmt/devices/lcd-oem.c index c079505e..ed5f3407 100755..100644 --- a/drivers/video/wmt/devices/lcd-oem.c +++ b/drivers/video/wmt/devices/lcd-oem.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd-oem.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -42,46 +42,21 @@ /*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ /* void lcd_xxx(void); *//*Example*/ -#ifdef CONFIG_UBOOT -int lcd_bl_time; -void lcd_uboot_set_backlight(void) -{ - int cur; - do { - wmt_read_ostc(&cur); - } while (cur < lcd_bl_time); - REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x800; /* BL( bit 11 ) */ -} -#endif - -void lcd_oem_enable_backlight(int wait_ms) -{ -#ifdef CONFIG_UBOOT - wmt_read_ostc(&lcd_bl_time); - lcd_bl_time += (wait_ms * 1000); -#else - mdelay(wait_ms); - REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x800; -#endif -} - -#ifndef CONFIG_VPP_SHENZHEN static void lcd_oem_initial(void) { - outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, GPIO_BASE_ADDR + 0x80); - outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x801, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0x80) |= 0x801; + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x801; lcd_enable_signal(1); } static void lcd_oem_uninitial(void) { - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x801, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x801; lcd_enable_signal(0); } -#endif -struct lcd_parm_t lcd_oem_parm = { +lcd_parm_t lcd_oem_parm = { .bits_per_pixel = 24, .capability = LCD_CAP_VSYNC_HI, .vmode = { @@ -100,42 +75,34 @@ struct lcd_parm_t lcd_oem_parm = { .vmode = 0, .flag = 0, }, - .width = 222, - .height = 125, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_initial, - .uninitial = lcd_oem_uninitial -#endif +// .initial = lcd_oem_initial, +// .uninitial = lcd_oem_uninitial }; -#ifndef CONFIG_VPP_SHENZHEN static void lcd_oem_1024x600_initial(void) { - outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, GPIO_BASE_ADDR + 0x80); + REG32_VAL(GPIO_BASE_ADDR + 0x80) |= 0x801; /* GPIO enable */ /* DVDD */ - /* T2 > 0ms */ /* AVDD/VCOM( bit 0 ) */ - outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x01, GPIO_BASE_ADDR + 0xC0); + /* T2 > 0ms */ + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x01; /* AVDD/VCOM( bit 0 ) */ /* T4 > 0ms */ /* VGH */ /* 0 < T6 <= 10ms */ lcd_enable_signal(1); /* singal, DVO enable */ mdelay(200); /* T12 > 200ms */ - outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x800, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x800; /* BL( bit 11 ) */ } static void lcd_oem_1024x600_uninitial(void) { - /* BL( bit 11 ) */ - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x800, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x800; /* BL( bit 11 ) */ mdelay(200); /* T12 > 200ms */ lcd_enable_signal(0); /* singal, DVO enable */ - /* AVDD/VCOM( bit 0 ) */ - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x01, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x01; /* AVDD/VCOM( bit 0 ) */ } -#endif -struct lcd_parm_t lcd_oem_parm_1024x600 = { +lcd_parm_t lcd_oem_parm_1024x600 = { .bits_per_pixel = 24, .capability = LCD_CAP_VSYNC_HI, .vmode = { @@ -171,13 +138,11 @@ struct lcd_parm_t lcd_oem_parm_1024x600 = { .flag = 0, #endif }, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_1024x600_initial, - .uninitial = lcd_oem_1024x600_uninitial, -#endif +// .initial = lcd_oem_1024x600_initial, +// .uninitial = lcd_oem_1024x600_uninitial, }; -struct lcd_parm_t lcd_oem_parm_1024x768 = { +lcd_parm_t lcd_oem_parm_1024x768 = { .bits_per_pixel = 24, .capability = LCD_CAP_VSYNC_HI, .vmode = { @@ -196,15 +161,11 @@ struct lcd_parm_t lcd_oem_parm_1024x768 = { .vmode = 0, .flag = 0, }, - .width = 222, - .height = 125, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_initial, - .uninitial = lcd_oem_uninitial -#endif +// .initial = lcd_oem_initial, +// .uninitial = lcd_oem_uninitial }; -struct lcd_parm_t lcd_oem_parm_1366x768 = { +lcd_parm_t lcd_oem_parm_1366x768 = { .bits_per_pixel = 18, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -223,40 +184,11 @@ struct lcd_parm_t lcd_oem_parm_1366x768 = { .vmode = 0, .flag = 0, }, - .width = 293, - .height = 164, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_initial, - .uninitial = lcd_oem_uninitial -#endif -}; - -struct lcd_parm_t lcd_oem_parm_480x800 = { - .bits_per_pixel = 18, - .capability = LCD_CAP_CLK_HI, - .vmode = { - .name = "OEM 480x800", - .refresh = 60, - .xres = 480, - .yres = 800, - .pixclock = KHZ2PICOS(27000), - .left_margin = 78, - .right_margin = 78, - .upper_margin = 60, - .lower_margin = 60, - .hsync_len = 4, - .vsync_len = 4, - .sync = 0, - .vmode = 0, - .flag = 0, - }, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_initial, - .uninitial = lcd_oem_uninitial -#endif +// .initial = lcd_oem_initial, +// .uninitial = lcd_oem_uninitial }; -struct lcd_parm_t lcd_oem_parm_800x480 = { +lcd_parm_t lcd_oem_parm_800x480 = { .bits_per_pixel = 18, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -275,41 +207,33 @@ struct lcd_parm_t lcd_oem_parm_800x480 = { .vmode = 0, .flag = 0, }, - .width = 154, - .height = 85, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_initial, - .uninitial = lcd_oem_uninitial -#endif +// .initial = lcd_oem_initial, +// .uninitial = lcd_oem_uninitial }; -#ifndef CONFIG_VPP_SHENZHEN static void lcd_oem_1280x800_initial(void) { DBG_MSG("lcd 10 power sequence\n"); - outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, GPIO_BASE_ADDR + 0x80); + REG32_VAL(GPIO_BASE_ADDR + 0x80) |= 0x801; /* GPIO enable */ /* VDD on */ /* 0 < T < 50ms */ lcd_enable_signal(1); /* singal on */ - /* VGH,VGL low */ /* AVDD/VCOM( bit 0 ) */ - outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x01, GPIO_BASE_ADDR + 0xC0); + /* VGH,VGL low */ + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x01; /* AVDD/VCOM( bit 0 ) */ mdelay(150); /* T5 > 120ms */ - outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x800, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x800; /* BL( bit 11 ) */ } static void lcd_oem_1280x800_uninitial(void) { - /* turn off backlight */ - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x800, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x800; /* turn off backlight */ mdelay(150); - /* turn off LCD */ - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x01, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x01; /* turn off LCD */ lcd_enable_signal(0); /* turn off singal */ } -#endif -struct lcd_parm_t lcd_oem_parm_800x1280 = { +lcd_parm_t lcd_oem_parm_800x1280 = { .bits_per_pixel = 24, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -328,15 +252,11 @@ struct lcd_parm_t lcd_oem_parm_800x1280 = { .vmode = 0, .flag = 0, }, - .width = 135, - .height = 217, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_1280x800_initial, - .uninitial = lcd_oem_1280x800_uninitial, -#endif +// .initial = lcd_oem_1280x800_initial, +// .uninitial = lcd_oem_1280x800_uninitial, }; -struct lcd_parm_t lcd_oem_parm_1280x800 = { +lcd_parm_t lcd_oem_parm_1280x800 = { .bits_per_pixel = 24, .capability = LCD_CAP_CLK_HI, .vmode = { @@ -355,37 +275,12 @@ struct lcd_parm_t lcd_oem_parm_1280x800 = { .vmode = 0, .flag = 0, }, - .width = 217, - .height = 135, -#ifndef CONFIG_VPP_SHENZHEN - .initial = lcd_oem_1280x800_initial, - .uninitial = lcd_oem_1280x800_uninitial, -#endif -}; - -struct lcd_parm_t lcd_oem_parm_768x1024 = { - .bits_per_pixel = 24, - .capability = LCD_CAP_CLK_HI, - .vmode = { - .name = "oem_768x1024", - .refresh = 60, - .xres = 768, - .yres = 1024, - .pixclock = KHZ2PICOS(59300), - .left_margin = 80, - .right_margin = 80, - .upper_margin = 23, - .lower_margin = 18, - .hsync_len = 7, - .vsync_len = 5, - .sync = 0, - .vmode = 0, - .flag = 0, - }, +// .initial = lcd_oem_1280x800_initial, +// .uninitial = lcd_oem_1280x800_uninitial, }; /*----------------------- Function Body --------------------------------------*/ -struct lcd_parm_t *lcd_oem_get_parm(int arg) +lcd_parm_t *lcd_oem_get_parm(int arg) { return &lcd_oem_parm; } @@ -399,20 +294,18 @@ int lcd_oem_init(void) } /* End of lcd_oem_init */ module_init(lcd_oem_init); -struct lcd_parm_t *lcd_get_oem_parm(int resx, int resy) +lcd_parm_t *lcd_get_oem_parm(int resx, int resy) { - struct lcd_parm_t *oem_parm[] = { - &lcd_oem_parm_480x800, + lcd_parm_t *oem_parm[] = { &lcd_oem_parm_1024x600, &lcd_oem_parm_1024x768, &lcd_oem_parm_1366x768, &lcd_oem_parm_800x480, &lcd_oem_parm_800x1280, &lcd_oem_parm_1280x800, - &lcd_oem_parm_768x1024, 0 }; - struct lcd_parm_t *p; + lcd_parm_t *p; int i; for (i = 0; ; i++) { diff --git a/drivers/video/wmt/devices/lcd.c b/drivers/video/wmt/devices/lcd.c index a6099294..195d3483 100755..100644 --- a/drivers/video/wmt/devices/lcd.c +++ b/drivers/video/wmt/devices/lcd.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -26,15 +26,9 @@ /* #define DEBUG */ /* #define DEBUG_DETAIL */ /*----------------------- DEPENDENCE -----------------------------------------*/ +#include <linux/gpio.h> #include "../lcd.h" #include "../vout.h" -#ifdef CONFIG_KERNEL -#include <linux/gpio.h> -#endif - -#ifdef CONFIG_VPP_SHENZHEN -#include <mach/wmt_iomux.h> -#endif /*----------------------- PRIVATE MACRO --------------------------------------*/ /* #define LCD_XXXX xxxx *//*Example*/ @@ -45,7 +39,7 @@ /*----------------------- PRIVATE TYPE --------------------------------------*/ /* typedef xxxx lcd_xxx_t; *//*Example*/ struct lcd_device_t { - struct lcd_parm_t* (*get_parm)(int arg); + lcd_parm_t* (*get_parm)(int arg); }; /*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ @@ -54,127 +48,102 @@ struct lcd_device_t { struct lcd_device_t lcd_device_array[LCD_PANEL_MAX]; int lcd_panel_on = 1; int lcd_pwm_enable; -enum lcd_panel_t lcd_panel_id = LCD_PANEL_MAX; +lcd_panel_t lcd_panel_id = LCD_PANEL_MAX; int lcd_panel_bpp = 24; -struct vout_dev_t lcd_vout_dev_ops; +vout_dev_t lcd_vout_dev_ops; /*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ /* void lcd_xxx(void); *//*Example*/ -enum lcd_panel_t lcd_lvds_id = LCD_PANEL_MAX; +lcd_panel_t lcd_lvds_id = LCD_PANEL_MAX; int lcd_type; /*----------------------- Function Body --------------------------------------*/ /*----------------------- Backlight --------------------------------------*/ void lcd_set_type(int type) { - lcd_type = type; /* 0-LCD, 1-LVDS */ + lcd_type = type; /* 0-LCD, 1-LVDS */ } int lcd_get_type(void) { - return lcd_type; + return lcd_type; } -#ifdef CONFIG_VPP_SHENZHEN - -#define MAX_LCD_GPIO_NUM 5 - static struct { - int gpio; - int active; -} lcd_power[MAX_LCD_GPIO_NUM] = {{-1, 0}}; + int gpio; + int active; +} lcd_power; +/*----------------------- Function Body --------------------------------------*/ static int parse_uboot_param(void) { - char buf[64]; - unsigned int parm[32]; - int l = sizeof(buf); - int ret, i, gpio_num; - - for(i = 0; i < MAX_LCD_GPIO_NUM; i++) - lcd_power[i].gpio = -1; - - /* - * In hardware, maybe there are several gpio to control LCD power - * We can set the wmt.lcd.power as follows: - * setenv wmt.lcd.power gpio0:active0,gpio1:active1,....,gpio4:active4 - */ - if (wmt_getsyspara("wmt.lcd.power", buf, &l)) { - pr_err("please set wmt.lcd.power\n"); - return -EINVAL; - } - - i = vpp_parse_param(buf, parm, 2 * MAX_LCD_GPIO_NUM, 0); - gpio_num = i / 2; - - for(i = 0; i < gpio_num; i++) { - - lcd_power[i].gpio = parm[i * 2]; - lcd_power[i].active = parm[i * 2 + 1]; - - ret = gpio_request(lcd_power[i].gpio, "lcd power"); - if (ret) { - pr_err("request gpio %d failed for lcd power\n", - lcd_power[i].gpio); - return ret; - } - - DPRINT("lcd power%d: gpio%d, active %d\n", - i, lcd_power[i].gpio, lcd_power[i].active); - } - - return 0; + char buf[64]; + size_t l = sizeof(buf); + int ret; + + if (wmt_getsyspara("wmt.lcd.power", buf, &l)) { + pr_err("please set wmt.lcd.power\n"); + return -EINVAL; + } + + ret = sscanf(buf, "%d:%d", &lcd_power.gpio, &lcd_power.active); + if (ret < 2) { + pr_err("Batt: bat env param: %s\n", buf); + return -EINVAL; + } + + printk("lcd power: gpio-%d, active %d\n", lcd_power.gpio, lcd_power.active); + + ret = gpio_request(lcd_power.gpio, "lcd power"); + if (ret) { + pr_err("request gpio %d failed\n", lcd_power.gpio); + return ret; + } + + return 0; } void lcd_power_on(bool on) { - int i; - - for(i = 0; i < MAX_LCD_GPIO_NUM; i++) { - if (lcd_power[i].gpio < 0) - return; - - gpio_direction_output(lcd_power[i].gpio, on ? - lcd_power[i].active : !lcd_power[i].active); + if (lcd_power.gpio < 0) + return; - DBG_MSG("lcd_power_on: i = %d, on = %d, gpio = %d, active = %d\n", - i, on, lcd_power[i].gpio, lcd_power[i].active); - } + gpio_direction_output(lcd_power.gpio, on ? lcd_power.active : !lcd_power.active); } -#endif +/*----------------------- Backlight --------------------------------------*/ void lcd_set_lvds_id(int id) { - lcd_lvds_id = id; + lcd_lvds_id = id; } int lcd_get_lvds_id(void) { - return lcd_lvds_id; + return lcd_lvds_id; } void lcd_set_parm(int id, int bpp) { - lcd_panel_id = id; - lcd_panel_bpp = bpp; + lcd_panel_id = id; + lcd_panel_bpp = bpp; } -struct lcd_parm_t *lcd_get_parm(enum lcd_panel_t id, unsigned int arg) +lcd_parm_t *lcd_get_parm(lcd_panel_t id, unsigned int arg) { - struct lcd_device_t *p; + struct lcd_device_t *p; - p = &lcd_device_array[id]; - if (p && p->get_parm) - return p->get_parm(arg); - return 0; + p = &lcd_device_array[id]; + if (p && p->get_parm) + return p->get_parm(arg); + return 0; } -struct vout_dev_t *lcd_get_dev(void) +vout_dev_t *lcd_get_dev(void) { - if (lcd_panel_id >= LCD_PANEL_MAX) - return 0; - return &lcd_vout_dev_ops; + if (lcd_panel_id >= LCD_PANEL_MAX) + return 0; + return &lcd_vout_dev_ops; } #ifdef CONFIG_KERNEL @@ -183,257 +152,270 @@ static DEFINE_SEMAPHORE(lcd_sem); void lcd_set_mutex(int lock) { #ifdef CONFIG_KERNEL - if (lock) - down(&lcd_sem); - else - up(&lcd_sem); + if (lock) + down(&lcd_sem); + else + up(&lcd_sem); #endif } + +/* #define CONFIG_PANEL_SET_CLOCK */ void lcd_set_enable(int enable) { - DBG_MSG("%d\n", enable); - if (!p_lcd) - return; - - lcd_set_mutex(1); - if (enable) { - if (p_lcd->initial) - p_lcd->initial(); - else { - lcd_enable_signal(1); /* singal enable */ -#ifndef CONFIG_VPP_SHENZHEN - outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, - GPIO_BASE_ADDR + 0x80); - outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x801, - GPIO_BASE_ADDR + 0xC0); +#ifdef CONFIG_PANEL_SET_CLOCK + int hdmi_off; #endif - } - } else { - if (p_lcd->uninitial) - p_lcd->uninitial(); - else { - lcd_enable_signal(0); /* singal disable */ -#ifndef CONFIG_VPP_SHENZHEN - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x801, - GPIO_BASE_ADDR + 0xC0); + + DBG_MSG("%d\n", enable); + if (!p_lcd) + return; + + lcd_set_mutex(1); +#ifdef CONFIG_PANEL_SET_CLOCK + /* enable NA12 in Panel on */ + hdmi_off = (govrh_get_MIF_enable(p_govrh)) ? 0 : 1; + if (hdmi_off && enable) + vpp_set_clock_enable(DEV_NA12, enable, 1); #endif - } - } - lcd_set_mutex(0); + + if (enable) { + if (p_lcd->initial) + p_lcd->initial(); + else { + lcd_enable_signal(1); /* singal enable */ + //REG32_VAL(GPIO_BASE_ADDR + 0x80) |= 0x801; + //REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x801; + } + } else { + if (p_lcd->uninitial) + p_lcd->uninitial(); + else { + lcd_enable_signal(0); /* singal disable */ + //REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x801; + } + } + +#ifdef CONFIG_PANEL_SET_CLOCK + /* disable VPP & NA12 clock in Panel off */ + if (hdmi_off) { + vpp_set_clock_enable(DEV_VPP, enable, 1); + vpp_set_clock_enable(DEV_GOVRHD, enable, 1); + vpp_set_clock_enable(DEV_HDMILVDS, enable, 1); + if (enable == 0) + vpp_set_clock_enable(DEV_NA12, enable, 1); + } +#endif + lcd_set_mutex(0); } void lcd_enable_signal(int enable) { - int hdmi_off; + int hdmi_off; - DBG_MSG("%d\n", enable); - if (lcd_get_type()) { /* LVDS */ - /* TODO */ - } else { /* LCD */ - govrh_set_dvo_enable(p_govrh2, enable); - } + DBG_MSG("%d\n", enable); + if (lcd_get_type()) { /* LVDS */ + /* TODO */ + } else { /* LCD */ + govrh_set_dvo_enable(p_govrh2, enable); + } - hdmi_off = (govrh_get_MIF_enable(p_govrh)) ? 0 : 1; - vpp_set_clock_enable(DEV_DVO, (hdmi_off && !enable) ? 0 : 1, 1); + hdmi_off = (govrh_get_MIF_enable(p_govrh)) ? 0 : 1; + vpp_set_clock_enable(DEV_DVO, (hdmi_off && !enable) ? 0 : 1, 1); } #ifdef __KERNEL__ /*----------------------- LCD --------------------------------------*/ static int __init lcd_arg_panel_id ( - char *str /*!<; // argument string */ + char *str /*!<; // argument string */ ) { - sscanf(str, "%d", (int *) &lcd_panel_id); - if (lcd_panel_id >= LCD_PANEL_MAX) - lcd_panel_id = LCD_PANEL_MAX; - DBGMSG(KERN_INFO "set lcd panel id = %d\n", lcd_panel_id); - return 1; + sscanf(str, "%d", (int *) &lcd_panel_id); + if (lcd_panel_id >= LCD_PANEL_MAX) + lcd_panel_id = LCD_PANEL_MAX; + DBGMSG(KERN_INFO "set lcd panel id = %d\n", lcd_panel_id); + return 1; } /* End of lcd_arg_panel_id */ __setup("lcdid=", lcd_arg_panel_id); #endif int lcd_panel_register(int no, void (*get_parm)(int mode)) { - struct lcd_device_t *p; - - if (no >= LCD_PANEL_MAX) { - DBGMSG(KERN_ERR "*E* lcd device no max is %d !\n", - LCD_PANEL_MAX); - return -1; - } - - p = &lcd_device_array[no]; - if (p->get_parm) { - DBGMSG(KERN_ERR "*E* lcd device %d exist !\n", no); - return -1; - } - p->get_parm = (void *) get_parm; - return 0; + struct lcd_device_t *p; + + if (no >= LCD_PANEL_MAX) { + DBGMSG(KERN_ERR "*E* lcd device no max is %d !\n", + LCD_PANEL_MAX); + return -1; + } + + p = &lcd_device_array[no]; + if (p->get_parm) { + DBGMSG(KERN_ERR "*E* lcd device %d exist !\n", no); + return -1; + } + p->get_parm = (void *) get_parm; + return 0; } /* End of lcd_device_register */ -/*----------------------- vout device plugin --------------------------------*/ +/*----------------------- vout device plugin --------------------------------------*/ void lcd_set_power_down(int enable) { -#ifdef CONFIG_VPP_SHENZHEN - static int save_state = -1; - - if (save_state != enable) { - /* lcd enable control by user */ - lcd_power_on(enable ? false : true); - lcd_set_enable(enable ? false : true); - save_state = enable; - } -#endif + static int save_state = -1; + + if (save_state != enable) { + /* lcd enable control by user */ + lcd_power_on(enable ? false : true); + lcd_set_enable(enable ? false : true); + save_state = enable; + } } -static void wmt_config_govrh_polar(struct vout_t *vo) +static void wmt_config_govrh_polar(vout_t *vo) { - /* wmt.display.polar [clock polar]:[hsync polart]:[vsync polar]*/ - char buf[64]; - int l = sizeof(buf); - int clk_pol, hsync_pol, vsync_pol; - unsigned int parm[3]; - - if (wmt_getsyspara("wmt.display.polar", buf, &l)) - return; - - vpp_parse_param(buf, (unsigned int *)parm, 3, 0); - clk_pol = parm[0]; - hsync_pol = parm[1]; - vsync_pol = parm[2]; - DBG_MSG("govrh polar: clk-pol %d, hsync %d, vsync %d\n", - clk_pol, hsync_pol, vsync_pol); - govrh_set_dvo_clock_delay(vo->govr, clk_pol ? 0 : 1, 0); - govrh_set_dvo_sync_polar(vo->govr, - hsync_pol ? 0 : 1, vsync_pol ? 0 : 1); + /* wmt.display.polar [clock polar]:[hsync polart]:[vsync polar]*/ + char buf[64]; + size_t l = sizeof(buf); + int clk_pol, hsync_pol, vsync_pol; + + if (wmt_getsyspara("wmt.display.polar", buf, &l)) { + return; + } + + sscanf(buf, "%d:%d:%d", &clk_pol, &hsync_pol, &vsync_pol); + + printk("govrh polar: clk-pol %d, hsync %d, vsync %d\n", clk_pol, hsync_pol, vsync_pol); + govrh_set_dvo_clock_delay(vo->govr, clk_pol ? 0 : 1, 0); + govrh_set_dvo_sync_polar(vo->govr, hsync_pol ? 0 : 1, vsync_pol ? 0 : 1); } int lcd_set_mode(unsigned int *option) { - struct vout_t *vo; - enum vout_inf_mode_t inf_mode; - - DBG_MSG("option %d,%d\n", option[0], option[1]); - - vo = lcd_vout_dev_ops.vout; - inf_mode = vo->inf->mode; - if (option) { - unsigned int capability; - - if (lcd_panel_id == 0) - p_lcd = lcd_get_oem_parm(vo->resx, vo->resy); - else - p_lcd = lcd_get_parm(lcd_panel_id, lcd_panel_bpp); - - if (!p_lcd) { - DBG_ERR("lcd %d not support\n", lcd_panel_id); - return -1; - } - DBG_MSG("[%s] %s (id %d,bpp %d)\n", vout_inf_str[inf_mode], - p_lcd->vmode.name, lcd_panel_id, lcd_panel_bpp); - capability = p_lcd->capability; - switch (inf_mode) { - case VOUT_INF_LVDS: - lvds_set_sync_polar( - (capability & LCD_CAP_HSYNC_HI) ? 0 : 1, - (capability & LCD_CAP_VSYNC_HI) ? 0 : 1); - lvds_set_rgb_type(lcd_panel_bpp); - break; - case VOUT_INF_DVI: - govrh_set_dvo_clock_delay(vo->govr, - (capability & LCD_CAP_CLK_HI) ? 0 : 1, 0); - govrh_set_dvo_sync_polar(vo->govr, - (capability & LCD_CAP_HSYNC_HI) ? 0 : 1, - (capability & LCD_CAP_VSYNC_HI) ? 0 : 1); - switch (lcd_panel_bpp) { - case 15: - govrh_IGS_set_mode(vo->govr, 0, 1, 1); - break; - case 16: - govrh_IGS_set_mode(vo->govr, 0, 3, 1); - break; - case 18: - govrh_IGS_set_mode(vo->govr, 0, 2, 1); - break; - case 24: - govrh_IGS_set_mode(vo->govr, 0, 0, 0); - break; - default: - break; - } - break; - default: - break; - } - } else - p_lcd = 0; - - wmt_config_govrh_polar(vo); - return 0; + vout_t *vo; + vout_inf_mode_t inf_mode; + + DBG_MSG("option %d,%d\n", option[0], option[1]); + + vo = lcd_vout_dev_ops.vout; + inf_mode = vo->inf->mode; + if (option) { + unsigned int capability; + + if (lcd_panel_id == 0) + p_lcd = lcd_get_oem_parm(vo->resx, vo->resy); + else + p_lcd = lcd_get_parm(lcd_panel_id, lcd_panel_bpp); + + if (!p_lcd) { + DBG_ERR("lcd %d not support\n", lcd_panel_id); + return -1; + } + DBG_MSG("[%s] %s (id %d,bpp %d)\n", vout_inf_str[inf_mode], + p_lcd->vmode.name, lcd_panel_id, lcd_panel_bpp); + capability = p_lcd->capability; + switch (inf_mode) { + case VOUT_INF_LVDS: + lvds_set_sync_polar( + (capability & LCD_CAP_HSYNC_HI) ? 0 : 1, + (capability & LCD_CAP_VSYNC_HI) ? 0 : 1); + lvds_set_rgb_type(lcd_panel_bpp); + break; + case VOUT_INF_DVI: + govrh_set_dvo_clock_delay(vo->govr, + (capability & LCD_CAP_CLK_HI) ? 0 : 1, 0); + govrh_set_dvo_sync_polar(vo->govr, + (capability & LCD_CAP_HSYNC_HI) ? 0 : 1, + (capability & LCD_CAP_VSYNC_HI) ? 0 : 1); + switch (lcd_panel_bpp) { + case 15: + govrh_IGS_set_mode(vo->govr, 0, 1, 1); + break; + case 16: + govrh_IGS_set_mode(vo->govr, 0, 3, 1); + break; + case 18: + govrh_IGS_set_mode(vo->govr, 0, 2, 1); + break; + case 24: + govrh_IGS_set_mode(vo->govr, 0, 0, 0); + break; + default: + break; + } + break; + default: + break; + } + } else + p_lcd = 0; + + wmt_config_govrh_polar(vo); + return 0; } int lcd_check_plugin(int hotplug) { - return (p_lcd) ? 1 : 0; + return (p_lcd) ? 1 : 0; } int lcd_get_edid(char *buf) { - return 1; + return 1; } -int lcd_config(struct vout_info_t *info) +int lcd_config(vout_info_t *info) { - info->resx = p_lcd->vmode.xres; - info->resy = p_lcd->vmode.yres; - info->fps = p_lcd->vmode.refresh; - return 0; + info->resx = p_lcd->vmode.xres; + info->resy = p_lcd->vmode.yres; + info->fps = p_lcd->vmode.refresh; + return 0; } -int lcd_init(struct vout_t *vo) +int lcd_init(vout_t *vo) { - DBG_MSG("%d\n", lcd_panel_id); + DBG_MSG("%d\n", lcd_panel_id); - /* vo_set_lcd_id(LCD_CHILIN_LW0700AT9003); */ - if (lcd_panel_id >= LCD_PANEL_MAX) - return -1; + /* vo_set_lcd_id(LCD_CHILIN_LW0700AT9003); */ + if (lcd_panel_id >= LCD_PANEL_MAX) + return -1; - if (lcd_panel_id == 0) - p_lcd = lcd_get_oem_parm(vo->resx, vo->resy); - else - p_lcd = lcd_get_parm(lcd_panel_id, 24); + if (lcd_panel_id == 0) + p_lcd = lcd_get_oem_parm(vo->resx, vo->resy); + else + p_lcd = lcd_get_parm(lcd_panel_id, 24); - if (p_lcd == 0) - return -1; + if (p_lcd == 0) + return -1; - /* set default parameters */ - vo->resx = p_lcd->vmode.xres; - vo->resy = p_lcd->vmode.yres; - vo->pixclk = PICOS2KHZ(p_lcd->vmode.pixclock) * 1000; - return 0; + /* set default parameters */ + vo->resx = p_lcd->vmode.xres; + vo->resy = p_lcd->vmode.yres; + vo->pixclk = PICOS2KHZ(p_lcd->vmode.pixclock) * 1000; + return 0; } -struct vout_dev_t lcd_vout_dev_ops = { - .name = "LCD", - .mode = VOUT_INF_DVI, - .capability = VOUT_DEV_CAP_FIX_RES + VOUT_DEV_CAP_FIX_PLUG, - - .init = lcd_init, - .set_power_down = lcd_set_power_down, - .set_mode = lcd_set_mode, - .config = lcd_config, - .check_plugin = lcd_check_plugin, - .get_edid = lcd_get_edid, +vout_dev_t lcd_vout_dev_ops = { + .name = "LCD", + .mode = VOUT_INF_DVI, + .capability = VOUT_DEV_CAP_FIX_RES + VOUT_DEV_CAP_FIX_PLUG, + + .init = lcd_init, + .set_power_down = lcd_set_power_down, + .set_mode = lcd_set_mode, + .config = lcd_config, + .check_plugin = lcd_check_plugin, + .get_edid = lcd_get_edid, }; int lcd_module_init(void) { - parse_uboot_param(); + if (parse_uboot_param()) { + lcd_power.gpio = -1; + } - vout_device_register(&lcd_vout_dev_ops); - return 0; + vout_device_register(&lcd_vout_dev_ops); + return 0; } /* End of lcd_module_init */ module_init(lcd_module_init); /*--------------------End of Function Body -----------------------------------*/ diff --git a/drivers/video/wmt/devices/vt1625.c b/drivers/video/wmt/devices/vt1625.c index 83d1a403..892f287c 100755..100644 --- a/drivers/video/wmt/devices/vt1625.c +++ b/drivers/video/wmt/devices/vt1625.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/vt1625.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -22,22 +22,15 @@ --*/ #define VT1625_C -/* #define DEBUG */ +#define DEBUG /* #define DEBUG_DETAIL */ /*----------------------- DEPENDENCE -----------------------------------------*/ #include "../vout.h" -#ifdef CONFIG_KERNEL -#include <linux/workqueue.h> -#endif - /*----------------------- PRIVATE MACRO --------------------------------------*/ /* #define VT1625_XXXX xxxx *//*Example*/ -#ifdef CONFIG_KERNEL -#define CONFIG_VT1625_INTERRUPT -#endif +// #define CONFIG_VT1625_INTERRUPT #define CONFIG_VT1625_POWER -#define CONFIG_VM700 /*----------------------- PRIVATE CONSTANTS ----------------------------------*/ /* #define VT1625_XXXX 1 *//*Example*/ @@ -56,7 +49,7 @@ enum { VT1625_START_ACTIVE_VIDEO = 0x07, VT1625_START_HORIZONTAL_POSITION = 0x08, VT1625_START_VERTICAL_POSITION = 0x09, - + /* amplitude factor */ VT1625_CR_AMPLITUDE_FACTOR = 0x0A, VT1625_BLACK_LEVEL = 0x0B, @@ -84,7 +77,7 @@ enum { VT1625_VERSION_ID = 0x1B, VT1625_DAC_OVERFLOW = 0x1C, - + /* test */ VT1625_TEST_0 = 0x1D, VT1625_TEST_1 = 0x1E, @@ -155,329 +148,53 @@ enum { /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int vt1625_xxx; *//*Example*/ -static char vt1625_ntsc_param[] = { - 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x82, /* 00 - 07 */ -#ifdef CONFIG_VM700 - 0x14, 0x05, 0x6E, 0x15, 0x51, 0x50, 0x37, 0xB7, /* 08 - 0f */ - 0x00, 0x80, 0x04, 0x08, 0x08, 0x90, 0xD6, 0x7B, /* 10 - 17 */ -#else - 0x14, 0x05, 0x6E, 0x15, 0x52, 0x4E, 0x37, 0xB7, /* 08 - 0f */ +const char vt1625_ntsc_param[] = { + 0x03, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x88, /* 00 - 07 */ + 0x09, 0x05, 0x6E, 0x15, 0x52, 0x4E, 0x37, 0xB7, /* 08 - 0f */ 0x08, 0x80, 0x04, 0x08, 0x08, 0x90, 0xD6, 0x7B, /* 10 - 17 */ -#endif - 0xF0, 0x21, 0x02, 0x50, 0x43, 0x80, 0x00, 0xFC, /* 18 - 1f */ - 0x16, 0x08, 0xDC, 0x7D, 0x02, 0x56, 0x33, 0x8F, /* 20 - 27 */ - 0x58, 0x00, 0x00, 0xA6, 0x29, 0xD4, 0x81, 0x00, /* 28 - 2f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 37 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38 - 3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 40 - 47 */ -#ifdef CONFIG_VM700 - 0x00, 0x00, 0xC5, 0x0F, 0x08, 0x01, 0x01, 0x43, /* 48 - 4f */ -#else + 0xF0, 0x21, 0x02, 0x50, 0x43, 0x80, 0x00, 0x10, /* 18 - 1f */ + 0x16, 0x08, 0xDC, 0x7D, 0x02, 0x56, 0x33, 0x8F, /* 20 - 27 */ + 0x58, 0x00, 0x00, 0xA6, 0x29, 0xD4, 0x81, 0x00, /* 28 - 2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38 - 3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 40 - 47 */ 0x00, 0x00, 0xC5, 0x0F, 0x00, 0x01, 0x10, 0x44, /* 48 - 4f */ -#endif - 0x59, 0xCF, 0x23, 0x0C, 0x02, 0x59, 0xCF, 0x7F, /* 50 - 57 */ - 0x23, 0x94, 0xD6, 0x00, 0x9C, 0x06, 0x00, 0x00, /* 58 - 5f */ - 0x80, 0x28, 0xFF, 0x59, 0x03, 0x55, 0x56, 0x56, /* 60 - 67 */ - 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 68 - 6f */ - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 - 77 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78 - 7f */ - 0x00, 0x00, 0x00 -}; - -static char vt1625_pal_param[] = { - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x8C, /* 00 - 07 */ -#ifdef CONFIG_VM700 - 0x0E, 0x01, 0x6E, 0x00, 0x51, 0x50, 0x37, 0xB7, /* 08 - 0f */ - 0x00, 0x80, 0x04, 0x08, 0x08, 0x90, 0xCB, 0x8A, /* 10 - 17 */ -#else - 0x0E, 0x01, 0x7a, 0x00, 0x55, 0x58, 0x37, 0xB7, /* 08 - 0f */ - 0xff, 0x87, 0x04, 0x08, 0x08, 0x90, 0xCB, 0x8A, /* 10 - 17 */ -#endif - 0x09, 0x2A, 0x06, 0x50, 0x41, 0x80, 0x00, 0xFC, /* 18 - 1f */ - 0x17, 0x0C, 0x4E, 0x76, 0x02, 0x5F, 0x34, 0x8C, /* 20 - 27 */ - 0x4F, 0x5E, 0x15, 0xA2, 0x22, 0x80, 0xD3, 0x10, /* 28 - 2f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 37 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38 - 3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 40 - 47 */ -#ifdef CONFIG_VM700 - 0x00, 0x00, 0xC5, 0x0F, 0x08, 0x02, 0x01, 0x43, /* 48 - 4f */ -#else - 0x00, 0x00, 0xC5, 0x0F, 0x00, 0x02, 0x10, 0x4C, /* 48 - 4f */ -#endif - 0x5f, 0xCF, 0x23, 0x70, 0x02, 0x5F, 0xD0, 0x7F, /* 50 - 57 */ - 0x23, 0x92, 0xCE, 0xDF, 0xA0, 0x06, 0x00, 0x00, /* 58 - 5f */ - 0x80, 0x20, 0xFF, 0x5F, 0x03, 0x5f, 0x00, 0x00, /* 60 - 67 */ - 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 68 - 6f */ - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 - 77 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78 - 7f */ - 0x00, 0x00, 0x00 + 0x59, 0xCF, 0x23, 0x0C, 0x02, 0x59, 0xCF, 0x7F, /* 50 - 57 */ + 0x23, 0x94, 0xD6, 0xFE, 0x78, 0x06, 0x00, 0x00, /* 58 - 5f */ + 0x80, 0x28, 0xFF, 0x59, 0x03, 0x55, 0x56, 0x56, /* 60 - 67 */ + 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 68 - 6f */ + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 - 77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78 - 7f */ + 0x00, 0x00, 0x00 }; -enum vt1625_out_t { - VT1625_OUT_CVBS, - VT1625_OUT_YUV, - VT1625_OUT_VGA, - VT1625_OUT_MAX +const char vt1625_pal_param[] = { + 0x03, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x8f, /* 00 - 07 */ + 0x00, 0x01, 0x7A, 0x00, 0x55, 0x58, 0x37, 0xB7, /* 08 - 0f */ + 0x08, 0x80, 0x04, 0x08, 0x08, 0x90, 0xCB, 0x8A, /* 10 - 17 */ + 0x09, 0x2A, 0x06, 0x50, 0x41, 0x80, 0x00, 0x00, /* 18 - 1f */ + 0x17, 0x0C, 0x4E, 0x85, 0x02, 0x5F, 0x34, 0x8C, /* 20 - 27 */ + 0x4F, 0x5E, 0x15, 0xA2, 0x22, 0x80, 0xD3, 0x10, /* 28 - 2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38 - 3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 40 - 47 */ + 0x00, 0x00, 0xC5, 0x0F, 0x00, 0x01, 0x10, 0x4C, /* 48 - 4f */ + 0x5f, 0xCF, 0x23, 0x70, 0x02, 0x5F, 0xD0, 0x7F, /* 50 - 57 */ + 0x23, 0x92, 0xCE, 0xDF, 0x86, 0x06, 0x00, 0x00, /* 58 - 5f */ + 0x80, 0x20, 0xFF, 0x5F, 0x03, 0x5f, 0x00, 0x00, /* 60 - 67 */ + 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 68 - 6f */ + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 - 77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78 - 7f */ + 0x00, 0x00, 0x00 }; -enum vt1625_out_t vt1625_out_mode; - +int vt1625_vga_mode; int vt1625_tv_mode; -vdo_color_fmt vt1625_colfmt; - -static int pre_plugin; - -/* -* VT1625 U-Boot Env to Set Register -*/ -typedef struct { - unsigned char offset; - unsigned char value; -} vt1625_reg_env_t; - -#define VT1625_REG_MAX_OFFSET 0x82 /* Register Offset: 0x00 ~ 0x82 */ -/* -* setenv wmt.vt1625.pal.reg regOffset1=regValue1,regOffset2=regValue2,... -* for example: -* setenv wmt.vt1625.pal.reg 0a=75,0c=53,23=7a,4f=48 -* setenv wmt.vt1625.ntsc.reg 0a=75,0c=53,23=7a,4f=48 -*/ -#define VT1625_PAL_REG_ENV "wmt.vt1625.pal.reg" -#define VT1625_NTSC_REG_ENV "wmt.vt1625.ntsc.reg" - -/* -* setenv wmt.vt1625.cvbs.always.turnon 1 -* The cvbs is always turned on event if the av line is pluged out -* setenv wmt.vt1625.cvbs.always.turnon 0 -* The cvbs is turned on if the av line is pluged in. -* And the cvbs is turned off if the av line is pluged out -*/ -#define VT1625_CVBS_ALWAYS_TURNON "wmt.vt1625.cvbs.always.turnon" - -static int vt1625_cvbs_always_turnon; - -#ifdef CONFIG_KERNEL -/* -* VT1625 Timer to Monitor Register -*/ -/* -* Monitor the vt1625 register for avoiding the register is cleared. -* setenv wmt.vt1625.reg.monitor 1 -* -* If the wmt.vt1625.reg.monitor is Not set or set to 0, -* it will not monitor the register -* -*/ -#define VT1625_REG_MONITOR_ENV "wmt.vt1625.reg.monitor" - -#define VT1625_TIMER_INTERVAL 1000 // 1000 ms - -static struct timer_list vt1625_timer; -static struct work_struct vt1625_work; - -static void vt1625_set_tv_mode(int ntsc); - -#endif - -#ifdef CONFIG_UBOOT -#define msleep mdelay -#endif /*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ /* void vt1625_xxx(void); *//*Example*/ /*----------------------- Function Body --------------------------------------*/ -/* -* Function: register_is_right() -* Parametr: -* ntsc = 0: PAL -* ntsc = 1: NTSC -* Return : -* 0: the register's values is wrong -* 1: the register's values is right -*/ -static int register_is_right(int ntsc) -{ - int i; - char buf[32]; - - vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_INPUT_SELECTION, buf, 32); - - for(i = 0; i < 32; i++) { - /* - * reg 0x0E is power management register. Skip it - * reg 0x0F is status register. it is volatile. Skip it - */ - if(i == 14 || i == 15) - continue; - - - if(i == 0) { - if(vt1625_colfmt == VDO_COL_FMT_YUV444) { - if(buf[0] != 0x3A) - break; - } else { - if(buf[0] != 0x03) - break; - } - } else { - if(ntsc) { - /* - * NTSC - */ - if(buf[i] != vt1625_ntsc_param[i]) - break; - } else { - /* - * PAL - */ - if(buf[i] != vt1625_pal_param[i]) - break; - } - } - } - - if(i != 32) - return 0; - else - return 1; -} - -#ifdef CONFIG_KERNEL -static void vt1625_reconfig(struct work_struct *work) -{ - int right; - - if(vt1625_tv_mode) { - right = register_is_right((vt1625_tv_mode == 1) ? 1 : 0); - if(right == 0) { - DBG_ERR("VT1625 Reg Error, re-init the register\n"); - - vt1625_set_tv_mode((vt1625_tv_mode == 1) ? 1 : 0); - } - } - - mod_timer(&vt1625_timer, jiffies + msecs_to_jiffies(VT1625_TIMER_INTERVAL)); -} - -static DECLARE_WORK(vt1625_work, vt1625_reconfig); - -static void vt1625_config_timer(unsigned long fcontext) -{ - schedule_work(&vt1625_work); -} - -static void init_vt1625_timer(void) -{ - char buf[40]; - int varlen = 40; - char *endp; - int value, reg_monitor; - - reg_monitor = 0; - - if (wmt_getsyspara(VT1625_REG_MONITOR_ENV, buf, &varlen) == 0) { - value = simple_strtoul(buf, &endp, 0); - if( value != 0) - reg_monitor = 1; - } - - if(reg_monitor) { - init_timer(&vt1625_timer); - vt1625_timer.function = vt1625_config_timer; - vt1625_timer.data = 0; - } else - vt1625_timer.function = NULL; - -} - -static void start_vt1625_timer(void) -{ - if(vt1625_timer.function) - mod_timer(&vt1625_timer, jiffies + msecs_to_jiffies(VT1625_TIMER_INTERVAL)); -} - -static void stop_vt1625_timer(void) -{ - if(vt1625_timer.function) - del_timer_sync(&vt1625_timer); -} -#endif - -/* -* Function : vt1625_parse_reg_env -* Parameter: -* p_env : env name -* p_reg : store the vt1625 register offset and value -* p_regnum: register number -* Return: -* 0 : the env is set and the env's value is available -* -1 : the env is Not set or the env's value is wrong -* -12 : no memory for parsing register env -*/ -static int vt1625_parse_reg_env(char *p_env, - vt1625_reg_env_t *p_reg, int *p_regnum) -{ - int i; - char *buf; - int buflen = 1024; - unsigned int value; - const char *p; - char *endp; - - buf = kmalloc(buflen, GFP_KERNEL); - if(buf == NULL) { - DBG_ERR("kzalloc fail\n"); - return -12; - } - - if(wmt_getsyspara(p_env, buf, &buflen) != 0) { - kfree(buf); - return -1; - } - - *p_regnum = 0; - p = buf; - - for(i = 0; i <= VT1625_REG_MAX_OFFSET; i++) { - value = simple_strtoul(p, &endp, 16); - if(value > VT1625_REG_MAX_OFFSET) { - DBG_ERR("wrong register offset\n"); - kfree(buf); - return -1; - } - (p_reg + i)->offset = value; - /* - * reg_offset must be followed reg_value - * If reg_offset is NOT followed any reg_value, It is wrong format - */ - if(*endp == '\0'|| *(endp + 1) == '\0') { - DBG_ERR("wrong env(%s) format\n", p_env); - kfree(buf); - return -1; - } - - p = endp + 1; - - value = simple_strtoul(p, &endp, 16); - if(value > 0xFF) { - DBG_ERR("wrong register value\n"); - kfree(buf); - return -1; - } - (p_reg + i)->value = value; - *p_regnum = *p_regnum + 1; - - if(*endp == '\0') - break; - - p = endp + 1; - } - - kfree(buf); - return 0; -} /*the define and struct i2c_msg were declared int linux/i2c.h*/ void vt1625_reg_dump(void) @@ -488,79 +205,49 @@ void vt1625_reg_dump(void) vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INPUT_SELECTION, buf, 128); for (i = 0; i < 128; i += 8) { - MSG("0x%02X : 0x%02X,0x%02X,0x%02X,0x%02X", + MSG("%d : 0x%02x 0x%02x 0x%02x 0x%02x", i, buf[i], buf[i + 1], buf[i + 2], buf[i + 3]); - MSG(",0x%02X,0x%02X,0x%02X,0x%02X\n", + MSG(" 0x%02x 0x%02x 0x%02x 0x%02x\n", buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]); } } -static char vt1625_get_dac_val(enum vt1625_out_t mode) -{ - char ret; - - switch (mode) { - case VT1625_OUT_CVBS: - ret = 0x37; - break; - case VT1625_OUT_VGA: - ret = 0x38; - break; - case VT1625_OUT_YUV: - default: - ret = 0x0; - break; - } - return ret; -} - -static void vt1625_set_tv_mode(int ntsc) +void vt1625_set_tv_mode(int ntsc) { char *p; char buf[10]; -/* vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INPUT_SELECTION, buf, 5); DBG_MSG("ntsc %d, 0x%x, 0x%x\n", ntsc, buf[0], buf[4]); vt1625_tv_mode = (ntsc) ? 1 : 2; -#ifdef CONFIG_KERNEL - if (buf[0] && (vt1625_out_mode != VT1625_OUT_MAX)) { + if (buf[0] && (vt1625_vga_mode != -1)) { if (ntsc && !(buf[4] & BIT0)) return; if (!ntsc && (buf[4] & BIT0)) return; } -#endif -*/ - vt1625_tv_mode = (ntsc) ? 1 : 2; - if(register_is_right(ntsc)) - return; - DBG_MSG("tv %s,mode %d\n", (ntsc) ? "NTSC" : "PAL", vt1625_out_mode); + DBG_MSG("tv %s,vga %d\n", (ntsc) ? "NTSC" : "PAL", vt1625_vga_mode); p = (char *)((ntsc) ? vt1625_ntsc_param : vt1625_pal_param); vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INPUT_SELECTION, &p[VT1625_INPUT_SELECTION], 0x71); - if (vt1625_out_mode == VT1625_OUT_MAX) { /* not stable so no use */ - buf[0] = 0x0; - vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_POWER_MANAGEMENT, buf, 1); + if (vt1625_vga_mode == -1) { mdelay(10); vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_STATUS, buf, 1); - vt1625_out_mode = (buf[0] & 0x7) ? - VT1625_OUT_CVBS : VT1625_OUT_VGA; - DBG_MSG("get out mode %d, 0x%x\n", vt1625_out_mode, buf[0]); + vt1625_vga_mode = (buf[0] & 0x7) ? 0 : 1; + DBG_MSG("get vga mode %d, 0x%x\n", vt1625_vga_mode, buf[0]); } - - if (vt1625_out_mode == VT1625_OUT_VGA) { + + if (vt1625_vga_mode) { vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_SYNC_SELECTION_1, buf, 1); buf[0] |= 0xA0; vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_SYNC_SELECTION_1, buf, 1); - + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_DAC_OVERFLOW, buf, 1); buf[0] |= 0x20; @@ -575,165 +262,80 @@ static void vt1625_set_tv_mode(int ntsc) } else { #ifdef CONFIG_VT1625_INTERRUPT /* interrupt (VGA no work) */ - vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_INT_WSS_2, buf, 1); - buf[0] |= 0xA0; /* enable sense interrupt */ - vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_INT_WSS_2, buf, 1); + if (!g_vpp.virtual_display) { + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_INT_WSS_2, buf, 1); + buf[0] |= 0xA0; /* enable sense interrupt */ + vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, + VT1625_INT_WSS_2, buf, 1); + } #endif } - - if (vt1625_colfmt == VDO_COL_FMT_YUV444) { - /* - * Force write reg0x00 and reg0x4C - */ - buf[0] = 0x3A; - vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_INPUT_SELECTION, buf, 1); - buf[0] = 0x08; - vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_GPO, buf, 1); - } - #ifdef CONFIG_VT1625_POWER - buf[0] = vt1625_get_dac_val(vt1625_out_mode); + buf[0] = (vt1625_vga_mode) ? 0x38 : 0x37; vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT, buf, 1); #endif +// vt1625_reg_dump(); } -static int vt1625_check_plugin(int hotplug) +int vt1625_check_plugin(int hotplug) { - char buf[2]; - char cur[1]; + char buf[1]; int plugin; - /* - * Enable VT1625 Power First - */ - vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_POWER_MANAGEMENT, cur, 1); - - buf[0] = vt1625_get_dac_val(vt1625_out_mode); - - if(cur[0] != buf[0]) { - vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_POWER_MANAGEMENT, buf, 1); - - msleep(10); - } - - if((vt1625_out_mode == VT1625_OUT_CVBS) && vt1625_cvbs_always_turnon) + if (g_vpp.virtual_display) return 1; - vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT, - buf, 2); - plugin = ~buf[1] & (~buf[0] & 0x3F); + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_STATUS, buf, 1); + plugin = ((buf[0] & 0x3F) == 0x3F) ? 0 : 1; DBG_MSG("[VT1625] DAC A %d, B %d, C %d, D %d, E %d, F %d\n", - (plugin & 0x20) ? 1 : 0, (plugin & 0x10) ? 1 : 0, - (plugin & 0x08) ? 1 : 0, (plugin & 0x04) ? 1 : 0, - (plugin & 0x02) ? 1 : 0, (plugin & 0x01) ? 1 : 0); - return (plugin) ? 1 : 0; + (buf[0] & 0x20) ? 1 : 0, (buf[0] & 0x10) ? 1 : 0, + (buf[0] & 0x08) ? 1 : 0, (buf[0] & 0x04) ? 1 : 0, + (buf[0] & 0x02) ? 1 : 0, (buf[0] & 0x01) ? 1 : 0); + return plugin; } -static int vt1625_init(struct vout_t *vo) +int vt1625_init(struct vout_s *vo) { - char buf[40]; - int varlen = 40; - char *endp; - unsigned int value; + char buf[5]; DBG_MSG("\n"); + // vt1625_vga_mode = -1; + vt1625_vga_mode = 0; if (vt1625_tv_mode) { /* resume reinit */ MSG("[VT1625] DVI reinit\n"); vt1625_set_tv_mode((vt1625_tv_mode == 1) ? 1 : 0); - if (govrh_get_dvo_enable(p_govrh2) == 0) - govrh_set_dvo_enable(p_govrh2, VPP_FLAG_ENABLE); - pre_plugin = 0; return 0; } - + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_VERSION_ID, buf, 1); if (buf[0] != 0x50) /* check version id */ return -1; - - if (wmt_getsyspara("wmt.display.vt1625.mode", buf, &varlen) == 0) { - if (memcmp(buf, "yuv", 3) == 0) - vt1625_out_mode = VT1625_OUT_YUV; - else if (memcmp(buf, "vga", 3) == 0) - vt1625_out_mode = VT1625_OUT_VGA; - else - vt1625_out_mode = VT1625_OUT_CVBS; - DPRINT("[VT1625] mode %d\n", vt1625_out_mode); - } else - vt1625_out_mode = VT1625_OUT_CVBS; /* VT1625_OUT_MAX; */ - -#ifdef CONFIG_VM700 - vt1625_colfmt = VDO_COL_FMT_YUV444; -#else - vt1625_colfmt = VDO_COL_FMT_ARGB; -#endif - if (wmt_getsyspara("wmt.display.vt1625.colfmt", buf, &varlen) == 0) { - if (memcmp(buf, "yuv", 3) == 0) - vt1625_colfmt = VDO_COL_FMT_YUV444; - else if (memcmp(buf, "rgb", 3) == 0) - vt1625_colfmt = VDO_COL_FMT_ARGB; - } - - vo->option[0] = (unsigned int) vt1625_colfmt; - vo->option[1] = (unsigned int) VPP_DATAWIDHT_12; - + vo->option[0] = VDO_COL_FMT_ARGB; + vo->option[1] = VPP_DATAWIDHT_12; + vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INPUT_SELECTION, buf, 5); - if (buf[0]) + if (buf[0]) { vt1625_tv_mode = (buf[4]) ? 2 : 1; - - p_govrh2->fb_p->csc_mode = VPP_CSC_RGB2YUV_SDTV_0_255; - - if (wmt_getsyspara(VT1625_CVBS_ALWAYS_TURNON, buf, &varlen) == 0) { - value = simple_strtoul(buf, &endp, 0); - if(value != 0) - vt1625_cvbs_always_turnon = 1; - else - vt1625_cvbs_always_turnon = 0; - } else - vt1625_cvbs_always_turnon = 0; - -#ifdef CONFIG_KERNEL - vt1625_set_tv_mode((vt1625_tv_mode == 1) ? 1 : 0); - - start_vt1625_timer(); -#endif - + } MSG("[VT1625] DVI ext device\n"); return 0; } -static int vt1625_set_mode(unsigned int *option) +int vt1625_set_mode(unsigned int *option) { -#ifdef CONFIG_VT1625_INTERRUPT - char buf[1]; -#endif - DBG_MSG("\n"); #ifdef CONFIG_VT1625_INTERRUPT - if (!g_vpp.dvi_int_disable) { vout_set_int_type(1); - vout_set_int_enable(1); - - vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_INT_WSS_2, buf, 1); - buf[0] |= 0xA0; /* enable sense interrupt */ - vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_INT_WSS_2, buf, 1); - } #endif return 0; } -static void vt1625_set_power_down(int enable) +void vt1625_set_power_down(int enable) { - struct vout_t *vo; + vout_t *vo; char buf[1]; char cur[1]; @@ -745,16 +347,16 @@ static void vt1625_set_power_down(int enable) bit 7 : IO pad */ vo = vout_get_entry(VPP_VOUT_NUM_DVI); - if (vo->status & (VPP_VOUT_STS_BLANK + VPP_VOUT_STS_POWERDN)) + if (vo->status & (VPP_VOUT_STS_BLANK + VPP_VOUT_STS_POWERDN)) { enable = 1; + } - /* power down for not support resolution */ -//#ifndef CONFIG_VT1625_INTERRUPT - if ((vt1625_tv_mode != 0) && enable && g_vpp.dvi_int_disable) + if (vt1625_tv_mode == 0) /* power down for not support resolution */ buf[0] = 0xFF; + else if (vt1625_vga_mode == -1) + buf[0] = (enable) ? 0xFF : 0x37; else -//#endif - buf[0] = vt1625_get_dac_val(vt1625_out_mode); + buf[0] = (enable) ? 0xFF : ((vt1625_vga_mode) ? 0x38 : 0x37); vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT, cur, 1); @@ -769,8 +371,8 @@ static void vt1625_set_power_down(int enable) vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT, cur, 1); mdelay(3); - - cur[0] &= ~0x80; /* turn on IO pad */ + + cur[0] &= ~0x80; /* turn on IO pad */ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT, cur, 1); mdelay(3); @@ -782,7 +384,7 @@ static void vt1625_set_power_down(int enable) #endif } -static int vt1625_config(struct vout_info_t *info) +int vt1625_config(vout_info_t *info) { int ntsc = -1; @@ -808,13 +410,12 @@ static int vt1625_config(struct vout_info_t *info) return 0; } -static int vt1625_get_edid(char *buf) +int vt1625_get_edid(char *buf) { return 0; } -#ifdef CONFIG_VT1625_INTERRUPT -static int vt1625_interrupt(void) +int vt1625_interrupt(void) { char buf[1]; @@ -827,69 +428,8 @@ static int vt1625_interrupt(void) vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INT_WSS_2, buf, 1); return vt1625_check_plugin(1); } -#endif - -static void vt1625_poll(void) -{ - int plugin; - char buf[1]; - char cur[1]; - - if (govrh_get_dvo_enable(p_govrh2) == 0) - govrh_set_dvo_enable(p_govrh2, VPP_FLAG_ENABLE); - - plugin = vt1625_check_plugin(0); - if (plugin != pre_plugin) { - struct vout_t *vo; - - vo = vout_get_entry(VPP_VOUT_NUM_DVI); - vout_change_status(vo, VPP_VOUT_STS_PLUGIN, plugin); -#ifdef CONFIG_KERNEL - vpp_netlink_notify_plug(VPP_VOUT_NUM_DVI, plugin); -#endif - pre_plugin = plugin; - DMSG("%d\n", plugin); - } - - /* - * Disable VT1625 Power if CVBS Not plugin - */ - if(plugin == 0) { - vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_POWER_MANAGEMENT, cur, 1); - - buf[0] = 0xFF; - - if(cur[0] != buf[0]) { - vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, - VT1625_POWER_MANAGEMENT, buf, 1); - } - } -} - -static int vt1625_suspend(void) -{ - DMSG("\n"); - -#ifdef CONFIG_KERNEL - stop_vt1625_timer(); -#endif - - return 0; -} - -static int vt1625_resume(void) -{ - DMSG("\n"); - -#ifdef CONFIG_KERNEL - start_vt1625_timer(); -#endif - return 0; -} - /*----------------------- vout device plugin ---------------------------------*/ -struct vout_dev_t vt1625_vout_dev_ops = { +vout_dev_t vt1625_vout_dev_ops = { .name = "VT1625", .mode = VOUT_INF_DVI, @@ -902,43 +442,11 @@ struct vout_dev_t vt1625_vout_dev_ops = { #ifdef CONFIG_VT1625_INTERRUPT .interrupt = vt1625_interrupt, #endif - .poll = vt1625_poll, - .suspend = vt1625_suspend, - .resume = vt1625_resume, }; int vt1625_module_init(void) { - vt1625_reg_env_t *p_reg; - int i, ret, regnum; - - p_reg = kmalloc((VT1625_REG_MAX_OFFSET + 1) * sizeof(vt1625_reg_env_t), - GFP_KERNEL); - if(p_reg) { - ret = vt1625_parse_reg_env(VT1625_PAL_REG_ENV, p_reg, ®num); - if(ret == 0) { - for(i = 0; i < regnum; i++) - vt1625_pal_param[(p_reg + i)->offset] = - (p_reg + i)->value; - } - - ret = vt1625_parse_reg_env(VT1625_NTSC_REG_ENV, p_reg, ®num); - if(ret == 0) { - for(i = 0; i < regnum; i++) - vt1625_ntsc_param[(p_reg + i)->offset] = - (p_reg + i)->value; - } - - kfree(p_reg); - } else - DBG_ERR("kzalloc fail\n"); - -#ifdef CONFIG_KERNEL - init_vt1625_timer(); -#endif - vout_device_register(&vt1625_vout_dev_ops); - return 0; } module_init(vt1625_module_init); diff --git a/drivers/video/wmt/devices/vt1632.c b/drivers/video/wmt/devices/vt1632.c index b3950c0f..3ece9d9e 100755..100644 --- a/drivers/video/wmt/devices/vt1632.c +++ b/drivers/video/wmt/devices/vt1632.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/vt1632.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -62,7 +62,7 @@ int vt1632_check_plugin(int hotplug) return plugin; } -int vt1632_init(struct vout_t *vo) +int vt1632_init(struct vout_s *vo) { char buf[16]; @@ -119,7 +119,7 @@ void vt1632_set_power_down(int enable) vpp_i2c_write(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 1); } -int vt1632_config(struct vout_info_t *info) +int vt1632_config(vout_info_t *info) { return 0; } @@ -134,7 +134,7 @@ int vt1632_interrupt(void) return vt1632_check_plugin(1); } /*----------------------- vout device plugin ---------------------------------*/ -struct vout_dev_t vt1632_vout_dev_ops = { +vout_dev_t vt1632_vout_dev_ops = { .name = "VT1632", .mode = VOUT_INF_DVI, diff --git a/drivers/video/wmt/edid.h b/drivers/video/wmt/edid.h index b476a780..ec85a81b 100755..100644 --- a/drivers/video/wmt/edid.h +++ b/drivers/video/wmt/edid.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/edid.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -73,9 +73,6 @@ #define EDID_STRUCT_VERSION 0x12 #define EDID_STRUCT_REVISION 0x13 -#define EDID_MAX_HOR_IMAGE_SIZE 0x15 -#define EDID_MAX_VER_IMAGE_SIZE 0x16 - /*------------------------------------------------------------------------------ Offset 20-24: BASIC DISPLAY PARAMETERS ------------------------------------------------------------------------------*/ @@ -98,16 +95,11 @@ #define EDID_TMR_INTERLACE BIT(31) #define EDID_TMR_FREQ 0xFF -struct edid_timing_t { +typedef struct { unsigned int resx; unsigned int resy; int freq; /* EDID_TMR_XXX */ -}; - -struct vic_3d_t { - char vic; - unsigned int mask; -}; +} edid_timing_t; /* EDID option flag */ #define EDID_OPT_VALID 0x01 @@ -119,50 +111,45 @@ struct vic_3d_t { #define EDID_OPT_3D BIT(9) #define EDID_OPT_16_9 BIT(10) -struct edid_info_t { +typedef struct { unsigned int establish_timing; - struct edid_timing_t standard_timing[8]; + edid_timing_t standard_timing[8]; struct fb_videomode detail_timing[4]; struct fb_videomode cea_timing[6]; char cea_vic[8]; - struct vic_3d_t vic_3d[16]; unsigned int pixel_clock_limit; unsigned int option; unsigned short hdmi_phy_addr; - int width; - int height; -}; +} edid_info_t; #define VENDOR_NAME_LEN 4 #define MONITOR_NAME_LEN 20 #define AUD_SAD_NUM 32 -struct sad_t { +typedef struct { char flag; /* 0: sad available, 1: sad invalid */ char sad_byte[3]; -}; +} sad_t; -struct tv_name_t{ +typedef struct { char vendor_name[VENDOR_NAME_LEN]; char monitor_name[MONITOR_NAME_LEN]; -}; +} tv_name_t; -struct edid_parsed_t { - struct tv_name_t tv_name; - struct sad_t sad[AUD_SAD_NUM]; -}; +typedef struct { + tv_name_t tv_name; + sad_t sad[AUD_SAD_NUM]; +} edid_parsed_t; -extern struct edid_info_t edid_info; +extern edid_info_t edid_info; extern int edid_msg_enable; extern int edid_disable; -extern struct edid_parsed_t edid_parsed; +extern edid_parsed_t edid_parsed; -extern int edid_parse(char *edid, struct edid_info_t *info); -extern int edid_find_support(struct edid_info_t *info, unsigned int resx, +extern int edid_parse(char *edid, edid_info_t *info); +extern int edid_find_support(edid_info_t *info, unsigned int resx, unsigned int resy, int freq, struct fb_videomode **vmode); extern void edid_dump(char *edid); extern int edid_checksum(char *edid, int len); extern unsigned int edid_get_hdmi_phy_addr(void); -extern unsigned int edid_get_hdmi_3d_mask(struct edid_info_t *info, - int vic); #endif diff --git a/drivers/video/wmt/ge/Makefile b/drivers/video/wmt/ge/Makefile index 819c710a..819c710a 100755..100644 --- a/drivers/video/wmt/ge/Makefile +++ b/drivers/video/wmt/ge/Makefile diff --git a/drivers/video/wmt/ge/ge_accel.c b/drivers/video/wmt/ge/ge_accel.c index 753d264c..ef8ce133 100755..100644 --- a/drivers/video/wmt/ge/ge_accel.c +++ b/drivers/video/wmt/ge/ge_accel.c @@ -32,10 +32,16 @@ #include <mach/hardware.h> #include "ge_accel.h" +unsigned int fb_egl_swap; /* useless */ + +DECLARE_WAIT_QUEUE_HEAD(ge_wq); + int flipcnt; int flipreq; int vbl; int vsync = 1; +int sync2 = 1; +int sync3; int debug; module_param(flipcnt, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); @@ -50,6 +56,12 @@ MODULE_PARM_DESC(vbl, "Wait vsync for each frame (0)"); module_param(vsync, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); MODULE_PARM_DESC(vsync, "Can use vsync (1)"); +module_param(sync2, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(sync2, "Only wait vsync if truly necessary"); + +module_param(sync3, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(sync3, "Only wait vsync if truly necessary"); + module_param(debug, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); MODULE_PARM_DESC(debug, "Show debug information"); @@ -62,12 +74,28 @@ MODULE_PARM_DESC(debug, "Show debug information"); unsigned int phy_mem_end(void) { unsigned int memsize = (num_physpages << PAGE_SHIFT); - unsigned int n = 32 << 20; - - while (n <= memsize) - n <<= 1; - memsize = n; + if (memsize > M(3072)) { /* 4096M */ + memsize = M(4096); + } else if (memsize > M(2048)) { /* 3072M */ + memsize = M(3072); + } else if (memsize > M(1024)) { /* 2048M */ + memsize = M(2048); + } else if (memsize > M(512)) { /* 1024M */ + memsize = M(1024); + } else if (memsize > M(256)) { /* 512M */ + memsize = M(512); + } else if (memsize > M(128)) { /* 256M */ + memsize = M(256); + } else if (memsize > M(64)) { /* 128M */ + memsize = M(128); + } else if (memsize > M(32)) { /* 64M */ + memsize = M(64); + } else if (memsize > M(16)) { /* 32M */ + memsize = M(32); + } else { + memsize = M(0); + } printk(KERN_DEBUG "Detected RAM size %d MB\n", memsize>>20); return memsize; @@ -100,28 +128,55 @@ static int ge_vo_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { #ifdef HAVE_VPP - wmtfb_set_mutex(info, 1); + vpp_set_mutex(0, 1); vpp_pan_display(var, info); - wmtfb_set_mutex(info, 0); + vpp_set_mutex(0, 0); #endif flipcnt++; return 0; } +#if 0 +static void fbiomemcpy(struct fb_info *info, + unsigned long dst, unsigned long src, size_t len) +{ + void *psrc = info->screen_base + (src - info->fix.smem_start); + void *pdst = info->screen_base + (dst - info->fix.smem_start); + void *ptmp = info->screen_base + info->fix.smem_len - len; + unsigned long tmp = info->fix.smem_start + info->fix.smem_len - len; + + if (src < info->fix.smem_start || src > tmp) + psrc = ioremap(src, len); + if (dst < info->fix.smem_start || dst > tmp) + pdst = ioremap(dst, len); + if (psrc && pdst && ptmp) { + memcpy(ptmp, psrc, len); + memcpy(pdst, ptmp, len); + } + if (psrc && (src < info->fix.smem_start || src > tmp)) + iounmap(psrc); + if (pdst && (dst < info->fix.smem_start || dst > tmp)) + iounmap(pdst); +} +#endif + struct ge_var { struct fb_info *info; struct fb_var_screeninfo var[1]; struct fb_var_screeninfo new_var[1]; + struct workqueue_struct *wq; + struct work_struct notifier; struct timeval most_recent_flip_time; int dirty; int force_sync; + int vscnt; /* vsync counter */ spinlock_t lock[1]; void (*start)(struct ge_var *ge_var); void (*stop)(struct ge_var *ge_var); void (*get)(struct ge_var *ge_var, struct fb_var_screeninfo *var); void (*set)(struct ge_var *ge_var, struct fb_var_screeninfo *var); - void (*sync)(struct ge_var *ge_var, int wait); + void (*sync)(struct ge_var *ge_var); }; static struct ge_var *ge_var_s; @@ -130,7 +185,24 @@ static void ge_var_start(struct ge_var *ge_var); static void ge_var_stop(struct ge_var *ge_var); static void ge_var_get(struct ge_var *ge_var, struct fb_var_screeninfo *var); static void ge_var_set(struct ge_var *ge_var, struct fb_var_screeninfo *var); -static void ge_var_sync(struct ge_var *ge_var, int wait); +static void ge_var_sync(struct ge_var *ge_var); +static void ge_var_sync1(struct ge_var *ge_var); +static void ge_var_sync2(struct ge_var *ge_var); +static void ge_var_sync3(struct ge_var *ge_var); + +static void ge_var_vsync_notifier(struct work_struct *work) +{ + struct ge_var *ge_var = container_of(work, struct ge_var, notifier); + + ge_vo_wait_vsync(); + + spin_lock(ge_var->lock); + ge_var->vscnt++; + spin_unlock(ge_var->lock); + + if (debug) + printk(KERN_DEBUG "vsync!\n"); +} static struct ge_var *create_ge_var(struct fb_info *info) { @@ -139,6 +211,7 @@ static struct ge_var *create_ge_var(struct fb_info *info) ge_var = (struct ge_var *) kcalloc(1, sizeof(struct ge_var), GFP_KERNEL); + ge_var->wq = create_singlethread_workqueue("ge_var_wq"); ge_var->info = info; ge_var->start = &ge_var_start; ge_var->stop = &ge_var_stop; @@ -148,6 +221,8 @@ static struct ge_var *create_ge_var(struct fb_info *info) do_gettimeofday(&ge_var->most_recent_flip_time); + INIT_WORK(&ge_var->notifier, ge_var_vsync_notifier); + ge_var->start(ge_var); return ge_var; @@ -157,6 +232,8 @@ static void release_ge_var(struct ge_var *ge_var) { if (ge_var) { ge_var->stop(ge_var); + flush_workqueue(ge_var->wq); + destroy_workqueue(ge_var->wq); kfree(ge_var); } } @@ -164,6 +241,7 @@ static void release_ge_var(struct ge_var *ge_var) static void ge_var_start(struct ge_var *ge_var) { spin_lock_init(ge_var->lock); + queue_work(ge_var->wq, &ge_var->notifier); } static void ge_var_stop(struct ge_var *ge_var) @@ -179,8 +257,6 @@ static void ge_var_get(struct ge_var *ge_var, struct fb_var_screeninfo *var) static void ge_var_set(struct ge_var *ge_var, struct fb_var_screeninfo *var) { - int wait; - spin_lock(ge_var->lock); if (memcmp(ge_var->new_var, var, sizeof(struct fb_var_screeninfo))) { memcpy(ge_var->new_var, var, sizeof(struct fb_var_screeninfo)); @@ -188,11 +264,42 @@ static void ge_var_set(struct ge_var *ge_var, struct fb_var_screeninfo *var) } spin_unlock(ge_var->lock); - wait = vbl || (var->activate & FB_ACTIVATE_VBL); - ge_var->sync(ge_var, wait); + if (vbl || (var->activate & FB_ACTIVATE_VBL)) + ge_var->sync(ge_var); + else + ge_var_sync1(ge_var); +} + +static void ge_var_sync(struct ge_var *ge_var) +{ + if (sync3) + return ge_var_sync3(ge_var); + + if (sync2) + return ge_var_sync2(ge_var); + + ge_var_sync1(ge_var); } -static void ge_var_sync(struct ge_var *ge_var, int wait) +/* flip and don't wait */ +static void ge_var_sync1(struct ge_var *ge_var) +{ + spin_lock(ge_var->lock); + + if (ge_var->dirty == 0) { + spin_unlock(ge_var->lock); + return; + } + + memcpy(ge_var->var, ge_var->new_var, sizeof(struct fb_var_screeninfo)); + spin_unlock(ge_var->lock); + + ge_vo_pan_display(ge_var->var, ge_var->info); + ge_var->dirty = 0; +} + +/* for double buffer */ +static void ge_var_sync2(struct ge_var *ge_var) { struct timeval t; struct timeval *mrft; @@ -219,7 +326,7 @@ static void ge_var_sync(struct ge_var *ge_var, int wait) ge_var->dirty = 0; /* 60 fps */ - if (wait && us < 16667) { + if (us < 16667) { if (debug) { struct timeval t1; struct timeval t2; @@ -229,7 +336,7 @@ static void ge_var_sync(struct ge_var *ge_var, int wait) do_gettimeofday(&t2); ms = (t2.tv_sec - t1.tv_sec) * 1000 + (t2.tv_usec - t1.tv_usec) / 1000; - printk(KERN_DEBUG "ge: wait vsync for %d ms\n", ms); + printk(KERN_DEBUG "vsync2: wait vsync for %d ms\n", ms); } else ge_vo_wait_vsync(); } @@ -237,6 +344,78 @@ static void ge_var_sync(struct ge_var *ge_var, int wait) do_gettimeofday(&ge_var->most_recent_flip_time); } +/* for triple buffer */ +static void ge_var_sync3(struct ge_var *ge_var) +{ + spin_lock(ge_var->lock); + + if (ge_var->dirty == 0) { + spin_unlock(ge_var->lock); + return; + } + + if (ge_var->vscnt == 0) { + struct timeval t1; + struct timeval t2; + int ms; + int tmax = 16; + + if (debug) + do_gettimeofday(&t1); + + while (tmax && !ge_var->vscnt) { + usleep_range(1000, 2000); + tmax--; + } + + if (debug) { + do_gettimeofday(&t2); + ms = (t2.tv_sec - t1.tv_sec) * 1000 + + (t2.tv_usec - t1.tv_usec) / 1000; + printk(KERN_DEBUG "vsync3: wait vsync for %d ms\n", ms); + } + } + + memcpy(ge_var->var, ge_var->new_var, sizeof(struct fb_var_screeninfo)); + spin_unlock(ge_var->lock); + + ge_vo_pan_display(ge_var->var, ge_var->info); + ge_var->dirty = 0; + ge_var->vscnt = 0; + + queue_work(ge_var->wq, &ge_var->notifier); +} + +#if 0 +static unsigned long fb_get_phys_addr(struct fb_info *info, + struct fb_var_screeninfo *var) +{ + unsigned long offset; + + if (!var) + var = &info->var; + + offset = (var->yoffset * var->xres_virtual + var->xoffset); + offset *= var->bits_per_pixel >> 3; + + return info->fix.smem_start + offset; +} + +static unsigned long fb_get_disp_size(struct fb_info *info, + struct fb_var_screeninfo *var) +{ + unsigned long size; + + if (!var) + var = &info->var; + + size = (var->yres * var->xres_virtual); + size *= var->bits_per_pixel >> 3; + + return size; +} +#endif + static int fb_var_cmp(struct fb_var_screeninfo *var1, struct fb_var_screeninfo *var2) { @@ -298,7 +477,7 @@ int ge_release(struct fb_info *info) { struct ge_var *ge_var = ge_var_s; - ge_var->sync(ge_var, 0); /* apply pending changes */ + ge_var->sync(ge_var); /* apply pending changes */ return 0; } diff --git a/drivers/video/wmt/ge/ge_accel.h b/drivers/video/wmt/ge/ge_accel.h index c6934daa..d47d30f7 100755..100644 --- a/drivers/video/wmt/ge/ge_accel.h +++ b/drivers/video/wmt/ge/ge_accel.h @@ -41,6 +41,7 @@ extern int vbl; extern int vsync; +extern int sync2; unsigned int phy_mem_end(void); unsigned int phy_mem_end_sub(unsigned int size); @@ -60,8 +61,8 @@ void ge_vo_wait_vsync(void); #ifdef HAVE_VPP #include "../vpp.h" extern void vpp_wait_vsync(int idx, int cnt); -extern void wmtfb_set_mutex(struct fb_info *info, int lock); -extern int vpp_get_info(int fbn, struct fb_var_screeninfo *var); +extern void vpp_set_mutex(int idx, int lock); +extern void vpp_get_info(int fbn, struct fb_var_screeninfo *var); extern int vpp_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); extern int vpp_set_blank(struct fb_info *info, int blank); extern int vpp_set_par(struct fb_info *info); diff --git a/drivers/video/wmt/ge/ge_main.c b/drivers/video/wmt/ge/ge_main.c index 4b362fe3..1109ff5f 100755..100644 --- a/drivers/video/wmt/ge/ge_main.c +++ b/drivers/video/wmt/ge/ge_main.c @@ -50,6 +50,158 @@ static struct mali_device *malidev; #define MALI_PUT_UMP_SECURE_ID _IOWR('m', 321, unsigned int) #endif /* HAVE_MALI */ +#define USE_SID_ALIAS +/* +#define DEBUG_SID_ALIAS +*/ + +#ifdef USE_SID_ALIAS +#define SID_IDX_MAX 16 +#define SID_GET_INDEX_FROM_ALIAS _IOWR('s', 100, unsigned int) +#define SID_SET_ALIAS _IOWR('s', 101, unsigned int) +#define SID_GET_ALIAS _IOWR('s', 102, unsigned int) +#define SID_GET_AND_RESET_ALIAS _IOWR('s', 103, unsigned int) +#define SID_DUMP _IOWR('s', 104, unsigned int) + +struct sid_alias { + int sid; + int alias; +}; + +static struct sid_alias sid_alias_buf[SID_IDX_MAX]; +static spinlock_t sid_lock; + +int sid_get_index_from_empty(int *index) +{ + int i; + + for (i = 0; i < SID_IDX_MAX; i++) { + if (!sid_alias_buf[i].sid && !sid_alias_buf[i].alias) { + *index = i; + return 0; + } + } + return -1; +} + +int sid_get_index_from_alias(int alias, int *index) +{ + int i; + + for (i = 0; i < SID_IDX_MAX; i++) { + if (sid_alias_buf[i].alias == alias) { + *index = i; + return 0; + } + } + return -1; +} + +int sid_clear_alias(int sid) +{ + int idx; + + for (idx = 0; idx < SID_IDX_MAX; idx++) { + if (sid == sid_alias_buf[idx].sid || + sid == sid_alias_buf[idx].alias) { + sid_alias_buf[idx].sid = 0; + sid_alias_buf[idx].alias = 0; + } + } + + return 0; +} + +int sid_set_alias(int sid, int alias) +{ + int idx; + + if (alias <= 0) + return sid_clear_alias(sid); + + sid_clear_alias(alias); + + if (sid_get_index_from_alias(sid, &idx) == 0) { + sid_alias_buf[idx].alias = alias; + if (alias <= 0) + sid_alias_buf[idx].sid = 0; + return 0; + } + + sid_clear_alias(sid); + + if (sid_get_index_from_empty(&idx) == 0) { + sid_alias_buf[idx].sid = sid; + sid_alias_buf[idx].alias = alias; + return 0; + } + + return -1; +} + +int sid_get_alias(int sid, int *alias) +{ + int i; + int val = -1; + + for (i = 0; i < SID_IDX_MAX; i++) { + if (sid_alias_buf[i].sid == sid) { + if (sid_alias_buf[i].alias > 0) { + val = sid_alias_buf[i].alias; + if (sid != val) + break; + } else { + /* remove invalid alias */ + sid_alias_buf[i].sid = 0; + sid_alias_buf[i].alias = 0; + } + } + } + + if (val > 0) { + *alias = val; + return 0; + } else + return -1; +} + +int sid_get_and_reset_alias(int sid, int *alias) +{ + int i; + int val = -1; + + for (i = 0; i < SID_IDX_MAX; i++) { + if (sid_alias_buf[i].sid == sid) { + if (sid_alias_buf[i].alias > 0) { + val = sid_alias_buf[i].alias; + sid_alias_buf[i].sid = val; + if (sid != val) + break; + } else { + /* remove invalid alias */ + sid_alias_buf[i].sid = 0; + sid_alias_buf[i].alias = 0; + } + } + } + + if (val > 0) { + *alias = val; + return 0; + } else + return -1; +} + +void sid_dump(void) +{ + int i; + + for (i = 0; i < SID_IDX_MAX; i++) + printk(KERN_ERR "sid_alias_buf[%d] = { %d, %d }\n", + i, sid_alias_buf[i].sid, sid_alias_buf[i].alias); +} +#endif + #ifndef FBIO_WAITFORVSYNC #define FBIO_WAITFORVSYNC _IOW('F', 0x20, u_int32_t) #endif @@ -318,6 +470,64 @@ static int gefb_ioctl(struct fb_info *info, unsigned int cmd, break; } #endif /* GEIO_MAGIC */ +#ifdef USE_SID_ALIAS + case SID_GET_INDEX_FROM_ALIAS: { + unsigned int args[2]; + unsigned int index = -1; + copy_from_user(args, (void *)arg, sizeof(unsigned int) * 2); + spin_lock(&sid_lock); + retval = sid_get_index_from_alias(args[0], &index); + spin_unlock(&sid_lock); + put_user(index, (unsigned int __user *)args[1]); + break; + } + case SID_SET_ALIAS: { + unsigned int args[2]; + copy_from_user(args, (void *)arg, sizeof(unsigned int) * 2); + spin_lock(&sid_lock); + retval = sid_set_alias(args[0], args[1]); +#ifdef DEBUG_SID_ALIAS + printk(KERN_DEBUG "sid_set_alias %d, %d, ret = %d\n", + args[0], args[1], retval); + sid_dump(); +#endif + spin_unlock(&sid_lock); + break; + } + case SID_GET_ALIAS: { + unsigned int args[2]; + unsigned int alias = -1; + copy_from_user(args, (void *)arg, sizeof(unsigned int) * 2); + spin_lock(&sid_lock); + retval = sid_get_alias(args[0], &alias); + spin_unlock(&sid_lock); + put_user(alias, (unsigned int __user *)args[1]); + break; + } + case SID_GET_AND_RESET_ALIAS: { + unsigned int args[2]; + unsigned int alias = -1; + copy_from_user(args, (void *)arg, sizeof(unsigned int) * 2); + spin_lock(&sid_lock); + retval = sid_get_and_reset_alias(args[0], &alias); +#ifdef DEBUG_SID_ALIAS + printk(KERN_DEBUG "sid_get_and_reset_alias %d, %d, ret = %d\n", + args[0], alias, retval); + sid_dump(); +#endif + spin_unlock(&sid_lock); + put_user(alias, (unsigned int __user *)args[1]); + break; + } + case SID_DUMP: { + spin_lock(&sid_lock); + copy_to_user((void *)arg, sid_alias_buf, + sizeof(struct sid_alias) * SID_IDX_MAX); + retval = 0; + spin_unlock(&sid_lock); + break; + } +#endif default: break; } @@ -462,7 +672,7 @@ static int __init gefb_setup(char *options) /* The syntax is: * video=gefb:[<param>][,<param>=<val>] ... * e.g., - * video=gefb:vtotal=12, + * video=gefb:vtotal=12,sync2 */ while ((this_opt = strsep(&options, ",")) != NULL) { @@ -476,6 +686,8 @@ static int __init gefb_setup(char *options) ; else if (get_opt_bool(this_opt, "vsync", &vsync)) ; + else if (get_opt_bool(this_opt, "sync2", &sync2)) + ; } return 0; @@ -488,7 +700,7 @@ static struct mali_device *add_mali_device(unsigned int *smem_start_ptr, unsigned int len; struct mali_device *dev = create_mali_device(); if (dev) { - dev->set_memory_base(*smem_start_ptr); + dev->get_memory_base(smem_start_ptr); dev->get_memory_size(&len); *smem_start_ptr += len; *smem_len_ptr -= len; @@ -532,12 +744,11 @@ static int __devinit gefb_probe(struct platform_device *dev) { struct fb_info *info; int cmap_len, retval; -/* char mode_option[] = "1024x768@60"; */ + char mode_option[] = "1024x768@60"; unsigned int smem_start; unsigned int smem_len; unsigned int len; unsigned int min_smem_len; - unsigned int id; /* Allocate fb_info and par.*/ info = framebuffer_alloc(sizeof(unsigned int) * 16, &dev->dev); @@ -554,13 +765,6 @@ static int __devinit gefb_probe(struct platform_device *dev) smem_start = (num_physpages << PAGE_SHIFT); smem_len = phy_mem_end() - smem_start; - /* If newer than WM3498, reserve 1MiB for U-Boot env */ - id = (*(unsigned int *)SYSTEM_CFG_CTRL_BASE_ADDR) >> 16; - if (id > 0x3498) { - smem_start += 0x100000; - smem_len -= 0x100000; - } - #ifdef HAVE_MALI malidev = add_mali_device(&smem_start, &smem_len); #endif /* HAVE_MALI */ @@ -617,7 +821,6 @@ static int __devinit gefb_probe(struct platform_device *dev) info->par = NULL; info->flags = FBINFO_DEFAULT; /* flag for fbcon */ -#if 0 /* * This should give a reasonable default video mode. */ @@ -626,7 +829,7 @@ static int __devinit gefb_probe(struct platform_device *dev) if (!retval || retval == 4) return -EINVAL; -#endif + /* * This has to been done !!! */ @@ -664,6 +867,11 @@ static int __devinit gefb_probe(struct platform_device *dev) info->dev->power.async_suspend = 1; /* Add by Charles */ dev_set_drvdata(&dev->dev, info); +#ifdef USE_SID_ALIAS + spin_lock_init(&sid_lock); + memset(sid_alias_buf, 0, sizeof(struct sid_alias) * SID_IDX_MAX); +#endif + return 0; } diff --git a/drivers/video/wmt/govrh.c b/drivers/video/wmt/govrh.c index 42635abf..7f851909 100755..100644 --- a/drivers/video/wmt/govrh.c +++ b/drivers/video/wmt/govrh.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/govrh.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -29,11 +29,11 @@ #include "govrh.h" #ifdef WMT_FTBLK_GOVRH -void govrh_reg_dump(struct vpp_mod_base_t *base) +void govrh_reg_dump(vpp_mod_base_t *base) { - struct govrh_mod_t *p_govr = (struct govrh_mod_t *) base; - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + govrh_mod_t *p_govr = (govrh_mod_t *) base; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; int igs_mode[4] = {888, 555, 666, 565}; DPRINT("========== GOVRH register dump ==========\n"); @@ -116,19 +116,29 @@ void govrh_reg_dump(struct vpp_mod_base_t *base) } -void govrh_set_tg_enable(struct govrh_mod_t *base, vpp_flag_t enable) +void govrh_set_tg_enable(govrh_mod_t *base, vpp_flag_t enable) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, enable); - regs->tg_enable.b.enable = enable; + switch (enable) { + case VPP_FLAG_ENABLE: + regs->tg_enable.b.enable = enable; + break; + case VPP_FLAG_DISABLE: + if (regs->tg_enable.b.enable) + regs->tg_enable.b.enable = enable; + break; + default: + break; + } + return; } -unsigned int govrh_set_clock(struct govrh_mod_t *base, - unsigned int pixel_clock) +unsigned int govrh_set_clock(govrh_mod_t *base, unsigned int pixel_clock) { int pmc_clk = 0; @@ -147,10 +157,10 @@ unsigned int govrh_set_clock(struct govrh_mod_t *base, return 0; } -void govrh_set_tg1(struct govrh_mod_t *base, vpp_clock_t *timing) +void govrh_set_tg1(govrh_mod_t *base, vpp_clock_t *timing) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); @@ -179,20 +189,20 @@ void govrh_set_tg1(struct govrh_mod_t *base, vpp_clock_t *timing) #endif } -int govrh_get_tg_mode(struct govrh_mod_t *base) +int govrh_get_tg_mode(govrh_mod_t *base) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); return regs->tg_enable.b.mode; } -void govrh_set_tg2(struct govrh_mod_t *base, vpp_clock_t *timing) +void govrh_set_tg2(govrh_mod_t *base, vpp_clock_t *timing) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); @@ -219,10 +229,10 @@ void govrh_set_tg2(struct govrh_mod_t *base, vpp_clock_t *timing) #endif } -void govrh_get_tg(struct govrh_mod_t *base, vpp_clock_t *tmr) +void govrh_get_tg(govrh_mod_t *base, vpp_clock_t *tmr) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); @@ -249,10 +259,10 @@ void govrh_get_tg(struct govrh_mod_t *base, vpp_clock_t *tmr) } } -int govrh_get_hscale_up(struct govrh_mod_t *base) +int govrh_get_hscale_up(govrh_mod_t *base) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; int reg; reg = regs->hscale_up & 0x1; @@ -261,10 +271,10 @@ int govrh_get_hscale_up(struct govrh_mod_t *base) return reg; } -void govrh_set_direct_path(struct govrh_mod_t *base, int enable) +void govrh_set_direct_path(govrh_mod_t *base, int enable) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, enable); @@ -272,11 +282,11 @@ void govrh_set_direct_path(struct govrh_mod_t *base, int enable) regs->dirpath = enable; } -enum vpp_int_err_t govrh_get_int_status(struct govrh_mod_t *base) +vpp_int_err_t govrh_get_int_status(govrh_mod_t *base) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; - enum vpp_int_err_t int_sts; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; + vpp_int_err_t int_sts; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); @@ -286,11 +296,10 @@ enum vpp_int_err_t govrh_get_int_status(struct govrh_mod_t *base) return int_sts; } -void govrh_clean_int_status(struct govrh_mod_t *base, - enum vpp_int_err_t int_sts) +void govrh_clean_int_status(govrh_mod_t *base, vpp_int_err_t int_sts) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; unsigned int val; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? @@ -303,11 +312,11 @@ void govrh_clean_int_status(struct govrh_mod_t *base, } } -void govrh_set_int_enable(struct govrh_mod_t *base, - vpp_flag_t enable, enum vpp_int_err_t int_bit) +void govrh_set_int_enable(govrh_mod_t *base, + vpp_flag_t enable, vpp_int_err_t int_bit) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, enable); @@ -319,44 +328,39 @@ void govrh_set_int_enable(struct govrh_mod_t *base, regs->interrupt.b.mem_enable = enable; } -int govrh_get_dvo_enable(struct govrh_mod_t *base) -{ - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; - return regs->dvo_set.b.enable; -} - -void govrh_set_dvo_enable(struct govrh_mod_t *base, vpp_flag_t enable) +void govrh_set_dvo_enable(govrh_mod_t *base, vpp_flag_t enable) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; /* DPRINT("[GOVRH] %s(%d)\n",__FUNCTION__,enable); */ DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, enable); regs->dvo_set.b.enable = enable; +#if 1 if (enable) { /* GPIO to function pin */ - outl(0x0, GPIO_BASE_ADDR + 0x44); + vppif_reg32_out(GPIO_BASE_ADDR + 0x44, 0x0); /* GPIO pull disable */ - outl(0x0, GPIO_BASE_ADDR + 0x484); + vppif_reg32_out(GPIO_BASE_ADDR + 0x484, 0x0); /* 1:pullup,0:pulldn */ - outl(0x0, GPIO_BASE_ADDR + 0x4C4); + vppif_reg32_out(GPIO_BASE_ADDR + 0x4C4, 0x0); return; } /* disable dvo */ - outl(0xFFFFFFFF, GPIO_BASE_ADDR + 0x44); /* Enable GPIO */ - outl(0x0, GPIO_BASE_ADDR + 0x84); /* GPIO output enable */ - outl(0x0, GPIO_BASE_ADDR + 0x484); /* GPIO pull disable */ - outl(0x0, GPIO_BASE_ADDR + 0x4C4); /* 1:pullup,0:pulldn */ + vppif_reg32_out(GPIO_BASE_ADDR + 0x44, 0xFFFFFFFF); /* Enable GPIO */ + vppif_reg32_out(GPIO_BASE_ADDR + 0x84, 0x0); /* GPIO output enable */ + vppif_reg32_out(GPIO_BASE_ADDR + 0x484, 0x0); /* GPIO pull disable */ + vppif_reg32_out(GPIO_BASE_ADDR + 0x4C4, 0x0); /* 1:pullup,0:pulldn */ +#endif } -void govrh_set_dvo_sync_polar(struct govrh_mod_t *base, +void govrh_set_dvo_sync_polar(govrh_mod_t *base, vpp_flag_t hsync, vpp_flag_t vsync) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, hsync, vsync); @@ -365,10 +369,10 @@ void govrh_set_dvo_sync_polar(struct govrh_mod_t *base, regs->dvo_set.b.vsync_polar = vsync; } -vdo_color_fmt govrh_get_dvo_color_format(struct govrh_mod_t *base) +vdo_color_fmt govrh_get_dvo_color_format(govrh_mod_t *base) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); @@ -379,11 +383,10 @@ vdo_color_fmt govrh_get_dvo_color_format(struct govrh_mod_t *base) return VDO_COL_FMT_YUV444; } -void govrh_set_dvo_color_format(struct govrh_mod_t *base, - vdo_color_fmt fmt) +void govrh_set_dvo_color_format(govrh_mod_t *base, vdo_color_fmt fmt) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%s)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, vpp_colfmt_str[fmt]); @@ -405,11 +408,10 @@ void govrh_set_dvo_color_format(struct govrh_mod_t *base, } } -void govrh_set_dvo_outdatw(struct govrh_mod_t *base, - vpp_datawidht_t width) +void govrh_set_dvo_outdatw(govrh_mod_t *base, vpp_datawidht_t width) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; unsigned int clk_delay; DBG_DETAIL("(govr %d,%d)\n", @@ -423,11 +425,11 @@ void govrh_set_dvo_outdatw(struct govrh_mod_t *base, clk_delay & 0x3FFF); } -void govrh_set_dvo_clock_delay(struct govrh_mod_t *base, +void govrh_set_dvo_clock_delay(govrh_mod_t *base, int inverse, int delay) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, inverse, delay); @@ -440,11 +442,11 @@ void govrh_set_dvo_clock_delay(struct govrh_mod_t *base, regs->dvo_dly_sel.b.delay = delay; } -void govrh_set_colorbar(struct govrh_mod_t *base, +void govrh_set_colorbar(govrh_mod_t *base, vpp_flag_t enable, int mode, int inv) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, enable); @@ -454,10 +456,10 @@ void govrh_set_colorbar(struct govrh_mod_t *base, regs->cb_enable.b.inversion = inv; } -void govrh_set_contrast(struct govrh_mod_t *base, unsigned int value) +void govrh_set_contrast(govrh_mod_t *base, unsigned int value) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,0x%x)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, value); @@ -465,20 +467,20 @@ void govrh_set_contrast(struct govrh_mod_t *base, unsigned int value) regs->contrast.val = value; } -unsigned int govrh_get_contrast(struct govrh_mod_t *base) +unsigned int govrh_get_contrast(govrh_mod_t *base) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); return regs->contrast.val; } -void govrh_set_brightness(struct govrh_mod_t *base, unsigned int value) +void govrh_set_brightness(govrh_mod_t *base, unsigned int value) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,0x%x)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, value); @@ -486,20 +488,20 @@ void govrh_set_brightness(struct govrh_mod_t *base, unsigned int value) regs->brightness = value; } -unsigned int govrh_get_brightness(struct govrh_mod_t *base) +unsigned int govrh_get_brightness(govrh_mod_t *base) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); return regs->brightness; } -void govrh_set_saturation(struct govrh_mod_t *base, unsigned int value) +void govrh_set_saturation(govrh_mod_t *base, unsigned int value) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,0x%x)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, value); @@ -508,20 +510,20 @@ void govrh_set_saturation(struct govrh_mod_t *base, unsigned int value) regs->saturation_enable.b.enable = 1; } -unsigned int govrh_get_saturation(struct govrh_mod_t *base) +unsigned int govrh_get_saturation(govrh_mod_t *base) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); return regs->saturation.val; } -void govrh_set_MIF_enable(struct govrh_mod_t *base, vpp_flag_t enable) +void govrh_set_MIF_enable(govrh_mod_t *base, vpp_flag_t enable) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, enable); @@ -529,21 +531,21 @@ void govrh_set_MIF_enable(struct govrh_mod_t *base, vpp_flag_t enable) regs->mif.b.enable = enable; } -int govrh_get_MIF_enable(struct govrh_mod_t *base) +int govrh_get_MIF_enable(govrh_mod_t *base) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); return regs->mif.b.enable; } -void govrh_set_frame_mode(struct govrh_mod_t *base, +void govrh_set_frame_mode(govrh_mod_t *base, unsigned int width, vdo_color_fmt colfmt) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; int y_byte, c_byte; int enable; @@ -559,7 +561,7 @@ void govrh_set_frame_mode(struct govrh_mod_t *base, } if (regs->bufwid % 128) enable = 0; - if (width == 720) + if ((width == 720) && (colfmt == VDO_COL_FMT_RGB_565)) enable = 0; regs->mif_frame_mode.b.frame_enable = enable; regs->mif_frame_mode.b.req_num = @@ -568,11 +570,10 @@ void govrh_set_frame_mode(struct govrh_mod_t *base, (c_byte) ? ((c_byte / 128) + ((c_byte % 128) ? 1 : 0)) : 0; } -void govrh_set_color_format(struct govrh_mod_t *base, - vdo_color_fmt format) +void govrh_set_color_format(govrh_mod_t *base, vdo_color_fmt format) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%s)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, vpp_colfmt_str[format]); @@ -607,16 +608,16 @@ void govrh_set_color_format(struct govrh_mod_t *base, return; } #ifdef WMT_FTBLK_GOVRH_CURSOR - govrh_CUR_set_colfmt((struct govrh_cursor_mod_t *)p_cursor, format); + govrh_CUR_set_colfmt((govrh_cursor_mod_t *)p_cursor, format); #endif govrh_set_frame_mode(base, regs->pixwid, format); regs->saturation_enable.b.format = (regs->yuv2rgb.b.rgb_mode) ? 1 : 0; } -vdo_color_fmt govrh_get_color_format(struct govrh_mod_t *base) +vdo_color_fmt govrh_get_color_format(govrh_mod_t *base) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); @@ -637,11 +638,11 @@ vdo_color_fmt govrh_get_color_format(struct govrh_mod_t *base) return VDO_COL_FMT_YUV422H; } -void govrh_set_source_format(struct govrh_mod_t *base, +void govrh_set_source_format(govrh_mod_t *base, vpp_display_format_t format) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, format); @@ -649,11 +650,11 @@ void govrh_set_source_format(struct govrh_mod_t *base, regs->srcfmt = (format == VPP_DISP_FMT_FIELD) ? 1 : 0; } -void govrh_set_output_format(struct govrh_mod_t *base, +void govrh_set_output_format(govrh_mod_t *base, vpp_display_format_t field) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, field); @@ -661,11 +662,11 @@ void govrh_set_output_format(struct govrh_mod_t *base, regs->dstfmt = (field == VPP_DISP_FMT_FIELD) ? 1 : 0; } -void govrh_set_fb_addr(struct govrh_mod_t *base, +void govrh_set_fb_addr(govrh_mod_t *base, unsigned int y_addr, unsigned int c_addr) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; /* DBG_DETAIL("(govr %d,0x%x,0x%x)\n", (base->mod == VPP_MOD_GOVRH)? 1:2,y_addr,c_addr); */ @@ -678,11 +679,11 @@ void govrh_set_fb_addr(struct govrh_mod_t *base, regs->csa = c_addr; } -void govrh_get_fb_addr(struct govrh_mod_t *base, +void govrh_get_fb_addr(govrh_mod_t *base, unsigned int *y_addr, unsigned int *c_addr) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; *y_addr = regs->ysa; *c_addr = regs->csa; @@ -691,11 +692,11 @@ void govrh_get_fb_addr(struct govrh_mod_t *base, (base->mod == VPP_MOD_GOVRH) ? 1 : 2, *y_addr, *c_addr); } -void govrh_set_fb2_addr(struct govrh_mod_t *base, +void govrh_set_fb2_addr(govrh_mod_t *base, unsigned int y_addr, unsigned int c_addr) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,0x%x,0x%x)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, y_addr, c_addr); @@ -708,11 +709,11 @@ void govrh_set_fb2_addr(struct govrh_mod_t *base, regs->csa2 = c_addr; } -void govrh_get_fb2_addr(struct govrh_mod_t *base, +void govrh_get_fb2_addr(govrh_mod_t *base, unsigned int *y_addr, unsigned int *c_addr) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; *y_addr = regs->ysa2; *c_addr = regs->csa2; @@ -721,10 +722,10 @@ void govrh_get_fb2_addr(struct govrh_mod_t *base, (base->mod == VPP_MOD_GOVRH) ? 1 : 2, *y_addr, *c_addr); } -void govrh_set_fb_width(struct govrh_mod_t *base, unsigned int width) +void govrh_set_fb_width(govrh_mod_t *base, unsigned int width) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, width); @@ -733,11 +734,11 @@ void govrh_set_fb_width(struct govrh_mod_t *base, unsigned int width) } #define GOVRH_CURSOR_RIGHT_POS 6 -void govrh_set_fb_info(struct govrh_mod_t *base, unsigned int width, +void govrh_set_fb_info(govrh_mod_t *base, unsigned int width, unsigned int act_width, unsigned int x_offset, unsigned int y_offset) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,fb_w %d,img_w %d,x %d,y %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, @@ -767,11 +768,11 @@ void govrh_set_fb_info(struct govrh_mod_t *base, unsigned int width, #endif } -void govrh_get_fb_info(struct govrh_mod_t *base, unsigned int *width, +void govrh_get_fb_info(govrh_mod_t *base, unsigned int *width, unsigned int *act_width, unsigned int *x_offset, unsigned int *y_offset) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); @@ -781,10 +782,10 @@ void govrh_get_fb_info(struct govrh_mod_t *base, unsigned int *width, *y_offset = regs->vcrop; } -void govrh_set_fifo_index(struct govrh_mod_t *base, unsigned int index) +void govrh_set_fifo_index(govrh_mod_t *base, unsigned int index) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, index); @@ -792,10 +793,10 @@ void govrh_set_fifo_index(struct govrh_mod_t *base, unsigned int index) regs->fhi = index; } -void govrh_set_reg_level(struct govrh_mod_t *base, vpp_reglevel_t level) +void govrh_set_reg_level(govrh_mod_t *base, vpp_reglevel_t level) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, level); @@ -803,10 +804,10 @@ void govrh_set_reg_level(struct govrh_mod_t *base, vpp_reglevel_t level) regs->sts.b.level = (level == VPP_REG_LEVEL_1) ? 0 : 1; } -void govrh_set_reg_update(struct govrh_mod_t *base, vpp_flag_t enable) +void govrh_set_reg_update(govrh_mod_t *base, vpp_flag_t enable) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, enable); @@ -814,11 +815,11 @@ void govrh_set_reg_update(struct govrh_mod_t *base, vpp_flag_t enable) regs->sts.b.update = enable; } -void govrh_set_tg(struct govrh_mod_t *base, +void govrh_set_tg(govrh_mod_t *base, vpp_clock_t *tmr, unsigned int pixel_clock) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; int tg_enable; DBG_DETAIL("(govr %d,%d)\n", @@ -833,12 +834,13 @@ void govrh_set_tg(struct govrh_mod_t *base, regs->tg_enable.b.enable = tg_enable; } -void govrh_set_csc_mode(struct govrh_mod_t *base, vpp_csc_t mode) +void govrh_set_csc_mode(govrh_mod_t *base, vpp_csc_t mode) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; vdo_color_fmt src_fmt, dst_fmt; unsigned int enable; + unsigned int csc_parm5; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, mode); @@ -878,10 +880,11 @@ void govrh_set_csc_mode(struct govrh_mod_t *base, vpp_csc_t mode) if (mode >= VPP_CSC_MAX) { enable = 0; /* for internal color bar (YUV base) */ - mode = base->fb_p->csc_mode; + mode = VPP_CSC_YUV2RGB_JFIF_0_255; } - - mode = (base->csc_mode_force) ? base->csc_mode_force : mode; + /* HDMI YUV mode too light 0xff00ff -> 0x01010001 */ + csc_parm5 = (mode == VPP_CSC_RGB2YUV_JFIF_0_255) ? + 0x01010001 : vpp_csc_parm[mode][5]; regs->dmacsc_coef0 = vpp_csc_parm[mode][0]; /* C1,C2 */ regs->dmacsc_coef1 = vpp_csc_parm[mode][1]; /* C3,C4 */ @@ -889,16 +892,14 @@ void govrh_set_csc_mode(struct govrh_mod_t *base, vpp_csc_t mode) regs->dmacsc_coef3 = vpp_csc_parm[mode][3]; /* C7,C8 */ regs->dmacsc_coef4 = vpp_csc_parm[mode][4] & 0xFFFF; /* C9 */ regs->dmacsc_coef5 = ((vpp_csc_parm[mode][4] & 0xFFFF0000) >> 16) + - ((vpp_csc_parm[mode][5] & 0xFFFF) << 16); /* I,J */ - regs->dmacsc_coef6 = (vpp_csc_parm[mode][5] & 0xFFFF0000) >> 16; /* K */ + ((csc_parm5 & 0xFFFF) << 16); /* I,J */ + regs->dmacsc_coef6 = (csc_parm5 & 0xFFFF0000) >> 16; /* K */ regs->csc_mode.val = (vpp_csc_parm[mode][6] & BIT0) + ((vpp_csc_parm[mode][6] & BIT8) ? BIT1 : 0x0); /* enable bit0:DVO, bit1:VGA, bit2:DISP, bit3:LVDS, bit4:HDMI */ - regs->yuv2rgb.b.blank_zero = 1; - regs->yuv2rgb.b.dac_clkinv = 1; - regs->yuv2rgb.b.reserved1 = - (mode >= VPP_CSC_RGB2YUV_SDTV_0_255) ? 1 : 0; + regs->yuv2rgb.val = (regs->yuv2rgb.val & ~0xFF) + + ((mode >= VPP_CSC_RGB2YUV_SDTV_0_255) ? 0x1C : 0x18); regs->yuv2rgb.b.dvo = (enable & BIT0) ? 1 : 0; #ifdef WMT_FTBLK_LVDS regs->yuv2rgb.b.lvds = (enable & BIT3) ? 1 : 0; @@ -908,10 +909,10 @@ void govrh_set_csc_mode(struct govrh_mod_t *base, vpp_csc_t mode) #endif } -void govrh_set_media_format(struct govrh_mod_t *base, vpp_flag_t h264) +void govrh_set_media_format(govrh_mod_t *base, vpp_flag_t h264) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, h264); @@ -919,21 +920,20 @@ void govrh_set_media_format(struct govrh_mod_t *base, vpp_flag_t h264) regs->mif.b.h264 = h264; } -void govrh_HDMI_set_blank_value(struct govrh_mod_t *base, - unsigned int val) +void govrh_HDMI_set_blank_value(govrh_mod_t *base, unsigned int val) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, val); regs->hdmi_3d.b.blank_value = val; } -void govrh_HDMI_set_3D_mode(struct govrh_mod_t *base, int mode) +void govrh_HDMI_set_3D_mode(govrh_mod_t *base, int mode) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, mode); @@ -942,10 +942,10 @@ void govrh_HDMI_set_3D_mode(struct govrh_mod_t *base, int mode) regs->hdmi_3d.b.mode = mode; } -int govrh_is_top_field(struct govrh_mod_t *base) +int govrh_is_top_field(govrh_mod_t *base) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); @@ -953,11 +953,11 @@ int govrh_is_top_field(struct govrh_mod_t *base) } /*----------------------- GOVRH IGS --------------------------------------*/ -void govrh_IGS_set_mode(struct govrh_mod_t *base, +void govrh_IGS_set_mode(govrh_mod_t *base, int no, int mode_18bit, int msb) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, no); @@ -972,10 +972,10 @@ void govrh_IGS_set_mode(struct govrh_mod_t *base, } } -void govrh_IGS_set_RGB_swap(struct govrh_mod_t *base, int mode) +void govrh_IGS_set_RGB_swap(govrh_mod_t *base, int mode) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, mode); @@ -987,42 +987,41 @@ void govrh_IGS_set_RGB_swap(struct govrh_mod_t *base, int mode) /*----------------------- GOVRH CURSOR --------------------------------------*/ #ifdef WMT_FTBLK_GOVRH_CURSOR #define CONFIG_GOVR2_CURSOR -void *govrh_CUR_get_mmio(struct govrh_cursor_mod_t *base) +void *govrh_CUR_get_mmio(govrh_cursor_mod_t *base) { #ifdef CONFIG_GOVR2_CURSOR - base = (struct govrh_cursor_mod_t *) + base = (govrh_cursor_mod_t *) ((govrh_get_MIF_enable(p_govrh)) ? p_govrh : p_govrh2); #endif return base->mmio; } -void govrh_CUR_set_enable(struct govrh_cursor_mod_t *base, - vpp_flag_t enable) +void govrh_CUR_set_enable(govrh_cursor_mod_t *base, vpp_flag_t enable) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base); + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) govrh_CUR_get_mmio(base); DBG_DETAIL("(0x%x,%d)\n", base->mmio, enable); regs->cur_status.b.enable = enable; } -void govrh_CUR_set_fb_addr(struct govrh_cursor_mod_t *base, +void govrh_CUR_set_fb_addr(govrh_cursor_mod_t *base, unsigned int y_addr, unsigned int c_addr) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base); + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) govrh_CUR_get_mmio(base); DBG_DETAIL("(0x%x,0x%x,0x%x)\n", base->mmio, y_addr, c_addr); regs->cur_addr = y_addr; } -void govrh_CUR_get_fb_addr(struct govrh_cursor_mod_t *base, +void govrh_CUR_get_fb_addr(govrh_cursor_mod_t *base, unsigned int *y_addr, unsigned int *c_addr) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base); + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) govrh_CUR_get_mmio(base); *y_addr = regs->cur_addr; *c_addr = 0; @@ -1030,11 +1029,11 @@ void govrh_CUR_get_fb_addr(struct govrh_cursor_mod_t *base, DBG_DETAIL("(0x%x,0x%x,0x%x)\n", base->mmio, *y_addr, *c_addr); } -void govrh_CUR_set_coordinate(struct govrh_cursor_mod_t *base, +void govrh_CUR_set_coordinate(govrh_cursor_mod_t *base, unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base); + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) govrh_CUR_get_mmio(base); DBG_DETAIL("(0x%x)\n", base->mmio); @@ -1044,11 +1043,11 @@ void govrh_CUR_set_coordinate(struct govrh_cursor_mod_t *base, regs->cur_vcoord.b.end = y2; } -void govrh_CUR_set_position(struct govrh_cursor_mod_t *base, +void govrh_CUR_set_position(govrh_cursor_mod_t *base, unsigned int x, unsigned int y) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base); + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) govrh_CUR_get_mmio(base); unsigned int w, h; DBG_DETAIL("(0x%x,%d,%d)\n", base->mmio, x, y); @@ -1059,7 +1058,7 @@ void govrh_CUR_set_position(struct govrh_cursor_mod_t *base, govrh_CUR_set_coordinate(base, x, y, x+w, y+h); } -void govrh_CUR_set_color_key_mode(struct govrh_cursor_mod_t *base, +void govrh_CUR_set_color_key_mode(govrh_cursor_mod_t *base, int enable, int alpha, int mode) { /* @@ -1069,8 +1068,8 @@ void govrh_CUR_set_color_key_mode(struct govrh_cursor_mod_t *base, if( (alpha_en) or (colkey_hit) or (alpha value) ) show pixel */ - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base); + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) govrh_CUR_get_mmio(base); DBG_DETAIL("(0x%x,%d,%d,%d)\n", base->mmio, enable, alpha, mode); @@ -1079,11 +1078,11 @@ void govrh_CUR_set_color_key_mode(struct govrh_cursor_mod_t *base, regs->cur_color_key.b.invert = mode; } -void govrh_CUR_set_color_key(struct govrh_cursor_mod_t *base, +void govrh_CUR_set_color_key(govrh_cursor_mod_t *base, int enable, int alpha, unsigned int colkey) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base); + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) govrh_CUR_get_mmio(base); DBG_DETAIL("(0x%x,0x%x)\n", base->mmio, colkey); @@ -1122,12 +1121,12 @@ void govrh_CUR_set_color_key(struct govrh_cursor_mod_t *base, #endif } -void govrh_CUR_set_colfmt(struct govrh_cursor_mod_t *base, +void govrh_CUR_set_colfmt(govrh_cursor_mod_t *base, vdo_color_fmt colfmt) { #ifdef __KERNEL__ - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base); + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) govrh_CUR_get_mmio(base); #endif DBG_DETAIL("(0x%x,%s)\n", base->mmio, vpp_colfmt_str[colfmt]); @@ -1147,9 +1146,9 @@ void govrh_CUR_set_colfmt(struct govrh_cursor_mod_t *base, int govrh_irqproc_set_position(void *arg) { - struct govrh_cursor_mod_t *base = (struct govrh_cursor_mod_t *) arg; - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base); + govrh_cursor_mod_t *base = (govrh_cursor_mod_t *) arg; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) govrh_CUR_get_mmio(base); int begin; int pos_x, pos_y; @@ -1232,7 +1231,7 @@ void govrh_CUR_irqproc(int arg) } } -void govrh_CUR_proc_view(struct govrh_cursor_mod_t *base, +void govrh_CUR_proc_view(govrh_cursor_mod_t *base, int read, vdo_view_t *view) { vdo_framebuf_t *fb; @@ -1258,11 +1257,11 @@ void govrh_CUR_proc_view(struct govrh_cursor_mod_t *base, } } -void govrh_CUR_set_framebuffer(struct govrh_cursor_mod_t *base, +void govrh_CUR_set_framebuffer(govrh_cursor_mod_t *base, vdo_framebuf_t *fb) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base); + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) govrh_CUR_get_mmio(base); DBG_DETAIL("(0x%x)\n", base->mmio); @@ -1288,18 +1287,18 @@ void govrh_CUR_set_framebuffer(struct govrh_cursor_mod_t *base, void govrh_CUR_init(void *base) { #ifdef CONFIG_GOVR2_CURSOR - HW_REG struct govrh_regs *regs; + volatile struct govrh_regs *regs; - regs = (HW_REG struct govrh_regs *) p_govrh->mmio; + regs = (volatile struct govrh_regs *) p_govrh->mmio; regs->cur_color_key.b.invert = 1; - regs = (HW_REG struct govrh_regs *) p_govrh2->mmio; + regs = (volatile struct govrh_regs *) p_govrh2->mmio; regs->cur_color_key.b.invert = 1; #else - struct govrh_cursor_mod_t *mod_p; - HW_REG struct govrh_regs *regs; + govrh_cursor_mod_t *mod_p; + volatile struct govrh_regs *regs; - mod_p = (struct govrh_cursor_mod_t *) base; - regs = (HW_REG struct govrh_regs *) mod_p->mmio; + mod_p = (govrh_cursor_mod_t *) base; + regs = (volatile struct govrh_regs *) mod_p->mmio; regs->cur_color_key.b.invert = 1; #endif @@ -1329,11 +1328,11 @@ void govrh_vmode_to_timing(vpp_mod_t mod, t->read_cycle = vpp_get_base_clock(mod) / pixel_clock; } -void govrh_set_videomode(struct govrh_mod_t *base, +void govrh_set_videomode(govrh_mod_t *base, struct fb_videomode *p_vmode) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) base->mmio; struct fb_videomode vmode; vpp_clock_t t1; int tg_enable; @@ -1387,11 +1386,10 @@ void govrh_set_videomode(struct govrh_mod_t *base, regs->tg_enable.b.enable = tg_enable; } -void govrh_get_videomode(struct govrh_mod_t *base, - struct fb_videomode *vmode) +void govrh_get_videomode(govrh_mod_t *base, struct fb_videomode *vmode) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs + = (volatile struct govrh_regs *) base->mmio; vpp_clock_t t; int htotal, vtotal; unsigned int pixel_clock; @@ -1423,18 +1421,14 @@ void govrh_get_videomode(struct govrh_mod_t *base, if (vmode->vmode & FB_VMODE_DOUBLE) vtotal *= 2; - if (htotal && vtotal) { - unsigned int temp; - temp = (pixel_clock * 10)/(htotal * vtotal); - vmode->refresh = temp / 10; - if ((temp % 10) >= 5) - vmode->refresh += 1; - } else + if (htotal && vtotal) + vmode->refresh = pixel_clock/(htotal * vtotal); + else vmode->refresh = 60; { /* get sync polar */ int hsync_hi, vsync_hi; - enum vout_inf_mode_t interface; + vout_inf_mode_t interface; switch (base->mod) { case VPP_MOD_GOVRH: @@ -1473,7 +1467,7 @@ void govrh_get_videomode(struct govrh_mod_t *base, } } -void govrh_set_framebuffer(struct govrh_mod_t *base, vdo_framebuf_t *fb) +void govrh_set_framebuffer(govrh_mod_t *base, vdo_framebuf_t *fb) { DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2); @@ -1484,10 +1478,10 @@ void govrh_set_framebuffer(struct govrh_mod_t *base, vdo_framebuf_t *fb) govrh_set_csc_mode(base, base->fb_p->csc_mode); } -void govrh_get_framebuffer(struct govrh_mod_t *base, vdo_framebuf_t *fb) +void govrh_get_framebuffer(govrh_mod_t *base, vdo_framebuf_t *fb) { - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs + = (volatile struct govrh_regs *) base->mmio; vpp_clock_t clock; int y_bpp, c_bpp; @@ -1509,11 +1503,11 @@ void govrh_get_framebuffer(struct govrh_mod_t *base, vdo_framebuf_t *fb) /*----------------------- GOVRH MODULE API -----------------------------*/ int govrh_suspend_yaddr; -void govrh_suspend(struct govrh_mod_t *base, int sts) +void govrh_suspend(govrh_mod_t *base, int sts) { #ifdef CONFIG_PM - HW_REG struct govrh_regs *regs = - (HW_REG struct govrh_regs *) base->mmio; + volatile struct govrh_regs *regs + = (volatile struct govrh_regs *) base->mmio; switch (sts) { case 0: /* disable module */ @@ -1537,9 +1531,12 @@ void govrh_suspend(struct govrh_mod_t *base, int sts) #endif } -void govrh_resume(struct govrh_mod_t *base, int sts) +void govrh_resume(govrh_mod_t *base, int sts) { #ifdef CONFIG_PM +/* volatile struct govrh_regs *regs + = (volatile struct govrh_regs *) base->mmio; */ + switch (sts) { case 0: /* restore register */ govrh_set_clock(base, base->vo_clock); @@ -1564,11 +1561,11 @@ void govrh_resume(struct govrh_mod_t *base, int sts) void govrh_init(void *base) { - struct govrh_mod_t *mod_p; - HW_REG struct govrh_regs *regs; + govrh_mod_t *mod_p; + volatile struct govrh_regs *regs; - mod_p = (struct govrh_mod_t *) base; - regs = (HW_REG struct govrh_regs *) mod_p->mmio; + mod_p = (govrh_mod_t *) base; + regs = (volatile struct govrh_regs *) mod_p->mmio; govrh_set_reg_level(base, VPP_REG_LEVEL_1); govrh_set_colorbar(base, VPP_FLAG_DISABLE, 1, 0); @@ -1757,13 +1754,12 @@ void govrh2_mod_set_color_fmt(vdo_color_fmt colfmt) #endif int govrh_mod_init(void) { - struct govrh_mod_t *mod_p; - struct vpp_fb_base_t *mod_fb_p; + govrh_mod_t *mod_p; + vpp_fb_base_t *mod_fb_p; vdo_framebuf_t *fb_p; - mod_p = (struct govrh_mod_t *) vpp_mod_register(VPP_MOD_GOVRH, - sizeof(struct govrh_mod_t), - VPP_MOD_FLAG_FRAMEBUF); + mod_p = (govrh_mod_t *) vpp_mod_register(VPP_MOD_GOVRH, + sizeof(govrh_mod_t), VPP_MOD_FLAG_FRAMEBUF); if (!mod_p) { DPRINT("*E* GOVRH module register fail\n"); return -1; @@ -1787,7 +1783,7 @@ int govrh_mod_init(void) /* module frame buffer */ mod_fb_p = mod_p->fb_p; - mod_fb_p->csc_mode = VPP_CSC_RGB2YUV_JFIF_0_255; + mod_fb_p->csc_mode = VPP_CSC_RGB2YUV_SDTV_0_255; mod_fb_p->framerate = VPP_HD_DISP_FPS; mod_fb_p->media_fmt = VPP_MEDIA_FMT_MPEG; mod_fb_p->wait_ready = 0; @@ -1821,9 +1817,8 @@ int govrh_mod_init(void) p_govrh = mod_p; #ifdef WMT_FTBLK_GOVRH_CURSOR - mod_p = (struct govrh_mod_t *) vpp_mod_register(VPP_MOD_CURSOR, - sizeof(struct govrh_cursor_mod_t), - VPP_MOD_FLAG_FRAMEBUF); + mod_p = (govrh_mod_t *) vpp_mod_register(VPP_MOD_CURSOR, + sizeof(govrh_cursor_mod_t), VPP_MOD_FLAG_FRAMEBUF); if (!mod_p) { DPRINT("*E* CURSOR module register fail\n"); return -1; @@ -1864,13 +1859,12 @@ int govrh_mod_init(void) fb_p->v_crop = 0; fb_p->flag = 0; - p_cursor = (struct govrh_cursor_mod_t *) mod_p; + p_cursor = (govrh_cursor_mod_t *) mod_p; #endif #ifdef WMT_FTBLK_GOVRH2 - mod_p = (struct govrh_mod_t *) vpp_mod_register(VPP_MOD_GOVRH2, - sizeof(struct govrh_mod_t), - VPP_MOD_FLAG_FRAMEBUF); + mod_p = (govrh_mod_t *) vpp_mod_register(VPP_MOD_GOVRH2, + sizeof(govrh_mod_t), VPP_MOD_FLAG_FRAMEBUF); if (!mod_p) { DPRINT("*E* GOVRH module register fail\n"); return -1; @@ -1894,7 +1888,7 @@ int govrh_mod_init(void) /* module frame buffer */ mod_fb_p = mod_p->fb_p; - mod_fb_p->csc_mode = VPP_CSC_RGB2YUV_JFIF_0_255; + mod_fb_p->csc_mode = VPP_CSC_RGB2YUV_SDTV_0_255; mod_fb_p->framerate = VPP_HD_DISP_FPS; mod_fb_p->media_fmt = VPP_MEDIA_FMT_MPEG; mod_fb_p->wait_ready = 0; diff --git a/drivers/video/wmt/govrh.h b/drivers/video/wmt/govrh.h index a7dc0625..b20c31ab 100755..100644 --- a/drivers/video/wmt/govrh.h +++ b/drivers/video/wmt/govrh.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/govrh.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -28,7 +28,7 @@ #ifndef GOVRH_H #define GOVRH_H -struct govrh_mod_t { +typedef struct { VPP_MOD_BASE; unsigned int *reg_bk2; @@ -36,12 +36,11 @@ struct govrh_mod_t { unsigned int pm_tg; unsigned int vo_clock; unsigned int underrun_cnt; - unsigned int csc_mode_force; -}; +} govrh_mod_t; #ifdef WMT_FTBLK_GOVRH_CURSOR #define GOVRH_CURSOR_HIDE_TIME 15 -struct govrh_cursor_mod_t { +typedef struct { VPP_MOD_BASE; unsigned int posx; @@ -54,7 +53,7 @@ struct govrh_cursor_mod_t { unsigned int cursor_addr2; int enable; int hide_cnt; -}; +} govrh_cursor_mod_t; #endif #ifdef __cplusplus @@ -67,110 +66,95 @@ extern "C" { #define EXTERN extern #endif -EXTERN struct govrh_mod_t *p_govrh; +EXTERN govrh_mod_t *p_govrh; #ifdef WMT_FTBLK_GOVRH_CURSOR -EXTERN struct govrh_cursor_mod_t *p_cursor; +EXTERN govrh_cursor_mod_t *p_cursor; #endif #ifdef WMT_FTBLK_GOVRH2 -EXTERN struct govrh_mod_t *p_govrh2; +EXTERN govrh_mod_t *p_govrh2; #endif -EXTERN void govrh_set_tg_enable(struct govrh_mod_t *base, - vpp_flag_t enable); -EXTERN int govrh_get_tg_mode(struct govrh_mod_t *base); -EXTERN int govrh_get_hscale_up(struct govrh_mod_t *base); -EXTERN void govrh_set_direct_path(struct govrh_mod_t *base, int enable); -EXTERN int govrh_get_dvo_enable(struct govrh_mod_t *base); -EXTERN void govrh_set_dvo_enable(struct govrh_mod_t *base, - vpp_flag_t enable); -EXTERN void govrh_set_dvo_sync_polar(struct govrh_mod_t *base, +EXTERN void govrh_set_tg_enable(govrh_mod_t *base, vpp_flag_t enable); +EXTERN int govrh_get_tg_mode(govrh_mod_t *base); +EXTERN int govrh_get_hscale_up(govrh_mod_t *base); +EXTERN void govrh_set_direct_path(govrh_mod_t *base, int enable); +EXTERN void govrh_set_dvo_enable(govrh_mod_t *base, vpp_flag_t enable); +EXTERN void govrh_set_dvo_sync_polar(govrh_mod_t *base, vpp_flag_t hsync, vpp_flag_t vsync); -EXTERN void govrh_set_dvo_outdatw(struct govrh_mod_t *base, +EXTERN void govrh_set_dvo_outdatw(govrh_mod_t *base, vpp_datawidht_t width); -EXTERN void govrh_set_dvo_clock_delay(struct govrh_mod_t *base, +EXTERN void govrh_set_dvo_clock_delay(govrh_mod_t *base, int inverse, int delay); -EXTERN void govrh_set_colorbar(struct govrh_mod_t *base, - vpp_flag_t enable, int mode, int inv); -EXTERN void govrh_set_contrast(struct govrh_mod_t *base, - unsigned int value); -EXTERN unsigned int govrh_get_contrast(struct govrh_mod_t *base); -EXTERN void govrh_set_brightness(struct govrh_mod_t *base, - unsigned int value); -EXTERN unsigned int govrh_get_brightness(struct govrh_mod_t *base); -EXTERN void govrh_set_saturation(struct govrh_mod_t *base, unsigned int value); -EXTERN unsigned int govrh_get_saturation(struct govrh_mod_t *base); -EXTERN void govrh_set_MIF_enable(struct govrh_mod_t *base, vpp_flag_t enable); -EXTERN int govrh_get_MIF_enable(struct govrh_mod_t *base); -EXTERN void govrh_set_color_format(struct govrh_mod_t *base, +EXTERN void govrh_set_colorbar(govrh_mod_t *base, vpp_flag_t enable, + int mode, int inv); +EXTERN void govrh_set_contrast(govrh_mod_t *base, unsigned int value); +EXTERN unsigned int govrh_get_contrast(govrh_mod_t *base); +EXTERN void govrh_set_brightness(govrh_mod_t *base, unsigned int value); +EXTERN unsigned int govrh_get_brightness(govrh_mod_t *base); +EXTERN void govrh_set_saturation(govrh_mod_t *base, unsigned int value); +EXTERN unsigned int govrh_get_saturation(govrh_mod_t *base); +EXTERN void govrh_set_MIF_enable(govrh_mod_t *base, vpp_flag_t enable); +EXTERN int govrh_get_MIF_enable(govrh_mod_t *base); +EXTERN void govrh_set_color_format(govrh_mod_t *base, vdo_color_fmt format); -EXTERN vdo_color_fmt govrh_get_color_format(struct govrh_mod_t *base); -EXTERN void govrh_set_source_format(struct govrh_mod_t *base, +EXTERN vdo_color_fmt govrh_get_color_format(govrh_mod_t *base); +EXTERN void govrh_set_source_format(govrh_mod_t *base, vpp_display_format_t format); -EXTERN void govrh_set_output_format(struct govrh_mod_t *base, +EXTERN void govrh_set_output_format(govrh_mod_t *base, vpp_display_format_t field); -EXTERN void govrh_set_fb_addr(struct govrh_mod_t *base, +EXTERN void govrh_set_fb_addr(govrh_mod_t *base, unsigned int y_addr, unsigned int c_addr); -EXTERN void govrh_get_fb_addr(struct govrh_mod_t *base, +EXTERN void govrh_get_fb_addr(govrh_mod_t *base, unsigned int *y_addr, unsigned int *c_addr); -EXTERN void govrh_set_fb_width(struct govrh_mod_t *base, - unsigned int width); -EXTERN void govrh_set_fb_info(struct govrh_mod_t *base, - unsigned int width, unsigned int act_width, - unsigned int x_offset, unsigned int y_offset); -EXTERN void govrh_get_fb_info(struct govrh_mod_t *base, - unsigned int *width, unsigned int *act_width, - unsigned int *x_offset, unsigned int *y_offset); -EXTERN void govrh_set_fifo_index(struct govrh_mod_t *base, - unsigned int index); -EXTERN void govrh_set_reg_level(struct govrh_mod_t *base, - vpp_reglevel_t level); -EXTERN void govrh_set_reg_update(struct govrh_mod_t *base, - vpp_flag_t enable); -EXTERN void govrh_set_csc_mode(struct govrh_mod_t *base, - vpp_csc_t mode); -EXTERN void govrh_set_framebuffer(struct govrh_mod_t *base, +EXTERN void govrh_set_fb_width(govrh_mod_t *base, unsigned int width); +EXTERN void govrh_set_fb_info(govrh_mod_t *base, unsigned int width, + unsigned int act_width, unsigned int x_offset, unsigned int y_offset); +EXTERN void govrh_get_fb_info(govrh_mod_t *base, unsigned int *width, + unsigned int *act_width, unsigned int *x_offset, + unsigned int *y_offset); +EXTERN void govrh_set_fifo_index(govrh_mod_t *base, unsigned int index); +EXTERN void govrh_set_reg_level(govrh_mod_t *base, vpp_reglevel_t level); +EXTERN void govrh_set_reg_update(govrh_mod_t *base, vpp_flag_t enable); +EXTERN void govrh_set_csc_mode(govrh_mod_t *base, vpp_csc_t mode); +EXTERN void govrh_set_framebuffer(govrh_mod_t *base, vdo_framebuf_t *inbuf); -EXTERN void govrh_get_framebuffer(struct govrh_mod_t *base, - vdo_framebuf_t *fb); -EXTERN vdo_color_fmt govrh_get_dvo_color_format( - struct govrh_mod_t *base); -EXTERN void govrh_set_dvo_color_format(struct govrh_mod_t *base, +EXTERN void govrh_get_framebuffer(govrh_mod_t *base, vdo_framebuf_t *fb); +EXTERN vdo_color_fmt govrh_get_dvo_color_format(govrh_mod_t *base); +EXTERN void govrh_set_dvo_color_format(govrh_mod_t *base, vdo_color_fmt fmt); -EXTERN enum vpp_int_err_t govrh_get_int_status(struct govrh_mod_t *base); -EXTERN void govrh_clean_int_status(struct govrh_mod_t *base, - enum vpp_int_err_t int_sts); -EXTERN unsigned int govrh_set_clock(struct govrh_mod_t *base, +EXTERN vpp_int_err_t govrh_get_int_status(govrh_mod_t *base); +EXTERN void govrh_clean_int_status(govrh_mod_t *base, + vpp_int_err_t int_sts); +EXTERN unsigned int govrh_set_clock(govrh_mod_t *base, unsigned int pixel_clock); -EXTERN void govrh_set_videomode(struct govrh_mod_t *base, +EXTERN void govrh_set_videomode(govrh_mod_t *base, struct fb_videomode *vmode); -EXTERN void govrh_get_tg(struct govrh_mod_t *base, vpp_clock_t *tmr); -EXTERN void govrh_get_videomode(struct govrh_mod_t *base, +EXTERN void govrh_get_tg(govrh_mod_t *base, vpp_clock_t *tmr); +EXTERN void govrh_get_videomode(govrh_mod_t *base, struct fb_videomode *vmode); -EXTERN void govrh_HDMI_set_blank_value(struct govrh_mod_t *base, +EXTERN void govrh_HDMI_set_blank_value(govrh_mod_t *base, unsigned int val); -EXTERN void govrh_HDMI_set_3D_mode(struct govrh_mod_t *base, - int mode); -EXTERN int govrh_is_top_field(struct govrh_mod_t *base); -EXTERN void govrh_IGS_set_mode(struct govrh_mod_t *base, +EXTERN void govrh_HDMI_set_3D_mode(govrh_mod_t *base, int mode); +EXTERN int govrh_is_top_field(govrh_mod_t *base); +EXTERN void govrh_IGS_set_mode(govrh_mod_t *base, int no, int mode_18bit, int msb); -EXTERN void govrh_IGS_set_RGB_swap(struct govrh_mod_t *base, - int mode); +EXTERN void govrh_IGS_set_RGB_swap(govrh_mod_t *base, int mode); EXTERN int govrh_mod_init(void); #ifdef WMT_FTBLK_GOVRH_CURSOR -EXTERN void govrh_CUR_set_enable(struct govrh_cursor_mod_t *base, +EXTERN void govrh_CUR_set_enable(govrh_cursor_mod_t *base, vpp_flag_t enable); -EXTERN void govrh_CUR_set_framebuffer(struct govrh_cursor_mod_t *base, +EXTERN void govrh_CUR_set_framebuffer(govrh_cursor_mod_t *base, vdo_framebuf_t *fb); -EXTERN void govrh_CUR_set_coordinate(struct govrh_cursor_mod_t *base, +EXTERN void govrh_CUR_set_coordinate(govrh_cursor_mod_t *base, unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2); -EXTERN void govrh_CUR_set_position(struct govrh_cursor_mod_t *base, +EXTERN void govrh_CUR_set_position(govrh_cursor_mod_t *base, unsigned int x, unsigned int y); -EXTERN void govrh_CUR_set_color_key_mode(struct govrh_cursor_mod_t *base, +EXTERN void govrh_CUR_set_color_key_mode(govrh_cursor_mod_t *base, int alpha, int enable, int mode); -EXTERN void govrh_CUR_set_color_key(struct govrh_cursor_mod_t *base, +EXTERN void govrh_CUR_set_color_key(govrh_cursor_mod_t *base, int enable, int alpha, unsigned int colkey); -EXTERN void govrh_CUR_set_colfmt(struct govrh_cursor_mod_t *base, +EXTERN void govrh_CUR_set_colfmt(govrh_cursor_mod_t *base, vdo_color_fmt colfmt); EXTERN void govrh_CUR_irqproc(int arg); #endif diff --git a/drivers/video/wmt/hdmi.c b/drivers/video/wmt/hdmi.c index c181d757..47626d77 100755..100644 --- a/drivers/video/wmt/hdmi.c +++ b/drivers/video/wmt/hdmi.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/hdmi.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -39,6 +39,8 @@ /* #define CONFIG_HDMI_EDID_DISABLE */ #define HDMI_I2C_FREQ 80000 + +#define MAX_ACR_TV_NUM 128 /*----------------------- PRIVATE TYPE --------------------------------------*/ /* typedef xxxx hdmi_xxx_t; *//*Example*/ enum hdmi_fifo_slot_t { @@ -53,14 +55,39 @@ enum hdmi_fifo_slot_t { /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int hdmi_xxx; *//*Example*/ -HW_REG struct hdmi_base1_regs *hdmi_regs1 = (void *) (HDMI_BASE_ADDR + 0x100); -HW_REG struct hdmi_base2_regs *hdmi_regs2 = (void *) HDMI_BASE2_ADDR; +/* +Added by howayhuo +Some TV need fix the HDMI ACR ration, otherwise these TV will show "overclock" +Fill in the TV vendor name and TV monitor name to this list if your TV needs fix acr +*/ +static const tv_name_t fix_acr_tv_list[] = { + {"TCL", "RTD2662"}, //another name: TCL L19E09 +}; + +static tv_name_t *p_fix_acr_tv; +static int fixed_acr_ration_val = 2300; /*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ /* void hdmi_xxx(void); *//*Example*/ /*----------------------- Function Body --------------------------------------*/ /*---------------------------- HDMI COMMON API -------------------------------*/ +unsigned int hdmi_reg32_write(U32 offset, U32 mask, U32 shift, U32 val) +{ + unsigned int new_val; + + new_val = (vppif_reg32_in(offset) & ~(mask)) + | (((val) << (shift)) & mask); + if (offset == REG_HDMI_GENERAL_CTRL) { + new_val &= ~(BIT24 | BIT25 | BIT26); + new_val |= g_vpp.hdmi_ctrl; + DBG_MSG("[HDMI] reg32_wr 0x%x ctrl 0x%x\n", + new_val, g_vpp.hdmi_ctrl); + } + vppif_reg32_out(offset, new_val); + return new_val; +} + unsigned char hdmi_ecc(unsigned char *buf, int bit_cnt) { #define HDMI_CRC_LEN 9 @@ -118,54 +145,52 @@ void hdmi_set_power_down(int pwrdn) { DBG_DETAIL("(%d)\n", pwrdn); - if ((hdmi_regs2->test.b.pd == 0) && (pwrdn == 0)) + if ((vppif_reg32_read(HDMI_PD) == 0) && (pwrdn == 0)) { return; /* avoid HDMI reset */ + } - hdmi_regs2->status.b.internal_ldo = (pwrdn) ? 0 : 1; - hdmi_regs2->test.b.pd = pwrdn; + vppif_reg32_write(HDMI_INTERNAL_LDO, (pwrdn) ? 0 : 1); + vppif_reg32_write(HDMI_PD, pwrdn); if (!pwrdn) { - hdmi_regs2->dftset2.b.reset_pll = 1; + vppif_reg32_write(HDMI_RESET_PLL, 1); mdelay(1); - hdmi_regs2->dftset2.b.reset_pll = 0; + vppif_reg32_write(HDMI_RESET_PLL, 0); } mdelay(1); - hdmi_regs2->test2.b.pd_l2ha = pwrdn; + vppif_reg32_write(HDMI_PD_L2HA, pwrdn); } int hdmi_get_power_down(void) { - return hdmi_regs2->test.b.pd; + return vppif_reg32_read(HDMI_PD); } void hdmi_set_enable(vpp_flag_t enable) { - hdmi_regs1->general_ctrl.b.enable = enable; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */ - hdmi_regs2->test2.b.mode = (enable) ? 0 : 1; + hdmi_reg32_write(HDMI_ENABLE, enable); + vppif_reg32_write(HDMI_MODE, (enable) ? 0 : 1); } void hdmi_set_avmute(vpp_flag_t mute) { - hdmi_regs1->aud_insert_ctrl.b.avmute_set_enable = mute; + vppif_reg32_write(HDMI_AVMUTE_SET_ENABLE, mute); } void hdmi_set_dvi_enable(vpp_flag_t enable) { - hdmi_regs1->general_ctrl.b.dvi_mode_enable = enable; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */ + hdmi_reg32_write(HDMI_DVI_MODE_ENABLE, enable); } void hdmi_set_sync_low_active(vpp_flag_t hsync, vpp_flag_t vsync) { - hdmi_regs1->general_ctrl.b.hsync_low_active = hsync; - hdmi_regs1->general_ctrl.b.vsync_low_active = vsync; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */ + hdmi_reg32_write(HDMI_HSYNC_LOW_ACTIVE, hsync); + hdmi_reg32_write(HDMI_VSYNC_LOW_ACTIVE, vsync); } void hdmi_get_sync_polar(int *hsync_hi, int *vsync_hi) { - *hsync_hi = (hdmi_regs1->general_ctrl.b.hsync_low_active) ? 0 : 1; - *vsync_hi = (hdmi_regs1->general_ctrl.b.vsync_low_active) ? 0 : 1; + *hsync_hi = (vppif_reg32_read(HDMI_HSYNC_LOW_ACTIVE)) ? 0 : 1; + *vsync_hi = (vppif_reg32_read(HDMI_VSYNC_LOW_ACTIVE)) ? 0 : 1; } void hdmi_set_output_colfmt(vdo_color_fmt colfmt) @@ -185,16 +210,15 @@ void hdmi_set_output_colfmt(vdo_color_fmt colfmt) val = 2; break; } - hdmi_regs1->general_ctrl.b.convert_yuv422 = (val == 2) ? 1 : 0; - hdmi_regs1->general_ctrl.b.output_format = val; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */ + hdmi_reg32_write(HDMI_CONVERT_YUV422, (val == 2) ? 1 : 0); + hdmi_reg32_write(HDMI_OUTPUT_FORMAT, val); } vdo_color_fmt hdmi_get_output_colfmt(void) { unsigned int val; - val = hdmi_regs1->general_ctrl.b.output_format; + val = vppif_reg32_read(HDMI_OUTPUT_FORMAT); switch (val) { default: case 0: @@ -211,15 +235,15 @@ int hdmi_get_plugin(void) { int plugin; - if (hdmi_regs1->hotplug_detect.b.in_enable) { - plugin = hdmi_regs1->hotplug_detect.b.sts; + if (vppif_reg32_read(HDMI_HOTPLUG_IN_INT)) { + plugin = vppif_reg32_read(HDMI_HOTPLUG_IN); } else { - int tre_en; + int tre_en; - tre_en = hdmi_regs2->test.b.tre_en; - hdmi_regs2->test.b.tre_en = 0; - plugin = hdmi_regs2->detect.b.rsen; - hdmi_regs2->test.b.tre_en = tre_en; + tre_en = vppif_reg32_read(HDMI_TRE_EN); + vppif_reg32_write(HDMI_TRE_EN, 0); + plugin = vppif_reg32_read(HDMI_RSEN); + vppif_reg32_write(HDMI_TRE_EN, tre_en); } return plugin; } @@ -228,20 +252,20 @@ int hdmi_get_plug_status(void) { int reg; - reg = hdmi_regs1->hotplug_detect.val; + reg = vppif_reg32_in(REG_HDMI_HOTPLUG_DETECT); return reg & 0x3000000; } void hdmi_clear_plug_status(void) { - hdmi_regs1->hotplug_detect.b.in_sts = 1; - hdmi_regs1->hotplug_detect.b.out_sts = 1; + vppif_reg32_write(HDMI_HOTPLUG_IN_STS, 1); + vppif_reg32_write(HDMI_HOTPLUG_OUT_STS, 1); } void hdmi_enable_plugin(int enable) { - hdmi_regs1->hotplug_detect.b.out_enable = enable; - hdmi_regs1->hotplug_detect.b.in_enable = enable; + vppif_reg32_write(HDMI_HOTPLUG_OUT_INT, enable); + vppif_reg32_write(HDMI_HOTPLUG_IN_INT, enable); } void hdmi_write_fifo(enum hdmi_fifo_slot_t no, unsigned int *buf, int cnt) @@ -264,11 +288,12 @@ void hdmi_write_fifo(enum hdmi_fifo_slot_t no, unsigned int *buf, int cnt) DPRINT("\n[HDMI] AVI info package end\n"); } #endif - hdmi_regs1->fifo_ctrl.val = (no << 8); + + vppif_reg32_out(REG_HDMI_FIFO_CTRL, (no << 8)); cnt = (cnt + 3) / 4; for (i = 0; i < cnt; i++) - hdmi_regs1->wr_fifo_addr[i] = buf[i]; - hdmi_regs1->fifo_ctrl.b.wr_strobe = 1; + vppif_reg32_out(REG_HDMI_WR_FIFO_ADDR + 4 * i, buf[i]); + vppif_reg32_write(HDMI_INFOFRAME_WR_STROBE, 1); } void hdmi_read_fifo(enum hdmi_fifo_slot_t no, unsigned int *buf, int cnt) @@ -279,16 +304,16 @@ void hdmi_read_fifo(enum hdmi_fifo_slot_t no, unsigned int *buf, int cnt) if (no > HDMI_FIFO_SLOT_MAX) return; - rdy = hdmi_regs1->infoframe_ctrl.b.fifo1_rdy; - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 0; + rdy = vppif_reg32_read(HDMI_INFOFRAME_FIFO1_RDY); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_RDY, 0); no = no - 1; - hdmi_regs1->fifo_ctrl.val = (no << 8); - hdmi_regs1->fifo_ctrl.b.rd_strobe = 1; + vppif_reg32_out(REG_HDMI_FIFO_CTRL, (no << 8)); + vppif_reg32_write(HDMI_INFOFRAME_RD_STROBE, 1); cnt = (cnt + 3) / 4; for (i = 0; i < cnt; i++) - buf[i] = hdmi_regs1->rd_fifo_addr[i]; - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = rdy; + buf[i] = vppif_reg32_in(REG_HDMI_RD_FIFO_ADDR + 4 * i); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_RDY, rdy); #ifdef DEBUG { char *ptr; @@ -335,14 +360,14 @@ int hdmi_DDC_check_status(unsigned int checkbits, int condition) udelay(HDMI_DDC_DELAY); if (condition) { /* wait 1 --> 0 */ - while ((hdmi_regs1->i2c_ctrl2.val & checkbits) + while ((vppif_reg32_in(REG_HDMI_I2C_CTRL2) & checkbits) && (i < maxloop)) { udelay(HDMI_DDC_CHK_DELAY); if (++i == maxloop) status = 0; } } else { /* wait 0 --> 1 */ - while (!(hdmi_regs1->i2c_ctrl2.val & checkbits) + while (!(vppif_reg32_in(REG_HDMI_I2C_CTRL2) & checkbits) && (i < maxloop)) { udelay(HDMI_DDC_CHK_DELAY); if (++i == maxloop) @@ -353,7 +378,7 @@ int hdmi_DDC_check_status(unsigned int checkbits, int condition) if ((status == 0) && (checkbits != HDMI_STATUS_SW_READ)) { unsigned int reg; - reg = hdmi_regs1->i2c_ctrl2.val; + reg = vppif_reg32_in(REG_HDMI_I2C_CTRL2); DBG_DETAIL("[HDMI] status timeout check 0x%x,wait to %s\n", checkbits, (condition) ? "0" : "1"); DBG_DETAIL("[HDMI] 0x%x,sta %d,stop %d,wr %d,rd %d,cp %d\n", @@ -374,15 +399,15 @@ void hdmi_DDC_set_freq(unsigned int hz) clock = 25000000*15/100; /* RTC clock source */ div = clock / hz; - hdmi_regs1->i2c_ctrl.b.i2c_clk_divider = div; + vppif_reg32_write(HDMI_I2C_CLK_DIVIDER, div); DBG_DETAIL("[HDMI] set freq(%d,clk %d,div %d)\n", hz, clock, div); } void hdmi_DDC_reset(void) { - hdmi_regs1->i2c_ctrl.b.i2c_sw_reset = 1; + vppif_reg32_write(HDMI_I2C_SW_RESET, 1); udelay(1); - hdmi_regs1->i2c_ctrl.b.i2c_sw_reset = 0; + vppif_reg32_write(HDMI_I2C_SW_RESET, 0); } int hdmi_DDC_read_func(char addr, int index, char *buf, int length) @@ -392,7 +417,7 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) int err_cnt = 0; DBG_DETAIL("[HDMI] read DDC(index 0x%x,len %d),reg 0x%x\n", - index, length, hdmi_regs1->i2c_ctrl2.val); + index, length, vppif_reg32_in(REG_HDMI_I2C_CTRL2)); #ifdef CONFIG_HDMI_EDID_DISABLE return status; @@ -402,8 +427,7 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) /* enhanced DDC read */ if (index >= 256) { /* sw start, write data avail */ - vppif_reg32_write((unsigned int) &hdmi_regs1->i2c_ctrl2, - BIT18 + BIT16, 16, 0x5); + vppif_reg32_write(REG_HDMI_I2C_CTRL2, BIT18 + BIT16, 16, 0x5); udelay(HDMI_DDC_CTRL_DELAY); /* wait start & wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_START + @@ -415,8 +439,8 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* Slave address */ - hdmi_regs1->i2c_ctrl2.b.wr_data = 0x60; - hdmi_regs1->i2c_ctrl2.b.wr_data_avail = 1; + vppif_reg32_write(HDMI_WR_DATA, 0x60); + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -427,8 +451,8 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* Offset */ - hdmi_regs1->i2c_ctrl2.b.wr_data = 0x1; - hdmi_regs1->i2c_ctrl2.b.wr_data_avail = 1; + vppif_reg32_write(HDMI_WR_DATA, 0x1); + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -441,7 +465,16 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* START */ - hdmi_regs1->i2c_ctrl2.val = 0x50000; /* start & data avail */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x50000); +#else +#if 0 + vppif_reg32_write(HDMI_SW_START_REQ, 1); /* sw start */ + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif + /* sw start, write data avail */ + vppif_reg32_write(REG_HDMI_I2C_CTRL2, BIT18 + BIT16, 16, 0x5); +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait start & wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_START + @@ -453,7 +486,16 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* Slave address */ - hdmi_regs1->i2c_ctrl2.val = 0x400A0; /* addr & data avail */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x400A0); +#else + vppif_reg32_write(HDMI_WR_DATA, addr); + udelay(HDMI_DDC_DELAY); + while (vppif_reg32_read(HDMI_WR_DATA) != addr) + ; + udelay(HDMI_DDC_DELAY); + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -464,7 +506,23 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* Offset */ - hdmi_regs1->i2c_ctrl2.val = (0x40000 + index); /* index & data avail */ +#ifdef HDMI_DDC_OUT +{ + unsigned int reg; + + reg = 0x40000; + reg |= index; + + vppif_reg32_out(REG_HDMI_I2C_CTRL2, reg); +} +#else + vppif_reg32_write(HDMI_WR_DATA, index); + udelay(HDMI_DDC_DELAY); + while (vppif_reg32_read(HDMI_WR_DATA) != index) + ; + udelay(HDMI_DDC_DELAY); + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -474,8 +532,19 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) goto ddc_read_fail; } +/* vppif_reg32_write(HDMI_WR_DATA,addr+1); */ + /* START */ - hdmi_regs1->i2c_ctrl2.val = 0x50000; /* start & data avail */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x50000); +#else +#if 0 + vppif_reg32_write(HDMI_SW_START_REQ, 1); /* sw start */ + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif + /* sw start, write data avail */ + vppif_reg32_write(REG_HDMI_I2C_CTRL2, BIT18 + BIT16, 16, 0x5); +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait start & wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_START + @@ -487,7 +556,16 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* Slave Address + 1 */ - hdmi_regs1->i2c_ctrl2.val = 0x400A1; /* addr(rd) & data avail */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x400A1); +#else + vppif_reg32_write(HDMI_WR_DATA, addr + 1); + udelay(HDMI_DDC_DELAY); + while (vppif_reg32_read(HDMI_WR_DATA) != (addr + 1)) + ; + udelay(HDMI_DDC_DELAY); + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -499,7 +577,12 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) /* Read Data */ for (i = 0; i < length; i++) { - hdmi_regs1->i2c_ctrl2.val = 0x40000; /* data avail */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x40000); +#else + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ + /* hdmi_reg32_write(HDMI_WR_DATA_AVAIL,1); */ +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -524,16 +607,23 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) /* break; */ } - *buf++ = hdmi_regs1->i2c_ctrl2.b.rd_data; + *buf++ = vppif_reg32_read(HDMI_RD_DATA); udelay(HDMI_DDC_DELAY); - hdmi_regs1->i2c_ctrl2.val = 0x2000000; /* clr sw read */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x2000000); +#else + vppif_reg32_write(HDMI_SW_READ, 1); +#endif udelay(HDMI_DDC_DELAY); } /* STOP */ +#if 0 + vppif_reg32_write(HDMI_SW_STOP_REQ, 1); /* sw stop */ + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif /* sw stop, write data avail */ - vppif_reg32_write((unsigned int) &hdmi_regs1->i2c_ctrl2.val, - BIT18 + BIT17, 17, 3); + vppif_reg32_write(REG_HDMI_I2C_CTRL2, BIT18 + BIT17, 17, 3); udelay(HDMI_DDC_CTRL_DELAY); /* wait start & wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_STOP + @@ -554,39 +644,24 @@ ddc_read_fail: int hdmi_DDC_read(char addr, int index, char *buf, int length) { int retry = 3; - int ret; - - DBG_MSG("(0x%x,0x%x,%d)\n", addr, index, length); - do { - ret = hdmi_DDC_read_func(addr, index, buf, length); - if (ret == 0) + if (hdmi_DDC_read_func(addr, index, buf, length) == 0) break; hdmi_DDC_reset(); - DPRINT("[HDMI] *W* DDC reset %d\n", ret); + DPRINT("[HDMI] *W* DDC reset\n"); retry--; } while (retry); - return (retry == 0) ? 1 : 0; } void hdmi_audio_enable(vpp_flag_t enable) { - if (hdmi_regs1->aud_enable != enable) { - if (!enable) { -#ifdef CONFIG_KERNEL - msleep(5); -#endif - if (g_vpp.hdmi_ch_change) - REG32_VAL(I2S_BASE_ADDR + 0x188) = 0; - } - hdmi_regs1->aud_enable = (enable) ? 1 : 0; - } + vppif_reg32_write(HDMI_AUD_ENABLE, enable); } void hdmi_audio_mute(vpp_flag_t enable) { - hdmi_regs1->aud_ratio.b.mute = enable; + vppif_reg32_write(HDMI_AUD_MUTE, enable); } /*----------------------- HDMI API --------------------------------------*/ @@ -638,7 +713,7 @@ void hdmi_tx_general_control_packet(int mute) hdmi_write_packet(HDMI_PACKET_GENERAL_CTRL, buf, 7); } -int hdmi_get_pic_aspect(enum hdmi_video_code_t vic) +int hdmi_get_pic_aspect(hdmi_video_code_t vic) { switch (vic) { case HDMI_640x480p60_4x3: @@ -663,7 +738,7 @@ int hdmi_get_pic_aspect(enum hdmi_video_code_t vic) int hdmi_get_vic(int resx, int resy, int fps, int interlace) { - struct hdmi_vic_t info; + hdmi_vic_t info; int i; info.resx = resx; @@ -673,15 +748,14 @@ int hdmi_get_vic(int resx, int resy, int fps, int interlace) info.option |= (vout_check_ratio_16_9(resx, resy)) ? HDMI_VIC_16x9 : HDMI_VIC_4x3; for (i = 0; i < HDMI_VIDEO_CODE_MAX; i++) { - if (memcmp(&hdmi_vic_info[i], &info, - sizeof(struct hdmi_vic_t)) == 0) + if (memcmp(&hdmi_vic_info[i], &info, sizeof(hdmi_vic_t)) == 0) return i; } return HDMI_UNKNOW; } void hdmi_tx_avi_infoframe_packet(vdo_color_fmt colfmt, - enum hdmi_video_code_t vic) + hdmi_video_code_t vic) { unsigned int header; unsigned char buf[28]; @@ -732,9 +806,7 @@ void hdmi_tx_audio_infoframe_packet(int channel, int freq) buf[1] = (channel - 1) + (HDMI_AUD_TYPE_REF_STM << 4); buf[2] = 0x0; /* HDMI_AUD_SAMPLE_24 + (freq << 2); */ buf[3] = 0x00; - /* 0x13: RRC RLC RR RL FC LFE FR FL - 0x1F: FRC FLC RR RL FC LFE FR FL */ - buf[4] = (channel == 8) ? 0x13 : 0; + buf[4] = 0x0; buf[5] = 0x0; /* 0 db */ buf[0] = hdmi_checksum((unsigned char *)&header, buf, 28); hdmi_write_packet(header, buf, 28); @@ -769,191 +841,270 @@ void hdmi_tx_vendor_specific_infoframe_packet(void) hdmi_write_packet(header, buf, 28); } -#define HDMI_N_CTS_USE_TABLE -#ifdef HDMI_N_CTS_USE_TABLE -struct hdmi_n_cts_s { - unsigned int n; - unsigned int cts; -}; +/* +--> Added by howayhuo. +Some TV (example: TCL L19E09) will overclock if ACR ratio too large, +So we need decrease the ACR ratio for some special TV +*/ +static void print_acr(void) +{ + int i; -struct hdmi_n_cts_s hdmi_n_cts_table[7][11] = { - /* 32kHz */ - {{ 9152, 84375 }, {4096, 37800}, {4096, 40500}, {8192, 81081}, - { 4096, 81000 }, {4096, 81081}, {11648, 316406}, {4096, 111375}, - { 11648, 632812}, {4096, 222750}, {4096, 0}}, - /* 44.1kHz */ - {{7007, 46875}, {6272, 42000}, {6272, 45000}, {6272, 45045}, - {6272, 90000}, {6272, 90090}, {17836, 351562}, {6272, 123750}, - {17836, 703125}, {6272, 247500}, {6272, 0}}, - /* 88.2kHz */ - {{14014, 46875}, {12544, 42000}, {12544, 45000}, {12544, 45045}, - {12544, 90000}, {12544, 90090}, {35672, 351562}, {12544, 123750}, - {35672, 703125}, {12544, 247500}, {12544, 0}}, - /* 176.4kHz */ - {{28028, 46875}, {25088, 42000}, {25088, 45000}, {25088, 45045}, - {25088, 90000}, {25088, 90090}, {71344, 351562}, {25088, 123750}, - {71344, 703125}, {25088, 247500}, {25088, 0}}, - /* 48kHz */ - {{9152, 56250}, {6144, 37800}, {6144, 40500}, {8192, 54054}, - {6144, 81000}, {6144, 81081}, {11648, 210937}, {6144, 111375}, - {11648, 421875}, {6144, 222750}, {6144, 0}}, - /* 96kHz */ - {{18304, 56250}, {12288, 37800}, {12288, 40500}, {16384, 54054}, - {12288, 81000}, {12288,81081}, {23296, 210937}, {12288, 111375}, - {23296, 421875}, {12288, 222750}, {12288, 0}}, - /* 192kHz */ - {{36608, 56250}, {24576, 37800}, {24576, 40500}, {32768, 54054}, - {24576, 81000}, {24576, 81081}, {46592, 210937}, {24576, 111375}, - {46592, 421875}, {24576, 222750}, {24576, 0}} -}; + if(p_fix_acr_tv != NULL) { + for(i = 0; i < MAX_ACR_TV_NUM; i++) { + if(strlen(p_fix_acr_tv[i].vendor_name) == 0 + || strlen(p_fix_acr_tv[i].monitor_name) == 0) + break; + + if(i == 0) + printk("ACR TV Name:\n"); -struct hdmi_n_cts_s *hdmi_get_n_cts(unsigned int tmds_clk, - unsigned int freq) + printk(" %s,%s\n", p_fix_acr_tv[i].vendor_name, p_fix_acr_tv[i].monitor_name); + } + } +} + +static void acr_init(void) { - int i, j; + char buf[512] = {0}; + int buflen = 512; + unsigned long val; + int i, j, k, tv_num; + int ret, to_save_vendor; + tv_name_t tv_name; + + if(p_fix_acr_tv != NULL) { + kfree(p_fix_acr_tv); + p_fix_acr_tv = NULL; + } - switch (freq) { - case 32000: - i = 0; - break; - case 44100: - i = 1; - break; - case 88200: - i = 2; - break; - case 176400: - i = 3; - break; - case 48000: - i = 4; - break; - case 96000: - i = 5; - break; - case 192000: - i = 6; - break; - default: - return 0; + if(wmt_getsyspara("wmt.acr.ratio", buf, &buflen) == 0) { + ret = strict_strtoul(buf, 10, &val); + if(ret) { + printk("[HDMI] Wrong wmt.acr.ratio value: %s\n", buf); + return; + } + if(val >= 0 && val < 0xFFFFF) // total 20 bits + fixed_acr_ration_val = (int)val; + else + printk("[HDMI] Invalid Fixed ACR Ratio: %lu\n", val); } - switch (tmds_clk) { - case 25174825: - j = 0; - break; - case 25200000: - j = 1; - break; - case 27000000: - j = 2; - break; - case 27027000: - j = 3; - break; - case 54000000: - j = 4; - break; - case 54054000: - j = 5; - break; - case 74175824: - j = 6; - break; - case 74250000: - j = 7; - break; - case 148351648: - j = 8; - break; - case 148500000: - j = 9; - break; - default: - j = 10; - break; + if(fixed_acr_ration_val == 0) + return; + + /* + For example: setenv wmt.acr.tv 'TCH,RTD2662;PHL,Philips 244E' + */ + if(wmt_getsyspara("wmt.acr.tv", buf, &buflen) != 0) { + p_fix_acr_tv = (tv_name_t *)kzalloc(sizeof(fix_acr_tv_list) + sizeof(tv_name_t), GFP_KERNEL); + if(p_fix_acr_tv) { + memcpy(p_fix_acr_tv, fix_acr_tv_list, sizeof(fix_acr_tv_list)); + print_acr(); + } else + printk("[HDMI] malloc for ACR fail. malloc len = %d\n", + sizeof(fix_acr_tv_list) + sizeof(tv_name_t)); + + return; + } + + tv_num = 0; + buflen = strlen(buf); + if(buflen == 0) + return; + + if(buflen == sizeof(buf)) { + printk("[HDMI] wmt.acr.tv too long\n"); + return; + } + + for(i = 0; i < buflen; i++) { + if(buf[i] == ',') + tv_num++; + } + + /* + Limit TV Number + */ + if(tv_num > MAX_ACR_TV_NUM) + tv_num = MAX_ACR_TV_NUM; + + if(tv_num == 0) + return; + + printk("acr_tv_num = %d\n", tv_num); + p_fix_acr_tv = (tv_name_t *)kzalloc((tv_num + 1) * sizeof(tv_name_t), GFP_KERNEL); + if(!p_fix_acr_tv) { + printk("[HDMI] malloc for ACR fail. malloc len = %d\n", + sizeof(fix_acr_tv_list) + sizeof(tv_name_t)); + return; + } + memset(&tv_name, 0, sizeof(tv_name_t)); + + j = 0; + k = 0; + to_save_vendor= 1; + for(i = 0; i < buflen + 1; i++) { + if(buf[i] != ',' && buf[i] != ';' && buf[i] != '\0') { + if(to_save_vendor) { + if(k < VENDOR_NAME_LEN) + tv_name.vendor_name[k] = buf[i]; + } else { + if(k < MONITOR_NAME_LEN) + tv_name.monitor_name[k] = buf[i]; + } + k++; + } else if(buf[i] == ',') { + to_save_vendor = 0; + k = 0; + } else { + if(strlen(tv_name.vendor_name) == 0 || strlen(tv_name.monitor_name) == 0) { + printk("[HDMI] Wrong wmt.acr.tv format\n"); + kfree(p_fix_acr_tv); + p_fix_acr_tv = NULL; + break; + } else { + if(j < tv_num) { + memcpy(p_fix_acr_tv + j, &tv_name, sizeof(tv_name_t)); + memset(&tv_name, 0, sizeof(tv_name_t)); + j++; + } + + if(j == tv_num) + break; + } + + if(buf[i]== ';') { + to_save_vendor = 1; + k = 0; + } else + break; + } } - return &hdmi_n_cts_table[i][j]; + + print_acr(); } -#endif -void hdmi_set_audio_n_cts(unsigned int freq) +void acr_exit(void) { - unsigned int n = 0, cts = 0; + if(p_fix_acr_tv != NULL) { + kfree(p_fix_acr_tv); + p_fix_acr_tv = NULL; + } +} -#ifdef HDMI_N_CTS_USE_TABLE - struct hdmi_n_cts_s *p; +static int use_fix_acr_ratio(void) +{ + int i; + + if(fixed_acr_ration_val == 0 || p_fix_acr_tv == NULL) + return 0; + + for(i = 0; i < MAX_ACR_TV_NUM; i++) { + if(strlen(p_fix_acr_tv[i].vendor_name) == 0 + || strlen(p_fix_acr_tv[i].monitor_name) == 0) + break; - p = hdmi_get_n_cts(g_vpp.hdmi_pixel_clock, freq); - if (p) { - n = p->n; - cts = p->cts; - MSG("[HDMI] use table n %d, cts %d\n", n, cts); + if(!strcmp(edid_parsed.tv_name.vendor_name, p_fix_acr_tv[i].vendor_name) + && !strcmp(edid_parsed.tv_name.monitor_name, p_fix_acr_tv[i].monitor_name)) { + printk("TV is \"%s %s\". Use fixed HDMI ACR Ratio: %d\n", + edid_parsed.tv_name.vendor_name, + edid_parsed.tv_name.monitor_name, + fixed_acr_ration_val); + return 1; + } } -#endif - if (n == 0) - n = 128 * freq / 1000; + return 0; +} +/* +<-- end added by howayhuo +*/ + +void hdmi_set_audio_n_cts(unsigned int freq) +{ + unsigned int n, cts; - if (cts == 0) { + n = 128 * freq / 1000; #ifdef __KERNEL__ - unsigned int tmp; - unsigned int pll_clk; +{ + unsigned int tmp; + unsigned int pll_clk; - pll_clk = auto_pll_divisor(DEV_I2S, GET_FREQ, 0, 0); - tmp = (inl(AUDREGF_BASE_ADDR + 0x70) & 0xF); + pll_clk = auto_pll_divisor(DEV_I2S, GET_FREQ, 0, 0); + tmp = (vppif_reg32_in(AUDREGF_BASE_ADDR+0x70) & 0xF); - switch (tmp) { - case 0 ... 4: - tmp = 0x01 << tmp; - break; - case 9 ... 12: - tmp = 3 * (0x1 << (tmp-9)); - break; - default: - tmp = 1; - break; - } - { - unsigned long long tmp2; - unsigned long long div2; - unsigned long mod; - - tmp2 = g_vpp.hdmi_pixel_clock; - tmp2 = tmp2 * n * tmp; - div2 = pll_clk; - mod = do_div(tmp2, div2); - cts = tmp2; - } - DBGMSG("[HDMI] i2s %d,cts %d,reg 0x%x\n", pll_clk, cts, - vppif_reg32_in(AUDREGF_BASE_ADDR + 0x70)); + switch (tmp) { + case 0 ... 4: + tmp = 0x01 << tmp; + break; + case 9 ... 12: + tmp = 3 * (0x1 << (tmp-9)); + break; + default: + tmp = 1; + break; + } + + { + unsigned long long tmp2; + unsigned long long div2; + unsigned long mod; + + tmp2 = g_vpp.hdmi_pixel_clock; + tmp2 = tmp2 * n * tmp; + div2 = pll_clk; + mod = do_div(tmp2, div2); + cts = tmp2; + } + DBGMSG("[HDMI] i2s %d,cts %d,reg 0x%x\n", pll_clk, cts, + vppif_reg32_in(AUDREGF_BASE_ADDR + 0x70)); +} + + vppif_reg32_write(HDMI_AUD_N_20BITS, n); + if(use_fix_acr_ratio()) + vppif_reg32_write(HDMI_AUD_ACR_RATIO, fixed_acr_ration_val); + else + vppif_reg32_write(HDMI_AUD_ACR_RATIO, cts - 1); +#else +#if 1 + cts = g_vpp.hdmi_pixel_clock / 1000; #else - cts = (g_vpp.hdmi_pixel_clock / 1000) - 1; + cts = vpp_get_base_clock(VPP_MOD_GOVRH) / 1000; #endif - } - hdmi_regs1->aud_sample_rate1.b.n_20bits = n; - hdmi_regs1->aud_ratio.b.acr_ratio = cts - 1; - hdmi_regs1->aud_sample_rate2.b.cts_select = 0; + vppif_reg32_write(HDMI_AUD_N_20BITS, n); + if(use_fix_acr_ratio()) + vppif_reg32_write(HDMI_AUD_ACR_RATIO, fixed_acr_ration_val); + else + vppif_reg32_write(HDMI_AUD_ACR_RATIO, cts - 2); +#endif + +#if 1 /* auto detect CTS */ + vppif_reg32_write(HDMI_AUD_CTS_SELECT, 0); cts = 0; - hdmi_regs1->aud_sample_rate1.b.cts_low_12bits = cts & 0xFFF; - hdmi_regs1->aud_sample_rate2.b.cts_hi_8bits = (cts & 0xFF000) >> 12; +#else + vppif_reg32_write(HDMI_AUD_CTS_SELECT, 1); +#endif + vppif_reg32_write(HDMI_AUD_CTS_LOW_12BITS, cts & 0xFFF); + vppif_reg32_write(HDMI_AUD_CTS_HI_8BITS, (cts & 0xFF000) >> 12); + DBGMSG("[HDMI] set audio freq %d,n %d,cts %d,tmds %d\n", freq, n, cts, g_vpp.hdmi_pixel_clock); } - -void hdmi_config_audio(struct vout_audio_t *info) +void hdmi_config_audio(vout_audio_t *info) { unsigned int freq; - g_vpp.hdmi_audio_channel = info->channel; - g_vpp.hdmi_audio_freq = info->sample_rate; + hdmi_info.channel = info->channel; + hdmi_info.freq = info->sample_rate; /* enable ARF & ARFP clock */ REG32_VAL(PM_CTRL_BASE_ADDR + 0x254) |= (BIT4 | BIT3); - hdmi_tx_audio_infoframe_packet(info->channel, info->sample_rate); + hdmi_tx_audio_infoframe_packet(info->channel - 1, info->sample_rate); hdmi_audio_enable(VPP_FLAG_DISABLE); - hdmi_regs1->aud_mode.b.layout = (info->channel > 2) ? 1 : 0; - hdmi_regs1->aud_mode.b._2ch_eco = (info->channel > 2) ? 0 : 1; + vppif_reg32_write(HDMI_AUD_LAYOUT, (info->channel == 8) ? 1 : 0); + vppif_reg32_write(HDMI_AUD_2CH_ECO, 1); + switch (info->sample_rate) { case 32000: freq = 0x3; @@ -981,20 +1132,22 @@ void hdmi_config_audio(struct vout_audio_t *info) freq = 0x9; break; } - hdmi_regs1->aud_chan_status0 = (freq << 24) + 0x4; - hdmi_regs1->aud_chan_status1 = 0x0; - hdmi_regs1->aud_chan_status2 = 0xb; - hdmi_regs1->aud_chan_status3 = 0x0; - hdmi_regs1->aud_chan_status4 = 0x0; - hdmi_regs1->aud_chan_status5 = 0x0; + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS0, (freq << 24) + 0x4); + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS1, 0x0); + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS2, 0xb); + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS3, 0x0); + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS4, 0x0); + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS5, 0x0); hdmi_set_audio_n_cts(info->sample_rate); - hdmi_regs1->aud_ratio.b.acr_enable = 1; - hdmi_regs1->aud_sample_rate2.b.aipclk_rate = 0; - hdmi_audio_enable(VPP_FLAG_ENABLE); + vppif_reg32_write(HDMI_AUD_ACR_ENABLE, VPP_FLAG_ENABLE); + vppif_reg32_write(HDMI_AUD_AIPCLK_RATE, 0); + hdmi_audio_enable(hdmi_get_plugin() ? + VPP_FLAG_ENABLE : VPP_FLAG_DISABLE); + } -void hdmi_config_video(struct hdmi_info_t *info) +void hdmi_config_video(hdmi_info_t *info) { hdmi_set_output_colfmt(info->outfmt); hdmi_tx_avi_infoframe_packet(info->outfmt, info->vic); @@ -1031,16 +1184,16 @@ void hdmi_set_option(unsigned int option) DBG_MSG("[HDMI] set option(8-HDMI,6-AUDIO) 0x%x\n", option); } -void hdmi_config(struct hdmi_info_t *info) +void hdmi_config(hdmi_info_t *info) { - struct vout_audio_t audio_info; + vout_audio_t audio_info; int h_porch; int delay_cfg; vpp_clock_t clock; - hdmi_regs1->ctrl.b.hden = 0; - hdmi_regs1->infoframe_ctrl.b.select = 0; - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 0; + vppif_reg32_write(HDMI_HDEN, 0); + vppif_reg32_write(HDMI_INFOFRAME_SELECT, 0); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_RDY, 0); hdmi_config_video(info); govrh_get_tg(p_govrh, &clock); @@ -1054,10 +1207,8 @@ void hdmi_config(struct hdmi_info_t *info) h_porch = 1; if (h_porch >= 8) h_porch = 0; - - hdmi_regs1->general_ctrl.b.cp_delay = delay_cfg; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */ - hdmi_regs1->infoframe_ctrl.b.horiz_blank_max_pck = h_porch; + hdmi_reg32_write(HDMI_CP_DELAY, delay_cfg); + vppif_reg32_write(HDMI_HORIZ_BLANK_MAX_PCK, h_porch); DBGMSG("[HDMI] H blank max pck %d,delay %d\n", h_porch, delay_cfg); audio_info.fmt = 16; @@ -1065,12 +1216,13 @@ void hdmi_config(struct hdmi_info_t *info) audio_info.sample_rate = info->freq; hdmi_config_audio(&audio_info); - hdmi_regs1->infoframe_ctrl.b.fifo1_addr = 0; - hdmi_regs1->infoframe_ctrl.b.fifo1_len = 2; - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 1; + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_ADDR, 0); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_LEN, 2); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_RDY, 1); + hdmi_set_option(info->option); - hdmi_regs2->test.b.tre_en = - (g_vpp.hdmi_pixel_clock < 40000000) ? 3 : 2; + vppif_reg32_write(HDMI_TRE_EN, + (g_vpp.hdmi_pixel_clock < 40000000) ? 3 : 2); } /*----------------------- Module API --------------------------------------*/ @@ -1110,9 +1262,14 @@ void hdmi_get_bksv(unsigned int *bksv) #ifdef __KERNEL__ void hdmi_hotplug_notify(int plug_status) { - if (g_vpp.hdmi_disable) - return; - vpp_netlink_notify_plug(VPP_VOUT_NUM_HDMI, plug_status); + if (g_vpp.hdmi_disable) + return; + if (g_vpp.virtual_display || (g_vpp.dual_display == 0)) { + vpp_netlink_notify_plug(VPP_VOUT_ALL, 0); + vpp_netlink_notify_plug(VPP_VOUT_ALL, 1); + return; + } + vpp_netlink_notify_plug(VPP_VOUT_NUM_HDMI, plug_status); } #else #define hdmi_hotplug_notify @@ -1120,44 +1277,44 @@ void hdmi_hotplug_notify(int plug_status) int hdmi_check_plugin(int hotplug) { - static int last_plugin = -1; - int plugin; - int flag; + static int last_plugin = -1; + int plugin; + int flag; - if (g_vpp.hdmi_disable) - return 0; + if (g_vpp.hdmi_disable) + return 0; - plugin = hdmi_get_plugin(); - hdmi_clear_plug_status(); + plugin = hdmi_get_plugin(); + hdmi_clear_plug_status(); #ifdef __KERNEL__ - /* disable HDMI before change clock */ - if (plugin == 0) { - hdmi_set_enable(0); - hdmi_set_power_down(1); - } - vpp_set_clock_enable(DEV_HDMII2C, plugin, 1); - vpp_set_clock_enable(DEV_HDCE, plugin, 1); - - /* slow down clock for plugout */ - flag = (auto_pll_divisor(DEV_HDMILVDS, GET_FREQ, 0, 0) - == 8000000) ? 0 : 1; - if ((plugin != flag) && !g_vpp.virtual_display) { - int pixclk; - - pixclk = (plugin) ? g_vpp.hdmi_pixel_clock : 8000000; - auto_pll_divisor(DEV_HDMILVDS, SET_PLLDIV, 0, pixclk); - } + /* disable HDMI before change clock */ + if (plugin == 0) { + hdmi_set_enable(0); + hdmi_set_power_down(1); + } + vpp_set_clock_enable(DEV_HDMII2C, plugin, 1); + vpp_set_clock_enable(DEV_HDCE, plugin, 1); + + /* slow down clock for plugout */ + flag = (auto_pll_divisor(DEV_HDMILVDS, GET_FREQ, 0, 0) + == 8000000) ? 0 : 1; + if ((plugin != flag) && !g_vpp.virtual_display) { + int pixclk; + + pixclk = (plugin) ? g_vpp.hdmi_pixel_clock : 8000000; + auto_pll_divisor(DEV_HDMILVDS, SET_PLLDIV, 0, pixclk); + } #endif - if (last_plugin != plugin) { - DPRINT("[HDMI] HDMI plug%s,hotplug %d\n", (plugin) ? - "in" : "out", hotplug); - last_plugin = plugin; - } -#if 0 /* Denzel test */ - if (plugin == 0) - hdmi_set_dvi_enable(VPP_FLAG_ENABLE); + if (last_plugin != plugin) { + DPRINT("[HDMI] HDMI plug%s,hotplug %d\n", (plugin) ? + "in" : "out", hotplug); + last_plugin = plugin; + } +#if 0 /* Denzel test */ + if (plugin == 0) + hdmi_set_dvi_enable(VPP_FLAG_ENABLE); #endif - return plugin; + return plugin; } void hdmi_reg_dump(void) @@ -1168,107 +1325,106 @@ void hdmi_reg_dump(void) DPRINT("---------- HDMI common ----------\n"); DPRINT("enable %d,hden %d,reset %d,dvi %d\n", - hdmi_regs1->general_ctrl.b.enable, - hdmi_regs1->ctrl.b.hden, - hdmi_regs1->general_ctrl.b.reset, - hdmi_regs1->general_ctrl.b.dvi_mode_enable); + vppif_reg32_read(HDMI_ENABLE), vppif_reg32_read(HDMI_HDEN), + vppif_reg32_read(HDMI_RESET), + vppif_reg32_read(HDMI_DVI_MODE_ENABLE)); DPRINT("colfmt %d,conv 422 %d,hsync low %d,vsync low %d\n", - hdmi_regs1->general_ctrl.b.output_format, - hdmi_regs1->general_ctrl.b.convert_yuv422, - hdmi_regs1->general_ctrl.b.hsync_low_active, - hdmi_regs1->general_ctrl.b.vsync_low_active); + vppif_reg32_read(HDMI_OUTPUT_FORMAT), + vppif_reg32_read(HDMI_CONVERT_YUV422), + vppif_reg32_read(HDMI_HSYNC_LOW_ACTIVE), + vppif_reg32_read(HDMI_VSYNC_LOW_ACTIVE)); DPRINT("dbg bus sel %d,state mach %d\n", - hdmi_regs1->general_ctrl.b.dbg_bus_select, - hdmi_regs1->general_ctrl.b.state_machine_status); + vppif_reg32_read(HDMI_DBG_BUS_SELECT), + vppif_reg32_read(HDMI_STATE_MACHINE_STATUS)); DPRINT("eep reset %d,encode %d,eess %d\n", - hdmi_regs1->ctrl.b.eeprom_reset, - hdmi_regs1->ctrl.b.encode_enable, - hdmi_regs1->ctrl.b.eess_enable); + vppif_reg32_read(HDMI_EEPROM_RESET), + vppif_reg32_read(HDMI_ENCODE_ENABLE), + vppif_reg32_read(HDMI_EESS_ENABLE)); DPRINT("verify pj %d,auth test %d,cipher %d\n", - hdmi_regs1->ctrl.b.verify_pj_enable, - hdmi_regs1->ctrl.b.auth_test_key, - hdmi_regs1->ctrl.b.cipher_1_1); - DPRINT("preamble %d\n", hdmi_regs1->ctrl.b.preamble); + vppif_reg32_read(HDMI_VERIFY_PJ_ENABLE), + vppif_reg32_read(HDMI_AUTH_TEST_KEY), + vppif_reg32_read(HDMI_CIPHER_1_1)); + DPRINT("preamble %d\n", vppif_reg32_read(HDMI_PREAMBLE)); DPRINT("---------- HDMI hotplug ----------\n"); - DPRINT("plug %s\n", (hdmi_regs1->hotplug_detect.b.sts) ? "in" : "out"); + DPRINT("plug %s\n", vppif_reg32_read(HDMI_HOTPLUG_IN) ? "in" : "out"); DPRINT("plug in enable %d, status %d\n", - hdmi_regs1->hotplug_detect.b.in_enable, - hdmi_regs1->hotplug_detect.b.in_sts); + vppif_reg32_read(HDMI_HOTPLUG_IN_INT), + vppif_reg32_read(HDMI_HOTPLUG_IN_STS)); DPRINT("plug out enable %d, status %d\n", - hdmi_regs1->hotplug_detect.b.out_enable, - hdmi_regs1->hotplug_detect.b.out_sts); + vppif_reg32_read(HDMI_HOTPLUG_OUT_INT), + vppif_reg32_read(HDMI_HOTPLUG_OUT_STS)); DPRINT("debounce detect %d,sample %d\n", - hdmi_regs1->hotplug_debounce.b.detect, - hdmi_regs1->hotplug_debounce.b.sample); + vppif_reg32_read(HDMI_DEBOUNCE_DETECT), + vppif_reg32_read(HDMI_DEBOUNCE_SAMPLE)); DPRINT("---------- I2C ----------\n"); DPRINT("enable %d,exit FSM %d,key read %d\n", - hdmi_regs1->ctrl.b.i2c_enable, - hdmi_regs1->i2c_ctrl.b.force_exit_fsm, - hdmi_regs1->i2c_ctrl.b.key_read_word); + vppif_reg32_read(HDMI_I2C_ENABLE), + vppif_reg32_read(HDMI_FORCE_EXIT_FSM), + vppif_reg32_read(HDMI_KEY_READ_WORD)); DPRINT("clk divid %d,rd data 0x%x,wr data 0x%x\n", - hdmi_regs1->i2c_ctrl.b.i2c_clk_divider, - hdmi_regs1->i2c_ctrl2.b.rd_data, - hdmi_regs1->i2c_ctrl2.b.wr_data); + vppif_reg32_read(HDMI_I2C_CLK_DIVIDER), + vppif_reg32_read(HDMI_RD_DATA), + vppif_reg32_read(HDMI_WR_DATA)); DPRINT("start %d,stop %d,wr avail %d\n", - hdmi_regs1->i2c_ctrl2.b.sw_start_req, - hdmi_regs1->i2c_ctrl2.b.sw_stop_req, - hdmi_regs1->i2c_ctrl2.b.wr_data_avail); + vppif_reg32_read(HDMI_SW_START_REQ), + vppif_reg32_read(HDMI_SW_STOP_REQ), + vppif_reg32_read(HDMI_WR_DATA_AVAIL)); DPRINT("status %d,sw read %d,sw i2c req %d\n", - hdmi_regs1->i2c_ctrl2.b.i2c_status, - hdmi_regs1->i2c_ctrl2.b.sw_read, - hdmi_regs1->i2c_ctrl2.b.sw_i2c_req); + vppif_reg32_read(HDMI_I2C_STATUS), + vppif_reg32_read(HDMI_SW_READ), + vppif_reg32_read(HDMI_SW_I2C_REQ)); DPRINT("---------- AUDIO ----------\n"); DPRINT("enable %d,sub pck %d,spflat %d\n", - hdmi_regs1->aud_enable, - hdmi_regs1->aud_mode.b.sub_packet, - hdmi_regs1->aud_mode.b.spflat); + vppif_reg32_read(HDMI_AUD_ENABLE), + vppif_reg32_read(HDMI_AUD_SUB_PACKET), + vppif_reg32_read(HDMI_AUD_SPFLAT)); DPRINT("aud pck insert reset %d,enable %d,delay %d\n", - hdmi_regs1->aud_insert_ctrl.b.pck_insert_reset, - hdmi_regs1->aud_insert_ctrl.b.pck_insert_enable, - hdmi_regs1->aud_insert_ctrl.b.insert_delay); + vppif_reg32_read(HDMI_AUD_PCK_INSERT_RESET), + vppif_reg32_read(HDMI_AUD_PCK_INSERT_ENABLE), + vppif_reg32_read(HDMI_AUD_INSERT_DELAY)); DPRINT("avmute set %d,clr %d,pixel repete %d\n", - hdmi_regs1->aud_insert_ctrl.b.avmute_set_enable, - hdmi_regs1->aud_insert_ctrl.b.avmute_clr_enable, - hdmi_regs1->aud_insert_ctrl.b.pixel_repetition); + vppif_reg32_read(HDMI_AVMUTE_SET_ENABLE), + vppif_reg32_read(HDMI_AVMUTE_CLR_ENABLE), + vppif_reg32_read(HDMI_AUD_PIXEL_REPETITION)); DPRINT("acr ratio %d,acr enable %d,mute %d\n", - hdmi_regs1->aud_ratio.b.acr_ratio, - hdmi_regs1->aud_ratio.b.acr_enable, - hdmi_regs1->aud_ratio.b.mute); + vppif_reg32_read(HDMI_AUD_ACR_RATIO), + vppif_reg32_read(HDMI_AUD_ACR_ENABLE), + vppif_reg32_read(HDMI_AUD_MUTE)); DPRINT("layout %d,pwr save %d,n 20bits %d\n", - hdmi_regs1->aud_mode.b.layout, - hdmi_regs1->aud_mode.b.pwr_saving, - hdmi_regs1->aud_sample_rate1.b.n_20bits); + vppif_reg32_read(HDMI_AUD_LAYOUT), + vppif_reg32_read(HDMI_AUD_PWR_SAVING), + vppif_reg32_read(HDMI_AUD_N_20BITS)); DPRINT("cts low 12 %d,hi 8 %d,cts sel %d\n", - hdmi_regs1->aud_sample_rate1.b.cts_low_12bits, - hdmi_regs1->aud_sample_rate2.b.cts_hi_8bits, - hdmi_regs1->aud_sample_rate2.b.cts_select); - DPRINT("aipclk rate %d\n", hdmi_regs1->aud_sample_rate2.b.aipclk_rate); + vppif_reg32_read(HDMI_AUD_CTS_LOW_12BITS), + vppif_reg32_read(HDMI_AUD_CTS_HI_8BITS), + vppif_reg32_read(HDMI_AUD_CTS_SELECT)); + DPRINT("aipclk rate %d\n", vppif_reg32_read(HDMI_AUD_AIPCLK_RATE)); DPRINT("---------- INFOFRAME ----------\n"); DPRINT("sel %d,hor blank pck %d\n", - hdmi_regs1->infoframe_ctrl.b.select, - hdmi_regs1->infoframe_ctrl.b.horiz_blank_max_pck); + vppif_reg32_read(HDMI_INFOFRAME_SELECT), + vppif_reg32_read(HDMI_HORIZ_BLANK_MAX_PCK)); DPRINT("fifo1 ready %d,addr 0x%x,len %d\n", - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy, - hdmi_regs1->infoframe_ctrl.b.fifo1_addr, - hdmi_regs1->infoframe_ctrl.b.fifo1_len); + vppif_reg32_read(HDMI_INFOFRAME_FIFO1_RDY), + vppif_reg32_read(HDMI_INFOFRAME_FIFO1_ADDR), + vppif_reg32_read(HDMI_INFOFRAME_FIFO1_LEN)); DPRINT("fifo2 ready %d,addr 0x%x,len %d\n", - hdmi_regs1->infoframe_ctrl.b.fifo2_rdy, - hdmi_regs1->infoframe_ctrl.b.fifo2_addr, - hdmi_regs1->infoframe_ctrl.b.fifo2_len); + vppif_reg32_read(HDMI_INFOFRAME_FIFO2_RDY), + vppif_reg32_read(HDMI_INFOFRAME_FIFO2_ADDR), + vppif_reg32_read(HDMI_INFOFRAME_FIFO2_LEN)); DPRINT("wr strobe %d,rd strobe %d,fifo addr %d\n", - hdmi_regs1->fifo_ctrl.b.wr_strobe, - hdmi_regs1->fifo_ctrl.b.rd_strobe, - hdmi_regs1->fifo_ctrl.b.addr); + vppif_reg32_read(HDMI_INFOFRAME_WR_STROBE), + vppif_reg32_read(HDMI_INFOFRAME_RD_STROBE), + vppif_reg32_read(HDMI_INFOFRAME_FIFO_ADDR)); { int i; unsigned int buf[32]; - for (i = 0; i <= hdmi_regs1->infoframe_ctrl.b.fifo1_len; i++) { + for (i = 0; i <= vppif_reg32_read(HDMI_INFOFRAME_FIFO1_LEN); i++) { DPRINT("----- infoframe %d -----\n", i); hdmi_read_fifo(i, buf, 32); vpp_reg_dump((unsigned int) buf, 32); @@ -1277,14 +1433,15 @@ void hdmi_reg_dump(void) DPRINT("---------- HDMI test ----------\n"); DPRINT("ch0 enable %d, data 0x%x\n", - hdmi_regs1->channel_test.b.ch0_enable, - hdmi_regs1->channel_test.b.ch0_data); + vppif_reg32_read(HDMI_CH0_TEST_MODE_ENABLE), + vppif_reg32_read(HDMI_CH0_TEST_DATA)); DPRINT("ch1 enable %d, data 0x%x\n", - hdmi_regs1->channel_test.b.ch1_enable, - hdmi_regs1->channel_test.b.ch1_data); + vppif_reg32_read(HDMI_CH1_TEST_MODE_ENABLE), + vppif_reg32_read(HDMI_CH1_TEST_DATA)); DPRINT("ch2 enable %d, data 0x%x\n", - hdmi_regs1->hotplug_detect.b.ch2_enable, - hdmi_regs1->hotplug_detect.b.ch2_data); + vppif_reg32_read(HDMI_CH2_TEST_MODE_ENABLE), + vppif_reg32_read(HDMI_CH2_TEST_DATA)); + if (hdmi_cp) hdmi_cp->dump(); } @@ -1295,12 +1452,13 @@ static unsigned int *hdmi_pm_bk2; static unsigned int hdmi_pm_enable; static unsigned int hdmi_pm_enable2; static int hdmi_plug_enable = 0xFF; +extern struct switch_dev vpp_sdev; static int hdmi_resume_plug_cnt; #define HDMI_RESUME_PLUG_MS 50 #define HDMI_RESUME_PLUG_CNT 20 static void hdmi_do_resume_plug(struct work_struct *ptr) { - struct vout_t *vo; + vout_t *vo; int plugin; struct delayed_work *dwork = to_delayed_work(ptr); @@ -1309,7 +1467,7 @@ static void hdmi_do_resume_plug(struct work_struct *ptr) vout_change_status(vo, VPP_VOUT_STS_PLUGIN, plugin); if (plugin) hdmi_hotplug_notify(1); - hdmi_resume_plug_cnt--; + hdmi_resume_plug_cnt --; if (hdmi_resume_plug_cnt && (vpp_sdev.state == 0)) schedule_delayed_work(dwork, msecs_to_jiffies(HDMI_RESUME_PLUG_MS)); @@ -1323,14 +1481,13 @@ void hdmi_suspend(int sts) switch (sts) { case 0: /* disable module */ cancel_delayed_work_sync(&hdmi_resume_work); - hdmi_pm_enable = hdmi_regs1->general_ctrl.b.enable; - hdmi_regs1->general_ctrl.b.enable = 0; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for wr only */ - hdmi_pm_enable2 = hdmi_regs1->ctrl.b.hden; - hdmi_regs1->ctrl.b.hden = 0; + hdmi_pm_enable = vppif_reg32_read(HDMI_ENABLE); + hdmi_reg32_write(HDMI_ENABLE, 0); + hdmi_pm_enable2 = vppif_reg32_read(HDMI_HDEN); + vppif_reg32_write(HDMI_HDEN, 0); if (hdmi_plug_enable == 0xFF) hdmi_plug_enable = - hdmi_regs1->hotplug_detect.b.out_enable; + vppif_reg32_read(HDMI_HOTPLUG_OUT_INT); hdmi_enable_plugin(0); break; case 1: /* disable tg */ @@ -1340,6 +1497,7 @@ void hdmi_suspend(int sts) (REG_HDMI_END - REG_HDMI_BEGIN)); hdmi_pm_bk2 = vpp_backup_reg(REG_HDMI2_BEGIN, (REG_HDMI2_END - REG_HDMI2_BEGIN)); + switch_set_state(&vpp_sdev, 0); hdmi_resume_plug_cnt = 20; break; default: @@ -1353,7 +1511,6 @@ void hdmi_resume(int sts) vo_hdmi_set_clock(1); switch (sts) { case 0: /* restore register */ - switch_set_state(&vpp_sdev, 0); vpp_restore_reg(REG_HDMI_BEGIN, (REG_HDMI_END - REG_HDMI_BEGIN), hdmi_pm_bk); vpp_restore_reg(REG_HDMI2_BEGIN, @@ -1365,9 +1522,8 @@ void hdmi_resume(int sts) hdmi_cp->init(); break; case 1: /* enable module */ - hdmi_regs1->general_ctrl.b.enable = hdmi_pm_enable; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for wr only */ - hdmi_regs1->ctrl.b.hden = hdmi_pm_enable2; + hdmi_reg32_write(HDMI_ENABLE, hdmi_pm_enable); + vppif_reg32_write(HDMI_HDEN, hdmi_pm_enable2); break; case 2: /* enable tg */ hdmi_check_plugin(0); @@ -1409,8 +1565,6 @@ void hdmi_init(void) hdmi_info.freq = 48000; hdmi_info.option = EDID_OPT_AUDIO + EDID_OPT_HDMI; - hdmi_enable_plugin(0); - if (g_vpp.govrh_preinit) { DBGMSG("[HDMI] hdmi_init for uboot logo\n"); } else { @@ -1427,31 +1581,34 @@ void hdmi_init(void) /* Wake3 disable pull ctrl */ vppif_reg32_write(GPIO_BASE_ADDR+0x480, BIT19, 19, 0); #endif - hdmi_regs2->level.b.level = 1; - hdmi_regs2->level.b.update = 1; - hdmi_regs2->igs.b.ldi_shift_left = 1; - hdmi_regs2->status.val = 0x0008c000; - hdmi_regs2->test.val = 0x00450409; - hdmi_regs2->test2.val = 0x00005022; - hdmi_regs2->test3 = (g_vpp.hdmi_sp_mode) ? - 0x00010100 : 0x00000100; + vppif_reg32_write(HDMI_REG_LEVEL, 1); + vppif_reg32_write(HDMI_REG_UPDATE, 1); + vppif_reg32_write(HDMI_LDI_SHIFT_LEFT, 1); + vppif_reg32_out(REG_HDMI_STATUS, 0x0008c000); + vppif_reg32_out(REG_HDMI_TEST, 0x00450409); + vppif_reg32_out(REG_HDMI_TEST2, 0x00005022); + vppif_reg32_out(REG_HDMI_TEST3, + (g_vpp.hdmi_sp_mode) ? 0x00010100 : 0x00000100); hdmi_set_enable(VPP_FLAG_DISABLE); hdmi_set_dvi_enable(VPP_FLAG_DISABLE); - hdmi_regs1->ctrl.b.cipher_1_1 = 0; + vppif_reg32_write(HDMI_CIPHER_1_1, 0); - hdmi_regs1->tmds_ctrl.b.infoframe_sram_enable = 1; - hdmi_regs1->infoframe_ctrl.b.select = 0; - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 0; + vppif_reg32_write(HDMI_INFOFRAME_SRAM_ENABLE, 1); + vppif_reg32_write(HDMI_INFOFRAME_SELECT, 0); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_RDY, 0); - hdmi_regs1->hotplug_detect.val = 0x0; - hdmi_regs1->channel_test.val = 0x1; + vppif_reg32_out(HDMI_BASE_ADDR+0x3ec, 0x0); + vppif_reg32_out(HDMI_BASE_ADDR+0x3e8, 0x1); + /* vppif_reg32_write(HDMI_AUD_LAYOUT, 1); */ hdmi_DDC_reset(); hdmi_DDC_set_freq(g_vpp.hdmi_i2c_freq); - hdmi_regs1->ctrl.b.i2c_enable = 1; + vppif_reg32_write(HDMI_I2C_ENABLE, 1); } g_vpp.hdmi_init = 1; if (hdmi_cp) hdmi_cp->init(); + + acr_init(); } #endif /* WMT_FTBLK_HDMI */ diff --git a/drivers/video/wmt/hdmi.h b/drivers/video/wmt/hdmi.h index 13c80940..83845100 100755..100644 --- a/drivers/video/wmt/hdmi.h +++ b/drivers/video/wmt/hdmi.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/hdmi.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -38,7 +38,7 @@ extern "C" { #define HDMI_PLUG_DELAY 300 /* plug stable delay ms */ #define HDMI_CP_TIME 3 /* should more than 2 seconds */ -enum hdmi_packet_type_t { +typedef enum { HDMI_PACKET_NULL = 0x0, HDMI_PACKET_AUD_CLOCK_REGEN = 0x1, HDMI_PACKET_AUD_SAMPLE = 0x2, @@ -55,7 +55,7 @@ enum hdmi_packet_type_t { HDMI_PACKET_INFOFRAME_SRC_PRODUCT_DESC = 0x83, HDMI_PACKET_INFOFRAME_AUDIO = 0x84, HDMI_PACKET_INFOFRAME_MPEG_SOURCE = 0x85 -}; +} hdmi_packet_type_t; /* color depth (CD field) */ #define HDMI_COLOR_DEPTH_24 0x4 @@ -124,7 +124,7 @@ enum hdmi_packet_type_t { #define HDMI_PIXEL_REP_10 0x9 /* Video Code */ -enum hdmi_video_code_t { +typedef enum { HDMI_UNKNOW = 0, HDMI_640x480p60_4x3, HDMI_720x480p60_4x3, @@ -161,10 +161,10 @@ enum hdmi_video_code_t { HDMI_1920x1080p25_16x9, HDMI_1920x1080p30_16x9, HDMI_VIDEO_CODE_MAX -}; +} hdmi_video_code_t; /* Audio Channel Count (Audio InfoFrame CC0/CC1/CC2) */ -enum hdmi_audio_channel_count_t { +typedef enum { HDMI_AUD_CHAN_REF_STM = 0, HDMI_AUD_CHAN_2CH, HDMI_AUD_CHAN_3CH, @@ -173,7 +173,7 @@ enum hdmi_audio_channel_count_t { HDMI_AUD_CHAN_6CH, HDMI_AUD_CHAN_7CH, HDMI_AUD_CHAN_8CH -}; +} hdmi_audio_channel_count_t; /* Audio Coding type (Audio InfoFrame CT0/CT1/CT2/CT3) */ #define HDMI_AUD_TYPE_REF_STM 0x0 @@ -214,7 +214,7 @@ enum hdmi_audio_channel_count_t { /*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/ /* typedef void hdmi_xxx_t; *//*Example*/ -struct hdmi_info_t { +typedef struct { /* video */ vdo_color_fmt outfmt; int vic; @@ -226,34 +226,34 @@ struct hdmi_info_t { /* option */ int option; -}; +} hdmi_info_t; #define HDMI_VIC_INTERLACE BIT(0) #define HDMI_VIC_PROGRESS 0 #define HDMI_VIC_4x3 BIT(1) #define HDMI_VIC_16x9 0 -struct hdmi_vic_t { +typedef struct { unsigned short resx; unsigned short resy; char freq; char option; -}; +} hdmi_vic_t; -struct hdmi_cp_t { +typedef struct { void (*init)(void); void (*enable)(int on); int (*poll)(void); void (*dump)(void); int (*interrupt)(void); void (*get_bksv)(unsigned int *bksv); -}; +} hdmi_cp_t; /*-------------------- EXPORTED PRIVATE VARIABLES ---------------------------*/ #ifdef VPP_C #define EXTERN -const struct hdmi_vic_t hdmi_vic_info[HDMI_VIDEO_CODE_MAX] = { +const hdmi_vic_t hdmi_vic_info[HDMI_VIDEO_CODE_MAX] = { { 0, 0, 0, 0 }, /* HDMI_UNKNOW = 0 */ { 640, 480, 60, HDMI_VIC_4x3 }, /* HDMI_640x480p60_4x3 */ { 720, 480, 60, HDMI_VIC_4x3 }, /* HDMI_720x480p60_4x3 */ @@ -293,19 +293,12 @@ const struct hdmi_vic_t hdmi_vic_info[HDMI_VIDEO_CODE_MAX] = { #else #define EXTERN extern -EXTERN const struct hdmi_vic_t hdmi_vic_info[HDMI_VIDEO_CODE_MAX]; +EXTERN const hdmi_vic_t hdmi_vic_info[HDMI_VIDEO_CODE_MAX]; #endif /* ifdef HDMI_C */ -EXTERN struct hdmi_cp_t *hdmi_cp; +EXTERN hdmi_cp_t *hdmi_cp; EXTERN int hdmi_ri_tm_cnt; -EXTERN struct hdmi_info_t hdmi_info; - -#ifdef VPP_C -EXPORT_SYMBOL(hdmi_cp); -EXPORT_SYMBOL(hdmi_ri_tm_cnt); -EXPORT_SYMBOL(hdmi_regs1); -EXPORT_SYMBOL(hdmi_regs2); -#endif +EXTERN hdmi_info_t hdmi_info; /* EXTERN int hdmi_xxx; *//*Example*/ #undef EXTERN @@ -324,7 +317,7 @@ void hdmi_set_avmute(vpp_flag_t mute); void hdmi_set_dvi_enable(vpp_flag_t enable); void hdmi_set_cp_enable(vpp_flag_t enable); int hdmi_check_cp_int(void); -void hdmi_config(struct hdmi_info_t *info); +void hdmi_config(hdmi_info_t *info); int hdmi_DDC_read(char addr, int index, char *buf, int length); int hdmi_get_plugin(void); int hdmi_get_plug_status(void); diff --git a/drivers/video/wmt/hdmi_cp.c b/drivers/video/wmt/hdmi_cp.c new file mode 100644 index 00000000..10fdead0 --- /dev/null +++ b/drivers/video/wmt/hdmi_cp.c @@ -0,0 +1,45 @@ +/*++ + * linux/drivers/video/wmt/hdmi_cp.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2013 WonderMedia Technologies, Inc. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#define HDMI_CP_C +// #define DEBUG +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "hdmi_cp.h" + +/*----------------------- PRIVATE MACRO --------------------------------------*/ + +/*----------------------- PRIVATE CONSTANTS ----------------------------------*/ +/* #define HDMI_CP_XXXX 1 *//*Example*/ + +/*----------------------- PRIVATE TYPE --------------------------------------*/ +/* typedef xxxx hdmi_cp_xxx_t; *//*Example*/ + +/*----------EXPORTED PRIVATE VARIABLES are defined in hdmi_cp.h -------------*/ +/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ +/* int hdmi_cp_xxx; *//*Example*/ + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void hdmi_cp_xxx(void); *//*Example*/ + +/*----------------------- Function Body --------------------------------------*/ + diff --git a/drivers/video/wmt/hdmi_cp.h b/drivers/video/wmt/hdmi_cp.h new file mode 100644 index 00000000..55ab1bab --- /dev/null +++ b/drivers/video/wmt/hdmi_cp.h @@ -0,0 +1,63 @@ +/*++ + * linux/drivers/video/wmt/hdmi_cp.h + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2013 WonderMedia Technologies, Inc. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +#ifndef HDMI_CP_H +/* To assert that only one occurrence is included */ +#define HDMI_CP_H +/*-------------------- MODULE DEPENDENCY -------------------------------------*/ +#include "vpp.h" + +/* following is the C++ header */ +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------- EXPORTED PRIVATE CONSTANTS ----------------------------*/ +/* #define HDMI_CP_XXXX 1 *//*Example*/ +/* #define CONFIG_HDMI_CP_DISABLE */ + +/*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/ +/* typedef void hdmi_cp_xxx_t; *//*Example*/ + +/*-------------------- EXPORTED PRIVATE VARIABLES ----------------------------*/ +#ifdef HDMI_CP_C +#define EXTERN + +#else +#define EXTERN extern + +#endif /* ifdef HDMI_CP_C */ + +/* EXTERN int hdmi_cp_xxx; *//*Example*/ +#undef EXTERN + +/*--------------------- EXPORTED PRIVATE MACROS ------------------------------*/ +/* #define HDMI_CP_XXX_YYY xxxx *//*Example*/ +/*--------------------- EXPORTED PRIVATE FUNCTIONS --------------------------*/ +/* extern void hdmi_cp_xxx(void); *//*Example*/ + +#ifdef __cplusplus +} +#endif +#endif /* ifndef HDMI_CP_H */ + diff --git a/drivers/video/wmt/hw/wmt-cec-reg.h b/drivers/video/wmt/hw/wmt-cec-reg.h index 17e7275c..e93939fd 100755..100644 --- a/drivers/video/wmt/hw/wmt-cec-reg.h +++ b/drivers/video/wmt/hw/wmt-cec-reg.h @@ -28,193 +28,142 @@ #define CEC_BASE_ADDR (LVDS_BASE_ADDR + 0x100) #define CEC_BASE2_ADDR (LVDS_BASE_ADDR + 0x200) -struct cec_base_regs { - union { - unsigned int val; - struct { - unsigned int wr_start:1; - } b; - } enable; /* 0x0 */ - - union { - unsigned int val; - struct { - unsigned int wr_num:8; - } b; - } encode_number; /* 0x04 */ - - union { - unsigned int val; - struct { - unsigned int wr_data_ack:1; - unsigned int wr_data_eom:1; - unsigned int _02_03:2; - unsigned int wr_data:8; - } b; - } encode_data[16]; /* 0x08 header,0x0c - 0x44 */ - - union { - unsigned int val; - struct { - unsigned int finish_reset:1; - } b; - } decode_reset; /* 0x48 */ - - union { - unsigned int val; - struct { - unsigned int rd_start:1; - unsigned int rd_all_ack:1; - unsigned int rd_finish:1; - } b; - } decode_start; /* 0x4c */ - - union { - unsigned int val; - struct { - unsigned int rd_data_ack:1; - unsigned int rd_data_eom:1; - unsigned int _02_03:2; - unsigned int rd_data:8; - } b; - } decode_data[16]; /* 0x50 header, 0x54 - 0x8c */ - - unsigned int wr_start_set0; /* 0x90 */ - unsigned int wr_start_set1; /* 0x94 */ - unsigned int wr_logic0_set0; /* 0x98 */ - unsigned int wr_logic0_set1; /* 0x9c */ - unsigned int wr_logic1_set0; /* 0xa0 */ - unsigned int wr_logic1_set1; /* 0xa4 */ - unsigned int rd_start_l_set0; /* 0xa8 */ - unsigned int rd_start_r_set0; /* 0xac */ - unsigned int rd_start_l_set1; /* 0xb0 */ - unsigned int rd_start_r_set1; /* 0xb4 */ - unsigned int rd_logic0_l_set0; /* 0xb8 */ - unsigned int rd_logic0_r_set0; /* 0xbc */ - unsigned int rd_logic0_l_set1; /* 0xc0 */ - unsigned int rd_logic0_r_set1; /* 0xc4 */ - unsigned int rd_logic1_l_set0; /* 0xc8 */ - unsigned int rd_logic1_r_set0; /* 0xcc */ - unsigned int rd_logic1_l_set1; /* 0xd0 */ - unsigned int rd_logic1_r_set1; /* 0xd4 */ - unsigned int physical_addr; /* 0xd8 */ - - union { - unsigned int val; - struct { - unsigned int addr1:4; - unsigned int addr2:4; - unsigned int addr3:4; - unsigned int addr4:4; - unsigned int addr5:4; - unsigned int _20_23:4; - unsigned int valid1:1; - unsigned int valid2:1; - unsigned int valid3:1; - unsigned int valid4:1; - unsigned int valid5:1; - } b; - } logical_addr; /* 0xdc */ - - union { - unsigned int val; - struct { - unsigned int retry:4; - } b; - } wr_retry; /* 0xe0 */ - - union { - unsigned int val; - struct { - unsigned int free_3x:4; - unsigned int _04_07:4; - unsigned int free_5x:4; - unsigned int _12_15:4; - unsigned int free_7x:4; - } b; - } free_3x; /* 0xe4 */ - - unsigned int wr_set0_error; /* 0xe8 */ - unsigned int wr_set1_error; /* 0xec */ - - union { - unsigned int val; - struct { - unsigned int next_decode:1; /*read enable*/ - } b; - } reject; /* 0xf0 */ - - unsigned int rd_l_set0_error; /* 0xf4 */ - unsigned int rd_r_set1_error; /* 0xf8 */ - unsigned int rd_l_error; /* 0xfc */ - - unsigned int rx_trig_range; /* 0x100 */ - unsigned int rx_sample_l_range; /* 0x104 */ - unsigned int rx_sample_r_range; /* 0x108 */ - - union { - unsigned int val; - struct { - unsigned int disable:1; - } b; - } comp; /* 0x10c */ - - union { - unsigned int val; - struct { - unsigned int err:1; - unsigned int no_ack:1; - } b; - } handle_disable; /* 0x110 */ - - union { - unsigned int val; - struct { - unsigned int r1_encode_ok:1; /* write finish */ - unsigned int r1_decode_ok:1; /* read finish */ - unsigned int r1_error:1; /* read error */ - unsigned int r1_arb_fail:1; /* wr arb fail */ - unsigned int r1_no_ack:1; /* wr no ack */ - } b; - } status; /* 0x114 */ - - unsigned int int_enable; /* 0x118 */ - - union { - unsigned int val; - struct { - unsigned int disable:1; - } b; - } decode_full; /* 0x11c */ - - union { - unsigned int val; - struct { - unsigned int start:1; - unsigned int logic0:1; - unsigned int logic1:1; - } b; - } status4_disable; /* 0x120 */ - - union { - unsigned int val; - struct { - unsigned int enable:1; /*1:rd self wr & all dest data */ - } b; - } rd_encode; /* 0x124 */ - - union { - unsigned int val; - struct { - unsigned int disable:1; /* 1 : disable arb check */ - } b; - } arb_check; /* 0x128 */ -}; - -#define REG_CEC_BEGIN (CEC_BASE_ADDR + 0x0) -#define REG_CEC_END (CEC_BASE2_ADDR + 0x28) -#ifndef CEC_C -extern struct cec_base_regs *cec_regs; -#endif + +#define REG_CEC_BEGIN (CEC_BASE_ADDR + 0x0) +#define REG_CEC_ENABLE (CEC_BASE_ADDR + 0x0) +#define REG_CEC_ENCODE_NUMBER (CEC_BASE_ADDR + 0x4) +#define REG_CEC_ENCODE_HEADER (CEC_BASE_ADDR + 0x8) +#define REG_CEC_ENCODE_DATA (CEC_BASE_ADDR + 0xC) /* Data1(0x0C) - Data15(0x44) */ +#define REG_CEC_DECODE_RESET (CEC_BASE_ADDR + 0x48) +#define REG_CEC_DECODE_START (CEC_BASE_ADDR + 0x4C) +#define REG_CEC_DECODE_HEADER (CEC_BASE_ADDR + 0x50) +#define REG_CEC_DECODE_DATA (CEC_BASE_ADDR + 0x54) /* Data1(0x54) - Data15(0x8C) */ +#define REG_CEC_WR_START_SET0 (CEC_BASE_ADDR + 0x90) /* val * CEC_CLK = 3.7 ms */ +#define REG_CEC_WR_START_SET1 (CEC_BASE_ADDR + 0x94) /* val * CEC_CLK = 4.5 ms */ +#define REG_CEC_WR_LOGIC0_SET0 (CEC_BASE_ADDR + 0x98) /* val * CEC_CLK = 0.6 ms */ +#define REG_CEC_WR_LOGIC0_SET1 (CEC_BASE_ADDR + 0x9C) /* val * CEC_CLK = 2.4 ms */ +#define REG_CEC_WR_LOGIC1_SET0 (CEC_BASE_ADDR + 0xA0) /* val * CEC_CLK = 1.5 ms */ +#define REG_CEC_WR_LOGIC1_SET1 (CEC_BASE_ADDR + 0xA4) /* val * CEC_CLK = 2.4 ms */ +#define REG_CEC_RD_START_L_SET0 (CEC_BASE_ADDR + 0xA8) /* val * CEC_CLK = 3.5 ms */ +#define REG_CEC_RD_START_R_SET0 (CEC_BASE_ADDR + 0xAC) /* val * CEC_CLK = 3.9 ms */ +#define REG_CEC_RD_START_L_SET1 (CEC_BASE_ADDR + 0xB0) /* val * CEC_CLK = 4.3 ms */ +#define REG_CEC_RD_START_R_SET1 (CEC_BASE_ADDR + 0xB4) /* val * CEC_CLK = 4.7 ms */ +#define REG_CEC_RD_LOGIC0_L_SET0 (CEC_BASE_ADDR + 0xB8) /* val * CEC_CLK = 1.3 ms */ +#define REG_CEC_RD_LOGIC0_R_SET0 (CEC_BASE_ADDR + 0xBC) /* val * CEC_CLK = 1.7 ms */ +#define REG_CEC_RD_LOGIC0_L_SET1 (CEC_BASE_ADDR + 0xC0) /* val * CEC_CLK = 2.05 ms */ +#define REG_CEC_RD_LOGIC0_R_SET1 (CEC_BASE_ADDR + 0xC4) /* val * CEC_CLK = 2.75 ms */ +#define REG_CEC_RD_LOGIC1_L_SET0 (CEC_BASE_ADDR + 0xC8) /* val * CEC_CLK = 0.4 ms */ +#define REG_CEC_RD_LOGIC1_R_SET0 (CEC_BASE_ADDR + 0xCC) /* val * CEC_CLK = 0.8 ms */ +#define REG_CEC_RD_LOGIC1_L_SET1 (CEC_BASE_ADDR + 0xD0) /* val * CEC_CLK = 2.05 ms */ +#define REG_CEC_RD_LOGIC1_R_SET1 (CEC_BASE_ADDR + 0xD4) /* val * CEC_CLK = 2.75 ms */ +#define REG_CEC_PHYSICAL_ADDR (CEC_BASE_ADDR + 0xD8) +#define REG_CEC_LOGICAL_ADDR (CEC_BASE_ADDR + 0xDC) +#define REG_CEC_WR_RETRY (CEC_BASE_ADDR + 0xE0) +#define REG_CEC_FREE_3X (CEC_BASE_ADDR + 0xE4) +#define REG_CEC_WR_SET0_ERROR (CEC_BASE_ADDR + 0xE8) /* val * CEC_CLK = 2.25 ms */ +#define REG_CEC_WR_SET1_ERROR (CEC_BASE_ADDR + 0xEC) +#define REG_CEC_REJECT (CEC_BASE_ADDR + 0xF0) +#define REG_CEC_RD_L_SET0_ERROR (CEC_BASE_ADDR + 0xF4) /* val * CEC_CLK = 1.82 ms */ +#define REG_CEC_RD_R_SET1_ERROR (CEC_BASE_ADDR + 0xF8) /* val * CEC_CLK = 2.38 ms */ +#define REG_CEC_RD_L_ERROR (CEC_BASE_ADDR + 0xFC) /* val * CEC_CLK = 2.87 ms */ + +#define REG_CEC_RX_TRIG_RANGE (CEC_BASE2_ADDR + 0x00) +#define REG_CEC_RX_SAMPLE_L_RANGE (CEC_BASE2_ADDR + 0x04) /* val * CEC_CLK = 0.85 ms */ +#define REG_CEC_RX_SAMPLE_R_RANGE (CEC_BASE2_ADDR + 0x08) /* val * CEC_CLK = 1.25 ms */ +#define REG_CEC_COMP_DISABLE (CEC_BASE2_ADDR + 0x0C) +#define REG_CEC_ERR_HANDLE_DISABLE (CEC_BASE2_ADDR + 0x10) +#define REG_CEC_STATUS (CEC_BASE2_ADDR + 0x14) +#define REG_CEC_INT_ENABLE (CEC_BASE2_ADDR + 0x18) +#define REG_CEC_DECODE_FULL_DISABLE (CEC_BASE2_ADDR + 0x1C) +#define REG_CEC_STATUS4_DISABLE (CEC_BASE2_ADDR + 0x20) +#define REG_CEC_RD_ENCODE_ENABLE (CEC_BASE2_ADDR + 0x24) +#define REG_CEC_DIS_ARB_CHECK (CEC_BASE2_ADDR + 0x28) +#define REG_CEC_END (CEC_BASE2_ADDR + 0x28) + +/* REG_CEC_ENABLE,0x0 */ +#define CEC_WR_START REG_CEC_ENABLE, BIT0, 0 + +/* REG_CEC_ENCODE_NUMBER,0x4 */ +#define CEC_WR_NUM REG_CEC_ENCODE_NUMBER, 0xFF, 0x0 + +/* REG_CEC_ENCODE_HEADER,0x8 */ +#define CEC_WR_HEADER_ACK REG_CEC_ENCODE_HEADER, BIT0, 0 +#define CEC_WR_HEADER_EOM REG_CEC_ENCODE_HEADER, BIT1, 1 +#define CEC_WR_HEADER_DATA REG_CEC_ENCODE_HEADER, 0xFF0, 4 + +/* REG_CEC_ENCODE_DATA,Data1(0x0C) - Data15(0x44) */ +#define CEC_WR_DATA_ACK REG_CEC_ENCODE_DATA, BIT0, 0 +#define CEC_WR_DATA_EOM REG_CEC_ENCODE_DATA, BIT1, 1 +#define CEC_WR_DATA REG_CEC_ENCODE_DATA, 0xFF0, 4 + +/* REG_CEC_DECODE_RESET,0x48 */ +#define CEC_FINISH_RESET REG_CEC_DECODE_RESET, BIT0, 0 + +/* REG_CEC_DECODE_START,0x4C */ +#define CEC_RD_START REG_CEC_DECODE_START, BIT0, 0 +#define CEC_RD_ALL_ACK REG_CEC_DECODE_START, BIT1, 1 +#define CEC_RD_FINISH REG_CEC_DECODE_START, BIT2, 2 + +/* REG_CEC_DECODE_HEADER,0x50 */ +#define CEC_RD_HEADER_ACK REG_CEC_DECODE_HEADER, BIT0, 0 +#define CEC_RD_HEADER_EOM REG_CEC_DECODE_HEADER, BIT1, 1 +#define CEC_RD_HEADER_DATA REG_CEC_DECODE_HEADER, 0xFF0, 4 + +/* REG_CEC_DECODE_DATA,Data1(0x54) - Data15(0x8C) */ +#define CEC_RD_DATA_ACK REG_CEC_DECODE_DATA, BIT0, 0 +#define CEC_RD_DATA_EOM REG_CEC_DECODE_DATA, BIT1, 1 +#define CEC_RD_DATA REG_CEC_DECODE_DATA, 0xFF0, 4 + +/* REG_CEC_LOGICAL_ADDR,0xDC */ +#define CEC_LOGICAL_ADDR1 REG_CEC_LOGICAL_ADDR, 0xF, 0 +#define CEC_LOGICAL_ADDR2 REG_CEC_LOGICAL_ADDR, 0xF0, 4 +#define CEC_LOGICAL_ADDR3 REG_CEC_LOGICAL_ADDR, 0xF00, 8 +#define CEC_LOGICAL_ADDR4 REG_CEC_LOGICAL_ADDR, 0xF000, 12 +#define CEC_LOGICAL_ADDR5 REG_CEC_LOGICAL_ADDR, 0xF0000, 16 +#define CEC_ADDR_VALID1 REG_CEC_LOGICAL_ADDR, BIT24, 24 +#define CEC_ADDR_VALID2 REG_CEC_LOGICAL_ADDR, BIT25, 25 +#define CEC_ADDR_VALID3 REG_CEC_LOGICAL_ADDR, BIT26, 26 +#define CEC_ADDR_VALID4 REG_CEC_LOGICAL_ADDR, BIT27, 27 +#define CEC_ADDR_VALID5 REG_CEC_LOGICAL_ADDR, BIT28, 28 + +/* REG_CEC_WR_RETRY,0xE0 */ +#define CEC_WR_RETRY REG_CEC_WR_RETRY, 0xF, 0 + +/* REG_CEC_FREE_3X,0xE4 */ +#define CEC_FREE_3X REG_CEC_FREE_3X, 0xF, 0 +#define CEC_FREE_5X REG_CEC_FREE_3X, 0xF00, 8 +#define CEC_FREE_7X REG_CEC_FREE_3X, 0xF0000, 16 + +/* REG_CEC_REJECT,0xF0 */ +#define CEC_REJECT_NEXT_DECODE REG_CEC_REJECT, BIT0, 0 /*read enable*/ + +/* REG_CEC_COMP_DISABLE,0x0C */ +#define CEC_COMP_DISABLE REG_CEC_COMP_DISABLE, BIT0, 0 + +/* REG_CEC_ERR_HANDLE_DISABLE,0x10 */ +#define CEC_ERR_HANDLE_DISABLE REG_CEC_ERR_HANDLE_DISABLE, BIT0, 0 +#define CEC_NO_ACK_DISABLE REG_CEC_ERR_HANDLE_DISABLE, BIT1, 1 + +/* REG_CEC_STATUS,0x14 */ +#define CEC_R1_ENCODE_OK REG_CEC_STATUS, BIT0, 0 /* write finish */ +#define CEC_R1_DECODE_OK REG_CEC_STATUS, BIT1, 1 /* read finish */ +#define CEC_R1_ERROR REG_CEC_STATUS, BIT2, 2 /* read error */ +#define CEC_R1_ARB_FAIL REG_CEC_STATUS, BIT3, 3 /* wr arb fail */ +#define CEC_R1_NO_ACK REG_CEC_STATUS, BIT4, 4 /* wr no ack */ + +/* REG_CEC_DECODE_FULL_DISABLE,0x1C */ +#define CEC_DECODE_FULL_DISABLE REG_CEC_DECODE_FULL_DISABLE, BIT0, 0 + +/* REG_CEC_STATUS4_DISABLE,0x20 */ +#define CEC_STATUS4_START_DISABLE REG_CEC_STATUS4_DISABLE, BIT0, 0 +#define CEC_STATUS4_LOGIC0_DISABLE REG_CEC_STATUS4_DISABLE, BIT1, 1 +#define CEC_STATUS4_LOGIC1_DISABLE REG_CEC_STATUS4_DISABLE, BIT2, 2 + +/* REG_CEC_RD_ENCODE_ENABLE,0x24 */ +#define CEC_RD_ENCODE_ENABLE REG_CEC_RD_ENCODE_ENABLE, BIT0, 0 /* 1 : read self write and all dest data */ + +/* REG_CEC_DIS_ARB_CHECK,0x28 */ +#define CEC_ARB_CHECK_DISABLE REG_CEC_DIS_ARB_CHECK, BIT0, 0 /* 1 : disable arbitration check */ + #endif /* WMT_CEC_REG_H */ diff --git a/drivers/video/wmt/hw/wmt-govrh-reg.h b/drivers/video/wmt/hw/wmt-govrh-reg.h index ecdeb4f2..4e2e2341 100755..100644 --- a/drivers/video/wmt/hw/wmt-govrh-reg.h +++ b/drivers/video/wmt/hw/wmt-govrh-reg.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/hw/wmt-govrh-reg.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -43,38 +43,38 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int start:11; - unsigned int reserved:5; - unsigned int end:11; + unsigned int start : 11; + unsigned int reserved : 5; + unsigned int end : 11; } b; } cur_hcoord; /* 0x14 */ union { unsigned int val; struct { - unsigned int start:11; - unsigned int reserved:5; - unsigned int end:11; + unsigned int start : 11; + unsigned int reserved : 5; + unsigned int end : 11; } b; } cur_vcoord; /* 0x18 */ union { unsigned int val; struct { - unsigned int enable:1; - unsigned int reserved:7; - unsigned int out_field:1; /* 0:frame,1-field */ + unsigned int enable : 1; + unsigned int reserved : 7; + unsigned int out_field : 1; /* 0:frame,1-field */ } b; } cur_status; /* 0x1C */ union { unsigned int val; struct { - unsigned int colkey:24; - unsigned int enable:1; - unsigned int invert:1; - unsigned int reserved:2; - unsigned int alpha:1; + unsigned int colkey : 24; + unsigned int enable : 1; + unsigned int invert : 1; + unsigned int reserved : 2; + unsigned int alpha : 1; } b; } cur_color_key; /* 0x20 */ @@ -83,29 +83,29 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int rgb:1; - unsigned int yuv422:1; + unsigned int rgb : 1; + unsigned int yuv422 : 1; } b; } dvo_pix; /* 0x30 */ union { unsigned int val; struct { - unsigned int delay:14; - unsigned int inv:1; + unsigned int delay : 14; + unsigned int inv : 1; } b; } dvo_dly_sel; /* 0x34 */ union { unsigned int val; struct { - unsigned int cur_enable:1; - unsigned int mem_enable:1; - unsigned int reserved:7; - unsigned int err_sts:1; - unsigned int reserved2:6; - unsigned int cur_sts:1; - unsigned int mem_sts:1; + unsigned int cur_enable : 1; + unsigned int mem_enable : 1; + unsigned int reserved : 7; + unsigned int err_sts : 1; + unsigned int reserved2 : 6; + unsigned int cur_sts : 1; + unsigned int mem_sts : 1; } b; } interrupt; /* 0x38 */ @@ -114,17 +114,17 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int v:8; - unsigned int u:8; - unsigned int y:8; + unsigned int v : 8; + unsigned int u : 8; + unsigned int y : 8; } b; } saturation; /* 0x44 */ union { unsigned int val; struct { - unsigned int enable:1; - unsigned int format:1; /* 0:YCbCr, 1:RGB */ + unsigned int enable : 1; + unsigned int format : 1; /* 0:YCbCr, 1:RGB */ } b; } saturation_enable; /* 0x48 */ @@ -132,31 +132,31 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int enable:1; - unsigned int reserved:7; - unsigned int h264:1; + unsigned int enable : 1; + unsigned int reserved : 7; + unsigned int h264 : 1; } b; } mif; /* 0x80 */ unsigned int colfmt; /* 0x84, 0:422,1:420 */ unsigned int srcfmt; /* 0x88, 0:frame,1:field */ unsigned int dstfmt; /* 0x8C, 0:frame,1:field */ - unsigned int ysa; /* 0x90 */ + unsigned int ysa; /* 0x90 */ unsigned int csa; unsigned int pixwid; unsigned int bufwid; - unsigned int vcrop; /* 0xA0 */ + unsigned int vcrop; /* 0xA0 */ unsigned int hcrop; unsigned int fhi; - unsigned int colfmt2; /* 0xAC, 1-444,other refer 0x84 */ + unsigned int colfmt2; /* 0xAC, 1-444,other refer 0x84 */ unsigned int ysa2; /* 0xB0 */ unsigned int csa2; union { unsigned int val; struct { - unsigned int req_num:8; /* Y & RGB */ - unsigned int req_num_c:8; /* C */ - unsigned int frame_enable:1; + unsigned int req_num : 8; /* Y & RGB */ + unsigned int req_num_c : 8; /* C */ + unsigned int frame_enable : 1; } b; } mif_frame_mode; /* 0xB8 */ @@ -164,17 +164,17 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int update:1; - unsigned int reserved:7; - unsigned int level:1; /* 0:level 1, 1:level2 */ + unsigned int update : 1; + unsigned int reserved : 7; + unsigned int level : 1; /* 0:level 1, 1:level2 */ } b; } sts; /* 0xE4 */ union { unsigned int val; struct { - unsigned int fixed:1; /* 0-top, 1-bottom */ - unsigned int enable:1; + unsigned int fixed : 1; /* 0-top, 1-bottom */ + unsigned int enable : 1; } b; } swfld; /* 0xE8 */ @@ -183,9 +183,9 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int enable:1; - unsigned int reserved:7; - unsigned int mode:1; /* 0-frame,1-field */ + unsigned int enable : 1; + unsigned int reserved : 7; + unsigned int mode : 1; /* 0-frame,1-field */ } b; } tg_enable; /* 0x100 */ @@ -203,9 +203,9 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int offset:12; - unsigned int reserved:4; - unsigned int field_invert:1; + unsigned int offset : 12; + unsigned int reserved : 4; + unsigned int field_invert : 1; } b; } vsync_offset; /* 0x130 */ @@ -214,13 +214,11 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int mode:3; /* 011-frame packing progressive - format,111-frame packing interlace format */ - unsigned int inv_filed_polar:1; - unsigned int blank_value:16; - unsigned int reserved:11; - unsigned int addr_sel:1; /* in frame packing - interlace mode */ + unsigned int mode : 3; /* 011-frame packing progressive format,111-frame packing interlace format */ + unsigned int inv_filed_polar : 1; + unsigned int blank_value : 16; + unsigned int reserved : 11; + unsigned int addr_sel : 1; /* in frame packing interlace mode */ } b; } hdmi_3d; /* 0x13C */ @@ -228,16 +226,14 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int outwidth:1; /* 0-24bit,1-12bit */ - unsigned int hsync_polar:1; /* 0-act high,1-act low */ - unsigned int enable:1; - unsigned int vsync_polar:1; /* 0-act high,1-act low */ - unsigned int reserved:4; - unsigned int rgb_swap:2; /* 0-RGB[7:0],1-RGB[0:7], - 2-BGR[7:0],3-BGR[0:7] */ - unsigned int reserved2:6; - unsigned int blk_dis:1; /* 0-Blank Data, - 1-Embeded sync CCIR656 */ + unsigned int outwidth : 1; /* 0-24bit,1-12bit */ + unsigned int hsync_polar : 1; /* 0-active high,1-active low */ + unsigned int enable : 1; + unsigned int vsync_polar : 1; /* 0-active high,1-active low */ + unsigned int reserved : 4; + unsigned int rgb_swap : 2; /* 0-RGB[7:0],1-RGB[0:7],2-BGR[7:0],3-BGR[0:7] */ + unsigned int reserved2 : 6; + unsigned int blk_dis : 1; /* 0-Blank Data,1-Embeded sync CCIR656 */ } b; } dvo_set; /* 0x148 */ @@ -245,11 +241,11 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int enable:1; - unsigned int reserved1:7; - unsigned int mode:1; - unsigned int reserved2:7; - unsigned int inversion:1; + unsigned int enable : 1; + unsigned int reserved1 : 7; + unsigned int mode : 1; + unsigned int reserved2 : 7; + unsigned int inversion : 1; } b; } cb_enable; /* 0x150 */ @@ -267,17 +263,17 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int outwidth:1; /* 0-24bit,1-12bit */ - unsigned int hsync_polar:1; /* 0-act high,1-act low */ - unsigned int enable:1; - unsigned int vsync_polar:1; /* 0-act high,1-act low */ + unsigned int outwidth : 1; /* 0-24bit,1-12bit */ + unsigned int hsync_polar : 1; /* 0-active high,1-active low */ + unsigned int enable : 1; + unsigned int vsync_polar : 1; /* 0-active high,1-active low */ } b; } lvds_ctrl; /* 0x180 */ union { unsigned int val; struct { - unsigned int pix:2; /* 0-YUV444,1-RGB,2-YUV422,3-RGB */ + unsigned int pix : 2; /* 0-YUV444,1-RGB,2-YUV422,3-RGB */ } b; } lvds_ctrl2; /* 0x184 */ @@ -286,9 +282,9 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int praf:8; - unsigned int pbaf:8; - unsigned int yaf:8; + unsigned int praf : 8; + unsigned int pbaf : 8; + unsigned int yaf : 8; } b; } contrast; /* 0x1B8 */ @@ -304,45 +300,45 @@ struct govrh_regs { union { unsigned int val; struct { - unsigned int mode:1; /* 1: YUV2RGB, 0: RGB2YUV */ - unsigned int clamp:1; /* 0:Y,1:Y-16 */ + unsigned int mode : 1; /* 1: YUV2RGB, 0: RGB2YUV */ + unsigned int clamp : 1; /* 0:Y,1:Y-16 */ } b; } csc_mode; /* 0x1E0 */ union { unsigned int val; struct { - unsigned int dvo:1; - unsigned int vga:1; - unsigned int reserved1:1; - unsigned int dac_clkinv:1; - unsigned int blank_zero:1; - unsigned int disp:1; - unsigned int lvds:1; - unsigned int hdmi:1; - unsigned int rgb_mode:2; /*0-YUV,1-RGB24,2-1555,3-565*/ + unsigned int dvo : 1; + unsigned int vga : 1; + unsigned int reserved1 : 1; + unsigned int dac_clkinv : 1; + unsigned int blank_zero : 1; + unsigned int disp : 1; + unsigned int lvds : 1; + unsigned int hdmi : 1; + unsigned int rgb_mode : 2; /* 0-YUV, 1-RGB24, 2-1555, 3-565 */ } b; } yuv2rgb; /* 0x1E4 */ unsigned int h264_input_en; /* 0x1E8 */ unsigned int reserved9; - unsigned int lvds_clkinv; /* 0x1F0 */ + unsigned int lvds_clkinv; /* 0x1F0 */ unsigned int hscale_up; /* 0x1F4 */ union { unsigned int val; struct { - unsigned int mode:3; /* 0:888,1:555,2:666,3:565,4:ori */ - unsigned int reserved:5; - unsigned int ldi:1; /* 0:shift right,1:shift left */ + unsigned int mode : 3; /* 0:888,1:555,2:666,3:565,4:original */ + unsigned int reserved : 5; + unsigned int ldi : 1; /* 0:shift right,1:shift left */ } b; } igs_mode; /* 0x1F8 */ union { unsigned int val; struct { - unsigned int mode:3; /* 0:888,1:555,2:666,3:565,4:ori */ - unsigned int reserved:5; - unsigned int ldi:1; /* 0:shift right,1:shift left */ + unsigned int mode : 3; /* 0:888,1:555,2:666,3:565,4:original */ + unsigned int reserved : 5; + unsigned int ldi : 1; /* 0:shift right,1:shift left */ } b; } igs_mode2; /* 0x1FC */ }; diff --git a/drivers/video/wmt/hw/wmt-hdmi-reg.h b/drivers/video/wmt/hw/wmt-hdmi-reg.h index c0650555..919d6ab3 100755..100644 --- a/drivers/video/wmt/hw/wmt-hdmi-reg.h +++ b/drivers/video/wmt/hw/wmt-hdmi-reg.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/hw/wmt-hdmi-reg.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -26,354 +26,241 @@ #define WMT_FTBLK_HDMI -#define HDMI_BASE_ADDR (HDMI_TRANSMITTE_BASE_ADDR + 0xC000) - -struct hdmi_base1_regs { - unsigned int _100_11c[8]; - - union { - unsigned int val; - struct { - unsigned int eeprom_reset:1; - unsigned int encode_enable:1; - unsigned int hden:1; - unsigned int eess_enable:1; - unsigned int verify_pj_enable:1; - unsigned int i2c_enable:1; - unsigned int auth_test_key:1; - unsigned int _7:1; - unsigned int cipher_1_1:1; - unsigned int _9_11:3; - unsigned int preamble:4; - unsigned int _16_19:4; - unsigned int encode_window:3; - } b; - } ctrl; /* 0x120 */ - - union { - unsigned int val; - struct { - unsigned int _0_6:7; - unsigned int force_exit_fsm:1; - unsigned int key_read_word:7; - unsigned int i2c_sw_reset:1; - unsigned int i2c_clk_divider:16; - } b; - } i2c_ctrl; /* 0x124 */ - - union { - unsigned int val; - struct { - unsigned int wr_data:8; - unsigned int rd_data:8; - unsigned int sw_start_req:1; - unsigned int sw_stop_req:1; - unsigned int wr_data_avail:1; - unsigned int i2c_status:1; /* 0-not using,1-in using */ - unsigned int cp_key_req:1; - unsigned int cp_key_read:1; - unsigned int cp_key_last:1; - unsigned int _23:1; - unsigned int cp_src_sel:1; - unsigned int sw_read:1; - unsigned int sw_i2c_req:1; - unsigned int ksv_list_avail:1; - unsigned int ksv_verify_done:1; - } b; - } i2c_ctrl2; /* 0x128 */ - - unsigned int _12c_27c[85]; - - union { - unsigned int val; - struct { - unsigned int reset:1; - unsigned int enable:1; - unsigned int _2_5:4; - unsigned int dvi_mode_enable:1; - unsigned int output_format:2; /* 0-RGB, - 1-YUV444,2-YUV422 */ - unsigned int convert_yuv422:1; - unsigned int hsync_low_active:1; /* 0-active hi,1-lo */ - unsigned int dbg_bus_select:1; /* 0-before,1-after */ - unsigned int _12:1; - unsigned int vsync_low_active:1; /* 0-active hi,1-lo */ - unsigned int _14_15:2; - unsigned int cp_delay:7; - unsigned int _23:1; - unsigned int vsync_enable:3; /* write only */ - unsigned int state_machine_status:5; - } b; - } general_ctrl; /* 0x280 */ - - union { - unsigned int val; - struct { - unsigned int select:1; /* 0-fifo1,1-fifo2 */ - unsigned int fifo1_rdy:1; /* Info frame FIFO 1 ready */ - unsigned int fifo2_rdy:1; /* Info frame FIFO 2 ready */ - unsigned int _3:1; - unsigned int fifo1_addr:4; /* FIFO 1 start address */ - unsigned int fifo1_len:5; /* FIFO 1 length */ - unsigned int _13_15:3; - unsigned int fifo2_addr:4; /* FIFO 2 start address */ - unsigned int fifo2_len:5; /* FIFO 2 length */ - unsigned int _25_27:3; - unsigned int horiz_blank_max_pck:3; /* Max packets - that insert during HSYNC */ - } b; - } infoframe_ctrl; /* 0x284 */ - unsigned int _288_290[3]; - - union { - unsigned int val; - struct { - unsigned int pck_insert_reset:1; - unsigned int pck_insert_enable:1; - unsigned int avmute_set_enable:1; - unsigned int avmute_clr_enable:1; - unsigned int insert_delay:12; - unsigned int _16_29:14; - unsigned int pixel_repetition:2; /* 0-none,1-2x,2-4x */ - } b; - } aud_insert_ctrl; /* 0x294 */ - - unsigned int _298; - - union { - unsigned int val; - struct { - unsigned int _0_7:8; - unsigned int acr_ratio:20; - unsigned int acr_enable:1; - unsigned int mute:1; - } b; - } aud_ratio; /* 0x29c */ - - unsigned int aud_enable; /* 0x2a0 */ - unsigned int _2a4_2a8[2]; - - union { - unsigned int val; - struct { - unsigned int sub_packet:4; - unsigned int spflat:4; - unsigned int _2ch_eco:1; - unsigned int _9:1; - unsigned int layout:1; /* 0-2 channel,1-8 channel */ - unsigned int pwr_saving:1; /* 0-normal,1-power saving */ - } b; - } aud_mode; /* 0x2ac */ - - unsigned int _2b0_38c[56]; - unsigned int aud_chan_status0; /* 0x390 */ - unsigned int aud_chan_status1; /* 0x394 */ - unsigned int aud_chan_status2; /* 0x398 */ - unsigned int aud_chan_status3; /* 0x39c */ - unsigned int aud_chan_status4; /* 0x3a0 */ - unsigned int aud_chan_status5; /* 0x3a4 */ - - union { - unsigned int val; - struct { - unsigned int n_20bits:20; - unsigned int cts_low_12bits:12; - } b; - } aud_sample_rate1; /* 0x3a8 */ - - union { - unsigned int val; - struct { - unsigned int cts_hi_8bits:8; - unsigned int _8_27:20; - unsigned int aipclk_rate:2; /* 0-N/2,1-N,2-N/4,3-N*2 */ - unsigned int cts_select:1; /* 0-auto,1-fixed from reg */ - } b; - } aud_sample_rate2; /* 0x3ac */ - - unsigned int _3b0_3bc[4]; - unsigned int wr_fifo_addr[9]; /* 0x3c0 - 0x3e0 */ - - union { - unsigned int val; - struct { - unsigned int wr_strobe:1; - unsigned int rd_strobe:1; - unsigned int _2_7:6; - unsigned int addr:8; - } b; - } fifo_ctrl; /* 0x3e4 */ - - union { - unsigned int val; - struct { - unsigned int ch0_data:10; - unsigned int ch0_enable:1; - unsigned int _11_15:5; - unsigned int ch1_data:10; - unsigned int ch1_enable:1; - } b; - } channel_test; /* 0x3e8 */ - - union { - unsigned int val; - struct { - unsigned int ch2_data:10; - unsigned int ch2_enable:1; - unsigned int _11_15:5; - unsigned int in_enable:1; - unsigned int out_enable:1; - unsigned int _18_23:6; - unsigned int in_sts:1; - unsigned int out_sts:1; - unsigned int _26_30:5; - unsigned int sts:1; /* 0-plug out,1-plug in */ - } b; - } hotplug_detect; /* 0x3ec */ - - union { - unsigned int val; - struct { - unsigned int sample:8; - unsigned int _8_15:8; - unsigned int detect:9; - } b; - } hotplug_debounce; /* 0x3f0 */ - - unsigned int _3f4; - - union { - unsigned int val; - struct { - unsigned int test_enable:1; - unsigned int test_format:1; - unsigned int _2_9:8; - unsigned int infoframe_sram_enable:1; - unsigned int _11_15:5; - unsigned int clock_select:1; /* 0-clk 1x, 1-clk 2x */ - } b; - } tmds_ctrl; /* 0x3f8 */ - - unsigned int _3fc; - unsigned int rd_fifo_addr[9]; /* 0x400 - 0x420 */ -}; - -struct hdmi_base2_regs { - union { - unsigned int val; - struct { - unsigned int inv_clk:1; - unsigned int _1_3:3; - unsigned int dual_channel:1; - unsigned int _5_7:3; - unsigned int test:4; - unsigned int _12_18:7; - unsigned int internal_ldo:1; - } b; - } status; /* 0x00 */ - - union { - unsigned int val; - struct { - unsigned int drv_pdmode:1; - unsigned int _1:1; - unsigned int vbg_sel:2; - unsigned int _4_7:4; - unsigned int pd:1; - unsigned int tre_en:2; - unsigned int _11:1; - unsigned int pllck_dly:3; - unsigned int _15:1; - unsigned int pll_cpset:2; - unsigned int pll_r_f:1; - } b; - } test; /* 0x04 */ - - union { - unsigned int val; - struct { - unsigned int update:1; - unsigned int _1_7:7; - unsigned int level:1; - } b; - } level; /* 0x08 */ - - union { - unsigned int val; - struct { - unsigned int bpp_type:3; /* 0-888,1-555,2-666,3-565 */ - unsigned int _3_7:5; - unsigned int ldi_shift_left:1; /* 0-right,1-left */ - } b; - } igs; /* 0x0c */ - - union { - unsigned int val; - struct { - unsigned int out_data_12:1; /* 0-24bit,1-12bit */ - unsigned int hsync_polar_lo:1; /* 0-act hi,1-act low */ - unsigned int dvo_enable:1; - unsigned int vsync_polar_lo:1; /* 0-act hi,1-act low */ - } b; - } set; /* 0x10 */ - - union { - unsigned int val; - struct { - unsigned int colfmt_rgb:1;/* 0-RGB or YUV444,1-YUV422 */ - unsigned int colfmt_yuv422:1; - } b; - } set2; /* 0x14 */ - - union { - unsigned int val; - struct { - unsigned int pll_ready:1; - unsigned int _1_7:7; - unsigned int rsen:1; - } b; - } detect; /* 0x18 */ - - union { - unsigned int val; - struct { - unsigned int pll_tsync:1; - unsigned int tp2s_type:1; - unsigned int div_sel:2; - unsigned int pd_v2i:1; - unsigned int vco_sx:1; - unsigned int vco_mode:1; - unsigned int _7:1; - unsigned int vsref_sel:2; - unsigned int mode:1; - unsigned int pd_l2ha:1; - unsigned int pd_l2hb:1; - unsigned int l2ha_hsen:1; - unsigned int resa_en:1; - unsigned int resa_s:1; - unsigned int pll_lpfs:2; - } b; - } test2; /* 0x1c */ - - unsigned int test3; /* 0x20 */ - - union { - unsigned int val; - struct { - unsigned int _0_15:16; - unsigned int reset_pll:1; - } b; - } dftset2; /* 0x24 */ -}; - -#define REG_HDMI_BEGIN (HDMI_BASE_ADDR + 0x100) -#define REG_HDMI_END (HDMI_BASE_ADDR + 0x420) -#define REG_HDMI2_BEGIN (HDMI_BASE2_ADDR + 0x00) -#define REG_HDMI2_END (HDMI_BASE2_ADDR + 0x28) - -#ifndef HDMI_C -extern HW_REG struct hdmi_base1_regs *hdmi_regs1; -extern HW_REG struct hdmi_base2_regs *hdmi_regs2; -#endif +#define HDMI_BASE_ADDR (HDMI_TRANSMITTE_BASE_ADDR + 0xC000) + +/* HDMI registers */ +#define REG_HDMI_BEGIN (HDMI_BASE_ADDR + 0x100) +#define REG_HDMI_CTRL (HDMI_BASE_ADDR + 0x120) +#define REG_HDMI_I2C_CTRL (HDMI_BASE_ADDR + 0x124) +#define REG_HDMI_I2C_CTRL2 (HDMI_BASE_ADDR + 0x128) +#define REG_HDMI_GENERAL_CTRL (HDMI_BASE_ADDR + 0x280) +#define REG_HDMI_INFOFRAME_CTRL (HDMI_BASE_ADDR + 0x284) +#define REG_HDMI_AUD_INSERT_CTRL (HDMI_BASE_ADDR + 0x294) +#define REG_HDMI_AUD_RATIO (HDMI_BASE_ADDR + 0x29c) +#define REG_HDMI_AUD_ENABLE (HDMI_BASE_ADDR + 0x2a0) +#define REG_HDMI_AUD_MODE (HDMI_BASE_ADDR + 0x2ac) +#define REG_HDMI_AUD_CHAN_STATUS0 (HDMI_BASE_ADDR + 0x390) +#define REG_HDMI_AUD_CHAN_STATUS1 (HDMI_BASE_ADDR + 0x394) +#define REG_HDMI_AUD_CHAN_STATUS2 (HDMI_BASE_ADDR + 0x398) +#define REG_HDMI_AUD_CHAN_STATUS3 (HDMI_BASE_ADDR + 0x39c) +#define REG_HDMI_AUD_CHAN_STATUS4 (HDMI_BASE_ADDR + 0x3a0) +#define REG_HDMI_AUD_CHAN_STATUS5 (HDMI_BASE_ADDR + 0x3a4) +#define REG_HDMI_AUD_SAMPLE_RATE1 (HDMI_BASE_ADDR + 0x3a8) +#define REG_HDMI_AUD_SAMPLE_RATE2 (HDMI_BASE_ADDR + 0x3ac) + +/* HDMI info WR FIFO 0x3c0 - 0x3e0 */ +#define REG_HDMI_WR_FIFO_ADDR (HDMI_BASE_ADDR + 0x3c0) +#define REG_HDMI_FIFO_CTRL (HDMI_BASE_ADDR + 0x3e4) +#define REG_HDMI_CHANNEL_TEST (HDMI_BASE_ADDR + 0x3e8) +#define REG_HDMI_HOTPLUG_DETECT (HDMI_BASE_ADDR + 0x3ec) +#define REG_HDMI_HOTPLUG_DEBOUNCE (HDMI_BASE_ADDR + 0x3f0) +#define REG_HDMI_TMDS_CTRL (HDMI_BASE_ADDR + 0x3f8) + +/* HDMI info RD FIFO 0x400 - 0x420 */ +#define REG_HDMI_RD_FIFO_ADDR (HDMI_BASE_ADDR + 0x400) + +#define REG_HDMI_END (HDMI_BASE_ADDR + 0x420) + +/* REG_HDMI_CTRL,0x120 */ +#define HDMI_EEPROM_RESET REG_HDMI_CTRL, BIT0, 0 +#define HDMI_ENCODE_ENABLE REG_HDMI_CTRL, BIT1, 1 +#define HDMI_HDEN REG_HDMI_CTRL, BIT2, 2 +#define HDMI_EESS_ENABLE REG_HDMI_CTRL, BIT3, 3 +#define HDMI_VERIFY_PJ_ENABLE REG_HDMI_CTRL, BIT4, 4 +#define HDMI_I2C_ENABLE REG_HDMI_CTRL, BIT5, 5 +#define HDMI_AUTH_TEST_KEY REG_HDMI_CTRL, BIT6, 6 +#define HDMI_CIPHER_1_1 REG_HDMI_CTRL, BIT8, 8 +#define HDMI_PREAMBLE REG_HDMI_CTRL, 0xF000, 12 +#define HDMI_ENCODE_WINDOW REG_HDMI_CTRL, 0x700000, 20 + +/* REG_HDMI_I2C_CTRL,0x124 */ +#define HDMI_FORCE_EXIT_FSM REG_HDMI_I2C_CTRL, BIT7, 7 +#define HDMI_KEY_READ_WORD REG_HDMI_I2C_CTRL, 0xFF00, 8 +#define HDMI_I2C_SW_RESET REG_HDMI_I2C_CTRL, 0x8000, 15 +#define HDMI_I2C_CLK_DIVIDER REG_HDMI_I2C_CTRL, 0xFFFF0000, 16 + +/* REG_HDMI_I2C_CTRL2,0x128 */ +#define HDMI_WR_DATA REG_HDMI_I2C_CTRL2, 0xFF, 0 +#define HDMI_RD_DATA REG_HDMI_I2C_CTRL2, 0xFF00, 8 +#define HDMI_SW_START_REQ REG_HDMI_I2C_CTRL2, BIT16, 16 +#define HDMI_SW_STOP_REQ REG_HDMI_I2C_CTRL2, BIT17, 17 +#define HDMI_WR_DATA_AVAIL REG_HDMI_I2C_CTRL2, BIT18, 18 +#define HDMI_I2C_STATUS REG_HDMI_I2C_CTRL2, BIT19, 19 /* 0-not using, 1-in using */ +#define HDMI_CP_KEY_REQ REG_HDMI_I2C_CTRL2, BIT20, 20 +#define HDMI_CP_KEY_READ REG_HDMI_I2C_CTRL2, BIT21, 21 +#define HDMI_CP_KEY_LAST REG_HDMI_I2C_CTRL2, BIT22, 22 +#define HDMI_CP_SRC_SEL REG_HDMI_I2C_CTRL2, BIT24, 24 +#define HDMI_SW_READ REG_HDMI_I2C_CTRL2, BIT25, 25 +#define HDMI_SW_I2C_REQ REG_HDMI_I2C_CTRL2, BIT26, 26 +#define HDMI_KSV_LIST_AVAIL REG_HDMI_I2C_CTRL2, BIT27, 27 +#define HDMI_KSV_VERIFY_DONE REG_HDMI_I2C_CTRL2, BIT28, 28 + +/* REG_HDMI_GENERAL_CTRL,0x280 */ +#define HDMI_RESET REG_HDMI_GENERAL_CTRL, BIT0, 0 +#define HDMI_ENABLE REG_HDMI_GENERAL_CTRL, BIT1, 1 +#define HDMI_DVI_MODE_ENABLE REG_HDMI_GENERAL_CTRL, BIT6, 6 +#define HDMI_OUTPUT_FORMAT REG_HDMI_GENERAL_CTRL, 0x180, 7 /* 0-RGB,1-YUV444,2-YUV422 */ +#define HDMI_CONVERT_YUV422 REG_HDMI_GENERAL_CTRL, BIT9, 9 +#define HDMI_HSYNC_LOW_ACTIVE REG_HDMI_GENERAL_CTRL, BIT10, 10 /* 0-active high,1-active low */ +#define HDMI_DBG_BUS_SELECT REG_HDMI_GENERAL_CTRL, BIT11, 11 /* 0-before,1-after */ +#define HDMI_VSYNC_LOW_ACTIVE REG_HDMI_GENERAL_CTRL, BIT13, 13 /* 0-active high,1-active low */ +#define HDMI_CP_DELAY REG_HDMI_GENERAL_CTRL, 0x7F0000, 16 /* delay for CP after HSYNC raising edge */ +#define HDMI_VSYNC_384_ENABLE REG_HDMI_GENERAL_CTRL, BIT24, 24 +#define HDMI_VSYNC_385_507_ENABLE REG_HDMI_GENERAL_CTRL, BIT25, 25 +#define HDMI_VSYNC_650_ENABLE REG_HDMI_GENERAL_CTRL, BIT26, 26 +#define HDMI_STATE_MACHINE_STATUS REG_HDMI_GENERAL_CTRL, 0xF8000000, 27 + +/* REG_HDMI_INFOFRAME_CTRL,0x284 */ +#define HDMI_INFOFRAME_SELECT REG_HDMI_INFOFRAME_CTRL, BIT0, 0 /* 0-fifo1,1-fifo2 */ +#define HDMI_INFOFRAME_FIFO1_RDY REG_HDMI_INFOFRAME_CTRL, BIT1, 1 /* Info frame FIFO 1 ready */ +#define HDMI_INFOFRAME_FIFO2_RDY REG_HDMI_INFOFRAME_CTRL, BIT2, 2 /* Info frame FIFO 2 ready */ +#define HDMI_INFOFRAME_FIFO1_ADDR REG_HDMI_INFOFRAME_CTRL, 0xF0, 4 /* Info frame FIFO 1 start address */ +#define HDMI_INFOFRAME_FIFO1_LEN REG_HDMI_INFOFRAME_CTRL, 0x1F00, 8 /* Info frame FIFO 1 length */ +#define HDMI_INFOFRAME_FIFO2_ADDR REG_HDMI_INFOFRAME_CTRL, 0xF0000, 16 /* Info frame FIFO 2 start address */ +#define HDMI_INFOFRAME_FIFO2_LEN REG_HDMI_INFOFRAME_CTRL, 0x1F00000, 20 /* Info frame FIFO 2 length */ +#define HDMI_HORIZ_BLANK_MAX_PCK REG_HDMI_INFOFRAME_CTRL, 0x70000000, 28 /* Max packets that insert during HSYNC */ + +/* REG_HDMI_AUD_INSERT_CTRL,0x294 */ +#define HDMI_AUD_PCK_INSERT_RESET REG_HDMI_AUD_INSERT_CTRL, BIT0, 0 +#define HDMI_AUD_PCK_INSERT_ENABLE REG_HDMI_AUD_INSERT_CTRL, BIT1, 1 +#define HDMI_AVMUTE_SET_ENABLE REG_HDMI_AUD_INSERT_CTRL, BIT2, 2 +#define HDMI_AVMUTE_CLR_ENABLE REG_HDMI_AUD_INSERT_CTRL, BIT3, 3 +#define HDMI_AUD_INSERT_DELAY REG_HDMI_AUD_INSERT_CTRL, 0xFFF0, 4 +#define HDMI_AUD_PIXEL_REPETITION REG_HDMI_AUD_INSERT_CTRL, 0xC0000000, 30 /* 0-none,1-2 times,2-4 times */ + +/* REG_HDMI_AUD_RATIO,0x29c */ +#define HDMI_AUD_ACR_RATIO REG_HDMI_AUD_RATIO, 0x0FFFFF00, 8 +#define HDMI_AUD_ACR_ENABLE REG_HDMI_AUD_RATIO, BIT28, 28 +#define HDMI_AUD_MUTE REG_HDMI_AUD_RATIO, BIT29, 29 + +/* REG_HDMI_AUD_ENABLE,0x2a0 */ +#define HDMI_AUD_ENABLE REG_HDMI_AUD_ENABLE, BIT0, 0 + +/* REG_HDMI_AUD_MODE,0x2ac */ +#define HDMI_AUD_SUB_PACKET REG_HDMI_AUD_MODE, 0xF, 0 +#define HDMI_AUD_SPFLAT REG_HDMI_AUD_MODE, 0xF0, 4 +#define HDMI_AUD_2CH_ECO REG_HDMI_AUD_MODE, BIT8, 8 +#define HDMI_AUD_LAYOUT REG_HDMI_AUD_MODE, BIT10, 10 /* 0-2 channel,1-8 channel */ +#define HDMI_AUD_PWR_SAVING REG_HDMI_AUD_MODE, BIT11, 11 /* 0-normal, 1-power saving */ + +/* REG_HDMI_AUD_CHAN_STATUS0,0x390 */ +/* REG_HDMI_AUD_CHAN_STATUS1,0x394 */ +/* REG_HDMI_AUD_CHAN_STATUS2,0x398 */ +/* REG_HDMI_AUD_CHAN_STATUS3,0x39c */ +/* REG_HDMI_AUD_CHAN_STATUS4,0x3a0 */ +/* REG_HDMI_AUD_CHAN_STATUS5,0x3a4 */ + +/* REG_HDMI_AUD_SAMPLE_RATE1,0x3a8 */ +#define HDMI_AUD_N_20BITS REG_HDMI_AUD_SAMPLE_RATE1, 0xFFFFF, 0 +#define HDMI_AUD_CTS_LOW_12BITS REG_HDMI_AUD_SAMPLE_RATE1, 0xFFF00000, 20 + +/* REG_HDMI_AUD_SAMPLE_RATE2,0x3ac */ +#define HDMI_AUD_CTS_HI_8BITS REG_HDMI_AUD_SAMPLE_RATE2, 0xFF, 0 +#define HDMI_AUD_AIPCLK_RATE REG_HDMI_AUD_SAMPLE_RATE2, 0x30000000, 28 /* 0-N/2,1-N,2-N/4,3-N*2 */ +#define HDMI_AUD_CTS_SELECT REG_HDMI_AUD_SAMPLE_RATE2, BIT30, 30 /* 0-auto, 1-fixed from register */ + +/* 0x3c0 - 0x3e0 : Info frame FIFO data */ + +/* REG_HDMI_FIFO_CTRL,0x3e4 */ +#define HDMI_INFOFRAME_WR_STROBE REG_HDMI_FIFO_CTRL, BIT0, 0 +#define HDMI_INFOFRAME_RD_STROBE REG_HDMI_FIFO_CTRL, BIT1, 1 +#define HDMI_INFOFRAME_FIFO_ADDR REG_HDMI_FIFO_CTRL, 0xFF00, 8 + +/* REG_HDMI_CHANNEL_TEST,0x3e8 */ +#define HDMI_CH1_TEST_MODE_ENABLE REG_HDMI_CHANNEL_TEST, BIT26, 26 +#define HDMI_CH1_TEST_DATA REG_HDMI_CHANNEL_TEST, 0x3FF0000, 16 +#define HDMI_CH0_TEST_MODE_ENABLE REG_HDMI_CHANNEL_TEST, BIT10, 10 +#define HDMI_CH0_TEST_DATA REG_HDMI_CHANNEL_TEST, 0x3FF, 0 + +/* REG_HDMI_HOTPLUG_DETECT,0x3ec */ +#define HDMI_HOTPLUG_IN REG_HDMI_HOTPLUG_DETECT, BIT31, 31 /* 0-plug out,1-plug in */ +#define HDMI_HOTPLUG_OUT_STS REG_HDMI_HOTPLUG_DETECT, BIT25, 25 +#define HDMI_HOTPLUG_IN_STS REG_HDMI_HOTPLUG_DETECT, BIT24, 24 +#define HDMI_HOTPLUG_OUT_INT REG_HDMI_HOTPLUG_DETECT, BIT17, 17 +#define HDMI_HOTPLUG_IN_INT REG_HDMI_HOTPLUG_DETECT, BIT16, 16 +#define HDMI_CH2_TEST_MODE_ENABLE REG_HDMI_HOTPLUG_DETECT, BIT10, 10 +#define HDMI_CH2_TEST_DATA REG_HDMI_HOTPLUG_DETECT, 0x3FF, 0 + +/* REG_HDMI_HOTPLUG_DEBOUNCE,0x3f0 */ +#define HDMI_DEBOUNCE_DETECT REG_HDMI_HOTPLUG_DEBOUNCE, 0x1FF0000, 16 +#define HDMI_DEBOUNCE_SAMPLE REG_HDMI_HOTPLUG_DEBOUNCE, 0xFF, 0 + +/* REG_HDMI_TMDS_CTRL,0x3f8 */ +#define HDMI_CLOCK_SELECT REG_HDMI_TMDS_CTRL, BIT16, 16 /* 0-clk 1x, 1-clk 2x */ +#define HDMI_INFOFRAME_SRAM_ENABLE REG_HDMI_TMDS_CTRL, BIT10, 10 +#define HDMI_TMDS_TST_FORMAT REG_HDMI_TMDS_CTRL, BIT1, 1 +#define HDMI_TMDS_TST_ENABLE REG_HDMI_TMDS_CTRL, BIT0, 0 + +/* 0x400 - 0x420 : HDMI info frame FIFO data (RO) */ + +#define REG_HDMI2_BEGIN (HDMI_BASE2_ADDR + 0x00) +#define REG_HDMI_STATUS (HDMI_BASE2_ADDR + 0x00) +#define REG_HDMI_TEST (HDMI_BASE2_ADDR + 0x04) +#define REG_HDMI_LEVEL (HDMI_BASE2_ADDR + 0x08) +#define REG_HDMI_IGS (HDMI_BASE2_ADDR + 0x0C) +#define REG_HDMI_SET (HDMI_BASE2_ADDR + 0x10) +#define REG_HDMI_SET2 (HDMI_BASE2_ADDR + 0x14) +#define REG_HDMI_DETECT (HDMI_BASE2_ADDR + 0x18) +#define REG_HDMI_TEST2 (HDMI_BASE2_ADDR + 0x1C) +#define REG_HDMI_TEST3 (HDMI_BASE2_ADDR + 0x20) +#define REG_HDMI_DFTSET2 (HDMI_BASE2_ADDR + 0x24) +#define REG_HDMI2_END (HDMI_BASE2_ADDR + 0x28) + +/* REG_HDMI_STATUS,0x00 */ +#define HDMI_INTERNAL_LDO REG_HDMI_STATUS, 0x80000, 19 +#define HDMI_TEST REG_HDMI_STATUS, 0xF00, 8 +#define HDMI_DUAL_CHANNEL REG_HDMI_STATUS, BIT4, 4 +#define HDMI_INV_CLK REG_HDMI_STATUS, BIT0, 0 + +/* REG_HDMI_TEST,0x04 */ +#define HDMI_PLL_R_F REG_HDMI_TEST, BIT18, 18 +#define HDMI_PLL_CPSET REG_HDMI_TEST, 0x30000, 16 +#define HDMI_PLLCK_DLY REG_HDMI_TEST, 0x7000, 12 +#define HDMI_TRE_EN REG_HDMI_TEST, 0x600, 9 +#define HDMI_PD REG_HDMI_TEST, BIT8, 8 +#define HDMI_VBG_SEL REG_HDMI_TEST, 0xC, 2 +#define HDMI_DRV_PDMODE REG_HDMI_TEST, BIT0, 0 + +/* REG_HDMI_LEVEL,0x08 */ +#define HDMI_REG_LEVEL REG_HDMI_LEVEL, BIT8, 8 +#define HDMI_REG_UPDATE REG_HDMI_LEVEL, BIT0, 0 + +/* REG_HDMI_IGS,0x0C */ +#define HDMI_LDI_SHIFT_LEFT REG_HDMI_IGS, BIT8, 8 /* 0-shift right,1-shift left */ +#define HDMI_IGS_BPP_TYPE REG_HDMI_IGS, 0x7, 0 /* 0-888,1-555,2-666,3-565 */ + +/* REG_HDMI_SET,0x10 */ +#define HDMI_VSYNC_POLAR_LO REG_HDMI_SET, BIT3, 3 /* 0-active high,1-active low */ +#define HDMI_DVO_ENABLE REG_HDMI_SET, BIT2, 2 +#define HDMI_HSYNC_POLAR_LO REG_HDMI_SET, BIT1, 1 /* 0-active high,1-active low */ +#define HDMI_OUT_DATA_12 REG_HDMI_SET, BIT0, 0 /* 0-24bit,1-12bit */ + +/* REG_HDMI_SET2,0x14 */ +#define HDMI_COLFMT_YUV422 REG_HDMI_SET2, BIT1, 1 /* 0-RGB or YUV444,1-YUV422 */ +#define HDMI_COLFMT_RGB REG_HDMI_SET2, BIT0, 0 + +/* REG_HDMI_DETECT,0x18 */ +#define HDMI_RSEN REG_HDMI_DETECT, BIT8, 8 +#define HDMI_PLL_READY REG_HDMI_DETECT, BIT0, 0 + +/* REG_HDMI_TEST2,0x1C */ +#define HDMI_PLL_TSYNC REG_HDMI_TEST2, BIT0, 0 +#define HDMI_TP2S_TYPE REG_HDMI_TEST2, BIT1, 1 +#define HDMI_DIV_SEL REG_HDMI_TEST2, 0xC, 2 +#define HDMI_PD_V2I REG_HDMI_TEST2, BIT4, 4 +#define HDMI_VCO_SX REG_HDMI_TEST2, BIT5, 5 +#define HDMI_VCO_MODE REG_HDMI_TEST2, BIT6, 6 +#define HDMI_VSREF_SEL REG_HDMI_TEST2, 0x300, 8 +#define HDMI_MODE REG_HDMI_TEST2, BIT10, 10 +#define HDMI_PD_L2HA REG_HDMI_TEST2, BIT11, 11 +#define HDMI_PD_L2HB REG_HDMI_TEST2, BIT12, 12 +#define HDMI_L2HA_HSEN REG_HDMI_TEST2, BIT13, 13 +#define HDMI_RESA_EN REG_HDMI_TEST2, BIT14, 14 +#define HDMI_RESA_S REG_HDMI_TEST2, BIT15, 15 +#define HDMI_PLL_LPFS REG_HDMI_TEST2, 0x30000, 16 + +/* REG_HDMI_DFTSET2,0x24 */ +#define HDMI_RESET_PLL REG_HDMI_DFTSET2, BIT16, 16 + #endif /* WMT_HDMI_REG_H */ diff --git a/drivers/video/wmt/hw/wmt-lvds-reg.h b/drivers/video/wmt/hw/wmt-lvds-reg.h index 0a6e616c..d258d6e8 100755..100644 --- a/drivers/video/wmt/hw/wmt-lvds-reg.h +++ b/drivers/video/wmt/hw/wmt-lvds-reg.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/hw/wmt-lvds-reg.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -26,104 +26,67 @@ #define WMT_FTBLK_LVDS -struct lvds_base_regs { - union { - unsigned int val; - struct { - unsigned int inv_clk:1; - unsigned int _01_03:3; - unsigned int dual_channel:1; - unsigned int _05_07:3; - unsigned int test:4; - } b; - } status; /* 0x00 */ +#define REG_LVDS_BEGIN (LVDS_BASE_ADDR + 0x00) +#define REG_LVDS_STATUS (LVDS_BASE_ADDR + 0x00) +#define REG_LVDS_TEST (LVDS_BASE_ADDR + 0x04) +#define REG_LVDS_LEVEL (LVDS_BASE_ADDR + 0x08) +#define REG_LVDS_IGS (LVDS_BASE_ADDR + 0x0C) +#define REG_LVDS_SET (LVDS_BASE_ADDR + 0x10) +#define REG_LVDS_SET2 (LVDS_BASE_ADDR + 0x14) +#define REG_LVDS_DETECT (LVDS_BASE_ADDR + 0x18) +#define REG_LVDS_TEST2 (LVDS_BASE_ADDR + 0x1C) +#define REG_LVDS_END (LVDS_BASE_ADDR + 0x1C) - union { - unsigned int val; - struct { - unsigned int drv_pdmode:1; - unsigned int _01:1; - unsigned int vbg_sel:2; - unsigned int _04_07:4; - unsigned int pd:1; - unsigned int tre_en:2; - unsigned int _11:1; - unsigned int pllck_dly:3; - unsigned int _15:1; - unsigned int pll_cpset:2; - unsigned int pll_r_f:1; - } b; - } test; /* 0x04 */ +/* REG_LVDS_STATUS,0x00 */ +#define LVDS_TEST REG_LVDS_STATUS, 0xF00, 8 +#define LVDS_DUAL_CHANNEL REG_LVDS_STATUS, BIT4, 4 +#define LVDS_INV_CLK REG_LVDS_STATUS, BIT0, 0 - union { - unsigned int val; - struct { - unsigned int update:1; - unsigned int _01_07:7; - unsigned int level:1; - } b; - } level; /* 0x08 */ +/* REG_LVDS_TEST,0x04 */ +#define LVDS_PLL_R_F REG_LVDS_TEST, BIT18, 18 +#define LVDS_PLL_CPSET REG_LVDS_TEST, 0x30000, 16 +#define LVDS_PLLCK_DLY REG_LVDS_TEST, 0x7000, 12 +#define LVDS_TRE_EN REG_LVDS_TEST, 0x600, 9 +#define LVDS_PD REG_LVDS_TEST, BIT8, 8 +#define LVDS_VBG_SEL REG_LVDS_TEST, 0xC, 2 +#define LVDS_DRV_PDMODE REG_LVDS_TEST, BIT0, 0 - union { - unsigned int val; - struct { - unsigned int bpp_type:3; /* 0-888,1-555,2-666,3-565 */ - unsigned int _03_07:5; - unsigned int ldi_shift_left:1; /* 0-shift right,1-left*/ - } b; - } igs; /* 0x0c */ +/* REG_LVDS_LEVEL,0x08 */ +#define LVDS_REG_LEVEL REG_LVDS_LEVEL, BIT8, 8 +#define LVDS_REG_UPDATE REG_LVDS_LEVEL, BIT0, 0 - union { - unsigned int val; - struct { - unsigned int out_data_12:1; /* 0-24bit,1-12bit */ - unsigned int hsync_polar_lo:1; /* 0-active hi,1-low */ - unsigned int dvo_enable:1; - unsigned int vsync_polar_lo:1; /* 0-active hi,1-low */ - } b; - } set; /* 0x10 */ +/* REG_LVDS_IGS,0x0C */ +#define LVDS_LDI_SHIFT_LEFT REG_LVDS_IGS, BIT8, 8 /* 0-shift right,1-shift left */ +#define LVDS_IGS_BPP_TYPE REG_LVDS_IGS, 0x7, 0 /* 0-888,1-555,2-666,3-565 */ - union { - unsigned int val; - struct { - unsigned int colfmt:2; /* 0-YUV444,1/3-RGB,2-YUV422 */ - } b; - } set2; /* 0x14 */ +/* REG_LVDS_SET,0x10 */ +#define LVDS_VSYNC_POLAR_LO REG_LVDS_SET, BIT3, 3 /* 0-active high,1-active low */ +#define LVDS_DVO_ENABLE REG_LVDS_SET, BIT2, 2 +#define LVDS_HSYNC_POLAR_LO REG_LVDS_SET, BIT1, 1 /* 0-active high,1-active low */ +#define LVDS_OUT_DATA_12 REG_LVDS_SET, BIT0, 0 /* 0-24bit,1-12bit */ - union { - unsigned int val; - struct { - unsigned int pll_ready:1; - unsigned int _01_07:7; - unsigned int rsen:1; - } b; - } detect; /* 0x18 */ +/* REG_LVDS_SET2,0x14 */ +#define LVDS_COLFMT_YUV422 REG_LVDS_SET2, BIT1, 1 /* 0-RGB or YUV444,1-YUV422 */ +#define LVDS_COLFMT_RGB REG_LVDS_SET2, BIT0, 0 - union { - unsigned int val; - struct { - unsigned int pll_tsync:1; - unsigned int tp2s_type:1; - unsigned int div_sel:2; - unsigned int pd_v2i:1; - unsigned int vco_sx:1; - unsigned int vco_mode:1; - unsigned int _07:1; - unsigned int vsref_sel:2; - unsigned int mode:1; - unsigned int pd_l2ha:1; - unsigned int pd_l2hb:1; - unsigned int l2ha_hsen:1; - unsigned int resa_en:1; - unsigned int resa_s:1; - unsigned int pll_lpfs:2; - } b; - } test2; /* 0x1c */ -}; +/* REG_LVDS_DETECT,0x18 */ +#define LVDS_RSEN REG_LVDS_DETECT, BIT8, 8 +#define LVDS_PLL_READY REG_LVDS_DETECT, BIT0, 0 + +/* REG_LVDS_TEST2,0x1C */ +#define LVDS_PLL_TSYNC REG_LVDS_TEST2, BIT0, 0 +#define LVDS_TP2S_TYPE REG_LVDS_TEST2, BIT1, 1 +#define LVDS_DIV_SEL REG_LVDS_TEST2, 0xC, 2 +#define LVDS_PD_V2I REG_LVDS_TEST2, BIT4, 4 +#define LVDS_VCO_SX REG_LVDS_TEST2, BIT5, 5 +#define LVDS_VCO_MODE REG_LVDS_TEST2, BIT6, 6 +#define LVDS_VSREF_SEL REG_LVDS_TEST2, 0x300, 8 +#define LVDS_MODE REG_LVDS_TEST2, BIT10, 10 +#define LVDS_PD_L2HA REG_LVDS_TEST2, BIT11, 11 +#define LVDS_PD_L2HB REG_LVDS_TEST2, BIT12, 12 +#define LVDS_L2HA_HSEN REG_LVDS_TEST2, BIT13, 13 +#define LVDS_RESA_EN REG_LVDS_TEST2, BIT14, 14 +#define LVDS_RESA_S REG_LVDS_TEST2, BIT15, 15 +#define LVDS_PLL_LPFS REG_LVDS_TEST2, 0x30000, 16 -#define REG_LVDS_BEGIN (LVDS_BASE_ADDR + 0x00) -#define REG_LVDS_END (LVDS_BASE_ADDR + 0x1C) -#ifndef LVDS_C -extern struct lvds_base_regs *lvds_regs; -#endif #endif /* WMT_LVDS_REG_H */ diff --git a/drivers/video/wmt/hw/wmt-scl-reg.h b/drivers/video/wmt/hw/wmt-scl-reg.h index 773fad96..cabb75a7 100755..100644 --- a/drivers/video/wmt/hw/wmt-scl-reg.h +++ b/drivers/video/wmt/hw/wmt-scl-reg.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/hw/wmt-scl-reg.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -33,511 +33,342 @@ #define WMT_SCL_V_DIV_MAX 8192 #define WMT_SCL_FB_WIDTH_MAX 8192 -#define WMT_SCL_SCALE_DST_H_MAX 1920 /* bypass no limit */ - -struct scl_base1_regs { - union { - unsigned int val; - struct { - unsigned int alu_enable:1; - } b; - } en; /* 0x0 */ - - union { - unsigned int val; - struct { - unsigned int reg_update:1; - } b; - } upd; /* 0x04 */ - - union { - unsigned int val; - struct { - unsigned int reg_level:1; - } b; - } sel; /* 0x08 */ - - unsigned int _0c_38[12]; - - union { - unsigned int val; - struct { - unsigned int hxwidth:13; - } b; - } hxwidth; /* 0x3c */ - - union { - unsigned int val; - struct { - unsigned int mif_en:1; - unsigned int _01_03:3; - unsigned int rgb_mode:2; /* 0-YUV,1-RGB565,3-RGB32 */ - unsigned int _06_07:2; - unsigned int _420c_fmt:1; /* 0-frame,1-field */ - unsigned int vfmt:3; /* 0-YUV422,1-YUV420, - 2-YUV444,4-RGB32 */ - unsigned int h264_fmt:1; /* 0-MPEG,1-H264 */ - unsigned int _13_15:3; - unsigned int iofmt:1; /* 0-frame,1-field */ - unsigned int _17_23:7; - unsigned int color_en:1; /* 0-disable,1-enable */ - unsigned int color_wide:1; /* 0-Normal,1-Wider */ - unsigned int color_inv:1; /* 0-Normal,1-Opposite color*/ - } b; - } r2_ctl; /* 0x40 */ - - unsigned int r2_ysa; /* 0x44 */ - unsigned int r2_csa; /* 0x48 */ - - union { - unsigned int val; - struct { - unsigned int fbw:13; /* frame buffer width pixel */ - unsigned int _13_15:3; - unsigned int lnsize:13; /* line width pixel */ - } b; - } r2_h_size; /* 0x4c */ - - union { - unsigned int val; - struct { - unsigned int hcrop:13; - unsigned int _13_15:3; - unsigned int vcrop:13; - } b; - } r2_crop; /* 0x50 */ - - union { - unsigned int val; - struct { - unsigned int src:2; /* 0-RMIF1,1-RMIF2,2-Fixed ALPHA */ - unsigned int _02_07:6; - unsigned int dst:2; /* 0-RMIF1,1-RMIF2,2-Fixed ALPHA */ - unsigned int _09_15:6; - unsigned int swap:1; /* 0-(alpha,1-a),1:(1-a,alpha) */ - } b; - } alpha_md; /* 0x54 */ - - union { - unsigned int val; - struct { - unsigned int src_fixed:8; - unsigned int dst_fixed:8; - } b; - } alpha_fxd; /* 0x58 */ - - union { - unsigned int val; - struct { - unsigned int enable:1; - unsigned int _01_07:7; - unsigned int from:1; /* 0-RMIF1,1-RMIF2 */ - unsigned int _09_15:7; - unsigned int comp:2; /* 0-888,1-777,2-666,3-555 */ - unsigned int _17_23:7; - unsigned int mode:3; /* (Non-Hit,Hit):0/1-(alpha,alpha), - 2-(alpha,pix1),3-(pix1,alpha),4-(alpha,pix2), - 5-(pix2,alpha),6-(pix1,pix2),7-(pix2,pix1) */ - } b; - } alpha_colorkey; /* 0x5c */ - - union { - unsigned int val; - struct { - unsigned int r:8; - unsigned int g:8; - unsigned int b:8; - } b; - } alpha_colorkey_rgb; /* 0x60 */ - - unsigned int _64_6c[3]; - - union { - unsigned int val; - struct { - unsigned int vxwidth:13; - unsigned int _13_15:3; - unsigned int dst_vxwidth:13; - } b; - } vxwidth; /* 0x70 */ - - union { - unsigned int val; - struct { - unsigned int h:1; - unsigned int _01_15:15; - unsigned int v:1; - } b; - } sclup_en; /* 0x74 */ - - union { - unsigned int val; - struct { - unsigned int thr:13; - unsigned int _13_15:3; - unsigned int substep:13; - } b; - } vscale1; /* 0x78 */ - - union { - unsigned int val; - struct { - unsigned int substepcnt:13; - unsigned int _13_15:3; - unsigned int step:13; - } b; - } vscale2; /* 0x7c */ - - union { - unsigned int val; - struct { - unsigned int stepcnt:17; - } b; - } vscale3; /* 0x80 */ - - union { - unsigned int val; - struct { - unsigned int thr:13; - unsigned int _13_15:3; - unsigned int substep:13; - } b; - } hscale1; /* 0x84 */ - - union { - unsigned int val; - struct { - unsigned int substepcnt:13; - unsigned int _13_15:3; - unsigned int step:13; - } b; - } hscale2; /* 0x88 */ - - union { - unsigned int val; - struct { - unsigned int stepcnt:17; - } b; - } hscale3; /* 0x8c */ - - union { - unsigned int val; - struct { - unsigned int y_req_num:8; - unsigned int c_req_num:8; - } b; - } r_req_num; /* 0x90 */ - - unsigned int scldw; /* 0x94 */ /* (VPU path, scale dn) - 0 - bilinear mode, quality better */ - unsigned int sw_426; /* 0x98 */ /* 1-follow 426, 0-437 */ - unsigned int vbypass; /* 0x9c */ - - union { - unsigned int val; - struct { - unsigned int enable:1; - unsigned int _1_3:3; - unsigned int err_off:1; /*disable TG_EN in tg timeout*/ - unsigned int _5_7:3; - unsigned int watchdog_enable:1; - unsigned int _9_15:7; - unsigned int rdcyc:8; - unsigned int oneshot:1; /* sacling complete will set - SCL tg enable to 0 */ - } b; - } tg_ctl; /* 0xa0 */ - - union { - unsigned int val; - struct { - unsigned int h_allpixel:13; - unsigned int _13_15:3; - unsigned int v_allline:13; - } b; - } tg_total; /* 0xa4 */ - - union { - unsigned int val; - struct { - unsigned int v_actbg:8; - unsigned int _8_15:8; - unsigned int v_actend:13; - } b; - } tg_v_active; /* 0xa8 */ - - union { - unsigned int val; - struct { - unsigned int h_actbg:10; - unsigned int _10_15:6; - unsigned int h_actend:13; - } b; - } tg_h_active; /* 0xac */ - - union { - unsigned int val; - struct { - unsigned int vbie:7; - unsigned int _7:1; - unsigned int pvbi:5; - } b; - } tg_vbi; /* 0xb0 */ - - unsigned int tg_watchdog; /* 0xb4 */ - - union { - unsigned int val; - struct { - unsigned int tgerr:1; - } b; - } tg_sts; /* 0xb8 */ - - union { - unsigned int val; - struct { - unsigned int enable:1; - } b; - } tg_govw; /* 0xbc */ - - union { - unsigned int val; - struct { - unsigned int mif_enable:1; /*0:Disable, 1:Enable */ - unsigned int _1_3:3; - unsigned int rgb_mode:2; /*0:YC,1:RGB565,3:RGB32 */ - unsigned int _6_7:2; - unsigned int src_disp_fmt:1; /*420C 0:Frame, 1:Field */ - unsigned int yuv:2; /*0:422,1:420,2:444*/ - unsigned int rgb:1; /*0:YCbCr, 1:RGB32 */ - unsigned int h264:1; /*0:MPEG, 1:H264 */ - unsigned int _13_15:3; - unsigned int field:1; /*0:Frame, 1:Field */ - unsigned int _17_23:7; - unsigned int colorbar_enable:1; - unsigned int colorbar_mode:1; - unsigned int colorbar_inv:1; - } b; - } r_ctl; /* 0xc0 */ - - unsigned int r_ysa; /* 0xc4 */ - unsigned int r_csa; /* 0xc8 */ - - union { - unsigned int val; - struct { - unsigned int fb_w:13; - unsigned int _13_15:3; - unsigned int pix_w:13; - } b; - } r_h_size; /* 0xcc */ - - union { - unsigned int val; - struct { - unsigned int hcrop:13; - unsigned int _13_15:3; - unsigned int vcrop:13; - } b; - } r_crop; /* 0xd0 */ - - union { - unsigned int val; - struct { - unsigned int thr:4; - unsigned int _4_7:4; - unsigned int r1_mif_err:1; - unsigned int r2_mif_err:1; - } b; - } r_fifo_ctl; /* 0xd4 */ - - unsigned int _d8_dc[2]; - - union { - unsigned int val; - struct { - unsigned int mif_enable:1; - unsigned int _1_7:7; - unsigned int yuv:1; /* 0-444,1-422 */ - unsigned int rgb:1; /* 0-YC,1-RGB32 */ - } b; - } w_ctl; /* 0xe0 */ - - unsigned int w_ysa; /* 0xe4 */ - unsigned int w_csa; /* 0xe8 */ - - union { - unsigned int val; - struct { - unsigned int fb_w:13; - unsigned int _13_15:3; - unsigned int pxl_w:13; - } b; - } w_y_time; /* 0xec */ - - union { - unsigned int val; - struct { - unsigned int fb_w:13; - unsigned int _13_15:3; - unsigned int pxl_w:12; - } b; - } w_c_time; /* 0xf0 */ - - union { - unsigned int val; - struct { - unsigned int mif_c_err:1; - unsigned int _1_7:7; - unsigned int mif_y_err:1; - unsigned int _9_15:7; - unsigned int mif_rgb_err:1; - } b; - } w_ff_ctl; /* 0xf4 */ - - union { - unsigned int val; - struct { - unsigned int mif_c_err:1; - unsigned int mif_y_err:1; - unsigned int mif_rgb_err:1; - unsigned int _3_7:5; - unsigned int r2_mif_enable:1; - unsigned int r1_mif_enable:1; - unsigned int _10_15:6; - unsigned int tg_err:1; - } b; - } w_int_en; /* 0xf8 */ - - union { - unsigned int val; - struct { - unsigned int h:1; - unsigned int _1_7:7; - unsigned int v:1; - } b; - } true_bilinear; /* 0xfc */ -}; - -struct scl_base2_regs { - union { - unsigned int val; - struct { - unsigned int mode:1; /* 0-RGB2YC,1-YC2RGB */ - unsigned int _01_07:7; - unsigned int clamp_enable:1; /* clamp to 16-235 */ - unsigned int _09_15:7; - unsigned int enable:1; - } b; - } csc_ctl; /* 0x0 */ - - unsigned int csc1; /* 0x4 */ - unsigned int csc2; /* 0x8 */ - unsigned int csc3; /* 0xc */ - unsigned int csc4; /* 0x10 */ - unsigned int csc5; /* 0x14 */ - unsigned int csc6; /* 0x18 */ - - union { - unsigned int val; - struct { - unsigned int enable:1; - unsigned int _01_07:7; - unsigned int data:8; - } b; - } argb_alpha; /* 0x1c */ - - union { - unsigned int val; - struct { - unsigned int mode:2; /* 0-888,1-555,2-666,3-565 */ - } b; - } igs; /* 0x20 */ - - union { - unsigned int val; - struct { - unsigned int mode:1; /* 0-CCIR/ITU-601 */ - unsigned int _01_07:7; - unsigned int clamp:1; /* 0-direct,1-16-235 */ - unsigned int _09_15:7; - unsigned int enable:1; - } b; - } r2_csc; /* 0x24 */ - - unsigned int r2_csc1; /* 0x28 */ - unsigned int r2_csc2; /* 0x2c */ - unsigned int r2_csc3; /* 0x30 */ - unsigned int r2_csc4; /* 0x34 */ - unsigned int r2_csc5; /* 0x38 */ - unsigned int r2_csc6; /* 0x3c */ - unsigned int _40_9c[24]; - - union { - unsigned int val; - struct { - unsigned int h:1; - unsigned int _01_07:7; - unsigned int v:1; - } b; - } recursive_mode; /* 0xa0 */ - - unsigned int _a4_bc[7]; - - union { - unsigned int val; - struct { - unsigned int deblock:1; - unsigned int field_deflicker:1; - unsigned int frame_deflicker:1; - } b; - } field_mode; /* 0xc0 */ - - union { - unsigned int val; - struct { - unsigned int layer1_boundary:8; - unsigned int layer2_boundary:8; - } b; - } dblk_threshold; /* 0xc4 */ - - union { - unsigned int val; - struct { - unsigned int condition:1; /* 0-up or down,1-up & down */ - unsigned int _01_07:7; - unsigned int y_thd:8; - unsigned int c_thd:8; - } b; - } field_flicker; /* 0xc8 */ - union { - unsigned int val; - struct { - unsigned int rgb:1; /* 0-Y,1-RGB */ - unsigned int _01_07:7; - unsigned int sampler:5; /* 2^x */ - unsigned int _13_15:3; - unsigned int scene_chg_thd:8; - } b; - } frame_flicker; /* 0xcc */ - - union { - unsigned int val; - struct { - unsigned int rdcyc_1t:1; - } b; - } readcyc_1t; /* 0xd0 */ - - unsigned int _d4_e0[4]; -}; +#define WMT_SCL_SCALE_DST_H_MAX 1920 /* bypass no limit */ +/* registers */ #define REG_SCL_BASE1_BEGIN (SCL_BASE_ADDR + 0x00) +#define REG_SCL_EN (SCL_BASE_ADDR + 0x00) +#define REG_SCL_UPD (SCL_BASE_ADDR + 0x04) +#define REG_SCL_SEL (SCL_BASE_ADDR + 0x08) +#define REG_SCL_HXWIDTH (SCL_BASE_ADDR + 0x3c) +#define REG_SCLR2_CTL (SCL_BASE_ADDR + 0x40) +#define REG_SCLR2_YSA (SCL_BASE_ADDR + 0x44) +#define REG_SCLR2_CSA (SCL_BASE_ADDR + 0x48) +#define REG_SCLR2_H_SIZE (SCL_BASE_ADDR + 0x4C) +#define REG_SCLR2_CROP (SCL_BASE_ADDR + 0x50) +#define REG_ALFA_MD (SCL_BASE_ADDR + 0x54) +#define REG_ALFA_FXD (SCL_BASE_ADDR + 0x58) +#define REG_ALFA_COLORKEY (SCL_BASE_ADDR + 0x5C) +#define REG_ALFA_COLORKEY_RGB (SCL_BASE_ADDR + 0x60) +#define REG_SCL_VXWIDTH (SCL_BASE_ADDR + 0x70) +#define REG_SCL_SCLUP_EN (SCL_BASE_ADDR + 0x74) + +#define REG_SCL_VSCALE1 (SCL_BASE_ADDR + 0x78) +#define REG_SCL_VSCALE2 (SCL_BASE_ADDR + 0x7c) +#define REG_SCL_VSCALE3 (SCL_BASE_ADDR + 0x80) +#define REG_SCL_HSCALE1 (SCL_BASE_ADDR + 0x84) +#define REG_SCL_HSCALE2 (SCL_BASE_ADDR + 0x88) +#define REG_SCL_HSCALE3 (SCL_BASE_ADDR + 0x8c) +#define REG_SCLR_REQ_NUM (SCL_BASE_ADDR + 0x90) +#define REG_SCL_SCLDW (SCL_BASE_ADDR + 0x94) +#define REG_SCL_426_SW (SCL_BASE_ADDR + 0x98) +#define REG_SCL_VBYPASS (SCL_BASE_ADDR + 0x9C) +/* SCL_TG */ +#define REG_SCL_TG_CTL (SCL_BASE_ADDR + 0xa0) +#define REG_SCL_TG_TOTAL (SCL_BASE_ADDR + 0xa4) +#define REG_SCL_TG_V_ACTIVE (SCL_BASE_ADDR + 0xa8) +#define REG_SCL_TG_H_ACTIVE (SCL_BASE_ADDR + 0xac) +#define REG_SCL_TG_VBI (SCL_BASE_ADDR + 0xb0) +#define REG_SCL_TG_WATCHDOG (SCL_BASE_ADDR + 0xb4) +#define REG_SCL_TG_STS (SCL_BASE_ADDR + 0xb8) +#define REG_SCL_TG_GOVW (SCL_BASE_ADDR + 0xbc) +/* SCLR */ +#define REG_SCLR_CTL (SCL_BASE_ADDR + 0xc0) +#define REG_SCLR_YSA (SCL_BASE_ADDR + 0xc4) +#define REG_SCLR_CSA (SCL_BASE_ADDR + 0xc8) +#define REG_SCLR_H_SIZE (SCL_BASE_ADDR + 0xcc) +#define REG_SCLR_CROP (SCL_BASE_ADDR + 0xd0) +#define REG_SCLR_FIFO_CTL (SCL_BASE_ADDR + 0xd4) +/* SCLW */ +#define REG_SCLW_CTL (SCL_BASE_ADDR + 0xe0) +#define REG_SCLW_YSA (SCL_BASE_ADDR + 0xe4) +#define REG_SCLW_CSA (SCL_BASE_ADDR + 0xe8) +#define REG_SCLW_Y_TIME (SCL_BASE_ADDR + 0xec) +#define REG_SCLW_C_TIME (SCL_BASE_ADDR + 0xf0) +#define REG_SCLW_FF_CTL (SCL_BASE_ADDR + 0xf4) +#define REG_SCLW_INT (SCL_BASE_ADDR + 0xf8) +#define REG_SCL_TRUE_BILINEAR (SCL_BASE_ADDR + 0xfc) + #define REG_SCL_BASE1_END (SCL_BASE_ADDR + 0xFC) + +/* SCL444 CSC */ #define REG_SCL_BASE2_BEGIN (SCL_BASE2_ADDR + 0x00) +#define REG_SCL_CSC_CTL (SCL_BASE2_ADDR + 0x00) +#define REG_SCL_CSC1 (SCL_BASE2_ADDR + 0x04) +#define REG_SCL_CSC2 (SCL_BASE2_ADDR + 0x08) +#define REG_SCL_CSC3 (SCL_BASE2_ADDR + 0x0c) +#define REG_SCL_CSC4 (SCL_BASE2_ADDR + 0x10) +#define REG_SCL_CSC5 (SCL_BASE2_ADDR + 0x14) +#define REG_SCL_CSC6 (SCL_BASE2_ADDR + 0x18) +#define REG_SCL_ARGB_ALPHA (SCL_BASE2_ADDR + 0x1C) +#define REG_SCL_IGS (SCL_BASE2_ADDR + 0x20) +#define REG_SCL_R2_CSC (SCL_BASE2_ADDR + 0x24) +#define REG_SCL_R2_CSC1 (SCL_BASE2_ADDR + 0x28) +#define REG_SCL_R2_CSC2 (SCL_BASE2_ADDR + 0x2C) +#define REG_SCL_R2_CSC3 (SCL_BASE2_ADDR + 0x30) +#define REG_SCL_R2_CSC4 (SCL_BASE2_ADDR + 0x34) +#define REG_SCL_R2_CSC5 (SCL_BASE2_ADDR + 0x38) +#define REG_SCL_R2_CSC6 (SCL_BASE2_ADDR + 0x3C) +#define REG_SCL_RECURSIVE_MODE (SCL_BASE2_ADDR + 0xA0) +#define REG_SCL_FIELD_MODE (SCL_BASE2_ADDR + 0xC0) +#define REG_SCL_DBLK_THRESHOLD (SCL_BASE2_ADDR + 0xC4) +#define REG_SCL_FIELD_FLICKER (SCL_BASE2_ADDR + 0xC8) +#define REG_SCL_FRAME_FLICKER (SCL_BASE2_ADDR + 0xCC) +#define REG_SCL_READCYC_1T (SCL_BASE2_ADDR + 0xD0) #define REG_SCL_BASE2_END (SCL_BASE2_ADDR + 0xE0) -#ifndef SCL_C -extern HW_REG struct scl_base1_regs *scl_regs1; -extern HW_REG struct scl_base2_regs *scl_regs2; -#endif +/* REG_SCL_EN,0x00 */ +#define SCL_ALU_ENABLE REG_SCL_EN, BIT0, 0 + +/* REG_SCL_UPD,0x04 */ +#define SCL_REG_UPDATE REG_SCL_UPD, BIT0, 0 + +/* REG_SCL_SEL,0x08 */ +#define SCL_REG_LEVEL REG_SCL_SEL, BIT0, 0 + +/* REG_SCL_HXWIDTH,0x3c */ +#define SCL_HXWIDTH REG_SCL_HXWIDTH, 0x1FFF, 0 + +/* REG_SCLR2_CTL,0x40 */ +#define SCL_R2_MIF_EN REG_SCLR2_CTL, BIT0, 0 +#define SCL_R2_RGB_MODE REG_SCLR2_CTL, 0x30, 4 /* 0-YUV,1-RGB565,3-RGB32 */ +#define SCL_R2_420C_FMT REG_SCLR2_CTL, BIT8, 8 /* 0-frame,1-field */ +#define SCL_R2_VFMT REG_SCLR2_CTL, 0xE00, 9 /* 0-YUV422,1-YUV420,2-YUV444,4-RGB32 */ +#define SCL_R2_H264_FMT REG_SCLR2_CTL, BIT12, 12 /* 0-MPEG,1-H264 */ +#define SCL_R2_IOFMT REG_SCLR2_CTL, BIT16, 16 /* 0-frame,1-field */ +#define SCL_R2_COLOR_EN REG_SCLR2_CTL, BIT24, 24 /* 0-disable,1-enable */ +#define SCL_R2_COLOR_WIDE REG_SCLR2_CTL, BIT25, 25 /* 0-Normal,1-Wider */ +#define SCL_R2_COLOR_INV REG_SCLR2_CTL, BIT26, 26 /* 0-Normal,1-Opposite color */ + +/* REG_SCLR2_YSA,0x44 */ +/* REG_SCLR2_CSA,0x48 */ + +/* REG_SCLR2_H_SIZE,0x4C */ +#define SCL_R2_FBW REG_SCLR2_H_SIZE, 0x1FFF, 0 /* frame buffer width pixel */ +#define SCL_R2_LNSIZE REG_SCLR2_H_SIZE, 0x1FFF0000, 16 /* line width pixel */ + +/* REG_SCLR2_CROP,0x50 */ +#define SCL_R2_HCROP REG_SCLR2_CROP, 0x1FFF, 0 +#define SCL_R2_VCROP REG_SCLR2_CROP, 0x1FFF0000, 16 + +/* REG_ALFA_MD,0x54 */ +#define SCL_ALPHA_SRC REG_ALFA_MD, 0x3, 0 /* 0-RMIF1,1-RMIF2,2-Fixed ALPHA */ +#define SCL_ALPHA_DST REG_ALFA_MD, 0x300, 8 /* 0-RMIF1,1-RMIF2,2-Fixed ALPHA */ +#define SCL_ALPHA_SWAP REG_ALFA_MD, 0x10000, 16 /* 0-(alpha,1-alpha),1:(1-alpha,alpha) */ + +/* REG_ALFA_FXD,0x58 */ +#define SCL_ALPHA_SRC_FIXED REG_ALFA_FXD, 0xFF, 0 +#define SCL_ALPHA_DST_FIXED REG_ALFA_FXD, 0xFF00, 8 + +/* REG_ALFA_COLORKEY,0x5C */ +#define SCL_ALPHA_COLORKEY_ENABLE REG_ALFA_COLORKEY, BIT0, 0 +#define SCL_ALPHA_COLORKEY_FROM REG_ALFA_COLORKEY, BIT8, 8 /* 0-RMIF1,1-RMIF2 */ +#define SCL_ALPHA_COLORKEY_COMP REG_ALFA_COLORKEY, 0x30000, 16 /* 0-888,1-777,2-666,3-555 */ +#define SCL_ALPHA_COLORKEY_MODE REG_ALFA_COLORKEY, 0x7000000, 24 /* (Non-Hit,Hit):0/1-(alpha,alpha), + 2-(alpha,pix1),3-(pix1,alpha),4-(alpha,pix2), + 5-(pix2,alpha),6-(pix1,pix2),7-(pix2,pix1) */ + +/* REG_ALFA_COLORKEY_RGB,0x60 */ +#define SCL_ALPHA_COLORKEY_R REG_ALFA_COLORKEY_RGB, 0xFF, 0 +#define SCL_ALPHA_COLORKEY_G REG_ALFA_COLORKEY_RGB, 0xFF00, 8 +#define SCL_ALPHA_COLORKEY_B REG_ALFA_COLORKEY_RGB, 0xFF0000, 16 + +/* REG_SCL_VXWIDTH,0x70 */ +#define SCL_VXWIDTH REG_SCL_VXWIDTH, 0x1FFF, 0 +#define SCL_DST_VXWIDTH REG_SCL_VXWIDTH, 0x1FFF0000, 16 + +/* REG_SCL_SCLUP_EN,0x74 */ +#define SCL_VSCLUP_ENABLE REG_SCL_SCLUP_EN, BIT16, 16 +#define SCL_HSCLUP_ENABLE REG_SCL_SCLUP_EN, BIT0, 0 + +/* REG_SCL_VSCALE1,0x78 */ +#define SCL_V_SUBSTEP REG_SCL_VSCALE1, 0x1FFF0000, 16 +#define SCL_V_THR REG_SCL_VSCALE1, 0x1FFF, 0 + +/* REG_SCL_VSCALE2,0x7c */ +#define SCL_V_STEP REG_SCL_VSCALE2, 0x1FFF0000, 16 +#define SCL_V_I_SUBSTEPCNT REG_SCL_VSCALE2, 0x1FFF, 0 + +/* REG_SCL_VSCALE3,0x80 */ +#define SCL_V_I_STEPCNT REG_SCL_VSCALE3, 0x1FFFF, 0 + +/* REG_SCL_HSCALE1,0x84 */ +#define SCL_H_SUBSTEP REG_SCL_HSCALE1, 0x1FFF0000, 16 +#define SCL_H_THR REG_SCL_HSCALE1, 0x1FFF, 0 + +/* REG_SCL_HSCALE2,0x88 */ +#define SCL_H_STEP REG_SCL_HSCALE2, 0x1FFF0000, 16 +#define SCL_H_I_SUBSTEPCNT REG_SCL_HSCALE2, 0x1FFF, 0 + +/* REG_SCL_HSCALE3,0x8c */ +#define SCL_H_I_STEPCNT REG_SCL_HSCALE3, 0x1FFFF, 0 + +/* REG_SCLR_REQ_NUM,0x90 */ +#define SCL_R_C_REQ_NUM REG_SCLR_REQ_NUM, 0xFF, 0 +#define SCL_R_Y_REQ_NUM REG_SCLR_REQ_NUM, 0xFF00, 8 + +/* REG_SCL_SCLDW,0x94 */ +#define SCL_SCLDW_METHOD REG_SCL_SCLDW, BIT0, 0 /* (VPU path, scale dn) 0 - bilinear mode, quality better */ + +/* REG_SCL_426_SW,0x98 */ +#define SCL_426_SW REG_SCL_426_SW, BIT0, 0 /* 1-follow 426, 0-437 */ + +/* REG_SCL_VBYPASS,0x9C */ +#define SCL_VBYPASS REG_SCL_VBYPASS, BIT0, 0 + +/* SCL_TG */ +/* REG_SCL_TG_CTL,0xa0 */ +#define SCL_ONESHOT_ENABLE REG_SCL_TG_CTL, BIT24, 24 /* sacling complete will set SCL tg enable to 0 */ +#define SCL_TG_RDCYC REG_SCL_TG_CTL, 0xFF0000, 16 +#define SCL_TG_WATCHDOG_ENABLE REG_SCL_TG_CTL, BIT8, 8 +#define SCL_TG_ERR_OFF REG_SCL_TG_CTL, BIT4, 4 /* disable TG_EN whtn tg timeout */ +#define SCL_TG_ENABLE REG_SCL_TG_CTL, BIT0, 0 + +/* REG_SCL_TG_TOTAL,0xa4 */ +#define SCL_TG_V_ALLLINE REG_SCL_TG_TOTAL, 0x1FFF0000, 16 +#define SCL_TG_H_ALLPIXEL REG_SCL_TG_TOTAL, 0x1FFF, 0 + +/* REG_SCL_TG_V_ACTIVE,0xa8 */ +#define SCL_TG_V_ACTEND REG_SCL_TG_V_ACTIVE, 0x1FFF0000, 16 +#define SCL_TG_V_ACTBG REG_SCL_TG_V_ACTIVE, 0xFF, 0 + +/* REG_SCL_TG_H_ACTIVE,0xac */ +#define SCL_TG_H_ACTEND REG_SCL_TG_H_ACTIVE, 0x1FFF0000, 16 +#define SCL_TG_H_ACTBG REG_SCL_TG_H_ACTIVE, 0x3FF, 0 + +/* REG_SCL_TG_VBI,0xb0 */ +#define SCL_TG_PVBI REG_SCL_TG_VBI, 0x1F00, 8 +#define SCL_TG_VBIE REG_SCL_TG_VBI, 0x7F, 0 + +/* REG_SCL_TG_WATCHDOG,0xb4 */ +#define SCL_TG_WATCHDOG_VALUE REG_SCL_TG_WATCHDOG, 0xFFFFFFFF, 0 + +/* REG_SCL_TG_STS,0xb8 */ +#define SCL_INTSTS_TGERR REG_SCL_TG_STS, BIT0, 0 + +/* REG_SCL_TG_GOVW,0xbc */ +#define SCL_TG_GOVWTG_ENABLE REG_SCL_TG_GOVW, BIT0, 0 + +/* SCLR */ +/* REG_SCL_MIF_CTL,0xc0 */ +#define SCLR_COLBAR_INVERSION REG_SCLR_CTL, BIT26, 26 +#define SCLR_COLBAR_MODE REG_SCLR_CTL, BIT25, 25 +#define SCLR_COLBAR_ENABLE REG_SCLR_CTL, BIT24, 24 +#define SCLR_TAR_DISP_FMT REG_SCLR_CTL, BIT16, 16 /*0:Frame, 1:Field */ +#define SCLR_MEDIAFMT_H264 REG_SCLR_CTL, BIT12, 12 /*0:MPEG, 1:H264 */ +#define SCLR_COLFMT_RGB REG_SCLR_CTL, BIT11, 11 /*0:YCbCr, 1:RGB32 */ +#define SCLR_COLFMT_YUV REG_SCLR_CTL, 0x600, 9 /*0:422,1:420,2:444*/ +#define SCLR_SRC_DISP_FMT REG_SCLR_CTL, BIT8, 8 /*420C 0:Frame, 1:Field */ +#define SCLR_RGB_MODE REG_SCLR_CTL, 0x30, 4 /*0:YC,1:RGB565,3:RGB32 */ +#define SCLR_MIF_ENABLE REG_SCLR_CTL, BIT0, 0 /*0:Disable, 1:Enable */ + +/* REG_SCLR_YSA,0xc4 */ + +/* REG_SCLR_CSA,0xc8 */ + +/* REG_SCLR_H_SIZE,0xcc */ +#define SCLR_YPXLWID REG_SCLR_H_SIZE, 0x1FFF0000, 16 +#define SCLR_YBUFWID REG_SCLR_H_SIZE, 0x1FFF, 0 + +/* REG_SCLR_CROP,0xd0 */ +#define SCLR_VCROP REG_SCLR_CROP, 0x1FFF0000, 16 +#define SCLR_HCROP REG_SCLR_CROP, 0x1FFF, 0 + +/* REG_SCLR_FIFO_CTL,0xd4 (W:0xf4) */ +#define SCLR_INTSTS_R2MIFERR REG_SCLR_FIFO_CTL, BIT9, 9 +#define SCLR_INTSTS_R1MIFERR REG_SCLR_FIFO_CTL, BIT8, 8 +#define SCLR_FIFO_THR REG_SCLR_FIFO_CTL, 0xF, 0 + +/* SCL_W */ +/* REG_SCLW_CTL,0xe0 */ +#define SCLW_COLFMT_RGB REG_SCLW_CTL, BIT9, 9 /* 0-YC,1-RGB32 */ +#define SCLW_COLFMT_YUV REG_SCLW_CTL, BIT8, 8 /* 0-444,1-422 */ +#define SCLW_MIF_ENABLE REG_SCLW_CTL, BIT0, 0 + +/* REG_SCLW_YSA,0xe4 */ + +/* REG_SCLW_CSA,0xe8 */ + +/* REG_SCLW_Y_TIME,0xec */ +#define SCLW_YPXLWID REG_SCLW_Y_TIME, 0x1FFF0000, 16 +#define SCLW_YBUFWID REG_SCLW_Y_TIME, 0x1FFF, 0 + +/* REG_SCLW_C_TIME,0xf0 */ +#define SCLW_CPXLWID REG_SCLW_C_TIME, 0xFFF0000, 16 +#define SCLW_CBUFWID REG_SCLW_C_TIME, 0x1FFF, 0 + +/* REG_SCLW_FF_CTL,0xf4 (R:0xd4) */ +#define SCLW_INTSTS_MIFRGBERR REG_SCLW_FF_CTL, BIT16, 16 +#define SCLW_INTSTS_MIFYERR REG_SCLW_FF_CTL, BIT8, 8 +#define SCLW_INTSTS_MIFCERR REG_SCLW_FF_CTL, BIT0, 0 + +/* REG_SCLW_INT,0xf8 */ +#define SCLW_INT_TGERR_ENABLE REG_SCLW_INT, BIT16, 16 +#define SCLW_INT_R1MIF_ENABLE REG_SCLW_INT, BIT9, 9 +#define SCLW_INT_R2MIF_ENABLE REG_SCLW_INT, BIT8, 8 +#define SCLW_INT_WMIFRGB_ENABLE REG_SCLW_INT, BIT2, 2 +#define SCLW_INT_WMIFYERR_ENABLE REG_SCLW_INT, BIT1, 1 +#define SCLW_INT_WMIFCERR_ENABLE REG_SCLW_INT, BIT0, 0 + +/* REG_SCL_TRUE_BILINEAR,0xfc */ +#define SCL_BILINEAR_H REG_SCL_TRUE_BILINEAR, BIT0, 0 +#define SCL_BILINEAR_V REG_SCL_TRUE_BILINEAR, BIT8, 8 + +/* SCL Base2 */ +/* REG_SCL_CSC_CTL,0x00 */ +#define SCL_CSC_ENABLE REG_SCL_CSC_CTL, BIT16, 16 +#define SCL_CSC_CLAMP_ENABLE REG_SCL_CSC_CTL, BIT8, 8 /* clamp to 16-235 */ +#define SCL_CSC_MODE REG_SCL_CSC_CTL, BIT0, 0 /* 0-RGB2YC,1-YC2RGB */ + +/* REG_SCL_CSC1,0x04 */ +/* REG_SCL_CSC2,0x08 */ +/* REG_SCL_CSC3,0x0c */ +/* REG_SCL_CSC4,0x10 */ +/* REG_SCL_CSC5,0x14 */ +/* REG_SCL_CSC6,0x18 */ + +/* REG_SCL_ARGB_ALPHA,0x1C */ +#define SCL_FIXED_ALPHA_ENABLE REG_SCL_ARGB_ALPHA, BIT0, 0 +#define SCL_FIXED_ALPHA_DATA REG_SCL_ARGB_ALPHA, 0xFF00, 8 + +/* REG_SCL_IGS,0x20 */ +#define SCL_IGS_MODE REG_SCL_IGS, 0x3, 0 /* 0-888,1-555,2-666,3-565 */ + +/* REG_SCL_R2_CSC,0x24 */ +#define SCL_R2_CSC_MODE REG_SCL_R2_CSC, BIT0, 0 /* 0-CCIR/ITU-601 */ +#define SCL_R2_CSC_CLAMP_EN REG_SCL_R2_CSC, BIT8, 8 /* 0-direct,1-16-235 */ +#define SCL_R2_CSC_EN REG_SCL_R2_CSC, BIT16, 16 + +/* REG_SCL_R2_CSC1,0x28 */ +/* REG_SCL_R2_CSC2,0x2C */ +/* REG_SCL_R2_CSC3,0x30 */ +/* REG_SCL_R2_CSC4,0x34 */ +/* REG_SCL_R2_CSC5,0x38 */ +/* REG_SCL_R2_CSC6,0x3C */ + +/* REG_SCL_RECURSIVE_MODE,0xA0 */ +#define SCL_RECURSIVE_H REG_SCL_RECURSIVE_MODE, BIT0, 0 +#define SCL_RECURSIVE_V REG_SCL_RECURSIVE_MODE, BIT8, 8 + +/* REG_SCL_FIELD_MODE,0xC0 */ +#define SCL_DEBLOCK_ENABLE REG_SCL_FIELD_MODE, BIT0, 0 +#define SCL_FIELD_DEFLICKER REG_SCL_FIELD_MODE, BIT1, 1 +#define SCL_FRAME_DEFLICKER REG_SCL_FIELD_MODE, BIT2, 2 + +/* REG_SCL_DBLK_THRESHOLD,0xC4 */ +#define SCL_1ST_LAYER_BOUNDARY REG_SCL_DBLK_THRESHOLD, 0xFF, 0 +#define SCL_2ND_LAYER_BOUNDARY REG_SCL_DBLK_THRESHOLD, 0xFF00, 8 + +/* REG_SCL_FIELD_FLICKER,0xC8 */ +#define SCL_FIELD_FILTER_CONDITION REG_SCL_FIELD_FLICKER, BIT0, 0 /* 0-up or down,1-up and down */ +#define SCL_FIELD_FILTER_Y_THD REG_SCL_FIELD_FLICKER, 0xFF00, 8 +#define SCL_FIELD_FILTER_C_THD REG_SCL_FIELD_FLICKER, 0xFF0000, 16 + +/* REG_SCL_FRAME_FLICKER,0xCC */ +#define SCL_FRAME_FILTER_RGB REG_SCL_FRAME_FLICKER, BIT0, 0 /* 0-Y,1-RGB */ +#define SCL_FRAME_FILTER_SAMPLER REG_SCL_FRAME_FLICKER, 0x1F00, 8 /* 2^x */ +#define SCL_FR_FILTER_SCENE_CHG_THD REG_SCL_FRAME_FLICKER, 0xFF0000, 16 + +/* REG_SCL_READCYC_1T,0xD0 */ +#define SCL_READCYC_1T REG_SCL_READCYC_1T,BIT0,0 #endif /* WMT_SCL_REG_H */ diff --git a/drivers/video/wmt/hw/wmt-vpp-hw.h b/drivers/video/wmt/hw/wmt-vpp-hw.h index 599ebe03..b3d3a7ad 100755..100644 --- a/drivers/video/wmt/hw/wmt-vpp-hw.h +++ b/drivers/video/wmt/hw/wmt-vpp-hw.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/hw/wmt-vpp-hw.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -85,37 +85,35 @@ #define VPP_IRQ_GOVR2_TG IRQ_VPP_IRQ25 /* DVI I2C */ -#define VPP_DVI_I2C_DEFAULT 1 /* default i2c bus */ -#define VPP_DVI_I2C_SW_BIT 0x10 /* hw or sw i2c */ -#define VPP_DVI_I2C_ID_MASK 0x1F -#define VPP_DVI_I2C_ID g_vpp.dvi_i2c_no -#define VPP_DVI_EDID_ID (VPP_DVI_I2C_SW_BIT + 0x1) /* DVO EDID use - sw i2c bus 1 */ +#define VPP_DVI_I2C_BIT 0x80 /* use sw id that can vary */ +#define VPP_DVI_I2C_SW_BIT 0x10 /* hw or sw i2c */ +#define VPP_DVI_I2C_ID_MASK 0x1F +#define VPP_DVI_I2C_ID (VPP_DVI_I2C_BIT + 0x1) +#define VPP_DVI_EDID_ID (VPP_DVI_I2C_SW_BIT + 0x1) /* DVO EDID use sw i2c bus 1 */ /* vout */ -#define VPP_VOUT_INFO_NUM 5 /* linux fb or govr number */ +#define VPP_VOUT_INFO_NUM 2 /* linux fb or govr number */ -#define VPP_VOUT_NUM 2 -#define VPP_VOUT_ALL 0xFFFFFFFF -#define VPP_VOUT_NUM_HDMI 0 -#define VPP_VOUT_NUM_LVDS 1 -#define VPP_VOUT_NUM_DVI 1 +#define VPP_VOUT_NUM 2 +#define VPP_VOUT_ALL 0xFFFFFFFF +#define VPP_VOUT_NUM_HDMI 0 +#define VPP_VOUT_NUM_LVDS 1 +#define VPP_VOUT_NUM_DVI 1 #define WMT_FTBLK_VOUT_DVI #define WMT_FTBLK_VOUT_HDMI #define WMT_FTBLK_VOUT_LVDS /* hw parameter */ -#define VPP_DVI_INT_DEFAULT 0 /* default interrupt gpio */ -#define VPP_VOINT_NO g_vpp.dvi_int_no -#define VPP_UBOOT_COLFMT VDO_COL_FMT_RGB_565 -#define VPP_FB_ADDR_ALIGN 64 -#define VPP_FB_WIDTH_ALIGN 64 /* hw should 4 byte align,android +#define VPP_VOINT_NO 0 /* DVO external board interrupt use GPIOxx */ +#define VPP_UBOOT_COLFMT VDO_COL_FMT_RGB_565 +#define VPP_FB_ADDR_ALIGN 64 +#define VPP_FB_WIDTH_ALIGN 64 /* hw should 4 byte align,android framework 8 byte align modify by aksenxu VPU need 64bytes alignment you need modify FramebufferNativeWindow::FramebufferNativeWindow in android framework together */ -#define VPP_GOVR_DVO_DELAY_24 0x4036 -#define VPP_GOVR_DVO_DELAY_12 0x120 +#define VPP_GOVR_DVO_DELAY_24 0x4036 +#define VPP_GOVR_DVO_DELAY_12 0x120 /*-------------------- DEPENDENCY -------------------------------------*/ #ifdef __KERNEL__ @@ -130,8 +128,8 @@ #ifdef WMT_FTBLK_VOUT_HDMI #include "wmt-hdmi-reg.h" #endif +#ifndef CFG_LOADER #include "wmt-scl-reg.h" -#ifndef CONFIG_UBOOT #include "wmt-cec-reg.h" #endif #endif /* WMT_VPP_HW_H */ diff --git a/drivers/video/wmt/hw/wmt-vpp-reg.h b/drivers/video/wmt/hw/wmt-vpp-reg.h index b96e64db..ffd02b87 100755..100644 --- a/drivers/video/wmt/hw/wmt-vpp-reg.h +++ b/drivers/video/wmt/hw/wmt-vpp-reg.h @@ -1,8 +1,8 @@ /*++ - * linux/drivers/video/wmt/hw/wmt-vpp-reg.h + * linux/drivers/video/wmt/register/wm8710/wmt-vpp-reg.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -24,109 +24,75 @@ #ifndef WMT_VPP_REG_H #define WMT_VPP_REG_H -#define VPP_DAC_SEL_TV 1 -#define VPP_DAC_SEL_VGA 0 - -struct vppm_base_regs { - unsigned int _00; /* 0x00 */ - - union { - unsigned int val; - struct { - unsigned int _0_7:8; - unsigned int govrh_pvbi:1; - unsigned int govrh_vbis:1; - unsigned int govrh_vbie:1; - unsigned int _11:1; - unsigned int govrh2_pvbi:1; - unsigned int govrh2_vbis:1; - unsigned int govrh2_vbie:1; - unsigned int _15:1; - unsigned int scl_pvbi:1; - unsigned int scl_vbis:1; - unsigned int scl_vbie:1; - unsigned int _19:1; - unsigned int ge_tg:1; - } b; - } int_sts; /* 0x4 */ - - union { - unsigned int val; - struct { - unsigned int _0_7:8; - unsigned int govrh_pvbi:1; - unsigned int govrh_vbis:1; - unsigned int govrh_vbie:1; - unsigned int _11:1; - unsigned int govrh2_pvbi:1; - unsigned int govrh2_vbis:1; - unsigned int govrh2_vbie:1; - unsigned int _15:1; - unsigned int scl_pvbi:1; - unsigned int scl_vbis:1; - unsigned int scl_vbie:1; - unsigned int _19:1; - unsigned int ge_tg:1; - } b; - } int_en; /* 0x8 */ - - unsigned int watch_sel; /* 0x0C */ - - union { - unsigned int val; - struct { - unsigned int scl:1; - unsigned int _1_7:7; - unsigned int vid:1; - unsigned int _9_15:7; - unsigned int ge:1; - } b; - } sw_reset1; /* 0x10 */ - - union { - unsigned int val; - struct { - unsigned int govrh:1; - unsigned int _1_3:3; - unsigned int lvds:1; - unsigned int _5_7:3; - unsigned int dvo:1; - unsigned int dvo2:1; - unsigned int _10_11:2; - unsigned int cec:1; - } b; - } sw_reset2; /* 0x14 */ - - unsigned int dac_sel; /* 0x18 */ - - union { - unsigned int val; - struct { - unsigned int hdmi:1; - unsigned int _1_7:7; - unsigned int ddc:1; - unsigned int _9_15:7; - unsigned int hdmi2:1; - } b; - } sw_reset3; /* 0x1C */ - - union { - unsigned int val; - struct { - unsigned int disable:1; - unsigned int _1_7:7; - unsigned int csi_act_lane_sel:1; /*0-lane 0/1,1-2/3*/ - } b; - } sscg; /* 0x20 */ -}; - #define REG_VPP_BEGIN (VPP_BASE_ADDR + 0x00) +#define REG_VPP_INTSTS (VPP_BASE_ADDR + 0x04) +#define REG_VPP_INTEN (VPP_BASE_ADDR + 0x08) +#define REG_VPP_WATCH_SEL (VPP_BASE_ADDR + 0x0c) +#define REG_VPP_SWRST1_SEL (VPP_BASE_ADDR + 0x10) +#define REG_VPP_SWRST2_SEL (VPP_BASE_ADDR + 0x14) +#define REG_VPP_DAC_SEL (VPP_BASE_ADDR + 0x18) +#define REG_VPP_SWRST3_SEL (VPP_BASE_ADDR + 0x1C) +#define REG_VPP_SSCG (VPP_BASE_ADDR + 0x20) #define REG_VPP_END (VPP_BASE_ADDR + 0x28) -#ifndef VPPM_C -extern HW_REG struct vppm_base_regs *vppm_regs; -#endif +/* REG_VPP_INTSTS,0x04 */ +#define VPP_GE_INTSTS_TG REG_VPP_INTSTS, BIT20, 20 +#define VPP_SCL_INTSTS_VBIE REG_VPP_INTSTS, BIT18, 18 +#define VPP_SCL_INTSTS_VBIS REG_VPP_INTSTS, BIT17, 17 +#define VPP_SCL_INTSTS_PVBI REG_VPP_INTSTS, BIT16, 16 +#define VPP_SCL_INTSTS REG_VPP_INTSTS, 0x70000, 16 +#define VPP_GOVRH2_INTSTS_VBIE REG_VPP_INTSTS, BIT14, 14 +#define VPP_GOVRH2_INTSTS_VBIS REG_VPP_INTSTS, BIT13, 13 +#define VPP_GOVRH2_INTSTS_PVBI REG_VPP_INTSTS, BIT12, 12 +#define VPP_GOVRH2_INTSTS REG_VPP_INTSTS, 0x7000, 12 +#define VPP_GOVRH_INTSTS_VBIE REG_VPP_INTSTS, BIT10, 10 +#define VPP_GOVRH_INTSTS_VBIS REG_VPP_INTSTS, BIT9, 9 +#define VPP_GOVRH_INTSTS_PVBI REG_VPP_INTSTS, BIT8, 8 +#define VPP_GOVRH_INTSTS REG_VPP_INTSTS, 0x700, 8 + +/* REG_VPP_INTEN,0x08 */ +#define VPP_GE_INTEN_TG REG_VPP_INTEN, BIT20, 20 +#define VPP_SCL_INTEN_VBIE REG_VPP_INTEN, BIT18, 18 +#define VPP_SCL_INTEN_VBIS REG_VPP_INTEN, BIT17, 17 +#define VPP_SCL_INTEN_PVBI REG_VPP_INTEN, BIT16, 16 +#define VPP_SCL_INTEN REG_VPP_INTEN, 0x70000, 16 +#define VPP_GOVRH2_INTEN_VBIE REG_VPP_INTEN, BIT14, 14 +#define VPP_GOVRH2_INTEN_VBIS REG_VPP_INTEN, BIT13, 13 +#define VPP_GOVRH2_INTEN_PVBI REG_VPP_INTEN, BIT12, 12 +#define VPP_GOVRH2_INTEN REG_VPP_INTEN, 0x7000, 12 +#define VPP_GOVRH_INTEN_VBIE REG_VPP_INTEN, BIT10, 10 +#define VPP_GOVRH_INTEN_VBIS REG_VPP_INTEN, BIT9, 9 +#define VPP_GOVRH_INTEN_PVBI REG_VPP_INTEN, BIT8, 8 +#define VPP_GOVRH_INTEN REG_VPP_INTEN, 0x700, 8 + +/* REG_VPP_WATCH_SEL,0x0c */ +#define VPP_WATCH_SEL REG_VPP_WATCH_SEL, 0x1F, 0 + +/* REG_VPP_SWRST1_SEL,0x10 */ +#define VPP_GE_RST REG_VPP_SWRST1_SEL, BIT16, 16 +#define VPP_VID_RST REG_VPP_SWRST1_SEL, BIT8, 8 +#define VPP_SCL_RST REG_VPP_SWRST1_SEL, BIT0, 0 + +/* REG_VPP_SWRST2_SEL,0x14 */ +#define VPP_CEC_RST REG_VPP_SWRST2_SEL, BIT12,12 +#define VPP_DVO2_RST REG_VPP_SWRST2_SEL, BIT9, 9 +#define VPP_DVO_RST REG_VPP_SWRST2_SEL, BIT8, 8 +#define VPP_LVDS_RST REG_VPP_SWRST2_SEL, BIT4, 4 +#define VPP_GOVRH_RST REG_VPP_SWRST2_SEL, BIT0, 0 + +/* REG_VPP_DAC_SEL,0x18 */ +#define VPP_DAC_SEL REG_VPP_DAC_SEL, BIT0, 0 +#define VPP_DAC_SEL_TV 1 +#define VPP_DAC_SEL_VGA 0 + +/* REG_VPP_SWRST3_SEL,0x1C */ +#define VPP_HDMI_RST REG_VPP_SWRST3_SEL, BIT0, 0 +#define VPP_DDC_RST REG_VPP_SWRST3_SEL, BIT8, 8 +#define VPP_HDMI2_RST REG_VPP_SWRST3_SEL, BIT16, 16 +/* REG_VPP_SSCG,0x20 */ +#define VPP_SSCG_DISABLE REG_VPP_SSCG, BIT0, 0 +#define VPP_CSI_ACT_LANE_SELECT REG_VPP_SSCG, BIT8, 8 /* 0-Active lane 0/1, 1-Active lane 2/3 */ #endif /* WMT_VPP_REG_H */ diff --git a/drivers/video/wmt/lcd.h b/drivers/video/wmt/lcd.h index 46925e9f..a2a5ecce 100755..100644 --- a/drivers/video/wmt/lcd.h +++ b/drivers/video/wmt/lcd.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -37,7 +37,7 @@ extern "C" { /*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/ /* typedef void lcd_xxx_t; *//*Example*/ -enum lcd_panel_t { +typedef enum { LCD_WMT_OEM, LCD_CHILIN_LW0700AT9003, LCD_INNOLUX_AT070TN83, @@ -45,30 +45,23 @@ enum lcd_panel_t { LCD_EKING_EK08009, LCD_HANNSTAR_HSD101PFW2, LCD_LVDS_1024x600, - LCD_GL5001W, LCD_B079XAN01, - LCD_TPO_TJ015NC02AA, + LCD_BP080WX7, LCD_PANEL_MAX -}; -enum { - LCD_POWER_OFF = 0, - LCD_POWER_ON, -}; +} lcd_panel_t; #define LCD_CAP_CLK_HI BIT(0) #define LCD_CAP_HSYNC_HI BIT(1) #define LCD_CAP_VSYNC_HI BIT(2) #define LCD_CAP_DE_LO BIT(3) -struct lcd_parm_t { +typedef struct { int bits_per_pixel; unsigned int capability; struct fb_videomode vmode; - int width; /* width of picture in mm */ - int height; /* height of picture in mm */ void (*initial)(void); void (*uninitial)(void); -}; +} lcd_parm_t; /*-------------------- EXPORTED PRIVATE VARIABLES ---------------------------*/ #ifdef LCD_C /* allocate memory for variables only in vout.c */ @@ -79,7 +72,7 @@ struct lcd_parm_t { /* EXTERN int lcd_xxx; *//*Example*/ -EXTERN struct lcd_parm_t *p_lcd; +EXTERN lcd_parm_t *p_lcd; #undef EXTERN /*--------------------- EXPORTED PRIVATE MACROS ------------------------------*/ @@ -88,9 +81,9 @@ EXTERN struct lcd_parm_t *p_lcd; /* extern void lcd_xxx(void); *//*Example*/ int lcd_panel_register(int no, void (*get_parm)(int mode)); -struct lcd_parm_t *lcd_get_parm(enum lcd_panel_t id, unsigned int arg); +lcd_parm_t *lcd_get_parm(lcd_panel_t id, unsigned int arg); void lcd_set_parm(int id, int bpp); -struct lcd_parm_t *lcd_get_oem_parm(int resx, int resy); +lcd_parm_t *lcd_get_oem_parm(int resx, int resy); void lcd_set_lvds_id(int id); int lcd_get_lvds_id(void); void lcd_set_type(int type); diff --git a/drivers/video/wmt/lvds.c b/drivers/video/wmt/lvds.c index 2516d788..3f8f8c83 100755..100644 --- a/drivers/video/wmt/lvds.c +++ b/drivers/video/wmt/lvds.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lvds.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -40,7 +40,6 @@ /*----------EXPORTED PRIVATE VARIABLES are defined in lvds.h -------------*/ /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int lvds_xxx; *//*Example*/ -struct lvds_base_regs *lvds_regs = (void *) LVDS_BASE_ADDR; /*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ /* void lvds_xxx(void); *//*Example*/ @@ -50,22 +49,22 @@ void lvds_set_power_down(int pwrdn) { DBG_DETAIL("(%d)\n", pwrdn); - lvds_regs->test.b.pd = pwrdn; + vppif_reg32_write(LVDS_PD, pwrdn); mdelay(1); - lvds_regs->test2.b.pd_l2ha = pwrdn; + vppif_reg32_write(LVDS_PD_L2HA, pwrdn); } void lvds_set_enable(vpp_flag_t enable) { DBG_DETAIL("(%d)\n", enable); - lvds_regs->test.b.tre_en = (enable) ? 0 : 1; - lvds_regs->test2.b.mode = (enable) ? 1 : 0; - lvds_regs->test2.b.resa_en = (enable) ? 0 : 1; + vppif_reg32_write(LVDS_TRE_EN, (enable) ? 0 : 1); + vppif_reg32_write(LVDS_MODE, (enable) ? 1 : 0); + vppif_reg32_write(LVDS_RESA_EN, (enable) ? 0 : 1); #ifdef CONFIG_UBOOT if ((enable) && (lcd_get_lvds_id() == LCD_LVDS_1024x600)) { /* GPIO10 VDD_EN->CLK delay 16->38ms */ - outl(inl(GPIO_BASE_ADDR + 0x80) | BIT10, GPIO_BASE_ADDR + 0x80); - outl(inl(GPIO_BASE_ADDR + 0xC0) | BIT10, GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0x80) |= 0x400; + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x400; mdelay(16); } #endif @@ -73,7 +72,7 @@ void lvds_set_enable(vpp_flag_t enable) int lvds_get_enable(void) { - return lvds_regs->test2.b.mode; + return vppif_reg32_read(LVDS_MODE); } void lvds_set_rgb_type(int bpp) @@ -103,8 +102,8 @@ void lvds_set_rgb_type(int bpp) #if 1 /* IGS default */ mode = 4; #endif - lvds_regs->status.b.test = mode_change; - lvds_regs->igs.b.bpp_type = mode; + vppif_reg32_write(LVDS_TEST, mode_change); + vppif_reg32_write(LVDS_IGS_BPP_TYPE, mode); } vdo_color_fmt lvds_get_colfmt(void) @@ -115,14 +114,15 @@ vdo_color_fmt lvds_get_colfmt(void) void lvds_set_sync_polar(int h_lo, int v_lo) { DBG_DETAIL("(%d,%d)\n", h_lo, v_lo); - lvds_regs->set.b.hsync_polar_lo = h_lo; - lvds_regs->set.b.vsync_polar_lo = v_lo; + + vppif_reg32_write(LVDS_HSYNC_POLAR_LO, h_lo); + vppif_reg32_write(LVDS_VSYNC_POLAR_LO, v_lo); } void lvds_get_sync_polar(int *hsync_hi, int *vsync_hi) { - *hsync_hi = (lvds_regs->set.b.hsync_polar_lo) ? 0 : 1; - *vsync_hi = (lvds_regs->set.b.vsync_polar_lo) ? 0 : 1; + *hsync_hi = (vppif_reg32_read(LVDS_HSYNC_POLAR_LO)) ? 0 : 1; + *vsync_hi = (vppif_reg32_read(LVDS_VSYNC_POLAR_LO)) ? 0 : 1; } /*----------------------- Module API --------------------------------------*/ @@ -132,13 +132,15 @@ void lvds_reg_dump(void) vpp_reg_dump(REG_LVDS_BEGIN, REG_LVDS_END-REG_LVDS_BEGIN); DPRINT("---------- LVDS common ----------\n"); - DPRINT("test %d,dual chan %d,inv clk %d\n", lvds_regs->status.b.test, - lvds_regs->status.b.dual_channel, lvds_regs->status.b.inv_clk); + DPRINT("test %d,dual chan %d,inv clk %d\n", vppif_reg32_read(LVDS_TEST), + vppif_reg32_read(LVDS_DUAL_CHANNEL), + vppif_reg32_read(LVDS_INV_CLK)); DPRINT("ldi shift left %d,IGS bpp type %d\n", - lvds_regs->igs.b.ldi_shift_left, lvds_regs->igs.b.bpp_type); - DPRINT("rsen %d,pll ready %d\n", lvds_regs->detect.b.rsen, - lvds_regs->detect.b.pll_ready); - DPRINT("pwr dn %d\n", lvds_regs->test.b.pd); + vppif_reg32_read(LVDS_LDI_SHIFT_LEFT), + vppif_reg32_read(LVDS_IGS_BPP_TYPE)); + DPRINT("rsen %d,pll ready %d\n", vppif_reg32_read(LVDS_RSEN), + vppif_reg32_read(LVDS_PLL_READY)); + DPRINT("pwr dn %d\n", vppif_reg32_read(LVDS_PD)); } #ifdef CONFIG_PM @@ -152,7 +154,7 @@ void lvds_suspend(int sts) case 1: /* disable tg */ break; case 2: /* backup register */ - lvds_pd_bk = lvds_regs->test.b.pd; + lvds_pd_bk = vppif_reg32_read(LVDS_PD); lvds_set_power_down(1); lvds_pm_bk = vpp_backup_reg(REG_LVDS_BEGIN, (REG_LVDS_END-REG_LVDS_BEGIN)); @@ -187,15 +189,15 @@ void lvds_resume(int sts) void lvds_init(void) { - lvds_regs->level.b.level = 1; - lvds_regs->level.b.update = 1; - lvds_regs->test.b.pll_r_f = 1; - lvds_regs->test.b.pll_cpset = 1; - lvds_regs->test.b.tre_en = 0; - lvds_regs->test.b.vbg_sel = 2; - lvds_regs->test.b.drv_pdmode = 0; - lvds_regs->igs.b.ldi_shift_left = 1; - lvds_regs->test2.val = 0x31432; + vppif_reg32_write(LVDS_REG_LEVEL, 1); + vppif_reg32_write(LVDS_REG_UPDATE, 1); + vppif_reg32_write(LVDS_PLL_R_F, 0x1); + vppif_reg32_write(LVDS_PLL_CPSET, 0x1); + vppif_reg32_write(LVDS_TRE_EN, 0x0); + vppif_reg32_write(LVDS_VBG_SEL, 2); + vppif_reg32_write(LVDS_DRV_PDMODE, 0); + vppif_reg32_write(LVDS_LDI_SHIFT_LEFT, 1); + vppif_reg32_out(REG_LVDS_TEST2, 0x31432); } #endif /* WMT_FTBLK_LVDS */ diff --git a/drivers/video/wmt/lvds.h b/drivers/video/wmt/lvds.h index 9821a667..7d6f3fea 100755..100644 --- a/drivers/video/wmt/lvds.h +++ b/drivers/video/wmt/lvds.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lvds.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 diff --git a/drivers/video/wmt/mali.c b/drivers/video/wmt/mali.c index 14ccc2a5..4ae9509c 100755..100644 --- a/drivers/video/wmt/mali.c +++ b/drivers/video/wmt/mali.c @@ -18,6 +18,8 @@ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C */ +/* Written by Vincent Chen, WonderMedia Technologies, Inc., 2008-2011 */ + #include <asm/cacheflush.h> #include <linux/io.h> #include <linux/slab.h> @@ -45,8 +47,8 @@ static unsigned int mali_cur_freq; static int on = 1; static int off; -static int acpi = 1; -static int mem_size; /* 0 MiB */ +static int acpi; +static int mem_size = 0x100000; /* 1 MiB */ static int debug; #define MALI_POWER_MASK 0xf @@ -118,7 +120,7 @@ static int __init malipm_setup(char *options) /* The syntax is: * malipm=[<param>][,<param>=<val>] ... * e.g., - * malipm=on:acpi + * malipm=on:acpi,mem_size=0x100000 */ while ((this_opt = strsep(&options, ",")) != NULL) { @@ -737,11 +739,7 @@ static int __init mali_init(void) /* Power on all Mali core at bootup, otherwise Mali driver will fail * at driver/src/devicedrv/mali/common/mali_pp.c: mali_pp_reset_wait(). */ - /* mali_pmu_power_up(MALI_POWER_MASK); - */ - ret = ioread32(REG_MALI400_PMU + 8); - printk(KERN_DEBUG "mali power on = %d\n", !ret); return err; } diff --git a/drivers/video/wmt/mali.h b/drivers/video/wmt/mali.h index 34605eae..34605eae 100755..100644 --- a/drivers/video/wmt/mali.h +++ b/drivers/video/wmt/mali.h diff --git a/drivers/video/wmt/parse-edid.c b/drivers/video/wmt/parse-edid.c index 8bf8da74..c0f18115 100755..100644 --- a/drivers/video/wmt/parse-edid.c +++ b/drivers/video/wmt/parse-edid.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/parse-edid.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -52,7 +52,7 @@ const char edid_v1_descriptor_flag[] = { 0x00, 0x00 }; #define UNKNOWN_DESCRIPTOR -1 #define DETAILED_TIMING_BLOCK -2 -struct edid_timing_t edid_establish_timing[] = { +edid_timing_t edid_establish_timing[] = { { 800, 600, 60 }, { 800, 600, 56 }, { 640, 480, 75 }, { 640, 480, 72 }, { 640, 480, 67 }, { 640, 480, 60 }, { 720, 400, 88 }, { 720, 400, 70 }, { 1280, 1024, 75 }, { 1024, 768, 75 }, { 1024, 768, 70 }, @@ -61,7 +61,7 @@ struct edid_timing_t edid_establish_timing[] = { }; int edid_msg_enable; int edid_disable; -struct edid_parsed_t edid_parsed; +edid_parsed_t edid_parsed; #undef DBGMSG #define DBGMSG(fmt, args...) if (edid_msg_enable) \ @@ -114,7 +114,7 @@ static char *get_monitor_name(char *block, char *name) return name; } /* End of get_monitor_name() */ -static int parse_timing_description(char *dtd, struct edid_info_t *info) +static int parse_timing_description(char *dtd, edid_info_t *info) { #define PIXEL_CLOCK_LO ((unsigned)dtd[0]) #define PIXEL_CLOCK_HI ((unsigned)dtd[1]) @@ -239,7 +239,7 @@ static int parse_dpms_capabilities(char flags) return 0; } /* End of parse_dpms_capabilities() */ -static int parse_monitor_limits(char *block, struct edid_info_t *info) +static int parse_monitor_limits(char *block, edid_info_t *info) { #define V_MIN_RATE block[5] #define V_MAX_RATE block[6] @@ -264,7 +264,7 @@ static int parse_monitor_limits(char *block, struct edid_info_t *info) return 0; } /* End of parse_monitor_limits() */ -static int get_established_timing(char *edid, struct edid_info_t *info) +static int get_established_timing(char *edid, edid_info_t *info) { char time_1, time_2; @@ -321,7 +321,7 @@ static int get_established_timing(char *edid, struct edid_info_t *info) return 0; } /* End of get_established_timing() */ -static int get_standard_timing(char *edid, struct edid_info_t *info) +static int get_standard_timing(char *edid, edid_info_t *info) { char *ptr = edid + STANDARD_TIMING_IDENTIFICATION_START; int h_res, v_res, v_freq; @@ -368,7 +368,7 @@ static int get_standard_timing(char *edid, struct edid_info_t *info) return 0; } /* End of get_standard_timing() */ -static int edid_parse_v1(char *edid, struct edid_info_t *info) +static int edid_parse_v1(char *edid, edid_info_t *info) { char *block; char *monitor_name = 0; @@ -388,8 +388,10 @@ static int edid_parse_v1(char *edid, struct edid_info_t *info) goto parse_end; } +//#ifdef DEBUG if(edid_msg_enable) edid_dump(edid); +//#endif DBGMSG("[EDID] EDID version: %d.%d\n", (int)edid[EDID_STRUCT_VERSION], @@ -397,10 +399,6 @@ static int edid_parse_v1(char *edid, struct edid_info_t *info) get_vendor_sign(edid + ID_MANUFACTURER_NAME, (char *) &vendor_sign); - info->width = edid[EDID_MAX_HOR_IMAGE_SIZE] * 10; - info->height = edid[EDID_MAX_VER_IMAGE_SIZE] * 10; - DBGMSG("[EDID] max hor %d cm ver %d cm\n", info->width, info->height); - /*--------------------------------------------------------------------- Parse Monitor name ---------------------------------------------------------------------*/ @@ -433,7 +431,7 @@ static int edid_parse_v1(char *edid, struct edid_info_t *info) strcpy(edid_parsed.tv_name.vendor_name, vendor_sign); memset(edid_parsed.tv_name.monitor_name, 0, sizeof(edid_parsed.tv_name.monitor_name)); - if (strlen(monitor_name) < MONITOR_NAME_LEN) + if(strlen(monitor_name) < MONITOR_NAME_LEN) strcpy(edid_parsed.tv_name.monitor_name, monitor_name); else strncpy(edid_parsed.tv_name.monitor_name, monitor_name, MONITOR_NAME_LEN - 1); @@ -468,7 +466,7 @@ parse_end: } void edid_parse_CEA_VendorSpecDataBlock(char *block, int len, - struct edid_info_t *info) + edid_info_t *info) { int index; char temp; @@ -541,10 +539,8 @@ void edid_parse_CEA_VendorSpecDataBlock(char *block, int len, if (hdmi_3d_len) { int struct_all_3d = 0; - int mask_3d = 0xFF; - int vic_order_2d; - char struct_3d, detail_3d; - int i; + int mask_3d = 0; + char vic_order_2d, struct_3d, detail_3d; hdmi_3d_len += index; switch (temp & 0x60) { @@ -574,11 +570,6 @@ void edid_parse_CEA_VendorSpecDataBlock(char *block, int len, if (struct_all_3d & BIT8) DBGMSG("\t\tSupport Side by Side\n"); - for (i = 0; i < 16; i++) { - if (mask_3d & (0x1 << i)) - info->vic_3d[i].mask = struct_all_3d; - } - DBGMSG("\t\t[3D Structure type 0-Frame packing"); DBGMSG(",6-Top and Bottom,8-Side by Side]\n"); while (index < hdmi_3d_len) { @@ -591,8 +582,6 @@ void edid_parse_CEA_VendorSpecDataBlock(char *block, int len, } else { detail_3d = 0; } - info->vic_3d[vic_order_2d].mask |= - (0x1 << struct_3d); DBGMSG("\t\tVIC %d,3D struct %d,detail %d\n", vic_order_2d, struct_3d, detail_3d); } @@ -600,7 +589,7 @@ void edid_parse_CEA_VendorSpecDataBlock(char *block, int len, } } -static int edid_parse_CEA(char *edid, struct edid_info_t *info) +static int edid_parse_CEA(char *edid, edid_info_t *info) { char *block, *block_end; char checksum = 0; @@ -617,15 +606,15 @@ static int edid_parse_CEA(char *edid, struct edid_info_t *info) checksum += edid[i]; if (checksum != 0) { - DPRINT("*E* CEA EDID checksum (0x%02x) - data is corrupt\n", - checksum); + DPRINT("*E* CEA EDID checksum (0x%02x) failed - data is corrupt\n", checksum); info->option |= (EDID_OPT_HDMI + EDID_OPT_AUDIO); - edid_dump(edid); return -1; } +//#ifdef DEBUG if(edid_msg_enable) edid_dump(edid); +//#endif DBGMSG("[EDID] CEA EDID Version %d.%d\n", edid[0], edid[1]); @@ -642,34 +631,27 @@ static int edid_parse_CEA(char *edid, struct edid_info_t *info) block = edid + 4; do { len = block[0] & 0x1F; - switch (((block[0] & 0xE0) >> 5)) { + switch (((block[0] & 0xE0)>>5)) { case 1: /* Audio Data Block */ DBGMSG("Audio Data Block (0x%02X)\n", block[0]); info->option |= EDID_OPT_AUDIO; sadcnt_in_block = len / 3; - for (i = 0; i < sadcnt_in_block; i++) { - if (num < AUD_SAD_NUM) { + for(i = 0; i < sadcnt_in_block; i++){ + if(num < AUD_SAD_NUM) { edid_parsed.sad[num].flag = 1; - edid_parsed.sad[num].sad_byte[0] = - block[i * 3 + 1]; - edid_parsed.sad[num].sad_byte[1] = - block[i * 3 + 2]; - edid_parsed.sad[num].sad_byte[2] = - block[i * 3 + 3]; + edid_parsed.sad[num].sad_byte[0] = block[i * 3 + 1]; + edid_parsed.sad[num].sad_byte[1] = block[i * 3 + 2]; + edid_parsed.sad[num].sad_byte[2] = block[i * 3 + 3]; num++; } else { - DPRINT("Lose SAD info:%02X %02X %02X\n", - block[i * 3 + 1], - block[i * 3 + 2], - block[i * 3 + 3]); + DPRINT("Lose SAD info: 0x%02X 0x%02X 0x%02X\n", + block[i * 3 + 1], block[i * 3 + 2], block[i * 3 + 3]); } DBGMSG("\t ======== SDA %d ========\n", i); DBGMSG("\t SDA Data: 0x%02X 0x%02X 0x%02X\n", - block[i * 3 + 1], - block[i * 3 + 2], - block[i * 3 + 3]); + block[i * 3 + 1], block[i * 3 + 2], block[i * 3 + 3]); audio_format = (block[i * 3 + 1] & 0x78) >> 3; switch (audio_format) { @@ -722,8 +704,7 @@ static int edid_parse_CEA(char *edid, struct edid_info_t *info) break; } - DBGMSG("\t Max channel: %d\n", - (block[i * 3 + 1] & 0x7) + 1); + DBGMSG("\t Max channel: %d\n", (block[i * 3 + 1] & 0x7) + 1); DBGMSG("\t %s support 32 KHz\n", (block[i * 3 + 2] & 0x1) ? "" : "no"); DBGMSG("\t %s support 44 KHz\n", @@ -738,26 +719,18 @@ static int edid_parse_CEA(char *edid, struct edid_info_t *info) (block[i * 3 + 2] & 0x20) ? "" : "no"); DBGMSG("\t %s support 192 KHz\n", (block[i * 3 + 2] & 0x40) ? "" : "no"); - if (audio_format == 1) { /* For LPCM */ + if(audio_format == 1) { /* For LPCM */ DBGMSG("\t %s support 16 bit\n", - (block[i * 3 + 3] & 0x1) ? - "" : "no"); + (block[i * 3 + 3] & 0x1) ? "" : "no"); DBGMSG("\t %s support 20 bit\n", - (block[i * 3 + 3] & 0x2) ? - "" : "no"); + (block[i * 3 + 3] & 0x2) ? "" : "no"); DBGMSG("\t %s support 24 bit\n", - (block[i * 3 + 3] & 0x4) ? - "" : "no"); - } else if (audio_format >= 2 && - audio_format <= 8) { - /* From AC3 to ATRAC */ - DBGMSG("\t Max bitrate: %d kbit/s\n", - block[i * 3 + 3] * 8); - } else if (audio_format >= 9 && - audio_format <= 14) { - /* From One-bit-audio to WMA Pro*/ - DBGMSG("\t Audio Format Code:0x%02X\n", - block[i * 3 + 3]); + (block[i * 3 + 3] & 0x4) ? "" : "no"); + } else if(audio_format >= 2 && audio_format <= 8) { /* From AC3 to ATRAC */ + DBGMSG("\t Max bitrate: %d kbit/s\n", block[i * 3 + 3] * 8); + } + else if(audio_format >= 9 && audio_format <= 14) { /* From One-bit-audio to WMA Pro*/ + DBGMSG("\t Audio Format Code dependent value: 0x%02X\n", block[i * 3 + 3]); } DBGMSG("\t ========================\n"); } @@ -769,8 +742,6 @@ static int edid_parse_CEA(char *edid, struct edid_info_t *info) vic = block[1 + i] & 0x7F; info->cea_vic[vic / 8] |= (0x1 << (vic % 8)); - if (i < 16) - info->vic_3d[i].vic = vic; DBGMSG("\t %2d : VIC %2d %dx%d@%d%s %s\n", i, vic, hdmi_vic_info[vic].resx, hdmi_vic_info[vic].resy, @@ -884,7 +855,7 @@ int edid_checksum(char *edid, int len) return checksum; } -int edid_parse(char *edid, struct edid_info_t *info) +int edid_parse(char *edid, edid_info_t *info) { int ext_cnt = 0; @@ -898,7 +869,7 @@ int edid_parse(char *edid, struct edid_info_t *info) DBG_MSG("[EDID] Enter\n"); - memset(info, 0, sizeof(struct edid_info_t)); + memset(info, 0, sizeof(edid_info_t)); info->option = EDID_OPT_VALID; if (edid_parse_v1(edid, info) == 0) { ext_cnt = edid[0x7E]; @@ -923,7 +894,7 @@ int edid_parse(char *edid, struct edid_info_t *info) return info->option; } -int edid_find_support(struct edid_info_t *info, unsigned int resx, +int edid_find_support(edid_info_t *info, unsigned int resx, unsigned int resy, int freq, struct fb_videomode **vmode) { struct fb_videomode *p; @@ -937,26 +908,6 @@ int edid_find_support(struct edid_info_t *info, unsigned int resx, if (!info) return 0; - /* find detail timing */ - for (i = 0; i < 4; i++) { - p = &info->detail_timing[i]; - if (p->pixclock == 0) - continue; - if (resx != p->xres) - continue; - if (resy != p->yres) - continue; - - temp = p->refresh; - temp |= (p->vmode & FB_VMODE_INTERLACED) ? - EDID_TMR_INTERLACE : 0; - if (freq != temp) - continue; - *vmode = p; - ret = 3; - goto find_end; - } - /* find cea timing */ for (i = 0; i < 6; i++) { p = &info->cea_timing[i]; @@ -1000,6 +951,26 @@ int edid_find_support(struct edid_info_t *info, unsigned int resx, goto find_end; } + /* find detail timing */ + for (i = 0; i < 4; i++) { + p = &info->detail_timing[i]; + if (p->pixclock == 0) + continue; + if (resx != p->xres) + continue; + if (resy != p->yres) + continue; + + temp = p->refresh; + temp |= (p->vmode & FB_VMODE_INTERLACED) ? + EDID_TMR_INTERLACE : 0; + if (freq != temp) + continue; + *vmode = p; + ret = 3; + goto find_end; + } + /* find established timing */ if (info->establish_timing) { for (i = 0; i < 17; i++) { @@ -1048,22 +1019,9 @@ find_end: unsigned int edid_get_hdmi_phy_addr(void) { - struct vout_t *vo; + vout_t *vo; vo = vout_get_entry(VPP_VOUT_NUM_HDMI); return vo->edid_info.hdmi_phy_addr; } -unsigned int edid_get_hdmi_3d_mask(struct edid_info_t *info, int vic) -{ - int i; - - if (!info) - return 0; - for (i = 0; i < 16; i++) { - if (info->vic_3d[i].vic == vic) - return info->vic_3d[i].mask; - } - return 0; -} - diff --git a/drivers/video/wmt/scl.c b/drivers/video/wmt/scl.c index f367a0dc..f8433a04 100755..100644 --- a/drivers/video/wmt/scl.c +++ b/drivers/video/wmt/scl.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/scl.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -28,9 +28,6 @@ #include "scl.h" -HW_REG struct scl_base1_regs *scl_regs1 = (void *) SCL_BASE_ADDR; -HW_REG struct scl_base2_regs *scl_regs2 = (void *) SCL_BASE2_ADDR; - #ifdef WMT_FTBLK_SCL void scl_reg_dump(void) { @@ -41,130 +38,144 @@ void scl_reg_dump(void) REG_SCL_BASE1_END - REG_SCL_BASE1_BEGIN); vpp_reg_dump(REG_SCL_BASE2_BEGIN, REG_SCL_BASE2_END - REG_SCL_BASE2_BEGIN); - DPRINT("---------- SCL scale ----------\n"); - DPRINT("scale enable %d\n", scl_regs1->en.b.alu_enable); + DPRINT("scale enable %d\n", vppif_reg32_read(SCL_ALU_ENABLE)); DPRINT("mode bilinear(H %d,V %d),recursive(H %d,V %d)\n", - scl_regs1->true_bilinear.b.h, scl_regs1->true_bilinear.b.v, - scl_regs2->recursive_mode.b.h, scl_regs2->recursive_mode.b.v); + vppif_reg32_read(SCL_BILINEAR_H), + vppif_reg32_read(SCL_BILINEAR_V), + vppif_reg32_read(SCL_RECURSIVE_H), + vppif_reg32_read(SCL_RECURSIVE_V)); DPRINT("src(%d,%d),dst(%d,%d)\n", - scl_regs1->r_h_size.b.pix_w, scl_regs1->vxwidth.b.vxwidth, - scl_regs1->hscale1.b.thr, scl_regs1->vscale1.b.thr); + vppif_reg32_read(SCLR_YPXLWID), + vppif_reg32_read(SCL_VXWIDTH), + vppif_reg32_read(SCL_H_THR), + vppif_reg32_read(SCL_V_THR)); DPRINT("scale width H %d,V %d\n", - scl_regs1->hxwidth.b.hxwidth, scl_regs1->vxwidth.b.vxwidth); + vppif_reg32_read(SCL_HXWIDTH), + vppif_reg32_read(SCL_VXWIDTH)); DPRINT("H scale up %d,V scale up %d\n", - scl_regs1->sclup_en.b.h, scl_regs1->sclup_en.b.v); + vppif_reg32_read(SCL_HSCLUP_ENABLE), + vppif_reg32_read(SCL_VSCLUP_ENABLE)); DPRINT("H sub step %d,thr %d,step %d,sub step cnt %d,i step cnt %d\n", - scl_regs1->hscale1.b.substep, scl_regs1->hscale1.b.thr, - scl_regs1->hscale2.b.step, scl_regs1->hscale2.b.substepcnt, - scl_regs1->hscale3.b.stepcnt); + vppif_reg32_read(SCL_H_SUBSTEP), + vppif_reg32_read(SCL_H_THR), + vppif_reg32_read(SCL_H_STEP), + vppif_reg32_read(SCL_H_I_SUBSTEPCNT), + vppif_reg32_read(SCL_H_I_STEPCNT)); DPRINT("V sub step %d,thr %d,step %d,sub step cnt %d,i step cnt %d\n", - scl_regs1->vscale1.b.substep, scl_regs1->vscale1.b.thr, - scl_regs1->vscale2.b.step, scl_regs1->vscale2.b.substepcnt, - scl_regs1->vscale3.b.stepcnt); + vppif_reg32_read(SCL_V_SUBSTEP), + vppif_reg32_read(SCL_V_THR), + vppif_reg32_read(SCL_V_STEP), + vppif_reg32_read(SCL_V_I_SUBSTEPCNT), + vppif_reg32_read(SCL_V_I_STEPCNT)); DPRINT("---------- SCL filter ----------\n"); DPRINT("DEBLOCK %d,boundary 1st 0x%x,2nd 0x%x\n,", - scl_regs2->field_mode.b.deblock, - scl_regs2->dblk_threshold.b.layer1_boundary, - scl_regs2->dblk_threshold.b.layer2_boundary); + vppif_reg32_read(SCL_DEBLOCK_ENABLE), + vppif_reg32_read(SCL_1ST_LAYER_BOUNDARY), + vppif_reg32_read(SCL_2ND_LAYER_BOUNDARY)); DPRINT("FIELD DEFLICKER %d,up %s down,thr Y %d,C %d\n", - scl_regs2->field_mode.b.field_deflicker, - (scl_regs2->field_mode.b.field_deflicker) ? "&" : "or", - scl_regs2->field_flicker.b.y_thd, - scl_regs2->field_flicker.b.c_thd); + vppif_reg32_read(SCL_FIELD_DEFLICKER), + vppif_reg32_read(SCL_FIELD_DEFLICKER) ? "&" : "or", + vppif_reg32_read(SCL_FIELD_FILTER_Y_THD), + vppif_reg32_read(SCL_FIELD_FILTER_C_THD)); DPRINT("FRAME DEFLICKER %d,%s,2^%d,scene chg %d\n", - scl_regs2->field_mode.b.frame_deflicker, - (scl_regs2->frame_flicker.b.rgb) ? "RGB" : "Y", - scl_regs2->frame_flicker.b.sampler, - scl_regs2->frame_flicker.b.scene_chg_thd); + vppif_reg32_read(SCL_FRAME_DEFLICKER), + vppif_reg32_read(SCL_FRAME_FILTER_RGB) ? "RGB" : "Y", + vppif_reg32_read(SCL_FRAME_FILTER_SAMPLER), + vppif_reg32_read(SCL_FR_FILTER_SCENE_CHG_THD)); DPRINT("CSC enable %d,CSC clamp %d\n", - scl_regs2->csc_ctl.b.enable, - scl_regs2->csc_ctl.b.clamp_enable); + vppif_reg32_read(SCL_CSC_ENABLE), + vppif_reg32_read(SCL_CSC_CLAMP_ENABLE)); DPRINT("---------- SCL TG ----------\n"); DPRINT("TG source : %s\n", - (scl_regs1->tg_govw.b.enable) ? "GOVW" : "SCL"); + (vppif_reg32_read(SCL_TG_GOVWTG_ENABLE)) ? "GOVW" : "SCL"); DPRINT("TG enable %d, wait ready enable %d\n", - scl_regs1->tg_ctl.b.enable, - scl_regs1->tg_ctl.b.watchdog_enable); + vppif_reg32_read(SCL_TG_ENABLE), + vppif_reg32_read(SCL_TG_WATCHDOG_ENABLE)); DPRINT("clk %d,Read cyc %d,1T %d\n", vpp_get_base_clock(VPP_MOD_SCL), - scl_regs1->tg_ctl.b.rdcyc, scl_regs2->readcyc_1t.b.rdcyc_1t); + vppif_reg32_read(SCL_TG_RDCYC), + vppif_reg32_read(SCL_READCYC_1T)); DPRINT("H total %d, beg %d, end %d\n", - scl_regs1->tg_total.b.h_allpixel, - scl_regs1->tg_h_active.b.h_actbg, - scl_regs1->tg_h_active.b.h_actend); + vppif_reg32_read(SCL_TG_H_ALLPIXEL), + vppif_reg32_read(SCL_TG_H_ACTBG), + vppif_reg32_read(SCL_TG_H_ACTEND)); DPRINT("V total %d, beg %d, end %d\n", - scl_regs1->tg_total.b.v_allline, - scl_regs1->tg_v_active.b.v_actbg, - scl_regs1->tg_v_active.b.v_actend); + vppif_reg32_read(SCL_TG_V_ALLLINE), + vppif_reg32_read(SCL_TG_V_ACTBG), + vppif_reg32_read(SCL_TG_V_ACTEND)); DPRINT("VBIE %d,PVBI %d\n", - scl_regs1->tg_vbi.b.vbie, scl_regs1->tg_vbi.b.pvbi); + vppif_reg32_read(SCL_TG_VBIE), + vppif_reg32_read(SCL_TG_PVBI)); DPRINT("Watch dog 0x%x\n", - scl_regs1->tg_watchdog); + vppif_reg32_read(SCL_TG_WATCHDOG_VALUE)); DPRINT("---------- SCLR FB ----------\n"); DPRINT("SCLR MIF enable %d\n", - scl_regs1->r_ctl.b.mif_enable); + vppif_reg32_read(SCLR_MIF_ENABLE)); DPRINT("color format %s\n", vpp_colfmt_str[sclr_get_color_format()]); DPRINT("color bar enable %d,mode %d,inv %d\n", - scl_regs1->r_ctl.b.colorbar_enable, - scl_regs1->r_ctl.b.colorbar_mode, - scl_regs1->r_ctl.b.colorbar_inv); + vppif_reg32_read(SCLR_COLBAR_ENABLE), + vppif_reg32_read(SCLR_COLBAR_MODE), + vppif_reg32_read(SCLR_COLBAR_INVERSION)); DPRINT("sourc mode : %s,H264 %d\n", - (scl_regs1->r_ctl.b.field) ? "field" : "frame", - scl_regs1->r_ctl.b.h264); + (vppif_reg32_read(SCLR_TAR_DISP_FMT)) ? "field" : "frame", + vppif_reg32_read(SCLR_MEDIAFMT_H264)); DPRINT("Y addr 0x%x, C addr 0x%x\n", - scl_regs1->r_ysa, scl_regs1->r_csa); + vppif_reg32_in(REG_SCLR_YSA), + vppif_reg32_in(REG_SCLR_CSA)); DPRINT("width %d, fb width %d\n", - scl_regs1->r_h_size.b.pix_w, scl_regs1->r_h_size.b.fb_w); + vppif_reg32_read(SCLR_YPXLWID), + vppif_reg32_read(SCLR_YBUFWID)); DPRINT("H crop %d, V crop %d\n", - scl_regs1->r_crop.b.hcrop, scl_regs1->r_crop.b.vcrop); + vppif_reg32_read(SCLR_HCROP), + vppif_reg32_read(SCLR_VCROP)); DPRINT("---------- SCLW FB ----------\n"); - DPRINT("SCLW MIF enable %d\n", scl_regs1->w_ctl.b.mif_enable); + DPRINT("SCLW MIF enable %d\n", vppif_reg32_read(SCLW_MIF_ENABLE)); DPRINT("color format %s\n", vpp_colfmt_str[sclw_get_color_format()]); DPRINT("Y addr 0x%x, C addr 0x%x\n", - scl_regs1->w_ysa, scl_regs1->w_csa); + vppif_reg32_in(REG_SCLW_YSA), vppif_reg32_in(REG_SCLW_CSA)); DPRINT("Y width %d, fb width %d\n", - scl_regs1->w_y_time.b.pxl_w, scl_regs1->w_y_time.b.fb_w); + vppif_reg32_read(SCLW_YPXLWID), vppif_reg32_read(SCLW_YBUFWID)); DPRINT("C width %d, fb width %d\n", - scl_regs1->w_c_time.b.pxl_w, scl_regs1->w_c_time.b.fb_w); + vppif_reg32_read(SCLW_CPXLWID), vppif_reg32_read(SCLW_CBUFWID)); DPRINT("Y err %d, C err %d\n", - scl_regs1->w_ff_ctl.b.mif_y_err, - scl_regs1->w_ff_ctl.b.mif_c_err); + vppif_reg32_read(SCLW_INTSTS_MIFYERR), + vppif_reg32_read(SCLW_INTSTS_MIFCERR)); DPRINT("---------- SCLR2 FB ----------\n"); - DPRINT("MIF enable %d\n", scl_regs1->r2_ctl.b.mif_en); + DPRINT("MIF enable %d\n", vppif_reg32_read(SCL_R2_MIF_EN)); DPRINT("color format %s\n", vpp_colfmt_str[scl_R2_get_color_format()]); DPRINT("color bar enable %d,mode %d,inv %d\n", - scl_regs1->r2_ctl.b.color_en, - scl_regs1->r2_ctl.b.color_wide, - scl_regs1->r2_ctl.b.color_inv); + vppif_reg32_read(SCL_R2_COLOR_EN), + vppif_reg32_read(SCL_R2_COLOR_EN), + vppif_reg32_read(SCL_R2_COLOR_INV)); DPRINT("sourc mode : %s,H264 %d\n", - (scl_regs1->r2_ctl.b.iofmt) ? "field" : "frame", - scl_regs1->r2_ctl.b.h264_fmt); + (vppif_reg32_read(SCL_R2_IOFMT)) ? "field" : "frame", + vppif_reg32_read(SCL_R2_H264_FMT)); DPRINT("Y addr 0x%x, C addr 0x%x\n", - scl_regs1->r2_ysa, scl_regs1->r2_csa); + vppif_reg32_in(REG_SCLR2_YSA), vppif_reg32_in(REG_SCLR2_CSA)); DPRINT("width %d, fb width %d\n", - scl_regs1->r2_h_size.b.lnsize, scl_regs1->r2_h_size.b.fbw); + vppif_reg32_read(SCL_R2_LNSIZE), vppif_reg32_read(SCL_R2_FBW)); DPRINT("H crop %d, V crop %d\n", - scl_regs1->r2_crop.b.hcrop, scl_regs1->r2_crop.b.vcrop); + vppif_reg32_read(SCL_R2_HCROP), vppif_reg32_read(SCL_R2_VCROP)); DPRINT("---------- ALPHA ----------\n"); DPRINT("src alpha %d,dst alpha %d,swap %d\n", - scl_regs1->alpha_md.b.src, - scl_regs1->alpha_md.b.dst, - scl_regs1->alpha_md.b.swap); + vppif_reg32_read(SCL_ALPHA_SRC), + vppif_reg32_read(SCL_ALPHA_DST), + vppif_reg32_read(SCL_ALPHA_SWAP)); DPRINT("src fix 0x%x,dst fix 0x%x\n", - scl_regs1->alpha_fxd.b.src_fixed, - scl_regs1->alpha_fxd.b.dst_fixed); + vppif_reg32_read(SCL_ALPHA_SRC_FIXED), + vppif_reg32_read(SCL_ALPHA_DST_FIXED)); DPRINT("---------- ColorKey ----------\n"); - DPRINT("enable %d\n", scl_regs1->alpha_colorkey.b.enable); + DPRINT("enable %d\n", vppif_reg32_read(SCL_ALPHA_COLORKEY_ENABLE)); DPRINT("from %s,comp %d,mode %d\n", - (scl_regs1->alpha_colorkey.b.from) ? "mif2" : "mif1", - scl_regs1->alpha_colorkey.b.comp, - scl_regs1->alpha_colorkey.b.mode); + (vppif_reg32_read(SCL_ALPHA_COLORKEY_FROM)) ? "mif2" : "mif1", + vppif_reg32_read(SCL_ALPHA_COLORKEY_COMP), + vppif_reg32_read(SCL_ALPHA_COLORKEY_MODE)); DPRINT("R 0x%x,G 0x%x,B 0x%x\n", - scl_regs1->alpha_colorkey_rgb.b.r, - scl_regs1->alpha_colorkey_rgb.b.g, - scl_regs1->alpha_colorkey_rgb.b.b); + vppif_reg32_read(SCL_ALPHA_COLORKEY_R), + vppif_reg32_read(SCL_ALPHA_COLORKEY_G), + vppif_reg32_read(SCL_ALPHA_COLORKEY_B)); DPRINT("---------- sw status ----------\n"); DPRINT("complete %d\n", p_scl->scale_complete); @@ -173,74 +184,83 @@ void scl_reg_dump(void) void scl_set_enable(vpp_flag_t enable) { - scl_regs1->en.b.alu_enable = enable; + vppif_reg32_write(SCL_ALU_ENABLE, enable); } void scl_set_reg_update(vpp_flag_t enable) { - scl_regs1->upd.b.reg_update = enable; + vppif_reg32_write(SCL_REG_UPDATE, enable); } void scl_set_reg_level(vpp_reglevel_t level) { - scl_regs1->sel.b.reg_level = level; + switch (level) { + case VPP_REG_LEVEL_1: + vppif_reg32_write(SCL_REG_LEVEL, 0x0); + break; + case VPP_REG_LEVEL_2: + vppif_reg32_write(SCL_REG_LEVEL, 0x1); + break; + default: + DBGMSG("*E* check the parameter.\n"); + return; + } } -void scl_set_int_enable(vpp_flag_t enable, enum vpp_int_t int_bit) +void scl_set_int_enable(vpp_flag_t enable, vpp_int_t int_bit) { /* clean status first before enable/disable interrupt */ scl_clean_int_status(int_bit); if (int_bit & VPP_INT_ERR_SCL_TG) - scl_regs1->w_int_en.b.tg_err = enable; + vppif_reg32_write(SCLW_INT_TGERR_ENABLE, enable); if (int_bit & VPP_INT_ERR_SCLR1_MIF) - scl_regs1->w_int_en.b.r1_mif_enable = enable; + vppif_reg32_write(SCLW_INT_R1MIF_ENABLE, enable); if (int_bit & VPP_INT_ERR_SCLR2_MIF) - scl_regs1->w_int_en.b.r2_mif_enable = enable; + vppif_reg32_write(SCLW_INT_R2MIF_ENABLE, enable); if (int_bit & VPP_INT_ERR_SCLW_MIFRGB) - scl_regs1->w_int_en.b.mif_rgb_err = enable; + vppif_reg32_write(SCLW_INT_WMIFRGB_ENABLE, enable); if (int_bit & VPP_INT_ERR_SCLW_MIFY) - scl_regs1->w_int_en.b.mif_y_err = enable; + vppif_reg32_write(SCLW_INT_WMIFYERR_ENABLE, enable); if (int_bit & VPP_INT_ERR_SCLW_MIFC) - scl_regs1->w_int_en.b.mif_c_err = enable; + vppif_reg32_write(SCLW_INT_WMIFCERR_ENABLE, enable); } -enum vpp_int_err_t scl_get_int_status(void) +vpp_int_err_t scl_get_int_status(void) { - enum vpp_int_err_t int_sts; + vpp_int_err_t int_sts; int_sts = 0; - if (scl_regs1->tg_sts.b.tgerr) + if (vppif_reg32_read(SCL_INTSTS_TGERR)) int_sts |= VPP_INT_ERR_SCL_TG; - if (scl_regs1->r_fifo_ctl.b.r1_mif_err) + if (vppif_reg32_read(SCLR_INTSTS_R1MIFERR)) int_sts |= VPP_INT_ERR_SCLR1_MIF; - if (scl_regs1->r_fifo_ctl.b.r2_mif_err) + if (vppif_reg32_read(SCLR_INTSTS_R2MIFERR)) int_sts |= VPP_INT_ERR_SCLR2_MIF; - if (scl_regs1->w_ff_ctl.b.mif_rgb_err) + if (vppif_reg32_read(SCLW_INTSTS_MIFRGBERR)) int_sts |= VPP_INT_ERR_SCLW_MIFRGB; - if (scl_regs1->w_ff_ctl.b.mif_y_err) + if (vppif_reg32_read(SCLW_INTSTS_MIFYERR)) int_sts |= VPP_INT_ERR_SCLW_MIFY; - if (scl_regs1->w_ff_ctl.b.mif_c_err) + if (vppif_reg32_read(SCLW_INTSTS_MIFCERR)) int_sts |= VPP_INT_ERR_SCLW_MIFC; + return int_sts; } -void scl_clean_int_status(enum vpp_int_err_t int_sts) +void scl_clean_int_status(vpp_int_err_t int_sts) { if (int_sts & VPP_INT_ERR_SCL_TG) - scl_regs1->tg_sts.val = BIT0; + vppif_reg32_out(REG_SCL_TG_STS + 0x0, BIT0); if (int_sts & VPP_INT_ERR_SCLR1_MIF) - scl_regs1->r_fifo_ctl.val = - (scl_regs1->r_fifo_ctl.val & ~0x300) | BIT8; + vppif_reg8_out(REG_SCLR_FIFO_CTL + 0x1, BIT0); if (int_sts & VPP_INT_ERR_SCLR2_MIF) - scl_regs1->r_fifo_ctl.val = - (scl_regs1->r_fifo_ctl.val & ~0x300) | BIT9; + vppif_reg8_out(REG_SCLR_FIFO_CTL + 0x1, BIT1); if (int_sts & VPP_INT_ERR_SCLW_MIFRGB) - scl_regs1->w_ff_ctl.val = BIT16; + vppif_reg32_out(REG_SCLW_FF_CTL, BIT16); if (int_sts & VPP_INT_ERR_SCLW_MIFY) - scl_regs1->w_ff_ctl.val = BIT8; + vppif_reg32_out(REG_SCLW_FF_CTL, BIT8); if (int_sts & VPP_INT_ERR_SCLW_MIFC) - scl_regs1->w_ff_ctl.val = BIT0; + vppif_reg32_out(REG_SCLW_FF_CTL, BIT0); } void scl_set_csc_mode(vpp_csc_t mode) @@ -250,42 +270,25 @@ void scl_set_csc_mode(vpp_csc_t mode) src_fmt = sclr_get_color_format(); dst_fmt = sclw_get_color_format(); mode = vpp_check_csc_mode(mode, src_fmt, dst_fmt, 0); - if (p_scl->abgr_mode) { - unsigned int parm[5]; - - parm[0] = (vpp_csc_parm[mode][1] & 0xFFFF) | - (vpp_csc_parm[mode][0] & 0xFFFF0000); /* C3,C2 */ - parm[1] = (vpp_csc_parm[mode][0] & 0xFFFF) | - (vpp_csc_parm[mode][2] & 0xFFFF0000); /* C1,C6 */ - parm[2] = (vpp_csc_parm[mode][2] & 0xFFFF) | - (vpp_csc_parm[mode][1] & 0xFFFF0000); /* C5,C4 */ - parm[3] = (vpp_csc_parm[mode][4] & 0xFFFF) | - (vpp_csc_parm[mode][3] & 0xFFFF0000); /* C9,C8 */ - parm[4] = (vpp_csc_parm[mode][3] & 0xFFFF) | - (vpp_csc_parm[mode][4] & 0xFFFF0000); /* C7,I */ - - scl_regs2->csc1 = parm[0]; - scl_regs2->csc2 = parm[1]; - scl_regs2->csc3 = parm[2]; - scl_regs2->csc4 = parm[3]; - scl_regs2->csc5 = parm[4]; - } else { - scl_regs2->csc1 = vpp_csc_parm[mode][0]; - scl_regs2->csc2 = vpp_csc_parm[mode][1]; - scl_regs2->csc3 = vpp_csc_parm[mode][2]; - scl_regs2->csc4 = vpp_csc_parm[mode][3]; - scl_regs2->csc5 = vpp_csc_parm[mode][4]; + if (mode >= VPP_CSC_MAX) + vppif_reg32_write(SCL_CSC_ENABLE, VPP_FLAG_DISABLE); + else { + vppif_reg32_out(REG_SCL_CSC1, vpp_csc_parm[mode][0]); + vppif_reg32_out(REG_SCL_CSC2, vpp_csc_parm[mode][1]); + vppif_reg32_out(REG_SCL_CSC3, vpp_csc_parm[mode][2]); + vppif_reg32_out(REG_SCL_CSC4, vpp_csc_parm[mode][3]); + vppif_reg32_out(REG_SCL_CSC5, vpp_csc_parm[mode][4]); + vppif_reg32_out(REG_SCL_CSC6, vpp_csc_parm[mode][5]); + vppif_reg32_out(REG_SCL_CSC_CTL, vpp_csc_parm[mode][6]); + vppif_reg32_write(SCL_CSC_ENABLE, VPP_FLAG_ENABLE); } - scl_regs2->csc6 = vpp_csc_parm[mode][5]; - scl_regs2->csc_ctl.val = vpp_csc_parm[mode][6]; - scl_regs2->csc_ctl.b.enable = (mode >= VPP_CSC_MAX) ? 0 : 1; } void scl_set_scale_enable(vpp_flag_t vscl_enable, vpp_flag_t hscl_enable) { DBGMSG("V %d,H %d\n", vscl_enable, hscl_enable); - scl_regs1->sclup_en.b.v = vscl_enable; - scl_regs1->sclup_en.b.h = hscl_enable; + vppif_reg32_write(SCL_VSCLUP_ENABLE, vscl_enable); + vppif_reg32_write(SCL_HSCLUP_ENABLE, hscl_enable); } void scl_set_V_scale(int A, int B) /* A dst,B src */ @@ -307,12 +310,14 @@ void scl_set_V_scale(int A, int B) /* A dst,B src */ DBG_DETAIL("V step %d,sub step %d, div2 %d\r\n", V_STEP, V_SUB_STEP, V_THR_DIV2); - scl_regs1->vxwidth.b.dst_vxwidth = (A > B) ? A : B; - scl_regs1->vxwidth.b.vxwidth = B; - scl_regs1->vscale2.b.step = V_STEP; - scl_regs1->vscale1.b.substep = V_SUB_STEP; - scl_regs1->vscale1.b.thr = V_THR_DIV2; - scl_regs1->vscale2.b.substepcnt = 0; +#ifdef SCL_DST_VXWIDTH + vppif_reg32_write(SCL_DST_VXWIDTH, (A > B) ? A : B); +#endif + vppif_reg32_write(SCL_VXWIDTH, B); + vppif_reg32_write(SCL_V_STEP, V_STEP); + vppif_reg32_write(SCL_V_SUBSTEP, V_SUB_STEP); + vppif_reg32_write(SCL_V_THR, V_THR_DIV2); + vppif_reg32_write(SCL_V_I_SUBSTEPCNT, 0); } void scl_set_H_scale(int A, int B) /* A dst,B src */ @@ -332,11 +337,12 @@ void scl_set_H_scale(int A, int B) /* A dst,B src */ H_THR_DIV2 = A; DBG_DETAIL("H step %d,sub step %d, div2 %d\r\n", H_STEP, H_SUB_STEP, H_THR_DIV2); - scl_regs1->hxwidth.b.hxwidth = ((A > B) ? A : B); - scl_regs1->hscale2.b.step = H_STEP; - scl_regs1->hscale1.b.substep = H_SUB_STEP; - scl_regs1->hscale1.b.thr = H_THR_DIV2; - scl_regs1->hscale2.b.substepcnt = 0; + + vppif_reg32_write(SCL_HXWIDTH, ((A > B) ? A : B)); + vppif_reg32_write(SCL_H_STEP, H_STEP); + vppif_reg32_write(SCL_H_SUBSTEP, H_SUB_STEP); + vppif_reg32_write(SCL_H_THR, H_THR_DIV2); + vppif_reg32_write(SCL_H_I_SUBSTEPCNT, 0); } void scl_set_crop(int offset_x, int offset_y) @@ -344,15 +350,16 @@ void scl_set_crop(int offset_x, int offset_y) /* offset_x &= VPU_CROP_ALIGN_MASK; */ /* ~0x7 */ offset_x &= ~0xf; - scl_regs1->hscale3.b.stepcnt = offset_x * 16; - scl_regs1->vscale3.b.stepcnt = offset_y * 16; + vppif_reg32_write(SCL_H_I_STEPCNT, offset_x * 16); + vppif_reg32_write(SCL_V_I_STEPCNT, offset_y * 16); + /* vppif_reg32_write(VPU_SCA_THR, 0xFF); */ DBGMSG("[VPU] crop - x : 0x%x, y : 0x%x \r\n", offset_x * 16, offset_y * 16); } void scl_set_tg_enable(vpp_flag_t enable) { - scl_regs1->tg_ctl.b.enable = enable; + vppif_reg32_write(SCL_TG_ENABLE, enable); } unsigned int scl_set_clock(unsigned int pixel_clock) @@ -373,16 +380,17 @@ void scl_set_timing(vpp_clock_t *timing, unsigned int pixel_clock) timing->read_cycle = (timing->read_cycle > 255) ? 0xFF : timing->read_cycle; #endif - scl_regs1->tg_ctl.b.rdcyc = timing->read_cycle; - scl_regs2->readcyc_1t.b.rdcyc_1t = (timing->read_cycle) ? 0 : 1; - scl_regs1->tg_total.b.h_allpixel = timing->total_pixel_of_line; - scl_regs1->tg_h_active.b.h_actbg = timing->begin_pixel_of_active; - scl_regs1->tg_h_active.b.h_actend = timing->end_pixel_of_active; - scl_regs1->tg_total.b.v_allline = timing->total_line_of_frame; - scl_regs1->tg_v_active.b.v_actbg = timing->begin_line_of_active; - scl_regs1->tg_v_active.b.v_actend = timing->end_line_of_active; - scl_regs1->tg_vbi.b.vbie = timing->line_number_between_VBIS_VBIE; - scl_regs1->tg_vbi.b.pvbi = timing->line_number_between_PVBI_VBIS; + vppif_reg32_write(SCL_TG_RDCYC, timing->read_cycle); + vppif_reg32_write(SCL_READCYC_1T, (timing->read_cycle) ? 0 : 1); + vppif_reg32_write(SCL_TG_H_ALLPIXEL, timing->total_pixel_of_line); + vppif_reg32_write(SCL_TG_H_ACTBG, timing->begin_pixel_of_active); + vppif_reg32_write(SCL_TG_H_ACTEND, timing->end_pixel_of_active); + vppif_reg32_write(SCL_TG_V_ALLLINE, timing->total_line_of_frame); + vppif_reg32_write(SCL_TG_V_ACTBG, timing->begin_line_of_active); + vppif_reg32_write(SCL_TG_V_ACTEND, timing->end_line_of_active); + vppif_reg32_write(SCL_TG_VBIE, timing->line_number_between_VBIS_VBIE); + vppif_reg32_write(SCL_TG_PVBI, timing->line_number_between_PVBI_VBIS); + #ifdef DEBUG_DETAIL vpp_show_timing("scl set timing", 0, timing); #endif @@ -390,87 +398,98 @@ void scl_set_timing(vpp_clock_t *timing, unsigned int pixel_clock) void scl_get_timing(vpp_clock_t *p_timing) { - p_timing->read_cycle = scl_regs1->tg_ctl.b.rdcyc; - p_timing->total_pixel_of_line = scl_regs1->tg_total.b.h_allpixel; - p_timing->begin_pixel_of_active = scl_regs1->tg_h_active.b.h_actbg; - p_timing->end_pixel_of_active = scl_regs1->tg_h_active.b.h_actend; - p_timing->total_line_of_frame = scl_regs1->tg_total.b.v_allline; - p_timing->begin_line_of_active = scl_regs1->tg_v_active.b.v_actbg; - p_timing->end_line_of_active = scl_regs1->tg_v_active.b.v_actend; - p_timing->line_number_between_VBIS_VBIE = scl_regs1->tg_vbi.b.vbie; - p_timing->line_number_between_PVBI_VBIS = scl_regs1->tg_vbi.b.pvbi; + p_timing->read_cycle = vppif_reg32_read(SCL_TG_RDCYC); + p_timing->total_pixel_of_line = vppif_reg32_read(SCL_TG_H_ALLPIXEL); + p_timing->begin_pixel_of_active = vppif_reg32_read(SCL_TG_H_ACTBG); + p_timing->end_pixel_of_active = vppif_reg32_read(SCL_TG_H_ACTEND); + p_timing->total_line_of_frame = vppif_reg32_read(SCL_TG_V_ALLLINE); + p_timing->begin_line_of_active = vppif_reg32_read(SCL_TG_V_ACTBG); + p_timing->end_line_of_active = vppif_reg32_read(SCL_TG_V_ACTEND); + p_timing->line_number_between_VBIS_VBIE = vppif_reg32_read(SCL_TG_VBIE); + p_timing->line_number_between_PVBI_VBIS = vppif_reg32_read(SCL_TG_PVBI); } void scl_set_watchdog(U32 count) { if (0 != count) { - scl_regs1->tg_watchdog = count; - scl_regs1->tg_ctl.b.watchdog_enable = 1; + vppif_reg32_write(SCL_TG_WATCHDOG_VALUE, count); + vppif_reg32_write(SCL_TG_WATCHDOG_ENABLE, VPP_FLAG_TRUE); } else - scl_regs1->tg_ctl.b.watchdog_enable = 0; + vppif_reg32_write(SCL_TG_WATCHDOG_ENABLE, VPP_FLAG_FALSE); } void scl_set_timing_master(vpp_mod_t mod_bit) { - scl_regs1->tg_govw.b.enable = (mod_bit == VPP_MOD_GOVW) ? 1 : 0; + if (VPP_MOD_SCL == mod_bit) + vppif_reg32_write(SCL_TG_GOVWTG_ENABLE, VPP_FLAG_DISABLE); + else if (VPP_MOD_GOVW == mod_bit) + vppif_reg32_write(SCL_TG_GOVWTG_ENABLE, VPP_FLAG_ENABLE); + else { + DBGMSG("*E* check the parameter.\n"); + return; + } } vpp_mod_t scl_get_timing_master(void) { - return (scl_regs1->tg_govw.b.enable) ? VPP_MOD_GOVW : VPP_MOD_SCL; + if (vppif_reg32_read(SCL_TG_GOVWTG_ENABLE)) + return VPP_MOD_GOVW; + return VPP_MOD_SCL; } void scl_set_drop_line(vpp_flag_t enable) { - scl_regs1->scldw = enable; + vppif_reg32_write(SCL_SCLDW_METHOD, enable); } /* only one feature can work, other should be disable */ -void scl_set_filter_mode(enum vpp_filter_mode_t mode, int enable) +void scl_set_filter_mode(vpp_filter_mode_t mode, int enable) { DBG_DETAIL("(%d,%d)\n", mode, enable); if (mode != VPP_FILTER_SCALE) { - if (scl_regs1->sclup_en.b.v || scl_regs1->sclup_en.b.h) + if (vppif_reg32_read(SCL_VSCLUP_ENABLE) || + vppif_reg32_read(SCL_HSCLUP_ENABLE)) DPRINT("[SCL] *W* filter can't work w scale\n"); } - scl_regs2->field_mode.b.deblock = 0; - scl_regs2->field_mode.b.field_deflicker = 0; - scl_regs2->field_mode.b.frame_deflicker = 0; + vppif_reg32_write(SCL_DEBLOCK_ENABLE, 0); + vppif_reg32_write(SCL_FIELD_DEFLICKER, 0); + vppif_reg32_write(SCL_FRAME_DEFLICKER, 0); switch (mode) { default: case VPP_FILTER_SCALE: /* scale mode */ break; case VPP_FILTER_DEBLOCK: /* deblock */ - scl_regs2->field_mode.b.deblock = enable; + vppif_reg32_write(SCL_DEBLOCK_ENABLE, enable); break; case VPP_FILTER_FIELD_DEFLICKER: /* field deflicker */ - scl_regs2->field_mode.b.field_deflicker = enable; + vppif_reg32_write(SCL_FIELD_DEFLICKER, enable); break; case VPP_FILTER_FRAME_DEFLICKER: /* frame deflicker */ - scl_regs2->field_mode.b.frame_deflicker = enable; + vppif_reg32_write(SCL_FRAME_DEFLICKER, enable); break; } } -enum vpp_filter_mode_t scl_get_filter_mode(void) +vpp_filter_mode_t scl_get_filter_mode(void) { - if (scl_regs1->sclup_en.b.v || scl_regs1->sclup_en.b.h) + if (vppif_reg32_read(SCL_VSCLUP_ENABLE) || + vppif_reg32_read(SCL_HSCLUP_ENABLE)) return VPP_FILTER_SCALE; - - if (scl_regs2->field_mode.b.deblock) + if (vppif_reg32_read(SCL_DEBLOCK_ENABLE)) return VPP_FILTER_DEBLOCK; - if (scl_regs2->field_mode.b.field_deflicker) + if (vppif_reg32_read(SCL_FIELD_DEFLICKER)) return VPP_FILTER_FIELD_DEFLICKER; - if (scl_regs2->field_mode.b.frame_deflicker) + if (vppif_reg32_read(SCL_FRAME_DEFLICKER)) return VPP_FILTER_FRAME_DEFLICKER; + return VPP_FILTER_SCALE; } void sclr_set_mif_enable(vpp_flag_t enable) { - scl_regs1->r_ctl.b.mif_enable = enable; + vppif_reg32_write(SCLR_MIF_ENABLE, enable); } void sclr_set_mif2_enable(vpp_flag_t enable) @@ -480,55 +499,81 @@ void sclr_set_mif2_enable(vpp_flag_t enable) void sclr_set_colorbar(vpp_flag_t enable, int width, int inverse) { - scl_regs1->r_ctl.b.colorbar_mode = width; - scl_regs1->r_ctl.b.colorbar_inv = inverse; - scl_regs1->r_ctl.b.colorbar_enable = enable; + vppif_reg32_write(SCLR_COLBAR_MODE, width); + vppif_reg32_write(SCLR_COLBAR_INVERSION, inverse); + vppif_reg32_write(SCLR_COLBAR_ENABLE, enable); } void sclr_set_field_mode(vpp_display_format_t fmt) { - scl_regs1->r_ctl.b.src_disp_fmt = fmt; + vppif_reg32_write(SCLR_SRC_DISP_FMT, fmt); } void sclr_set_display_format(vpp_display_format_t source, vpp_display_format_t target) { - scl_regs1->r_ctl.b.src_disp_fmt = - (source == VPP_DISP_FMT_FIELD) ? 1 : 0; - scl_regs1->r_ctl.b.field = (target == VPP_DISP_FMT_FIELD) ? 1 : 0; + /* source */ + switch (source) { + case VPP_DISP_FMT_FRAME: + vppif_reg32_write(SCLR_SRC_DISP_FMT, 0x0); + break; + case VPP_DISP_FMT_FIELD: + vppif_reg32_write(SCLR_SRC_DISP_FMT, 0x1); + break; + default: + DBGMSG("*E* check the parameter.\n"); + return; + } + + /* target */ + switch (target) { + case VPP_DISP_FMT_FRAME: + vppif_reg32_write(SCLR_TAR_DISP_FMT, 0x0); + break; + case VPP_DISP_FMT_FIELD: + vppif_reg32_write(SCLR_TAR_DISP_FMT, 0x1); + break; + default: + DBGMSG("*E* check the parameter.\n"); + return; + } } void sclr_set_color_format(vdo_color_fmt format) { - p_scl->abgr_mode = 0; if (format >= VDO_COL_FMT_ARGB) { - scl_regs1->r_ctl.b.rgb_mode = - (format == VDO_COL_FMT_RGB_565) ? 0x1 : 0x3; - if (format == VDO_COL_FMT_ABGR) - p_scl->abgr_mode = 1; + if (format == VDO_COL_FMT_RGB_565) + vppif_reg32_write(SCLR_RGB_MODE, 0x1); + else + vppif_reg32_write(SCLR_RGB_MODE, 0x3); return; } - scl_regs1->r_ctl.b.rgb_mode = 0; - scl_regs1->r_ctl.b.rgb = 0x0; + vppif_reg32_write(SCLR_RGB_MODE, 0x0); switch (format) { + case VDO_COL_FMT_ARGB: + vppif_reg32_write(SCLR_COLFMT_RGB, 0x1); + break; case VDO_COL_FMT_YUV444: - scl_regs1->r_ctl.b.yuv = 0x2; + vppif_reg32_write(SCLR_COLFMT_RGB, 0x0); + vppif_reg32_write(SCLR_COLFMT_YUV, 0x2); break; case VDO_COL_FMT_YUV422H: - scl_regs1->r_ctl.b.yuv = 0x0; + vppif_reg32_write(SCLR_COLFMT_RGB, 0x0); + vppif_reg32_write(SCLR_COLFMT_YUV, 0x0); break; case VDO_COL_FMT_YUV420: - scl_regs1->r_ctl.b.yuv = 0x1; + vppif_reg32_write(SCLR_COLFMT_RGB, 0x0); + vppif_reg32_write(SCLR_COLFMT_YUV, 0x1); break; default: - DBG_ERR("color fmt %d\n", format); + DBGMSG("*E* check the parameter.\n"); return; } } vdo_color_fmt sclr_get_color_format(void) { - switch (scl_regs1->r_ctl.b.rgb_mode) { + switch (vppif_reg32_read(SCLR_RGB_MODE)) { case 0x1: return VDO_COL_FMT_RGB_565; case 0x3: @@ -536,7 +581,7 @@ vdo_color_fmt sclr_get_color_format(void) default: break; } - switch (scl_regs1->r_ctl.b.yuv) { + switch (vppif_reg32_read(SCLR_COLFMT_YUV)) { case 0: return VDO_COL_FMT_YUV422H; case 1: @@ -551,7 +596,17 @@ vdo_color_fmt sclr_get_color_format(void) void sclr_set_media_format(vpp_media_format_t format) { - scl_regs1->r_ctl.b.h264 = (format == VPP_MEDIA_FMT_H264) ? 1 : 0; + switch (format) { + case VPP_MEDIA_FMT_MPEG: + vppif_reg32_write(SCLR_MEDIAFMT_H264, 0x0); + break; + case VPP_MEDIA_FMT_H264: + vppif_reg32_write(SCLR_MEDIAFMT_H264, 0x1); + break; + default: + DBGMSG("*E* check the parameter.\n"); + return; + } } void sclr_set_fb_addr(U32 y_addr, U32 c_addr) @@ -563,7 +618,7 @@ void sclr_set_fb_addr(U32 y_addr, U32 c_addr) DBGMSG("y_addr:0x%08x, c_addr:0x%08x\n", y_addr, c_addr); offset_y = offset_c = 0; - line_y = line_c = scl_regs1->r_h_size.b.fb_w; + line_y = line_c = vppif_reg32_read(SCLR_YBUFWID); switch (sclr_get_color_format()) { case VDO_COL_FMT_YUV420: offset_c /= 2; @@ -584,54 +639,54 @@ void sclr_set_fb_addr(U32 y_addr, U32 c_addr) line_c *= 2; break; } - pre_y = scl_regs1->r_ysa; - pre_c = scl_regs1->r_csa; - scl_regs1->r_ysa = y_addr + offset_y; - scl_regs1->r_csa = c_addr + offset_c; + pre_y = vppif_reg32_in(REG_SCLR_YSA); + pre_c = vppif_reg32_in(REG_SCLR_CSA); + vppif_reg32_out(REG_SCLR_YSA, y_addr + offset_y); + vppif_reg32_out(REG_SCLR_CSA, c_addr + offset_c); } void sclr_get_fb_addr(U32 *y_addr, U32 *c_addr) { - *y_addr = scl_regs1->r_ysa; - *c_addr = scl_regs1->r_csa; + *y_addr = vppif_reg32_in(REG_SCLR_YSA); + *c_addr = vppif_reg32_in(REG_SCLR_CSA); /* DBGMSG("y_addr:0x%08x, c_addr:0x%08x\n", *y_addr, *c_addr); */ } void sclr_set_width(U32 y_pixel, U32 y_buffer) { - scl_regs1->r_h_size.b.pix_w = y_pixel; - scl_regs1->r_h_size.b.fb_w = y_buffer; + vppif_reg32_write(SCLR_YPXLWID, y_pixel); + vppif_reg32_write(SCLR_YBUFWID, y_buffer); } void sclr_get_width(U32 *p_y_pixel, U32 *p_y_buffer) { - *p_y_pixel = scl_regs1->r_h_size.b.pix_w; - *p_y_buffer = scl_regs1->r_h_size.b.fb_w; + *p_y_pixel = vppif_reg32_read(SCLR_YPXLWID); + *p_y_buffer = vppif_reg32_read(SCLR_YBUFWID); } void sclr_set_crop(U32 h_crop, U32 v_crop) { - scl_regs1->r_crop.b.hcrop = h_crop; - scl_regs1->r_crop.b.vcrop = v_crop; + vppif_reg32_write(SCLR_HCROP, h_crop); + vppif_reg32_write(SCLR_VCROP, v_crop); } void sclr_get_fb_info(U32 *width, U32 *act_width, U32 *x_offset, U32 *y_offset) { - *width = scl_regs1->r_h_size.b.fb_w; - *act_width = scl_regs1->r_h_size.b.pix_w; - *x_offset = scl_regs1->r_crop.b.hcrop; - *y_offset = scl_regs1->r_crop.b.vcrop; + *width = vppif_reg32_read(SCLR_YBUFWID); + *act_width = vppif_reg32_read(SCLR_YPXLWID); + *x_offset = vppif_reg32_read(SCLR_HCROP); + *y_offset = vppif_reg32_read(SCLR_VCROP); } void sclr_set_threshold(U32 value) { - scl_regs1->r_fifo_ctl.b.thr = value; + vppif_reg32_write(SCLR_FIFO_THR, value); } void sclw_set_mif_enable(vpp_flag_t enable) { - scl_regs1->w_ctl.b.mif_enable = enable; + vppif_reg32_write(SCLW_MIF_ENABLE, enable); } void sclw_set_color_format(vdo_color_fmt format) @@ -639,31 +694,31 @@ void sclw_set_color_format(vdo_color_fmt format) /* 0-888(4 byte), 1-5515(2 byte), 2-666(4 byte), 3-565(2 byte) */ switch (format) { case VDO_COL_FMT_RGB_666: - scl_regs1->w_ctl.b.rgb = 1; - scl_regs2->igs.b.mode = 2; + vppif_reg32_write(SCLW_COLFMT_RGB, 1); + vppif_reg32_write(SCL_IGS_MODE, 2); break; case VDO_COL_FMT_RGB_565: - scl_regs1->w_ctl.b.rgb = 1; - scl_regs2->igs.b.mode = 3; + vppif_reg32_write(SCLW_COLFMT_RGB, 1); + vppif_reg32_write(SCL_IGS_MODE, 3); break; case VDO_COL_FMT_RGB_1555: - scl_regs1->w_ctl.b.rgb = 1; - scl_regs2->igs.b.mode = 1; + vppif_reg32_write(SCLW_COLFMT_RGB, 1); + vppif_reg32_write(SCL_IGS_MODE, 1); break; case VDO_COL_FMT_ARGB: - scl_regs1->w_ctl.b.rgb = 1; - scl_regs2->igs.b.mode = 0; + vppif_reg32_write(SCLW_COLFMT_RGB, 1); + vppif_reg32_write(SCL_IGS_MODE, 0); break; case VDO_COL_FMT_YUV444: - scl_regs1->w_ctl.b.rgb = 0; - scl_regs1->w_ctl.b.yuv = 0; - scl_regs2->igs.b.mode = 0; + vppif_reg32_write(SCLW_COLFMT_RGB, 0); + vppif_reg32_write(SCLW_COLFMT_YUV, 0); + vppif_reg32_write(SCL_IGS_MODE, 0); break; case VDO_COL_FMT_YUV422H: case VDO_COL_FMT_YUV420: - scl_regs1->w_ctl.b.rgb = 0; - scl_regs1->w_ctl.b.yuv = 1; - scl_regs2->igs.b.mode = 0; + vppif_reg32_write(SCLW_COLFMT_RGB, 0); + vppif_reg32_write(SCLW_COLFMT_YUV, 1); + vppif_reg32_write(SCL_IGS_MODE, 0); break; default: DBGMSG("*E* check the parameter.\n"); @@ -673,8 +728,8 @@ void sclw_set_color_format(vdo_color_fmt format) vdo_color_fmt sclw_get_color_format(void) { - if (scl_regs1->w_ctl.b.rgb) { - switch (scl_regs2->igs.b.mode) { + if (vppif_reg32_read(SCLW_COLFMT_RGB)) { + switch (vppif_reg32_read(SCL_IGS_MODE)) { case 0: return VDO_COL_FMT_ARGB; case 1: @@ -686,20 +741,20 @@ vdo_color_fmt sclw_get_color_format(void) } } - if (scl_regs1->w_ctl.b.yuv) + if (vppif_reg32_read(SCLW_COLFMT_YUV)) return VDO_COL_FMT_YUV422H; return VDO_COL_FMT_YUV444; } void sclw_set_alpha(int enable, char data) { - scl_regs2->argb_alpha.b.data = data; - scl_regs2->argb_alpha.b.enable = enable; + vppif_reg32_write(SCL_FIXED_ALPHA_DATA, data); + vppif_reg32_write(SCL_FIXED_ALPHA_ENABLE, enable); } void sclw_set_field_mode(vpp_display_format_t fmt) { - scl_regs1->r_ctl.b.field = fmt; + vppif_reg32_write(SCLR_TAR_DISP_FMT, fmt); } void sclw_set_fb_addr(U32 y_addr, U32 c_addr) @@ -708,77 +763,77 @@ void sclw_set_fb_addr(U32 y_addr, U32 c_addr) /* if( (y_addr & 0x3f) || (c_addr & 0x3f) ){ DPRINT("[SCL] *E* addr should align 64\n"); } */ - scl_regs1->w_ysa = y_addr; - scl_regs1->w_csa = c_addr; + vppif_reg32_out(REG_SCLW_YSA, y_addr); + vppif_reg32_out(REG_SCLW_CSA, c_addr); } void sclw_get_fb_addr(U32 *y_addr, U32 *c_addr) { - *y_addr = scl_regs1->w_ysa; - *c_addr = scl_regs1->w_csa; + *y_addr = vppif_reg32_in(REG_SCLW_YSA); + *c_addr = vppif_reg32_in(REG_SCLW_CSA); DBGMSG("y_addr:0x%08x, c_addr:0x%08x\n", *y_addr, *c_addr); } void sclw_set_fb_width(U32 width, U32 buf_width) { - scl_regs1->w_y_time.b.pxl_w = width; - scl_regs1->w_y_time.b.fb_w = buf_width; + vppif_reg32_write(SCLW_YPXLWID, width); + vppif_reg32_write(SCLW_YBUFWID, buf_width); if (sclw_get_color_format() == VDO_COL_FMT_YUV444) { - scl_regs1->w_c_time.b.pxl_w = width; - scl_regs1->w_c_time.b.fb_w = buf_width * 2; + vppif_reg32_write(SCLW_CPXLWID, width); + vppif_reg32_write(SCLW_CBUFWID, buf_width * 2); } else { - scl_regs1->w_c_time.b.pxl_w = width / 2; - scl_regs1->w_c_time.b.fb_w = buf_width; + vppif_reg32_write(SCLW_CPXLWID, width / 2); + vppif_reg32_write(SCLW_CBUFWID, buf_width); } } void sclw_get_fb_width(U32 *width, U32 *buf_width) { - *width = scl_regs1->w_y_time.b.pxl_w; - *buf_width = scl_regs1->w_y_time.b.fb_w; + *width = vppif_reg32_read(SCLW_YPXLWID); + *buf_width = vppif_reg32_read(SCLW_YBUFWID); } void scl_R2_set_mif_enable(int enable) { - scl_regs1->r2_ctl.b.mif_en = enable; + vppif_reg32_write(SCL_R2_MIF_EN, enable); } void scl_R2_set_colorbar(int enable, int wide, int inv) { - scl_regs1->r2_ctl.b.color_en = enable; - scl_regs1->r2_ctl.b.color_wide = wide; - scl_regs1->r2_ctl.b.color_inv = inv; + vppif_reg32_write(SCL_R2_COLOR_EN, enable); + vppif_reg32_write(SCL_R2_COLOR_WIDE, wide); + vppif_reg32_write(SCL_R2_COLOR_INV, inv); } void scl_R2_set_color_format(vdo_color_fmt colfmt) { if (colfmt >= VDO_COL_FMT_ARGB) { - scl_regs1->r2_ctl.b.rgb_mode = - (colfmt == VDO_COL_FMT_RGB_565) ? 0x1 : 0x3; + vppif_reg32_write(SCL_R2_RGB_MODE, + (colfmt == VDO_COL_FMT_RGB_565) ? 0x1 : 0x3); return; } - scl_regs1->r2_ctl.b.rgb_mode = 0; + vppif_reg32_write(SCL_R2_RGB_MODE, 0x0); switch (colfmt) { case VDO_COL_FMT_YUV444: - scl_regs1->r2_ctl.b.vfmt = 0x2; + vppif_reg32_write(SCL_R2_VFMT, 0x2); break; case VDO_COL_FMT_YUV422H: - scl_regs1->r2_ctl.b.vfmt = 0x0; + vppif_reg32_write(SCL_R2_VFMT, 0x0); break; case VDO_COL_FMT_YUV420: - scl_regs1->r2_ctl.b.vfmt = 0x1; + vppif_reg32_write(SCL_R2_VFMT, 0x1); break; default: - DBG_ERR("color fmt %d\n", colfmt); + DBGMSG("*E* check the parameter.\n"); return; } } vdo_color_fmt scl_R2_get_color_format(void) { - switch (scl_regs1->r2_ctl.b.rgb_mode) { + switch (vppif_reg32_read(SCL_R2_RGB_MODE)) { case 0: - switch (scl_regs1->r2_ctl.b.vfmt) { + switch (vppif_reg32_read(SCL_R2_VFMT)) { case 0: return VDO_COL_FMT_YUV422H; case 1: @@ -805,65 +860,70 @@ void scl_R2_set_csc_mode(vpp_csc_t mode) dst_fmt = sclw_get_color_format(); mode = vpp_check_csc_mode(mode, src_fmt, dst_fmt, 0); - scl_regs2->r2_csc1 = vpp_csc_parm[mode][0]; - scl_regs2->r2_csc2 = vpp_csc_parm[mode][1]; - scl_regs2->r2_csc3 = vpp_csc_parm[mode][2]; - scl_regs2->r2_csc4 = vpp_csc_parm[mode][3]; - scl_regs2->r2_csc5 = vpp_csc_parm[mode][4]; - scl_regs2->r2_csc6 = vpp_csc_parm[mode][5]; - scl_regs2->r2_csc.val = vpp_csc_parm[mode][6]; - scl_regs2->r2_csc.b.enable = (mode >= VPP_CSC_MAX) ? 0 : 1; + if (mode >= VPP_CSC_MAX) + vppif_reg32_write(SCL_R2_CSC_EN, VPP_FLAG_DISABLE); + else { + vppif_reg32_out(REG_SCL_R2_CSC1, vpp_csc_parm[mode][0]); + vppif_reg32_out(REG_SCL_R2_CSC2, vpp_csc_parm[mode][1]); + vppif_reg32_out(REG_SCL_R2_CSC3, vpp_csc_parm[mode][2]); + vppif_reg32_out(REG_SCL_R2_CSC4, vpp_csc_parm[mode][3]); + vppif_reg32_out(REG_SCL_R2_CSC5, vpp_csc_parm[mode][4]); + vppif_reg32_out(REG_SCL_R2_CSC6, vpp_csc_parm[mode][5]); + vppif_reg32_out(REG_SCL_R2_CSC, vpp_csc_parm[mode][6]); + vppif_reg32_write(SCL_R2_CSC_EN, VPP_FLAG_ENABLE); + } } void scl_R2_set_framebuffer(vdo_framebuf_t *fb) { - scl_regs1->r2_ctl.b.iofmt = (fb->flag & VDO_FLAG_INTERLACE) ? 1 : 0; + vppif_reg32_write(SCL_R2_IOFMT, + (fb->flag & VDO_FLAG_INTERLACE) ? 1 : 0); scl_R2_set_color_format(fb->col_fmt); - scl_regs1->r2_ysa = fb->y_addr; - scl_regs1->r2_csa = fb->c_addr; - scl_regs1->r2_h_size.b.fbw = fb->fb_w; - scl_regs1->r2_h_size.b.lnsize = fb->img_w; - scl_regs1->r2_crop.b.hcrop = fb->h_crop; - scl_regs1->r2_crop.b.vcrop = fb->v_crop; + vppif_reg32_out(REG_SCLR2_YSA, fb->y_addr); + vppif_reg32_out(REG_SCLR2_CSA, fb->c_addr); + vppif_reg32_write(SCL_R2_FBW, fb->fb_w); + vppif_reg32_write(SCL_R2_LNSIZE, fb->img_w); + vppif_reg32_write(SCL_R2_HCROP, fb->h_crop); + vppif_reg32_write(SCL_R2_VCROP, fb->v_crop); scl_R2_set_csc_mode(p_scl->fb_p->csc_mode); } void scl_ALPHA_set_enable(int enable) { - scl_regs1->alpha_colorkey.b.enable = enable; + vppif_reg32_write(SCL_ALPHA_COLORKEY_ENABLE, enable); } void scl_ALPHA_set_swap(int enable) { /* 0-(alpha,1-alpha),1:(1-alpha,alpha) */ - scl_regs1->alpha_md.b.swap = enable; + vppif_reg32_write(SCL_ALPHA_SWAP, enable); } void scl_ALPHA_set_src(int mode, int fixed) { /* 0-RMIF1,1-RMIF2,2-Fixed ALPHA */ - scl_regs1->alpha_md.b.src = mode; - scl_regs1->alpha_fxd.b.src_fixed = fixed; + vppif_reg32_write(SCL_ALPHA_SRC, mode); + vppif_reg32_write(SCL_ALPHA_SRC_FIXED, fixed); } void scl_ALPHA_set_dst(int mode, int fixed) { /* 0-RMIF1,1-RMIF2,2-Fixed ALPHA */ - scl_regs1->alpha_md.b.dst = mode; - scl_regs1->alpha_fxd.b.dst_fixed = fixed; + vppif_reg32_write(SCL_ALPHA_DST, mode); + vppif_reg32_write(SCL_ALPHA_DST_FIXED, fixed); } void scl_ALPHA_set_color_key(int rmif2, int comp, int mode, int colkey) { /* 0-RMIF1,1-RMIF2 */ - scl_regs1->alpha_colorkey.b.from = rmif2; + vppif_reg32_write(SCL_ALPHA_COLORKEY_FROM, rmif2); /* 0-888,1-777,2-666,3-555 */ - scl_regs1->alpha_colorkey.b.comp = comp; + vppif_reg32_write(SCL_ALPHA_COLORKEY_COMP, comp); /* (Non-Hit,Hit):0/1-(alpha,alpha), 2-(alpha,pix1),3-(pix1,alpha),4-(alpha,pix2), 5-(pix2,alpha),6-(pix1,pix2),7-(pix2,pix1) */ - scl_regs1->alpha_colorkey.b.mode = mode; - scl_regs1->alpha_colorkey_rgb.val = colkey; + vppif_reg32_write(SCL_ALPHA_COLORKEY_MODE, mode); + vppif_reg32_out(REG_ALFA_COLORKEY_RGB, colkey); } void scl_set_overlap(vpp_overlap_t *p) @@ -885,8 +945,8 @@ void scl_set_overlap(vpp_overlap_t *p) void scl_set_req_num(int ynum, int cnum) { - scl_regs1->r_req_num.b.y_req_num = ynum; - scl_regs1->r_req_num.b.c_req_num = cnum; + vppif_reg32_write(SCL_R_Y_REQ_NUM, ynum); + vppif_reg32_write(SCL_R_C_REQ_NUM, cnum); } static void scl_set_scale_PP(unsigned int src, unsigned int dst, @@ -979,15 +1039,17 @@ void scl_set_scale(unsigned int SRC_W, unsigned int SRC_H, rec_h = 1; if (SRC_H == DST_H) rec_v = 1; - scl_regs1->true_bilinear.b.h = h; - scl_regs1->true_bilinear.b.v = v; - scl_regs2->recursive_mode.b.h = rec_h; - scl_regs2->recursive_mode.b.v = rec_v; + vppif_reg32_write(SCL_BILINEAR_H, h); + vppif_reg32_write(SCL_BILINEAR_V, v); + vppif_reg32_write(SCL_RECURSIVE_H, rec_h); + vppif_reg32_write(SCL_RECURSIVE_V, rec_v); + + /* vertical bilinear mode */ if (v) { - scl_regs1->vxwidth.b.vxwidth = - scl_regs1->vxwidth.b.vxwidth - 1; - scl_regs1->vxwidth.b.dst_vxwidth = - scl_regs1->vxwidth.b.vxwidth; + vppif_reg32_write(SCL_VXWIDTH, + vppif_reg32_read(SCL_VXWIDTH) - 1); + vppif_reg32_write(SCL_DST_VXWIDTH, + vppif_reg32_read(SCL_VXWIDTH)); } sclr_set_mif2_enable((v) ? VPP_FLAG_ENABLE : VPP_FLAG_DISABLE); } @@ -1043,10 +1105,10 @@ void sclw_set_framebuffer(vdo_framebuf_t *fb) void scl_init(void *base) { - struct scl_mod_t *mod_p; - struct vpp_fb_base_t *fb_p; + scl_mod_t *mod_p; + vpp_fb_base_t *fb_p; - mod_p = (struct scl_mod_t *) base; + mod_p = (scl_mod_t *) base; fb_p = mod_p->fb_p; scl_set_reg_level(VPP_REG_LEVEL_1); @@ -1064,16 +1126,17 @@ void scl_init(void *base) sclr_set_threshold(0xf); /* filter default value */ - scl_regs2->dblk_threshold.b.layer1_boundary = 48; - scl_regs2->dblk_threshold.b.layer2_boundary = 16; + vppif_reg32_write(SCL_1ST_LAYER_BOUNDARY, 48); + vppif_reg32_write(SCL_2ND_LAYER_BOUNDARY, 16); + + vppif_reg32_write(SCL_FIELD_FILTER_Y_THD, 8); + vppif_reg32_write(SCL_FIELD_FILTER_C_THD, 8); + vppif_reg32_write(SCL_FIELD_FILTER_CONDITION, 0); - scl_regs2->field_flicker.b.y_thd = 8; - scl_regs2->field_flicker.b.c_thd = 8; - scl_regs2->field_flicker.b.condition = 0; + vppif_reg32_write(SCL_FRAME_FILTER_RGB, 0); + vppif_reg32_write(SCL_FRAME_FILTER_SAMPLER, 14); + vppif_reg32_write(SCL_FR_FILTER_SCENE_CHG_THD, 32); - scl_regs2->frame_flicker.b.rgb = 0; - scl_regs2->frame_flicker.b.sampler = 14; - scl_regs2->frame_flicker.b.scene_chg_thd = 32; scl_set_reg_update(VPP_FLAG_ENABLE); scl_set_tg_enable(VPP_FLAG_DISABLE); } @@ -1103,25 +1166,21 @@ static void scl_proc_scale_complete_work(int arg) #endif } -#ifdef __KERNEL__ struct timer_list scl_scale_timer; -#endif int scl_proc_scale_complete(void *arg) { -#ifdef __KERNEL__ del_timer(&scl_scale_timer); -#endif + /* DPRINT("[SCL] scl_proc_scale_complete\n"); */ - if (scl_regs1->tg_sts.b.tgerr) { + if (vppif_reg32_read(SCL_INTSTS_TGERR)) { DPRINT("[SCL] scale TG err 0x%x,0x%x\n", - scl_regs1->tg_sts.val, scl_regs1->w_ff_ctl.val); - scl_regs1->tg_sts.val = BIT0; - scl_regs1->w_ff_ctl.val = 0x10101; + vppif_reg32_in(REG_SCL_TG_STS), + vppif_reg32_in(REG_SCLW_FF_CTL)); + vppif_reg32_out(REG_SCL_TG_STS+0x0, BIT0); + vppif_reg32_out(REG_SCLW_FF_CTL, 0x10101); } scl_set_tg_enable(VPP_FLAG_DISABLE); -#ifndef CONFIG_UBOOT vppm_set_int_enable(VPP_FLAG_DISABLE, SCL_COMPLETE_INT); -#endif sclw_set_mif_enable(VPP_FLAG_DISABLE); sclr_set_mif_enable(VPP_FLAG_DISABLE); sclr_set_mif2_enable(VPP_FLAG_DISABLE); @@ -1150,21 +1209,18 @@ void scl_scale_timeout(int arg) void scl_set_scale_timer(int ms) { -#ifdef __KERNEL__ if (scl_scale_timer.function) del_timer(&scl_scale_timer); init_timer(&scl_scale_timer); scl_scale_timer.function = (void *) scl_scale_timeout; scl_scale_timer.expires = jiffies + msecs_to_jiffies(ms); add_timer(&scl_scale_timer); -#endif } int scl_proc_scale_finish(void) { - int ret = 0; - #ifdef __KERNEL__ + int ret; /* DPRINT("[SCL] scl_proc_scale_finish\n"); */ ret = wait_event_interruptible_timeout(scl_proc_scale_event, @@ -1302,25 +1358,20 @@ int scl_set_scale_overlap(vdo_framebuf_t *s, /* scale process */ scl_set_enable(VPP_FLAG_ENABLE); - scl_regs1->tg_ctl.b.oneshot = 1; + vppif_reg32_write(SCL_ONESHOT_ENABLE, 1); sclw_set_mif_enable(VPP_FLAG_ENABLE); scl_set_tg_enable(VPP_FLAG_ENABLE); #ifdef CONFIG_VPP_CHECK_SCL_STATUS - scl_regs1->tg_sts.val = BIT0; - scl_regs1->w_ff_ctl.val = 0x10101; + vppif_reg32_out(REG_SCL_TG_STS+0x0, BIT0); + vppif_reg32_out(REG_SCLW_FF_CTL, 0x10101); #endif p_scl->scale_complete = 0; -#ifndef CONFIG_UBOOT vppm_set_int_enable(VPP_FLAG_ENABLE, SCL_COMPLETE_INT); -#endif + #if 0 /* for debug scale */ scl_reg_dump(); #endif -#ifdef CONFIG_UBOOT - while (scl_regs1->tg_ctl.b.enable); - scl_proc_scale_complete(0); - scl_proc_scale_finish(); -#else + if (p_scl->scale_sync) { ret = vpp_irqproc_work(SCL_COMPLETE_INT, (void *)scl_proc_scale_complete, 0, 100, 1); @@ -1330,7 +1381,6 @@ int scl_set_scale_overlap(vdo_framebuf_t *s, (void *)scl_proc_scale_complete, 0, 0, 1); scl_set_scale_timer(100); } -#endif return ret; } @@ -1383,18 +1433,18 @@ void scl_suspend(int sts) switch (sts) { case 0: /* disable module */ vpp_mod_set_clock(VPP_MOD_SCL, VPP_FLAG_ENABLE, 1); - scl_pm_enable = scl_regs1->en.b.alu_enable; - scl_regs1->en.b.alu_enable = 0; - scl_pm_r_mif1 = scl_regs1->r_ctl.b.mif_enable; - scl_pm_r_mif2 = scl_regs1->r2_ctl.b.mif_en; - scl_regs1->r2_ctl.b.mif_en = 0; - scl_regs1->r_ctl.b.mif_enable = 0; - scl_pm_w_mif = scl_regs1->w_ctl.b.mif_enable; - scl_regs1->w_ctl.b.mif_enable = 0; + scl_pm_enable = vppif_reg32_read(SCL_ALU_ENABLE); + vppif_reg32_write(SCL_ALU_ENABLE, 0); + scl_pm_r_mif1 = vppif_reg32_read(SCLR_MIF_ENABLE); + scl_pm_r_mif2 = vppif_reg32_read(SCL_R2_MIF_EN); + vppif_reg32_write(SCL_R2_MIF_EN, 0); + vppif_reg32_write(SCLR_MIF_ENABLE, 0); + scl_pm_w_mif = vppif_reg32_read(SCLW_MIF_ENABLE); + vppif_reg32_write(SCLW_MIF_ENABLE, 0); break; case 1: /* disable tg */ - scl_pm_tg = scl_regs1->tg_ctl.b.enable; - scl_regs1->tg_ctl.b.enable = 0; + scl_pm_tg = vppif_reg32_read(SCL_TG_ENABLE); + vppif_reg32_write(SCL_TG_ENABLE, 0); break; case 2: /* backup register */ p_scl->reg_bk = vpp_backup_reg(REG_SCL_BASE1_BEGIN, @@ -1420,13 +1470,13 @@ void scl_resume(int sts) scl_pm_bk2 = 0; break; case 1: /* enable module */ - scl_regs1->w_ctl.b.mif_enable = scl_pm_w_mif; - scl_regs1->r_ctl.b.mif_enable = scl_pm_r_mif1; - scl_regs1->r2_ctl.b.mif_en = scl_pm_r_mif2; - scl_regs1->en.b.alu_enable = scl_pm_enable; + vppif_reg32_write(SCLW_MIF_ENABLE, scl_pm_w_mif); + vppif_reg32_write(SCLR_MIF_ENABLE, scl_pm_r_mif1); + vppif_reg32_write(SCL_R2_MIF_EN, scl_pm_r_mif2); + vppif_reg32_write(SCL_ALU_ENABLE, scl_pm_enable); break; case 2: /* enable tg */ - scl_regs1->tg_ctl.b.enable = scl_pm_tg; + vppif_reg32_write(SCL_TG_ENABLE, scl_pm_tg); vpp_mod_set_clock(VPP_MOD_SCL, VPP_FLAG_DISABLE, 1); break; default: @@ -1440,16 +1490,15 @@ void scl_resume(int sts) int scl_mod_init(void) { - struct vpp_fb_base_t *mod_fb_p; + vpp_fb_base_t *mod_fb_p; vdo_framebuf_t *fb_p; /* -------------------- SCL module -------------------- */ { - struct scl_mod_t *scl_mod_p; + scl_mod_t *scl_mod_p; - scl_mod_p = (struct scl_mod_t *) vpp_mod_register(VPP_MOD_SCL, - sizeof(struct scl_mod_t), - VPP_MOD_FLAG_FRAMEBUF); + scl_mod_p = (scl_mod_t *) vpp_mod_register(VPP_MOD_SCL, + sizeof(scl_mod_t), VPP_MOD_FLAG_FRAMEBUF); if (!scl_mod_p) { DPRINT("*E* SCL module register fail\n"); return -1; @@ -1506,11 +1555,10 @@ int scl_mod_init(void) /* -------------------- SCLW module -------------------- */ { - struct sclw_mod_t *sclw_mod_p; + sclw_mod_t *sclw_mod_p; - sclw_mod_p = (struct sclw_mod_t *) vpp_mod_register(VPP_MOD_SCLW, - sizeof(struct sclw_mod_t), - VPP_MOD_FLAG_FRAMEBUF); + sclw_mod_p = (sclw_mod_t *) vpp_mod_register(VPP_MOD_SCLW, + sizeof(sclw_mod_t), VPP_MOD_FLAG_FRAMEBUF); if (!sclw_mod_p) { DPRINT("*E* SCLW module register fail\n"); return -1; diff --git a/drivers/video/wmt/scl.h b/drivers/video/wmt/scl.h index 2d11b48f..5ab9d7b6 100755..100644 --- a/drivers/video/wmt/scl.h +++ b/drivers/video/wmt/scl.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/scl.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -28,25 +28,24 @@ #define SCL_COMPLETE_INT VPP_INT_SCL_PVBI -struct scl_mod_t { +typedef struct { VPP_MOD_BASE; int (*scale)(vdo_framebuf_t *src, vdo_framebuf_t *dst); int (*scale_finish)(void); - enum vpp_scale_mode_t scale_mode; - enum vpp_scale_mode_t scale_sync; + vpp_scale_mode_t scale_mode; + vpp_scale_mode_t scale_sync; int scale_complete; - enum vpp_filter_mode_t filter_mode; - int abgr_mode; + vpp_filter_mode_t filter_mode; - struct vpp_dbg_timer_t overlap_timer; - struct vpp_dbg_timer_t scale_timer; -}; + vpp_dbg_timer_t overlap_timer; + vpp_dbg_timer_t scale_timer; +} scl_mod_t; -struct sclw_mod_t { +typedef struct { VPP_MOD_BASE; -}; +} sclw_mod_t; #ifdef __cplusplus extern "C" { @@ -58,8 +57,8 @@ extern "C" { #define EXTERN extern #endif -EXTERN struct scl_mod_t *p_scl; -EXTERN struct sclw_mod_t *p_sclw; +EXTERN scl_mod_t *p_scl; +EXTERN sclw_mod_t *p_sclw; #ifdef WMT_FTBLK_SCL @@ -70,9 +69,9 @@ EXTERN void sclw_set_framebuffer(vdo_framebuf_t *outbuf); EXTERN void scl_set_enable(vpp_flag_t enable); EXTERN void scl_set_reg_update(vpp_flag_t enable); EXTERN void scl_set_reg_level(vpp_reglevel_t level); -EXTERN void scl_set_int_enable(vpp_flag_t enable, enum vpp_int_t int_bit); -EXTERN enum vpp_int_err_t scl_get_int_status(void); -EXTERN void scl_clean_int_status(enum vpp_int_err_t int_sts); +EXTERN void scl_set_int_enable(vpp_flag_t enable, vpp_int_t int_bit); +EXTERN vpp_int_err_t scl_get_int_status(void); +EXTERN void scl_clean_int_status(vpp_int_err_t int_sts); EXTERN void scl_set_csc_mode(vpp_csc_t mode); EXTERN void scl_set_scale_enable(vpp_flag_t vscl_enable, vpp_flag_t hscl_enable); @@ -118,7 +117,6 @@ EXTERN void scl_set_frame_filter_enable(int enable); EXTERN int scl_set_scale_overlap(vdo_framebuf_t *s, vdo_framebuf_t *in, vdo_framebuf_t *out); EXTERN void scl_set_overlap(vpp_overlap_t *p); -EXTERN int scl_mod_init(void); #ifdef __cplusplus } diff --git a/drivers/video/wmt/sw_i2c.c b/drivers/video/wmt/sw_i2c.c index 79acd966..af05e7a4 100755..100644 --- a/drivers/video/wmt/sw_i2c.c +++ b/drivers/video/wmt/sw_i2c.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/sw_i2c.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -49,7 +49,7 @@ void wmt_swi2c_lock(int lock) #endif } -struct swi2c_reg_s *swi2c_scl, *swi2c_sda; +swi2c_reg_t *swi2c_scl, *swi2c_sda; void wmt_swi2c_delay(unsigned int time) { @@ -58,38 +58,40 @@ void wmt_swi2c_delay(unsigned int time) void wmt_swi2c_SetSDAInput(void) { - outw(inw(swi2c_sda->gpio_en) | swi2c_sda->bit_mask, swi2c_sda->gpio_en); - outw(inw(swi2c_sda->out_en) & ~swi2c_sda->bit_mask, swi2c_sda->out_en); + REG16_VAL(swi2c_sda->gpio_en) |= swi2c_sda->bit_mask; + REG16_VAL(swi2c_sda->out_en) &= ~swi2c_sda->bit_mask; } void wmt_swi2c_SetSDAOutput(void) { - outw(inw(swi2c_sda->gpio_en) | swi2c_sda->bit_mask, swi2c_sda->gpio_en); - outw(inw(swi2c_sda->out_en) | swi2c_sda->bit_mask, swi2c_sda->out_en); + REG16_VAL(swi2c_sda->gpio_en) |= swi2c_sda->bit_mask; + REG16_VAL(swi2c_sda->out_en) |= swi2c_sda->bit_mask; } bool wmt_swi2c_GetSDA(void) /* bit */ { - if (inw(swi2c_sda->data_in) & swi2c_sda->bit_mask) + if (*(volatile unsigned short *)(swi2c_sda->data_in) & + swi2c_sda->bit_mask) #ifdef CFG_LOADER return 1; return 0; #else - return (HW_REG bool) 1; - return (HW_REG bool) 0; + return (volatile bool) 1; + return (volatile bool) 0; #endif } bool wmt_swi2c_GetSCL(void) /* bit */ { - if (inw(swi2c_scl->data_in) & swi2c_scl->bit_mask) + if (*(volatile unsigned short *)(swi2c_scl->data_in) & + swi2c_scl->bit_mask) #ifdef CFG_LOADER return 1; return 0; #else - return (HW_REG bool) 1; - return (HW_REG bool) 0; + return (volatile bool) 1; + return (volatile bool) 0; #endif } @@ -97,42 +99,30 @@ void wmt_swi2c_SetSDA(int high) { if (high) { /* set to GPI and pull high */ - outw(inw(swi2c_sda->gpio_en) | swi2c_sda->bit_mask, - swi2c_sda->gpio_en); - outw(inw(swi2c_sda->out_en) & ~swi2c_sda->bit_mask, - swi2c_sda->out_en); + REG16_VAL(swi2c_sda->gpio_en) |= swi2c_sda->bit_mask; + REG16_VAL(swi2c_sda->out_en) &= ~swi2c_sda->bit_mask; if (swi2c_sda->pull_en) - outw(inw(swi2c_sda->pull_en) & - ~swi2c_sda->pull_en_bit_mask, - swi2c_sda->pull_en); + REG16_VAL(swi2c_sda->pull_en) &= + ~swi2c_sda->pull_en_bit_mask; } else { - outw(inw(swi2c_sda->gpio_en) | swi2c_sda->bit_mask, - swi2c_sda->gpio_en); - outw(inw(swi2c_sda->out_en) | swi2c_sda->bit_mask, - swi2c_sda->out_en); - outw(inw(swi2c_sda->data_out) & ~swi2c_sda->bit_mask, - swi2c_sda->data_out); + REG16_VAL(swi2c_sda->gpio_en) |= swi2c_sda->bit_mask; + REG16_VAL(swi2c_sda->out_en) |= swi2c_sda->bit_mask; + REG16_VAL(swi2c_sda->data_out) &= ~swi2c_sda->bit_mask; } } void wmt_swi2c_SetSCL(int high) { if (high) { - outw(inw(swi2c_scl->gpio_en) | swi2c_scl->bit_mask, - swi2c_scl->gpio_en); - outw(inw(swi2c_scl->out_en) & ~swi2c_scl->bit_mask, - swi2c_scl->out_en); + REG16_VAL(swi2c_scl->gpio_en) |= swi2c_scl->bit_mask; + REG16_VAL(swi2c_scl->out_en) &= ~swi2c_scl->bit_mask; if (swi2c_scl->pull_en) - outw(inw(swi2c_scl->pull_en) & - ~swi2c_scl->pull_en_bit_mask, - swi2c_scl->pull_en); + REG16_VAL(swi2c_scl->pull_en) &= + ~swi2c_scl->pull_en_bit_mask; } else { - outw(inw(swi2c_scl->gpio_en) | swi2c_scl->bit_mask, - swi2c_scl->gpio_en); - outw(inw(swi2c_scl->out_en) | swi2c_scl->bit_mask, - swi2c_scl->out_en); - outw(inw(swi2c_scl->data_out) & ~swi2c_scl->bit_mask, - swi2c_scl->data_out); + REG16_VAL(swi2c_scl->gpio_en) |= swi2c_scl->bit_mask; + REG16_VAL(swi2c_scl->out_en) |= swi2c_scl->bit_mask; + REG16_VAL(swi2c_scl->data_out) &= ~swi2c_scl->bit_mask; } } @@ -310,24 +300,24 @@ rx_end: return ret; } -void wmt_swi2c_reg_bk(struct swi2c_reg_s *reg_p, - struct swi2c_reg_bk_t *reg_bk, int bk) +void wmt_swi2c_reg_bk(swi2c_reg_t *reg_p, struct swi2c_reg_bk_t *reg_bk, + int bk) { if (bk) { - reg_bk->gpio_en = inw(reg_p->gpio_en); - reg_bk->out_en = inw(reg_p->out_en); - reg_bk->data_out = inw(reg_p->data_out); - reg_bk->pull_en = inw(reg_p->pull_en); + reg_bk->gpio_en = REG16_VAL(reg_p->gpio_en); + reg_bk->out_en = REG16_VAL(reg_p->out_en); + reg_bk->data_out = REG16_VAL(reg_p->data_out); + reg_bk->pull_en = REG16_VAL(reg_p->pull_en); } else { - outw(reg_bk->gpio_en, reg_p->gpio_en); - outw(reg_bk->out_en, reg_p->out_en); - outw(reg_bk->data_out, reg_p->data_out); - outw(reg_bk->pull_en, reg_p->pull_en); + REG16_VAL(reg_p->gpio_en) = reg_bk->gpio_en; + REG16_VAL(reg_p->out_en) = reg_bk->out_en; + REG16_VAL(reg_p->data_out) = reg_bk->data_out; + REG16_VAL(reg_p->pull_en) = reg_bk->pull_en; } } int wmt_swi2c_read( - struct swi2c_handle_s *handle, + swi2c_handle_t *handle, char addr, char index, char *buf, @@ -364,7 +354,7 @@ exit: EXPORT_SYMBOL(wmt_swi2c_read); int wmt_swi2c_write( - struct swi2c_handle_s *handle, + swi2c_handle_t *handle, char addr, char index, char *buf, @@ -396,11 +386,11 @@ exit: } EXPORT_SYMBOL(wmt_swi2c_write); -int wmt_swi2c_check(struct swi2c_handle_s *handle) +int wmt_swi2c_check(swi2c_handle_t *handle) { int ret = 0; #if 0 - struct swi2c_reg_s *reg_p; + swi2c_reg_t *reg_p; struct swi2c_reg_bk_t scl_bk, sda_bk; swi2c_scl = handle->scl_reg; @@ -410,15 +400,15 @@ int wmt_swi2c_check(struct swi2c_handle_s *handle) wmt_swi2c_reg_bk(swi2c_sda, &sda_bk, 1); reg_p = handle->scl_reg; do { - outw(inw(reg_p->gpio_en) | reg_p->bit_mask, reg_p->gpio_en); - outw(inw(reg_p->out_en) | reg_p->bit_mask, reg_p->out_en); - outw(inw(reg_p->data_out) & ~reg_p->bit_mask, reg_p->data_out); + REG16_VAL(reg_p->gpio_en) |= reg_p->bit_mask; + REG16_VAL(reg_p->out_en) |= reg_p->bit_mask; + REG16_VAL(reg_p->data_out) &= ~reg_p->bit_mask; - outw(inw(reg_p->out_en) & ~reg_p->bit_mask, reg_p->out_en); + REG16_VAL(reg_p->out_en) &= ~reg_p->bit_mask; if (reg_p->pull_en) - outw(inw(reg_p->pull_en) & ~reg_p->pull_en_bit_mask, - reg_p->pull_en); - if (inw(reg_p->data_in) & reg_p->bit_mask) { + REG16_VAL(reg_p->pull_en) &= ~reg_p->pull_en_bit_mask; + if (*(volatile unsigned short *)(reg_p->data_in) & + reg_p->bit_mask) { if (reg_p == handle->sda_reg) break; reg_p = handle->sda_reg; diff --git a/drivers/video/wmt/sw_i2c.h b/drivers/video/wmt/sw_i2c.h index 593fd08f..ab4b8d4c 100755..100644 --- a/drivers/video/wmt/sw_i2c.h +++ b/drivers/video/wmt/sw_i2c.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/sw_i2c.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -24,7 +24,7 @@ #ifndef _SWI2C_H_ #define _SWI2C_H_ -struct swi2c_reg_s { +typedef struct { unsigned int bit_mask; unsigned int gpio_en; unsigned int out_en; @@ -32,17 +32,15 @@ struct swi2c_reg_s { unsigned int data_out; unsigned int pull_en_bit_mask; unsigned int pull_en; -}; -#define swi2c_reg_t struct swi2c_reg_s +} swi2c_reg_t; -struct swi2c_handle_s { - struct swi2c_reg_s *scl_reg; - struct swi2c_reg_s *sda_reg; -}; -#define swi2c_handle_t struct swi2c_handle_s +typedef struct { + swi2c_reg_t *scl_reg; + swi2c_reg_t *sda_reg; +} swi2c_handle_t; int wmt_swi2c_read( - struct swi2c_handle_s *handle, + swi2c_handle_t *handle, char addr, char index, char *buf, @@ -50,14 +48,14 @@ int wmt_swi2c_read( ); int wmt_swi2c_write( - struct swi2c_handle_s *handle, + swi2c_handle_t *handle, char addr, char index, char *buf, int cnt ); -int wmt_swi2c_check(struct swi2c_handle_s *handle); +int wmt_swi2c_check(swi2c_handle_t *handle); #endif diff --git a/drivers/video/wmt/vout-wmt.c b/drivers/video/wmt/vout-wmt.c index b7ff0bf4..323f9278 100755..100644 --- a/drivers/video/wmt/vout-wmt.c +++ b/drivers/video/wmt/vout-wmt.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/vout-wmt.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -31,13 +31,14 @@ static int vo_plug_flag; #endif int vo_plug_vout; int (*vo_plug_func)(int hotplug); -enum vout_mode_t dvo_vout_mode; -enum vout_mode_t int_vout_mode; +vout_mode_t dvo_vout_mode; +vout_mode_t int_vout_mode; +struct fb_videomode vo_oem_vmode; int hdmi_cur_plugin; -struct vout_t *vo_poll_vout; +vout_t *vo_poll_vout; /* GPIO 10 & 11 */ -struct swi2c_reg_s vo_gpio_scl = { +swi2c_reg_t vo_gpio_scl = { .bit_mask = BIT10, .gpio_en = (__GPIO_BASE + 0x40), .out_en = (__GPIO_BASE + 0x80), @@ -47,7 +48,7 @@ struct swi2c_reg_s vo_gpio_scl = { .pull_en_bit_mask = BIT10, }; -struct swi2c_reg_s vo_gpio_sda = { +swi2c_reg_t vo_gpio_sda = { .bit_mask = BIT11, .gpio_en = (__GPIO_BASE + 0x40), .out_en = (__GPIO_BASE + 0x80), @@ -57,66 +58,30 @@ struct swi2c_reg_s vo_gpio_sda = { .pull_en_bit_mask = BIT11, }; -struct swi2c_handle_s vo_swi2c_dvi = { +swi2c_handle_t vo_swi2c_dvi = { .scl_reg = &vo_gpio_scl, .sda_reg = &vo_gpio_sda, }; -#define DVI_POLL_TIME_MS 1000 - -extern void hdmi_config_audio(struct vout_audio_t *info); - -/*---------------------------------- API ------------------------------------*/ -#ifdef DEBUG -void vout_print_entry(struct vout_t *vo) -{ - if (vo == 0) - return; +struct vout_init_parm_t { + unsigned int virtual_display; + unsigned int def_resx; + unsigned int def_resy; + unsigned int def_fps; + unsigned int ub_resx; + unsigned int ub_resy; +}; - MSG(" =============== vout %d ===============\n", vo->num); - MSG("fix 0x%x", vo->fix_cap); - MSG("(inf %d,bus %d,govr %d,ext dev %d,fix plug %d,aud %d,edid %d)\n", - (vo->fix_cap & VOUT_CAP_INTERFACE), - (vo->fix_cap & VOUT_CAP_BUS) >> 8, - (vo->fix_cap & VOUT_CAP_GOVR) >> 12, - (vo->fix_cap & VOUT_CAP_EXT_DEV) ? 1 : 0, - (vo->fix_cap & VOUT_CAP_FIX_PLUG) ? 1 : 0, - (vo->fix_cap & VOUT_CAP_AUDIO) ? 1 : 0, - (vo->fix_cap & VOUT_CAP_EDID) ? 1 : 0); - MSG("info %d,%s\n", vo->info->num, vpp_mod_str[vo->govr->mod]); - MSG("inf 0x%x,dev 0x%x\n", (int)vo->inf, (int)vo->dev); - MSG("resx %d,resy %d,fps %d\n", vo->resx, vo->resy, vo->fps); - MSG("pixclk %d,option %d,%d,%d,disable %d\n", vo->pixclk, - vo->option[0], vo->option[1], vo->option[2], vo->disable); - MSG("sts(reg %d,act %d,plug %d,edid %d,blank %d,pwrdn %d,cp %d)\n", - (vo->status & VPP_VOUT_STS_REGISTER) ? 1 : 0, - (vo->status & VPP_VOUT_STS_ACTIVE) ? 1 : 0, - (vo->status & VPP_VOUT_STS_PLUGIN) ? 1 : 0, - (vo->status & VPP_VOUT_STS_EDID) ? 1 : 0, - (vo->status & VPP_VOUT_STS_BLANK) ? 1 : 0, - (vo->status & VPP_VOUT_STS_POWERDN) ? 1 : 0, - (vo->status & VPP_VOUT_STS_CONTENT_PROTECT) ? 1 : 0); - - if (vo->inf) { - MSG(" ===== inf entry =====\n"); - MSG("mode %d, %s\n", - vo->inf->mode, vout_inf_str[vo->inf->mode]); - } +#define DVI_POLL_TIME_MS 100 - if (vo->dev) { - MSG(" ===== dev entry =====\n"); - MSG("name %s,inf %d,%s\n", vo->dev->name, - vo->dev->mode, vout_inf_str[vo->dev->mode]); - MSG("vout 0x%x,capability 0x%x\n", - (int)vo->dev->vout, vo->dev->capability); - } -} -#endif +extern void hdmi_config_audio(vout_audio_t *info); +extern vout_dev_t *lcd_get_dev(void); +/*---------------------------------- API ------------------------------------*/ int vo_i2c_proc(int id, unsigned int addr, unsigned int index, char *pdata, int len) { - struct swi2c_handle_s *handle = 0; + swi2c_handle_t *handle = 0; int ret = 0; switch (id) { @@ -150,7 +115,7 @@ int vo_i2c_proc(int id, unsigned int addr, unsigned int index, #ifndef CONFIG_UBOOT static void vo_do_plug(struct work_struct *ptr) { - struct vout_t *vo; + vout_t *vo; int plugin; if (vo_plug_func == 0) @@ -159,7 +124,7 @@ static void vo_do_plug(struct work_struct *ptr) vo = vout_get_entry(vo_plug_vout); govrh_set_dvo_enable(vo->govr, 1); plugin = vo_plug_func(1); -/* govrh_set_dvo_enable(vo->govr, plugin); */ + govrh_set_dvo_enable(vo->govr, plugin); vout_change_status(vo, VPP_VOUT_STS_PLUGIN, plugin); vo_plug_flag = 0; DBG_DETAIL("vo_do_plug %d\n", plugin); @@ -183,12 +148,12 @@ static irqreturn_t vo_plug_interrupt_routine ) { DBG_DETAIL("Enter\n"); - if ((inb(GPIO_BASE_ADDR + 0x360) & + if ((vppif_reg8_in(GPIO_BASE_ADDR + 0x360) & (0x1 << VPP_VOINT_NO)) == 0) return IRQ_NONE; /* clear int status */ - outb(0x1 << VPP_VOINT_NO, GPIO_BASE_ADDR + 0x360); + vppif_reg8_out(GPIO_BASE_ADDR + 0x360, 0x1 << VPP_VOINT_NO); #ifdef __KERNEL__ /* if (vo_plug_flag == 0) { */ /* GPIO irq disable */ @@ -208,7 +173,7 @@ struct timer_list vo_poll_timer; #ifdef CONFIG_VO_POLL_WORKQUEUE static void vo_do_poll(struct work_struct *ptr) { - struct vout_t *vo; + vout_t *vo; vo = vo_poll_vout; if (vo) { @@ -228,7 +193,7 @@ static void vo_do_poll_tasklet unsigned long data /*!<; // tasklet input data */ ) { - struct vout_t *vo; + vout_t *vo; vpp_lock(); vo = vo_poll_vout; @@ -251,10 +216,8 @@ void vo_do_poll_tmr(int ms) #endif } -static void vo_set_poll(struct vout_t *vo, int on, int ms) +static void vo_set_poll(vout_t *vo, int on, int ms) { - DMSG("%d\n", on); - if (on) { vo_poll_vout = vo; if (vo_poll_timer.function) { @@ -286,7 +249,7 @@ void vout_set_int_type(int type) { unsigned char reg; - reg = inb(GPIO_BASE_ADDR + 0x300 + VPP_VOINT_NO); + reg = vppif_reg8_in(GPIO_BASE_ADDR+0x300 + VPP_VOINT_NO); reg &= ~0x7; switch (type) { case 0: /* low level */ @@ -299,7 +262,7 @@ void vout_set_int_type(int type) default: break; } - outb(reg, GPIO_BASE_ADDR + 0x300 + VPP_VOINT_NO); + vppif_reg8_out(GPIO_BASE_ADDR + 0x300 + VPP_VOINT_NO, reg); } EXPORT_SYMBOL(vout_set_int_type); @@ -312,18 +275,18 @@ EXPORT_SYMBOL(vout_set_int_enable); int vout_get_clr_int(void) { - if ((inb(GPIO_BASE_ADDR + 0x360) & + if ((vppif_reg8_in(GPIO_BASE_ADDR + 0x360) & (0x1 << VPP_VOINT_NO)) == 0) return 1; /* clear int status */ - outb(0x1 << VPP_VOINT_NO, GPIO_BASE_ADDR + 0x360); + vppif_reg8_out(GPIO_BASE_ADDR + 0x360, 0x1 << VPP_VOINT_NO); return 0; } EXPORT_SYMBOL(vout_get_clr_int); static void vo_plug_enable(int enable, void *func, int no) { - struct vout_t *vo; + vout_t *vo; DBG_DETAIL("%d\n", enable); vo_plug_vout = no; @@ -362,77 +325,78 @@ static void vo_plug_enable(int enable, void *func, int no) /*--------------------------------- DVI ------------------------------------*/ #ifdef WMT_FTBLK_VOUT_DVI -static int vo_dvi_blank(struct vout_t *vo, enum vout_blank_t arg) +static int vo_dvi_blank(vout_t *vo, vout_blank_t arg) { - DMSG("(%d, %d)\n", vo->pre_blank, arg); - if(vo->pre_blank == arg) - return 0; - - if (vo->pre_blank == VOUT_BLANK_POWERDOWN) { - if (vo->dev) { + DBG_DETAIL("(%d)\n", arg); + if (vo->pre_blank == VOUT_BLANK_POWERDOWN) { + if (vo->dev) { + vo->dev->init(vo); #ifdef __KERNEL__ - if (!g_vpp.dvi_int_disable && vo->dev->interrupt) - vo_plug_enable(VPP_FLAG_ENABLE, - vo->dev->interrupt, vo->num); - else if (vo->dev->poll) - vo_set_poll(vo, (vo->dev->poll) ? 1 : 0, - DVI_POLL_TIME_MS); + if (vo->dev->poll) + vo_set_poll(vo, (vo->dev->poll) ? 1 : 0, + DVI_POLL_TIME_MS); #endif - } - } + } + } #ifdef __KERNEL__ - if (arg == VOUT_BLANK_POWERDOWN) - vo_set_poll(vo, 0, 0); + if (arg == VOUT_BLANK_POWERDOWN) + vo_set_poll(vo, 0, 0); + + /* patch for virtual fb,if HDMI plugin then DVI blank */ + if (g_vpp.virtual_display || (g_vpp.dual_display == 0)) { + if (vout_chkplug(VPP_VOUT_NUM_HDMI)) { + arg = VOUT_BLANK_NORMAL; + vout_change_status(vo, VPP_VOUT_STS_BLANK, arg); + } + } #endif - if (!lcd_get_dev()) /* enable DVO not contain LCD */ - govrh_set_dvo_enable(vo->govr, - (arg == VOUT_BLANK_UNBLANK) ? 1 : 0); - vo->pre_blank = arg; - return 0; + if (!lcd_get_dev()) /* enable DVO not contain LCD */ + govrh_set_dvo_enable(vo->govr, + (arg == VOUT_BLANK_UNBLANK) ? 1 : 0); + vo->pre_blank = arg; + return 0; } -static int vo_dvi_config(struct vout_t *vo, int arg) +static int vo_dvi_config(vout_t *vo, int arg) { - struct vout_info_t *vo_info; + vout_info_t *vo_info; DBG_DETAIL("Enter\n"); - vo_info = (struct vout_info_t *) arg; + vo_info = (vout_info_t *) arg; govrh_set_dvo_sync_polar(vo->govr, - (vo_info->option & VPP_DVO_SYNC_POLAR_HI) ? 0 : 1, - (vo_info->option & VPP_DVO_VSYNC_POLAR_HI) ? 0 : 1); + (vo_info->option & VPP_DVO_SYNC_POLAR_HI) ? 0 : 1, + (vo_info->option & VPP_DVO_VSYNC_POLAR_HI) ? 0 : 1); return 0; } -static int vo_dvi_init(struct vout_t *vo, int arg) +static int vo_dvi_init(vout_t *vo, int arg) { unsigned int clk_delay; DBG_DETAIL("(%d)\n", arg); - vo->pre_blank = VOUT_BLANK_POWERDOWN; - lvds_set_enable(0); govrh_set_dvo_color_format(vo->govr, vo->option[0]); - govrh_set_dvo_outdatw(vo->govr, vo->option[1] & WMT_DISP_FB_DVI_24BIT); - govrh_IGS_set_mode(vo->govr, 0, WMT_DISP_FB_GET_RGB_MODE(vo->option[1]), - (vo->option[1] & WMT_DISP_FB_MSB) ? 1 : 0); - govrh_IGS_set_RGB_swap(vo->govr, WMT_DISP_FB_RGB_SWAP(vo->option[1])); - clk_delay = (vo->option[1] & WMT_DISP_FB_DVI_24BIT) ? + /* bit0:0-12 bit,1-24bit */ + govrh_set_dvo_outdatw(vo->govr, vo->option[1] & BIT0); + govrh_IGS_set_mode(vo->govr, 0, (vo->option[1] & 0x600) >> 9, + (vo->option[1] & 0x800) >> 11); + govrh_IGS_set_RGB_swap(vo->govr, (vo->option[1] & 0x3000) >> 12); + clk_delay = (vo->option[1] & BIT0) ? VPP_GOVR_DVO_DELAY_24 : VPP_GOVR_DVO_DELAY_12; govrh_set_dvo_clock_delay(vo->govr, ((clk_delay & BIT14) != 0x0), clk_delay & 0x3FFF); if (vo->dev) { vo->dev->set_mode(&vo->option[0]); vo->dev->set_power_down(VPP_FLAG_DISABLE); - if (!g_vpp.dvi_int_disable && vo->dev->interrupt) + if (vo->dev->interrupt) vo_plug_enable(VPP_FLAG_ENABLE, vo->dev->interrupt, vo->num); #ifdef __KERNEL__ - else if (vo->dev->poll) { + if (vo->dev->poll) vo_set_poll(vo, (vo->dev->poll) ? 1 : 0, DVI_POLL_TIME_MS); - } #endif vout_change_status(vo, VPP_VOUT_STS_PLUGIN, vo->dev->check_plugin(0)); @@ -445,7 +409,7 @@ static int vo_dvi_init(struct vout_t *vo, int arg) return 0; } -static int vo_dvi_uninit(struct vout_t *vo, int arg) +static int vo_dvi_uninit(vout_t *vo, int arg) { DBG_DETAIL("(%d)\n", arg); @@ -457,7 +421,7 @@ static int vo_dvi_uninit(struct vout_t *vo, int arg) return 0; } -static int vo_dvi_chkplug(struct vout_t *vo, int arg) +static int vo_dvi_chkplug(vout_t *vo, int arg) { int plugin = 1; @@ -465,7 +429,7 @@ static int vo_dvi_chkplug(struct vout_t *vo, int arg) return plugin; } -static int vo_dvi_get_edid(struct vout_t *vo, int arg) +static int vo_dvi_get_edid(vout_t *vo, int arg) { char *buf; int i, cnt; @@ -494,7 +458,7 @@ static int vo_dvi_get_edid(struct vout_t *vo, int arg) return 0; } -struct vout_inf_t vo_dvi_inf = { +vout_inf_t vo_dvi_inf = { .mode = VOUT_INF_DVI, .init = vo_dvi_init, .uninit = vo_dvi_uninit, @@ -532,9 +496,7 @@ static struct timer_list hdmi_plug_timer; void vo_hdmi_cp_set_enable_tmr(int sec) { -#ifdef __KERNEL__ int ms = sec * 1000; -#endif DBG_MSG("[HDMI] set enable tmr %d sec\n", sec); @@ -554,9 +516,8 @@ void vo_hdmi_cp_set_enable_tmr(int sec) hdmi_set_cp_enable(VPP_FLAG_ENABLE); #endif } -EXPORT_SYMBOL(vo_hdmi_cp_set_enable_tmr); -static int vo_hdmi_blank(struct vout_t *vo, enum vout_blank_t arg) +static int vo_hdmi_blank(vout_t *vo, vout_blank_t arg) { int enable; @@ -579,7 +540,7 @@ static irqreturn_t vo_hdmi_cp_interrupt void *dev_id /*!<; // device id */ ) { - struct vout_t *vo; + vout_t *vo; DBG_DETAIL("%d\n", irq); vo = vout_get_entry(VPP_VOUT_NUM_HDMI); @@ -610,7 +571,7 @@ static void vo_hdmi_do_plug(struct work_struct *ptr) static void vo_hdmi_do_plug(void) #endif { - struct vout_t *vo; + vout_t *vo; int plugin; int option = 0; @@ -636,14 +597,14 @@ DECLARE_WORK(vo_hdmi_plug_work, vo_hdmi_do_plug); static void hdmi_handle_plug(vpp_flag_t enable) { - schedule_work(&vo_hdmi_plug_work); + schedule_work(&vo_hdmi_plug_work); } static void vo_hdmi_handle_plug_tmr(int ms) { static int timer_init; - if (timer_init == 0) { + if(timer_init == 0) { init_timer(&hdmi_plug_timer); hdmi_plug_timer.data = VPP_FLAG_ENABLE; hdmi_plug_timer.function = (void *) hdmi_handle_plug; @@ -663,13 +624,13 @@ static irqreturn_t vo_hdmi_plug_interrupt hdmi_clear_plug_status(); if (g_vpp.hdmi_certify_flag) vo_hdmi_do_plug(0); - else + else vo_hdmi_handle_plug_tmr(HDMI_PLUG_DELAY); return IRQ_HANDLED; } #endif -static int vo_hdmi_init(struct vout_t *vo, int arg) +static int vo_hdmi_init(vout_t *vo, int arg) { DBG_DETAIL("(%d)\n", arg); @@ -679,7 +640,7 @@ static int vo_hdmi_init(struct vout_t *vo, int arg) hdmi_enable_plugin(1); if (g_vpp.hdmi_disable) - return 0; + return 0; #ifndef CONFIG_UBOOT if (vpp_request_irq(VPP_IRQ_HDMI_CP, vo_hdmi_cp_interrupt, SA_INTERRUPT, "hdmi cp", (void *) 0)) { @@ -699,7 +660,7 @@ static int vo_hdmi_init(struct vout_t *vo, int arg) return 0; } -static int vo_hdmi_uninit(struct vout_t *vo, int arg) +static int vo_hdmi_uninit(vout_t *vo, int arg) { DBG_DETAIL("(%d)\n", arg); hdmi_enable_plugin(0); @@ -714,15 +675,16 @@ static int vo_hdmi_uninit(struct vout_t *vo, int arg) return 0; } -static int vo_hdmi_config(struct vout_t *vo, int arg) +static int vo_hdmi_config(vout_t *vo, int arg) { - struct vout_info_t *vo_info; + vout_info_t *vo_info; vdo_color_fmt colfmt; hdmi_set_enable(0); - vo_info = (struct vout_info_t *) arg; + vo_info = (vout_info_t *) arg; DBG_DETAIL("(%dx%d@%d)\n", vo_info->resx, vo_info->resy, vo_info->fps); + DPRINT("hdmi config (%dx%d@%d)\n", vo_info->resx, vo_info->resy, vo_info->fps); /* 1280x720@60, HDMI pixel clock 74250060 not 74500000 */ if ((vo_info->resx == 1280) @@ -750,18 +712,18 @@ static int vo_hdmi_config(struct vout_t *vo, int arg) return 0; } -static int vo_hdmi_chkplug(struct vout_t *vo, int arg) +static int vo_hdmi_chkplug(vout_t *vo, int arg) { int plugin; if (g_vpp.hdmi_disable) - return 0; + return 0; plugin = hdmi_get_plugin(); DBG_DETAIL("%d\n", plugin); return plugin; } -static int vo_hdmi_get_edid(struct vout_t *vo, int arg) +static int vo_hdmi_get_edid(vout_t *vo, int arg) { char *buf; #ifdef CONFIG_WMT_EDID @@ -794,7 +756,7 @@ static int vo_hdmi_get_edid(struct vout_t *vo, int arg) return 0; } -struct vout_inf_t vo_hdmi_inf = { +vout_inf_t vo_hdmi_inf = { .mode = VOUT_INF_HDMI, .init = vo_hdmi_init, .uninit = vo_hdmi_uninit, @@ -816,11 +778,11 @@ module_init(vo_hdmi_initial); /*--------------------------------- LVDS ------------------------------------*/ #ifdef WMT_FTBLK_VOUT_LVDS int vo_lvds_init_flag; -static int vo_lvds_blank(struct vout_t *vo, enum vout_blank_t arg) +static int vo_lvds_blank(vout_t *vo, vout_blank_t arg) { DBG_DETAIL("(%d)\n", arg); if (arg == VOUT_BLANK_POWERDOWN) { - lvds_regs->test.b.tre_en = 0; + vppif_reg32_write(LVDS_TRE_EN, 0); } else { /* avoid suspend signal not clear */ lvds_set_enable((arg == VOUT_BLANK_UNBLANK) ? 1 : 0); } @@ -830,7 +792,7 @@ static int vo_lvds_blank(struct vout_t *vo, enum vout_blank_t arg) return 0; } -static int vo_lvds_config(struct vout_t *vo, int arg) +static int vo_lvds_config(vout_t *vo, int arg) { DBG_DETAIL("(%d)\n", arg); lvds_set_power_down(VPP_FLAG_DISABLE); @@ -838,7 +800,7 @@ static int vo_lvds_config(struct vout_t *vo, int arg) return 0; } -static int vo_lvds_init(struct vout_t *vo, int arg) +static int vo_lvds_init(vout_t *vo, int arg) { DBG_DETAIL("(%d)\n", arg); @@ -852,7 +814,7 @@ static int vo_lvds_init(struct vout_t *vo, int arg) return 0; } -static int vo_lvds_uninit(struct vout_t *vo, int arg) +static int vo_lvds_uninit(vout_t *vo, int arg) { DBG_DETAIL("(%d)\n", arg); lvds_set_enable(VPP_FLAG_DISABLE); @@ -864,7 +826,7 @@ static int vo_lvds_uninit(struct vout_t *vo, int arg) return 0; } -static int vo_lvds_chkplug(struct vout_t *vo, int arg) +static int vo_lvds_chkplug(vout_t *vo, int arg) { DBG_DETAIL("\n"); #if 0 @@ -875,7 +837,7 @@ static int vo_lvds_chkplug(struct vout_t *vo, int arg) return 1; } -struct vout_inf_t vo_lvds_inf = { +vout_inf_t vo_lvds_inf = { .mode = VOUT_INF_LVDS, .capability = VOUT_INF_CAP_FIX_PLUG, .init = vo_lvds_init, @@ -898,9 +860,9 @@ module_init(vo_lvds_initial); #endif /* WMT_FTBLK_VOUT_LVDS */ /*---------------------------------- API ------------------------------------*/ #ifndef CFG_LOADER -int vout_set_audio(struct vout_audio_t *arg) +int vout_set_audio(vout_audio_t *arg) { - struct vout_t *vout; + vout_t *vout; int ret = 0; #if 0 @@ -914,9 +876,7 @@ int vout_set_audio(struct vout_audio_t *arg) #ifdef WMT_FTBLK_VOUT_HDMI vout = vout_get_entry(VPP_VOUT_NUM_HDMI); if (vout) { - g_vpp.hdmi_ch_change = 1; hdmi_config_audio(arg); - g_vpp.hdmi_ch_change = 0; ret = 1; } #endif @@ -927,14 +887,14 @@ int vout_set_audio(struct vout_audio_t *arg) /* 3445 port1 : DVI/SDD, port2 : VGA/SDA, port3 : HDMI/LVDS */ /* 3481 port1 : HDMI/LVDS, port2 : DVI */ /* 3498 port1 : HDMI, port2 : DVI/LVDS */ -struct vout_t vout_entry_0 = { +vout_t vout_entry_0 = { .fix_cap = BIT(VOUT_INF_HDMI), .option[0] = VDO_COL_FMT_ARGB, .option[1] = VPP_DATAWIDHT_24, .option[2] = 0, }; -struct vout_t vout_entry_1 = { +vout_t vout_entry_1 = { .fix_cap = BIT(VOUT_INF_DVI) + BIT(VOUT_INF_LVDS) + VOUT_CAP_EXT_DEV + 0x100, /* i2c bus 1,ext dev */ .option[0] = VDO_COL_FMT_ARGB, @@ -942,256 +902,366 @@ struct vout_t vout_entry_1 = { .option[2] = 0, }; -int vout_add_display(int fb_no, unsigned int *parm) +void vout_init_param(struct vout_init_parm_t *init_parm) { - struct vout_info_t *info; - struct vout_t *vout; - int ret = 0; + char buf[100]; + int varlen = 100; + unsigned int parm[10]; - info = vout_info[fb_no]; - if (!info) { - info = kmalloc(sizeof(struct vout_info_t), GFP_KERNEL); - if (!info) - return 1; - memset(info, 0, sizeof(struct vout_info_t)); - vout_info[fb_no] = info; - DBG_MSG("malloc vout_info %d,0x%x\n", fb_no, (int) info); -#ifdef CONFIG_KERNEL - sema_init(&info->sem, 1); -#endif + memset(init_parm, 0, sizeof(struct vout_init_parm_t)); + + /* register vout & set default */ + vout_register(0, &vout_entry_0); + vout_entry_0.inf = vout_inf_get_entry(VOUT_INF_HDMI); + vout_register(1, &vout_entry_1); + vout_entry_1.inf = vout_inf_get_entry(VOUT_INF_DVI); + + /* [uboot parameter] up bound : resx:resy */ + if (wmt_getsyspara("wmt.display.upbound", buf, &varlen) == 0) { + vpp_parse_param(buf, parm, 2, 0); + init_parm->ub_resx = parm[0]; + init_parm->ub_resy = parm[1]; + MSG("up bound(%d,%d)\n", init_parm->ub_resx, + init_parm->ub_resy); } - if (parm[0] == VOUT_BOOT) { - struct vout_t *vo_boot; + /* [uboot parameter] default resolution : resx:resy:fps */ + init_parm->def_resx = VOUT_INFO_DEFAULT_RESX; + init_parm->def_resy = VOUT_INFO_DEFAULT_RESY; + init_parm->def_fps = VOUT_INFO_DEFAULT_FPS; + if (wmt_getsyspara("wmt.display.default.res", buf, &varlen) == 0) { + vpp_parse_param(buf, parm, 3, 0); + init_parm->def_resx = parm[0]; + init_parm->def_resy = parm[1]; + init_parm->def_fps = parm[2]; + MSG("default res(%d,%d,%d)\n", init_parm->def_resx, + init_parm->def_resy, init_parm->def_fps); + } else if (wmt_getsyspara("wmt.display.param", buf, &varlen) == 0) { + vpp_parse_param(buf, parm, 6, 0); + init_parm->def_resx = parm[3]; + init_parm->def_resy = parm[4]; + init_parm->def_fps = parm[5]; + MSG("param2 res(%d,%d,%d)\n", init_parm->def_resx, + init_parm->def_resy, init_parm->def_fps); + } +} - MSG("[VOUT] %s (%d:%d:%d)\n", - (fb_no == 0) ? "tvbox" : "virtual display", - parm[0], parm[1], parm[2]); - if (fb_no == 0) { +const char *vout_sys_parm_str[] = {"wmt.display.param", "wmt.display.param2"}; +int vout_check_display_info(struct vout_init_parm_t *init_parm) +{ + char buf[100]; + const char *display_param[] = { "2:0:24:1024:600:60", "4:0:24:1024:600:60" }; + int varlen = 100; + unsigned int parm[10]; + vout_t *vo = 0; + int ret = 1; + int i; + int info_no; + + DBG_DETAIL("Enter\n"); + + /* [uboot parameter] display param : type:op1:op2:resx:resy:fps */ + for (i = 0; i < 2; i++) { + strncpy(buf, display_param[i], 19); + DBG_MSG("display param %d : %s\n", i, buf); + vpp_parse_param(buf, (unsigned int *)parm, 6, 0); + MSG("boot parm vo %d opt %d,%d, %dx%d@%d\n", parm[0], + parm[1], parm[2], parm[3], parm[4], parm[5]); + vo = vout_get_entry_adapter(parm[0]); + if (vo == 0) { + vout_t *vo_boot; + + if (parm[0] != VOUT_BOOT) { + ret = 1; + DBG_ERR("uboot param invalid\n"); + break; + } + + g_vpp.virtual_display_mode = parm[1]; + if (parm[1] == 1) { + init_parm->def_resx = parm[3]; + init_parm->def_resy = parm[4]; + init_parm->def_fps = parm[5]; + parm[3] = 1920; + parm[4] = 1080; + parm[5] = 60; + } else if (parm[1] == 2) { + init_parm->def_resx = parm[3]; + init_parm->def_resy = parm[4]; + init_parm->def_fps = parm[5]; + g_vpp.dual_display = 0; + break; + } + + MSG("[VOUT] virtual display\n"); + init_parm->virtual_display = 1; g_vpp.virtual_display = 1; g_vpp.fb0_bitblit = 1; + vo_boot = kmalloc(sizeof(vout_t), GFP_KERNEL); + if (vo_boot == 0) { + ret = 1; + break; + } + vo_boot->resx = parm[3]; + vo_boot->resy = parm[4]; + vo_boot->pixclk = parm[5]; + vo_boot->inf = 0; + vo_boot->num = VPP_VOUT_INFO_NUM; + vo_boot->govr = 0; + info_no = vout_info_add_entry(vo_boot); + kfree(vo_boot); } else { - g_vpp.stream_fb = fb_no; + vo->inf = vout_get_inf_entry_adapter(parm[0]); + vo->option[0] = parm[1]; + vo->option[1] = parm[2]; + vo->resx = parm[3]; + vo->resy = parm[4]; + vo->pixclk = parm[5]; + vout_change_status(vo, VPP_VOUT_STS_BLANK, + (parm[2] & VOUT_OPT_BLANK) ? + VOUT_BLANK_NORMAL : VOUT_BLANK_UNBLANK); + info_no = vout_info_add_entry(vo); } - vo_boot = kmalloc(sizeof(struct vout_t), GFP_KERNEL); - if (vo_boot == 0) - return 1; - memset(vo_boot, 0, sizeof(struct vout_t)); - vo_boot->resx = parm[3]; - vo_boot->resy = parm[4]; - vo_boot->fps = parm[5]; - vo_boot->num = VPP_VOUT_NUM; - vout_info_add_entry(fb_no, vo_boot); - kfree(vo_boot); - return 0; - } - vout = vout_get_entry_adapter(parm[0]); - vout->inf = vout_get_inf_entry_adapter(parm[0]); - vout->option[0] = parm[1]; - vout->option[1] = parm[2]; - vout->resx = parm[3]; - vout->resy = parm[4]; - vout->fps = parm[5]; - vout->disable = (parm[2] & VOUT_OPT_BLANK) ? 1 : 0; - switch (parm[0]) { - case VOUT_LVDS: - { - struct fb_videomode *vmode = 0; - - /* lvds auto detect edid */ - if ((parm[1] == 0) && (parm[3] == 0) && (parm[4] == 0)) { - if (vout_get_edid_option(vout->num)) { - vmode = &vout->edid_info.detail_timing[0]; - if (vmode->pixclock == 0) { - vmode = 0; - DBG_ERR("LVDS timing\n"); + switch (parm[0]) { + case VOUT_LVDS: + { + struct fb_videomode *vmode; + vout_info_t *info; + + info = vout_info_get_entry(info_no); + vmode = 0; + if ((parm[1] == 0) && (parm[3] == 0) && + (parm[4] == 0)) { /* auto detect */ + if (vout_get_edid_option(vo->num)) { + vmode = &vo->edid_info.detail_timing[0]; + if (vmode->pixclock == 0) { + vmode = 0; + DBG_ERR("LVDS timing\n"); + } + } + + if (vo->inf->get_edid(vo, + (int)vo->edid) == 0) { + if (edid_parse(vo->edid, + &vo->edid_info) == 0) + DBG_ERR("LVDS edid parse\n"); + } else { + DBG_ERR("LVDS edid read\n"); } } - if (vout->inf->get_edid(vout, (int)vout->edid) == 0) { - if (edid_parse(vout->edid, - &vout->edid_info) == 0) - DBG_ERR("LVDS edid parse\n"); - } else { - DBG_ERR("LVDS edid read\n"); + if (vmode == 0) { /* use internal timing */ + lcd_parm_t *p = 0; + + if (parm[1]) { + p = lcd_get_parm(parm[1], parm[2]); + if (p) + lcd_set_lvds_id(parm[1]); + } + + if (p == 0) + p = lcd_get_oem_parm(parm[3], parm[4]); + vmode = &p->vmode; + } + memcpy(&vo_oem_vmode, vmode, + sizeof(struct fb_videomode)); + vo->option[2] = vmode->vmode; + info->resx = vmode->xres; + info->resy = vmode->yres; + info->fps = vmode->refresh; + vout_info_set_fixed_timing(info_no, &vo_oem_vmode); + lcd_set_type(1); } + case VOUT_LCD: + { + vout_dev_t *dev; + + lcd_set_parm(parm[1], parm[2] & 0xFF); + dev = lcd_get_dev(); + vo->ext_dev = dev; + vo->dev = dev; + dev->vout = vo; + vo->option[0] = VDO_COL_FMT_ARGB; + vo->option[1] &= ~0xFF; + vo->option[1] |= VPP_DATAWIDHT_24; + } + break; + case VOUT_DVI: + case VOUT_HDMI: + vout_info[info_no].option = (parm[2] & 0x2) ? + VPP_OPT_INTERLACE : 0; + break; + default: + break; } + ret = 0; + } - if (vmode == 0) { /* use internal timing */ - struct lcd_parm_t *p = 0; + if (g_vpp.virtual_display) + ret = 1; - if (parm[1]) { - p = lcd_get_parm(parm[1], parm[2]); - if (p) - lcd_set_lvds_id(parm[1]); + /* add vout entry to info */ + for (i = 0; i < VPP_VOUT_NUM; i++) { + vo = vout_get_entry(i); + if (vo) { + if (vo->resx == 0) { + vo->resx = init_parm->def_resx; + vo->resy = init_parm->def_resy; + vo->pixclk = init_parm->def_fps; } - - if (p == 0) - p = lcd_get_oem_parm(parm[3], parm[4]); - vmode = &p->vmode; - } - vout->option[2] = vmode->vmode; - info->resx = vmode->xres; - info->resy = vmode->yres; - info->fps = vmode->refresh; - vout_info_set_fixed_timing(fb_no, vmode); - lcd_set_type(1); + vout_info_add_entry(vo); } - case VOUT_LCD: - { - struct vout_dev_t *dev; - - lcd_set_parm(parm[1], parm[2] & 0xFF); - dev = lcd_get_dev(); - vout->dev = dev; - dev->vout = vout; - vout->option[0] = VDO_COL_FMT_ARGB; - vout->option[1] &= ~0xFF; - vout->option[1] |= VPP_DATAWIDHT_24; - vout->dev->init(vout); - vout_info_set_fixed_timing(fb_no, &p_lcd->vmode); + } + DBG_DETAIL("Leave\n"); + return ret; +} + +void vout_check_ext_device(void) +{ + char buf[100]; + int varlen = 100; + vout_t *vo = 0; + vout_dev_t *dev = 0; + int i; + vout_info_t *info; + + DBG_DETAIL("Enter\n"); + vpp_i2c_init(1, 0xA0); + + /* [uboot parameter] reg operation : addr op val */ + if (wmt_getsyspara("wmt.display.regop", buf, &varlen) == 0) { + unsigned int addr; + unsigned int val; + char op; + char *p, *endp; + + p = buf; + while (1) { + addr = simple_strtoul(p, &endp, 16); + if (*endp == '\0') + break; + + op = *endp; + if (endp[1] == '~') { + val = simple_strtoul(endp + 2, &endp, 16); + val = ~val; + } else { + val = simple_strtoul(endp + 1, &endp, 16); + } + + DBG_DETAIL(" reg op: 0x%X %c 0x%X\n", addr, op, val); + switch (op) { + case '|': + REG32_VAL(addr) |= val; + break; + case '=': + REG32_VAL(addr) = val; + break; + case '&': + REG32_VAL(addr) &= val; + break; + default: + DBG_ERR("Error, Unknown operator %c\n", op); + } + + if (*endp == '\0') + break; + p = endp + 1; } - break; - case VOUT_DVI: - { - struct vout_dev_t *dev = 0; - - g_vpp.dvi_int_disable = - (parm[2] & WMT_DISP_FB_DISBALE_DVI_INT) ? 1 : 0; - g_vpp.dvi_int_no = (parm[2] & WMT_DISP_FB_DVI_INT) ? - ((parm[1] & 0xF000) >> 12) : VPP_DVI_INT_DEFAULT; - g_vpp.dvi_i2c_no = (parm[2] & WMT_DISP_FB_DVI_I2C) ? - ((parm[1] & 0xF00) >> 8) : VPP_DVI_I2C_DEFAULT; - g_vpp.dvi_i2c_no &= VPP_DVI_I2C_ID_MASK; - - if (parm[2] & WMT_DISP_FB_DISABLE_EXTDEV) - vout->dev = 0; - else { - vpp_i2c_init(VPP_DVI_I2C_ID, 0xA0); + } + + /* [uboot parameter] dvi device : name:i2c id */ + vo = vout_get_entry(VPP_VOUT_NUM_DVI); + info = vout_get_info_entry(VPP_VOUT_NUM_DVI); + if (lcd_get_dev()) { + vo->dev->init(vo); + vout_info_set_fixed_timing(info->num, &p_lcd->vmode); + } else if (vo->ext_dev == 0) { + if (wmt_getsyspara("wmt.display.dvi.dev", buf, &varlen) == 0) { + unsigned int param[1]; + char *p; + + p = strchr(buf, ':'); + *p = 0; + vpp_parse_param(p + 1, param, 1, 0x1); + vpp_i2c_release(); + vpp_i2c_init(param[0], 0xA0); + MSG("dvi dev %s : %x\n", buf, param[0]); do { dev = vout_get_device(dev); if (dev == 0) break; - if (vout->fix_cap & BIT(dev->mode)) { - vout->inf = - vout_inf_get_entry(dev->mode); - if (dev->init(vout) == 0) { - vout->dev = dev; - dev->vout = vout; + if (strcmp(buf, dev->name) == 0) { + vo->ext_dev = dev; + vo->dev = dev; + dev->vout = vo; + + /* probe & init external device */ + if (dev->init(vo)) { + DBG_ERR("%s not exist\n", + dev->name); + vo->dev = vo->ext_dev = 0; break; + } else { + MSG("[VOUT] dvi dev %s\n", buf); } + + /* if LCD then set fixed timing */ + if (vo->dev == lcd_get_dev()) + vout_info_set_fixed_timing( + info->num, &p_lcd->vmode); } } while (1); } - - DBG_MSG("DVI ext dev : %s\n", - (vout->dev) ? vout->dev->name : "NO"); - } - info->option = (parm[2] & WMT_DISP_FB_INTERLACE) ? - VPP_OPT_INTERLACE : 0; - break; - case VOUT_HDMI: - info->option = (parm[2] & WMT_DISP_FB_INTERLACE) ? - VPP_OPT_INTERLACE : 0; -#if 0 /* use old uboot param and wait next chip */ - g_vpp.hdmi_disable = - (parm[2] & WMT_DISP_FB_HDMI_DISABLE) ? 1 : 0; - - g_vpp.hdmi_sp_mode = - (parm[2] & WMT_DISP_FB_HDMI_SP_MODE) ? 1 : 0; -#endif - break; - default: - break; } - if (ret == 0) - vout_info_add_entry(fb_no, vout); - return ret; -} + for (i = 0; i < VPP_VOUT_NUM; i++) { + vo = vout_get_entry(i); + if (vo == 0) + continue; -int vout_check_display(void) -{ - #define BUF_LEN 100 - char buf[BUF_LEN]; - int varlen = BUF_LEN; - unsigned int parm[32]; - int i, idx; - - if (wmt_getsyspara("wmt.display.fb0", buf, &varlen)) { - /* default for no uboot parameter */ - parm[0] = VOUT_HDMI; - parm[1] = VDO_COL_FMT_ARGB; - parm[2] = VPP_DATAWIDHT_24; - parm[3] = 1280; - parm[4] = 720; - parm[5] = 60; - vout_add_display(0, &parm[0]); - parm[0] = VOUT_DVI; - parm[1] = VDO_COL_FMT_ARGB; - parm[2] = VPP_DATAWIDHT_24; - parm[3] = 1024; - parm[4] = 768; - parm[5] = 60; - vout_add_display(0, &parm[0]); - return 1; - } else { - int fb_no = 0; - int num; - - while (fb_no < VPP_VOUT_INFO_NUM) { - sprintf(buf, "wmt.display.fb%d", fb_no); - varlen = BUF_LEN; - if (wmt_getsyspara(buf, buf, &varlen)) - break; - - DBG_DETAIL("fb%d : %s\n", fb_no, buf); - varlen = vpp_parse_param(buf, - (unsigned int *)parm, 32, 0x1C1C1C1D); - DBG_DETAIL("op 0x%x\n", parm[0]); - num = (varlen - 1) / 7; - for (i = 0; i < num; i++) { - idx = 1 + 8 * i; /* [ + 6 + ] = 8 */ - DBG_DETAIL("%d : %x, %x, %x (%dx%d@%d)\n", i, - parm[idx + 1], parm[idx + 2], - parm[idx + 3], parm[idx + 4], - parm[idx + 5], parm[idx + 6]); - vout_add_display(fb_no, &parm[idx + 1]); - } - - vout_info[fb_no]->multi = - (parm[0] & WMT_DISP_FB_MULTI) ? 1 : 0; - vout_info[fb_no]->alloc_mode = (parm[0] & 0xF); - vout_info[fb_no]->hwc_mode = (parm[0] & 0xF0) >> 4; - if (parm[0] & WMT_DISP_FB_COLFMT) - vout_info[fb_no]->fb.col_fmt = ((parm[0] & - WMT_DISP_FB_COLFMT_MASK) >> 16); - fb_no++; + if ((vo->fix_cap & VOUT_CAP_EXT_DEV) && !(vo->ext_dev)) { + dev = 0; + do { + dev = vout_get_device(dev); + if (dev == 0) + break; + if (vo->fix_cap & BIT(dev->mode)) { + vo->inf = vout_inf_get_entry(dev->mode); + if (dev->init(vo) == 0) { + vo->ext_dev = dev; + vo->dev = dev; + dev->vout = vo; + break; + } + } + } while (1); } + DBG_MSG("vout %d ext dev : %s\n", i, + (vo->dev) ? vo->dev->name : "NO"); } /* [uboot parameter] oem timing : pixclk:option:hsync:hbp:hpixel:hfp:vsync:vbp:vpixel:vfp */ - varlen = BUF_LEN; if (wmt_getsyspara("wmt.display.tmr", buf, &varlen) == 0) { + unsigned int param[10]; struct fb_videomode *p; int xres, yres; - struct fb_videomode vo_oem_vmode; p = &vo_oem_vmode; DBG_MSG("tmr %s\n", buf); - vpp_parse_param(buf, parm, 12, 0); - p->pixclock = parm[0]; - p->vmode = parm[1]; - p->hsync_len = parm[2]; - p->left_margin = parm[3]; - p->xres = parm[4]; - p->right_margin = parm[5]; - p->vsync_len = parm[6]; - p->upper_margin = parm[7]; - p->yres = parm[8]; - p->lower_margin = parm[9]; + vpp_parse_param(buf, param, 10, 0); + p->pixclock = param[0]; + p->vmode = param[1]; + p->hsync_len = param[2]; + p->left_margin = param[3]; + p->xres = param[4]; + p->right_margin = param[5]; + p->vsync_len = param[6]; + p->upper_margin = param[7]; + p->yres = param[8]; + p->lower_margin = param[9]; p->pixclock *= 1000; xres = p->hsync_len + p->left_margin + p->xres + p->right_margin; @@ -1200,9 +1270,6 @@ int vout_check_display(void) p->refresh = vpp_calc_refresh(p->pixclock, xres, yres); if (p->refresh == 59) p->refresh = 60; - p->vmode = (parm[1] & VPP_OPT_INTERLACE) ? FB_VMODE_INTERLACED : 0; - p->sync = (parm[1] & VPP_DVO_SYNC_POLAR_HI) ? FB_SYNC_HOR_HIGH_ACT : 0; - p->sync |= (parm[1] & VPP_DVO_VSYNC_POLAR_HI) ? FB_SYNC_VERT_HIGH_ACT : 0; DBG_MSG("tmr pixclk %d,option 0x%x\n", p->pixclock, p->vmode); DBG_MSG("H sync %d,bp %d,pixel %d,fp %d\n", p->hsync_len, @@ -1211,129 +1278,241 @@ int vout_check_display(void) p->upper_margin, p->yres, p->lower_margin); p->pixclock = KHZ2PICOS(p->pixclock / 1000); vout_info_set_fixed_timing(0, &vo_oem_vmode); - vout_info[0]->fixed_width = parm[10]; - vout_info[0]->fixed_height = parm[11]; - vout_info[0]->resx = p->xres; - vout_info[0]->resy = p->yres; - vout_info[0]->fps = p->refresh; - vout_info[0]->vout[0]->resx = p->xres; - vout_info[0]->vout[0]->resy = p->yres; - vout_info[0]->vout[0]->fps = p->refresh; + vout_info[0].resx = p->xres; + vout_info[0].resy = p->yres; + vout_info[0].fps = p->refresh; } - return 0; + DBG_DETAIL("Leave\n"); } -int vout_init(void) +void vout_check_monitor_resolution(struct vout_init_parm_t *init_parm) { - struct vout_info_t *info; - struct vout_t *vout; - int i, j; - - DBG_DETAIL("Enter\n"); + vout_info_t *p; + vout_t *vo; + int i; + + DBG_DETAIL("Check monitor support\n"); + + if (g_vpp.virtual_display) { + p = &vout_info[0]; + if ((p->resx == 0) || (p->resy == 0)) { + struct fb_videomode vmode; + int edid_option; + + for (i = 0; i < VPP_VOUT_NUM; i++) { + if (vout_chkplug(i) == 0) { + DBG_MSG("no plugin %d\n", i); + continue; + } - for(i = 0; i < VPP_VOUT_INFO_NUM; i++) { - if(vout_info[i] != NULL) { - kfree(vout_info[i]); - vout_info[i] = NULL; + edid_option = vout_get_edid_option(i); + if ((edid_option & EDID_OPT_VALID) == 0) { + DBG_MSG("no EDID %d\n", i); + continue; + } + break; + } + vmode.xres = (i == VPP_VOUT_NUM) ? 1280 : 1920; + vmode.yres = (i == VPP_VOUT_NUM) ? 720 : 1080; + vmode.refresh = 60; + vmode.vmode = 0; + vout_find_match_mode(1, &vmode, 1); + init_parm->def_resx = vmode.xres; + init_parm->def_resy = vmode.yres; + init_parm->def_fps = vmode.refresh; + + for (i = 0; i < VPP_VOUT_INFO_NUM; i++) { + p = &vout_info[i]; + p->resx = init_parm->def_resx; + p->resy = init_parm->def_resy; + p->fps = init_parm->def_fps; + } + DBG_MSG("virtual display %dx%d@%d\n", + vmode.xres, vmode.yres, vmode.refresh); } } - /* register vout & set default */ - vout_register(0, &vout_entry_0); - vout_entry_0.inf = vout_inf_get_entry(VOUT_INF_HDMI); - vout_entry_0.govr = p_govrh; - vout_register(1, &vout_entry_1); - vout_entry_1.inf = vout_inf_get_entry(VOUT_INF_DVI); - vout_entry_1.govr = p_govrh2; + for (i = 0; i < VPP_VOUT_INFO_NUM; i++) { + int support; + int vo_num; - /* check vout info */ - DBG_DETAIL("check display\n"); - vout_check_display(); + p = &vout_info[i]; - /* initial vout */ - DBG_DETAIL("init display\n"); - for (i = 0; i < VPP_VOUT_INFO_NUM; i++) { - info = vout_info[i]; - if (!info) + DBG_MSG("info %d (%d,%d,%d)\n", i, p->resx, p->resy, p->fps); + + if (p->vo_mask == 0) break; - for (j = 0; ; j++) { - vout = info->vout[j]; - if (vout == 0) - break; - if (vout->inf) - vout->inf->init(vout, 0); - } - } + if (p->govr == 0) + continue; + if (p->fixed_vmode) + continue; + if (init_parm->ub_resx) + p->resx = init_parm->ub_resx; + if (init_parm->ub_resy) + p->resy = init_parm->ub_resy; + if (!p->resx) + p->resx = init_parm->def_resx; + if (!p->resy) + p->resy = init_parm->def_resy; + if (!p->fps) + p->fps = init_parm->def_fps; + + DBG_DETAIL("info %d (%d,%d,%d)\n", i, p->resx, p->resy, p->fps); + + support = 0; + for (vo_num = 0; vo_num < VPP_VOUT_NUM; vo_num++) { + int edid_option; + + if ((p->vo_mask & (0x1 << vo_num)) == 0) + continue; + vo = vout_get_entry(vo_num); + if (vo == 0) + continue; +#ifdef CONFIG_WMT_EDID + if (vout_chkplug(vo_num) == 0) { + DBG_MSG("no plugin %d\n", vo_num); + continue; + } - /* check monitor resolution */ - DBG_DETAIL("check resolution\n"); - for (i = 0; i < VPP_VOUT_INFO_NUM; i++) { - struct vout_t *vout_first = 0; - struct vout_t *vout_plug = 0; + vout_change_status(vo, VPP_VOUT_STS_BLANK, 0); + edid_option = vout_get_edid_option(vo_num); + if (edid_option & EDID_OPT_VALID) { + struct fb_videomode *vmode; - info = vout_info[i]; - if (!info) + if (edid_find_support(&vo->edid_info, p->resx, + p->resy, p->fps, &vmode)) { + support = 1; + break; + } else { + if (vout_find_edid_support_mode( + &vo->edid_info, + (unsigned int *)&p->resx, + (unsigned int *)&p->resy, + (unsigned int *)&p->fps, + (edid_option & EDID_OPT_16_9) ? + 1 : 0)) { + support = 1; + break; + } + } + } +#else break; - for (j = 0; ; j++) { - vout = info->vout[j]; - if (vout == 0) - break; +#endif + } - if (vout_first == 0) /* first priority */ - vout_first = vout; - - if (vout_chkplug(vout->num)) { - struct fb_videomode vmode; - - vmode.xres = vout->resx; - vmode.yres = vout->resy; - vmode.refresh = vout->fps; - vmode.vmode = 0; - vout_find_match_mode(i, &vmode, 1); - vout->resx = vmode.xres; - vout->resy = vmode.yres; - vout->fps = vmode.refresh; - if (vout_plug == 0) /* first plugin */ - vout_plug = vout; + if (support == 0) { + if (vout_chkplug(VPP_VOUT_NUM_HDMI)) { + init_parm->def_resx = 1280; + init_parm->def_resy = 720; + init_parm->def_fps = 60; + } else { + char buf[40]; + int varlen = 40; + + if (wmt_getsyspara("wmt.display.tvformat", + buf, &varlen) == 0) { + if (strnicmp(buf, "PAL", 3) == 0) { + init_parm->def_resx = 720; + init_parm->def_resy = 576; + init_parm->def_fps = 50; + } else if (strnicmp(buf,"NTSC",4) == 0) { + init_parm->def_resx = 720; + init_parm->def_resy = 480; + init_parm->def_fps = 60; + } + } else { + init_parm->def_resx = 1024; + init_parm->def_resy = 768; + init_parm->def_fps = 60; + } } - - if (info->multi) - vout_change_status(vout, - VPP_VOUT_STS_ACTIVE, 1); + p->resx = init_parm->def_resx; + p->resy = init_parm->def_resy; + p->fps = init_parm->def_fps; + DBG_MSG("use default(%dx%d@%d)\n", p->resx, + p->resy, p->fps); } + DBG_MSG("fb%d(%dx%d@%d)\n", i, p->resx, p->resy, p->fps); + } + DBG_DETAIL("Leave\n"); +} - vout = (vout_plug) ? vout_plug : vout_first; - if (vout) { - vout_change_status(vout, VPP_VOUT_STS_ACTIVE, 1); - info->resx = vout->resx; - info->resy = vout->resy; - info->fps = vout->fps; +int vout_init(void) +{ + vout_t *vo; + int flag; + int i; + struct vout_init_parm_t init_parm; + + DBG_DETAIL("Enter\n"); + + vout_init_param(&init_parm); + + /* check vout info */ + memset(vout_info, 0, sizeof(vout_info_t) * VPP_VOUT_INFO_NUM); + flag = vout_check_display_info(&init_parm); + + /* probe external device */ + vout_check_ext_device(); + + /* check plug & EDID for resolution */ + if (flag) + vout_check_monitor_resolution(&init_parm); + + if ((init_parm.virtual_display) || (g_vpp.dual_display == 0)) { + int plugin; + + plugin = vout_chkplug(VPP_VOUT_NUM_HDMI); + vout_change_status(vout_get_entry(VPP_VOUT_NUM_HDMI), + VPP_VOUT_STS_BLANK, (plugin) ? 0 : 1); + vout_change_status(vout_get_entry(VPP_VOUT_NUM_DVI), + VPP_VOUT_STS_BLANK, (plugin) ? 1 : 0); + } + + DBG_DETAIL("Set mode\n"); + for (i = 0; i < VPP_VOUT_NUM; i++) { + vo = vout_get_entry(i); + if (vo && (vo->inf)) { + vout_inf_mode_t mode; + + mode = vo->inf->mode; + vo->inf = 0; /* force interface init */ + vout_set_mode(i, mode); + DBG_DETAIL("vout %d : inf %s, ext dev %s,status 0x%x\n", + i, + (vo->inf) ? vout_inf_str[vo->inf->mode] : "No", + (vo->dev) ? vo->dev->name : "No", vo->status); } } -#ifdef DEBUG - /* show display info */ +#ifndef CONFIG_UBOOT + for (i = 0; i < VPP_VOUT_NUM; i++) { + vo = vout_get_entry(i); + if (vo) + vout_set_blank((0x1 << i), + (vo->status & VPP_VOUT_STS_BLANK) ? 1 : 0); + } +#endif + + /* show vout info */ for (i = 0; i < VPP_VOUT_INFO_NUM; i++) { - info = vout_info[i]; - if (!info) + vout_info_t *info; + + info = &vout_info[i]; + if (info->vo_mask == 0) break; - MSG("-----------------------------------------------------\n"); - MSG("fb%d, resx %d,resy %d,fps %d\n", i, - info->resx, info->resy, info->fps); - MSG("resx_vir %d,resy_vir %d,pixclk %d\n", info->resx_virtual, - info->resy_virtual, info->pixclk); - MSG("multi %d,alloc %d,option 0x%x\n", info->multi, - info->alloc_mode, info->option); - - for (j = 0; ; j++) { - vout = info->vout[j]; - if (vout == 0) - break; - vout_print_entry(vout); + if (i == 0) { + if (info->govr) { +#ifdef WMT_FTBLK_GOVRH_CURSOR + p_cursor->mmio = info->govr->mmio; +#endif + } } + MSG("[VOUT] info %d,mask 0x%x,%s,%dx%d@%d\n", i, info->vo_mask, + (info->govr) ? vpp_mod_str[info->govr_mod] : "VIR", + info->resx, info->resy, info->fps); } - MSG("-----------------------------------------------------\n"); -#endif DBG_DETAIL("Leave\n"); return 0; } diff --git a/drivers/video/wmt/vout.c b/drivers/video/wmt/vout.c index 9291ac55..683fc97e 100755..100644 --- a/drivers/video/wmt/vout.c +++ b/drivers/video/wmt/vout.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/vout.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2012 WonderMedia Technologies, Inc. * * 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 @@ -40,60 +40,77 @@ /*----------EXPORTED PRIVATE VARIABLES are defined in vout.h -------------*/ /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int vo_xxx; *//*Example*/ -struct vout_t *vout_array[VPP_VOUT_NUM]; -struct vout_inf_t *vout_inf_array[VOUT_INF_MODE_MAX]; -struct vout_dev_t *vout_dev_list; +vout_t *vout_array[VPP_VOUT_NUM]; +vout_inf_t *vout_inf_array[VOUT_INF_MODE_MAX]; +vout_dev_t *vout_dev_list; /*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ /* void vo_xxx(void); *//*Example*/ /*----------------------- Function Body --------------------------------------*/ /*----------------------- vout API --------------------------------------*/ -void vout_register(int no, struct vout_t *vo) +void vout_print_entry(vout_t *vo) +{ + MSG(" ===== vout entry =====\n"); + MSG("0x%x\n", (int)vo); + if (vo == 0) + return; + + MSG("num %d,fix 0x%x,var 0x%x\n", vo->num, vo->fix_cap, vo->var_cap); + MSG("inf 0x%x,dev 0x%x,ext_dev 0x%x\n", (int)vo->inf, + (int)vo->dev, (int)vo->ext_dev); + MSG("resx %d,resy %d,pixclk %d\n", vo->resx, vo->resy, vo->pixclk); + MSG("status 0x%x,option %d,%d,%d\n", vo->status, + vo->option[0], vo->option[1], vo->option[2]); + + if (vo->inf) { + MSG(" ===== inf entry =====\n"); + MSG("mode %d, %s\n", + vo->inf->mode, vout_inf_str[vo->inf->mode]); + } + + if (vo->dev) { + MSG(" ===== dev entry =====\n"); + MSG("name %s,inf %d,%s\n", vo->dev->name, + vo->dev->mode, vout_inf_str[vo->dev->mode]); + MSG("vout 0x%x,capability 0x%x\n", + (int)vo->dev->vout, vo->dev->capability); + } +} + +void vout_register(int no, vout_t *vo) { if (no >= VPP_VOUT_NUM) return; vo->num = no; vo->govr = (void *) p_govrh; - vo->status = VPP_VOUT_STS_REGISTER; - vo->info = 0; + vo->status = VPP_VOUT_STS_REGISTER + VPP_VOUT_STS_BLANK; vout_array[no] = vo; } -struct vout_t *vout_get_entry(int no) +vout_t *vout_get_entry(int no) { if (no >= VPP_VOUT_NUM) return 0; return vout_array[no]; } -EXPORT_SYMBOL(vout_get_entry); -struct vout_info_t *vout_get_info_entry(int no) +vout_info_t *vout_get_info_entry(int no) { - struct vout_info_t *info; - struct vout_t *vout; - int i, j; + int i; if (no >= VPP_VOUT_NUM) return 0; - for (i = 0; i < VPP_VOUT_INFO_NUM; i++) { - info = vout_info[i]; - if (!info) - break; - for (j = 0; j < VPP_VOUT_NUM; j++) { - vout = info->vout[j]; - if (vout == 0) - break; - if (vout->num == no) - return info; - } + for (i = 0; i < VPP_VOUT_NUM; i++) { + if (vout_info[i].vo_mask & (0x1 << no)) + return &vout_info[i]; } return 0; } -void vout_change_status(struct vout_t *vo, int mask, int sts) +void vout_change_status(vout_t *vo, int mask, int sts) { DBG_DETAIL("(0x%x,%d)\n", mask, sts); if (sts) @@ -107,9 +124,7 @@ void vout_change_status(struct vout_t *vo, int mask, int sts) vo->status &= ~(VPP_VOUT_STS_EDID + VPP_VOUT_STS_CONTENT_PROTECT); vo->edid_info.option = 0; -#ifdef __KERNEL__ vpp_netlink_notify_cp(0); -#endif } break; default: @@ -117,9 +132,9 @@ void vout_change_status(struct vout_t *vo, int mask, int sts) } } -int vout_query_inf_support(int no, enum vout_inf_mode_t mode) +int vout_query_inf_support(int no, vout_inf_mode_t mode) { - struct vout_t *vo; + vout_t *vo; if (no >= VPP_VOUT_NUM) return 0; @@ -132,7 +147,7 @@ int vout_query_inf_support(int no, enum vout_inf_mode_t mode) } /*----------------------- vout interface API --------------------------------*/ -int vout_inf_register(enum vout_inf_mode_t mode, struct vout_inf_t *inf) +int vout_inf_register(vout_inf_mode_t mode, vout_inf_t *inf) { if (mode >= VOUT_INF_MODE_MAX) { DBG_ERR("vout interface mode invalid %d\n", mode); @@ -146,7 +161,7 @@ int vout_inf_register(enum vout_inf_mode_t mode, struct vout_inf_t *inf) return 0; } /* End of vout_register */ -struct vout_inf_t *vout_inf_get_entry(enum vout_inf_mode_t mode) +vout_inf_t *vout_inf_get_entry(vout_inf_mode_t mode) { if (mode >= VOUT_INF_MODE_MAX) { DBG_ERR("vout interface mode invalid %d\n", mode); @@ -156,9 +171,9 @@ struct vout_inf_t *vout_inf_get_entry(enum vout_inf_mode_t mode) } /*----------------------- vout device API -----------------------------------*/ -int vout_device_register(struct vout_dev_t *ops) +int vout_device_register(vout_dev_t *ops) { - struct vout_dev_t *list; + vout_dev_t *list; if (vout_dev_list == 0) { vout_dev_list = ops; @@ -173,14 +188,14 @@ int vout_device_register(struct vout_dev_t *ops) return 0; } -struct vout_dev_t *vout_get_device(struct vout_dev_t *ops) +vout_dev_t *vout_get_device(vout_dev_t *ops) { if (ops == 0) return vout_dev_list; return ops->next; } -struct vout_t *vout_get_entry_adapter(enum vout_mode_t mode) +vout_t *vout_get_entry_adapter(vout_mode_t mode) { int no; @@ -206,7 +221,7 @@ struct vout_t *vout_get_entry_adapter(enum vout_mode_t mode) return vout_get_entry(no); } -struct vout_inf_t *vout_get_inf_entry_adapter(enum vout_mode_t mode) +vout_inf_t *vout_get_inf_entry_adapter(vout_mode_t mode) { int no; @@ -232,107 +247,101 @@ struct vout_inf_t *vout_get_inf_entry_adapter(enum vout_mode_t mode) return vout_inf_get_entry(no); } -enum vpp_vout_s vout_get_mode_adapter(struct vout_t *vout) +int vout_info_add_entry(vout_t *vo) { - enum vpp_vout_s mode; + vout_info_t *p; + int i = 0; - switch (vout->inf->mode) { - case VOUT_INF_DVI: - mode = VPP_VOUT_DVI; - if (vout->dev && (strcmp("LCD", vout->dev->name) == 0)) - mode = VPP_VOUT_LCD; - break; - case VOUT_INF_HDMI: - mode = VPP_VOUT_HDMI; - break; - case VOUT_INF_LVDS: - mode = VPP_VOUT_LVDS; - break; - default: - mode = VPP_VOUT_NONE; - break; + if (vo == 0) /* invalid */ + return 0; + + if (vo->inf) { + switch (vo->inf->mode) { + case VOUT_INF_DVI: + case VOUT_INF_LVDS: + vo->govr = p_govrh2; + break; + default: + vo->govr = p_govrh; + break; + } } - return mode; -} -int vout_info_add_entry(int no, struct vout_t *vo) -{ - struct vout_info_t *info; - int i = 0; + if (g_vpp.virtual_display) { + if (vo->inf) + i = 1; + } else { + if (vo->inf == 0) /* invalid */ + return 0; - if ((vo == 0) || (vo->info)) - return 0; + if (g_vpp.dual_display) { + for (i = 0; i < VPP_VOUT_INFO_NUM; i++) { + p = &vout_info[i]; + if (p->vo_mask == 0) /* no use */ + break; - info = vout_info[no]; - info->num = no; - if (vo->num < VPP_VOUT_NUM) { /* not virtual vout */ - for (i = 0; i < VPP_VOUT_NUM; i++) { - if (info->vout[i] == 0) { - info->vout[i] = vo; - vo->info = info; - break; - } else { - if (info->vout[i] == vo) /* exist */ + if (p->vo_mask & (0x1 << vo->num)) /* exist */ + return i; + + if (vo->govr && (p->govr_mod == + ((vpp_mod_base_t *)(vo->govr))->mod)) break; } } } - if (i == 0) { /* new */ - info->resx = vo->resx; - info->resy = vo->resy; - info->resx_virtual = vpp_calc_align(info->resx, 4); - info->resy_virtual = info->resy; - info->fps = (int) vo->fps; - DBG_MSG("new %dx%d@%d\n", info->resx, info->resy, info->fps); + if (i >= VPP_VOUT_INFO_NUM) { + DBG_ERR("full\n"); + return 0; } - - DBG_MSG("info %d,%dx%d@%d\n", no, info->resx, info->resy, info->fps); - return no; + p = &vout_info[i]; + p->num = i; + if (p->vo_mask == 0) { + p->resx = vo->resx; + p->resy = vo->resy; + p->resx_virtual = vpp_calc_align(p->resx, 4); + p->resy_virtual = p->resy; + p->fps = (int) vo->pixclk; + p->govr_mod = (vo->govr) ? + ((vpp_mod_base_t *)vo->govr)->mod : VPP_MOD_MAX; + p->govr = vo->govr; + } + p->vo_mask |= (0x1 << vo->num); + DBG_MSG("info %d,vo mask 0x%x,%s,%dx%d@%d\n", i, p->vo_mask, + vpp_mod_str[p->govr_mod], p->resx, p->resy, p->fps); + return i; } -struct vout_info_t *vout_info_get_entry(int no) +vout_info_t *vout_info_get_entry(int no) { - if (no >= VPP_VOUT_INFO_NUM) - return 0; - return vout_info[no]; + if (g_vpp.dual_display == 0) + return &vout_info[0]; + + if ((no >= VPP_VOUT_INFO_NUM) || (vout_info[no].vo_mask == 0)) + no = 0; + + return &vout_info[no]; } void vout_info_set_fixed_timing(int no, struct fb_videomode *vmode) { - struct vout_info_t *info; + vout_info_t *info; DBG_MSG("(%d)\n", no); info = vout_info_get_entry(no); - if (!info->fixed_vmode) { - info->fixed_vmode = - kmalloc(sizeof(struct fb_videomode), GFP_KERNEL); - if (!info->fixed_vmode) - return; - } - memcpy(info->fixed_vmode, vmode, sizeof(struct fb_videomode)); + info->fixed_vmode = vmode; } -struct govrh_mod_t *vout_info_get_govr(int no) +govrh_mod_t *vout_info_get_govr(int no) { - struct vout_info_t *info; - struct govrh_mod_t *govr = 0; - int i; - - info = vout_info[no]; - if (!info) - return 0; + vout_info_t *info; + govrh_mod_t *govr; - for (i = 0; i < VPP_VOUT_NUM; i++) { - if (info->vout[i]) { - if (govr == 0) - govr = info->vout[i]->govr; - if (info->vout[i]->status & VPP_VOUT_STS_ACTIVE) { - govr = info->vout[i]->govr; - break; - } - } + info = vout_info_get_entry(no); + govr = info->govr; + if (g_vpp.virtual_display || (g_vpp.dual_display == 0)) { + govr = (hdmi_get_plugin()) ? p_govrh : p_govrh2; } return govr; } @@ -341,7 +350,7 @@ int vout_check_ratio_16_9(unsigned int resx, unsigned int resy) { int val; - val = (resy) ? ((resx * 10) / resy) : 0; + val = (resx * 10) / resy; return (val >= 15) ? 1 : 0; } @@ -354,20 +363,17 @@ struct fb_videomode *vout_get_video_mode(int vout_num, int d; int resx, resy, fps; unsigned int pixel_clock, diff_pixel_clock = -1; - struct vout_t *vo = 0; + vout_t *vo = 0; char *edid = 0; resx = vmode->xres; resy = vmode->yres; fps = vmode->refresh; -#ifdef DEBUG - pixel_clock = (vmode->pixclock) ? PICOS2KHZ(vmode->pixclock) * 1000 : 0; - DBG_MSG("%d,%dx%d@%d,%d,0x%x\n", vout_num, resx, resy, fps, - pixel_clock, option); -#endif pixel_clock = vmode->pixclock; + DBG_MSG("%d,%dx%d@%d,%d,0x%x\n", vout_num, resx, resy, fps, + (int) PICOS2KHZ(vmode->pixclock) * 1000, option); - /* EDID detail timing */ + /* EDID detail timing */ if (option & VOUT_MODE_OPTION_EDID) { unsigned int opt; struct fb_videomode *edid_vmode; @@ -457,51 +463,16 @@ struct fb_videomode *vout_get_video_mode(int vout_num, return best; } -int vout_get_width_height(int fbnum, int *width, int *height) -{ - struct vout_info_t *info; - int i; - - info = vout_info_get_entry(fbnum); - *width = 0; - *height = 0; - for (i = 0; i < VPP_VOUT_NUM; i++) { - struct vout_t *vout; - - vout = info->vout[i]; - if (vout) { - if ((vout->inf->mode == VOUT_INF_DVI) && p_lcd) { - if (info->fixed_width != 0 && info->fixed_height != 0) { - *width = info->fixed_width; - *height = info->fixed_height; - } else { - *width = p_lcd->width; - *height = p_lcd->height; - } - break; - } - if (vout_chkplug(vout->num)) { - if (vout_get_edid_option(vout->num) - & EDID_OPT_VALID) { - *width = vout->edid_info.width; - *height = vout->edid_info.height; - break; - } - } - } - } - return 0; -} - #ifndef CONFIG_VPOST int vout_find_match_mode(int fbnum, struct fb_videomode *vmode, int match) { - struct vout_info_t *info; + vout_info_t *info; struct fb_videomode *p; int no = VPP_VOUT_NUM; unsigned int option; int i; + unsigned int vo_mask; DBG_DETAIL("(%d)\n", fbnum); @@ -520,21 +491,28 @@ int vout_find_match_mode(int fbnum, p = info->fixed_vmode; goto label_find_match; } + + vo_mask = vout_get_mask(info); + if (vo_mask == 0 && vmode->pixclock) + return 0; + + /* find plugin or first vout */ for (i = 0; i < VPP_VOUT_NUM; i++) { - if (info->vout[i]) { - int vout_no = info->vout[i]->num; - - if (no == VPP_VOUT_NUM) - no = vout_no; /* get first vo */ - if (vout_chkplug(vout_no)) { - no = vout_no; - break; - } + if ((vo_mask & (0x1 << i)) == 0) + continue; + + if (no == VPP_VOUT_NUM) + no = i; /* get first vo */ + + if (vout_chkplug(i)) { + no = i; + break; } } + /* resolution match and interlace match */ - option = VOUT_MODE_OPTION_GREATER + VOUT_MODE_OPTION_LESS; - option |= (no == VPP_VOUT_NUM) ? 0 : VOUT_MODE_OPTION_EDID; + option = VOUT_MODE_OPTION_GREATER + VOUT_MODE_OPTION_LESS + + VOUT_MODE_OPTION_EDID; option |= (vmode->vmode & FB_VMODE_INTERLACED) ? VOUT_MODE_OPTION_INTERLACE : VOUT_MODE_OPTION_PROGRESS; p = vout_get_video_mode(no, vmode, option); @@ -542,8 +520,8 @@ int vout_find_match_mode(int fbnum, goto label_find_match; /* resolution match but interlace not match */ - option = VOUT_MODE_OPTION_GREATER + VOUT_MODE_OPTION_LESS; - option |= (no == VPP_VOUT_NUM) ? 0 : VOUT_MODE_OPTION_EDID; + option = VOUT_MODE_OPTION_GREATER + VOUT_MODE_OPTION_LESS + + VOUT_MODE_OPTION_EDID; option |= (vmode->vmode & FB_VMODE_INTERLACED) ? VOUT_MODE_OPTION_PROGRESS : VOUT_MODE_OPTION_INTERLACE; p = vout_get_video_mode(no, vmode, option); @@ -552,8 +530,7 @@ int vout_find_match_mode(int fbnum, /* if( !match ){ */ /* resolution less best mode */ - option = VOUT_MODE_OPTION_LESS; - option |= (no == VPP_VOUT_NUM) ? 0 : VOUT_MODE_OPTION_EDID; + option = VOUT_MODE_OPTION_LESS + VOUT_MODE_OPTION_EDID; p = vout_get_video_mode(no, vmode, option); if (p) goto label_find_match; @@ -570,7 +547,7 @@ label_find_match: #endif int vout_find_edid_support_mode( - struct edid_info_t *info, + edid_info_t *info, unsigned int *resx, unsigned int *resy, unsigned int *fps, @@ -583,8 +560,8 @@ int vout_find_edid_support_mode( struct fb_videomode *p; unsigned int w, h, f, option; - if ((*resx == 720) && (*resy == 480) && (*fps == 50)) - *fps = 60; + if ((*resx == 720) && (*resy == 480) && (*fps == 50)) + *fps = 60; for (i = 0, cnt = 0; ; i++) { if (vpp_videomode[i].pixclock == 0) @@ -626,45 +603,91 @@ int vout_find_edid_support_mode( } /*----------------------- vout control API ----------------------------------*/ -void vout_set_framebuffer(struct vout_info_t *info, vdo_framebuf_t *fb) +void vout_set_framebuffer(unsigned int mask, vdo_framebuf_t *fb) { int i; - struct vout_t *vo; + vout_t *vo; - if (!info) + if (mask == 0) return; for (i = 0; i < VPP_VOUT_NUM; i++) { - vo = info->vout[i]; - if (vo == 0) - break; - if (vo->govr) + if ((mask & (0x1 << i)) == 0) + continue; + vo = vout_get_entry(i); + if (vo && (vo->govr)) vo->govr->fb_p->set_framebuf(fb); } } -int vout_set_blank(int no, enum vout_blank_t arg) +void vout_set_tg_enable(unsigned int mask, int enable) { - struct vout_t *vo; + int i; + vout_t *vo; - DBG_DETAIL("(%d,%d)\n", no, arg); + if (mask == 0) + return; - vo = vout_get_entry(no); - if (vo && (vo->inf)) { - vout_change_status(vo, VPP_VOUT_STS_BLANK, arg); - vo->inf->blank(vo, arg); - if (vo->dev && vo->dev->set_power_down) - vo->dev->set_power_down( - (arg == VOUT_BLANK_POWERDOWN) ? 1 : 0); - if (vo->govr) - govrh_set_MIF_enable(vo->govr, (arg) ? 0 : 1); + for (i = 0; i < VPP_VOUT_NUM; i++) { + if ((mask & (0x1 << i)) == 0) + continue; + vo = vout_get_entry(i); + if (vo && (vo->govr)) + govrh_set_tg_enable(vo->govr, enable); + } +} + +int vout_set_blank(unsigned int mask, vout_blank_t arg) +{ + int i; + vout_t *vo; + + DBG_DETAIL("(0x%x,%d)\n", mask, arg); + + if (mask == 0) + return 0; + + for (i = 0; i < VPP_VOUT_NUM; i++) { + if ((mask & (0x1 << i)) == 0) + continue; + + vo = vout_get_entry(i); + if (vo && (vo->inf)) { + vout_change_status(vo, VPP_VOUT_STS_BLANK, arg); + vo->inf->blank(vo, arg); + if (vo->dev && vo->dev->set_power_down) + vo->dev->set_power_down( + (arg == VOUT_BLANK_POWERDOWN) ? 1 : 0); + } + } + + if (1) { + int govr_enable_mask, govr_mask; + govrh_mod_t *govr; + + govr_enable_mask = 0; + for (i = 0; i < VPP_VOUT_NUM; i++) { + vo = vout_get_entry(i); + if (vo && (vo->govr)) { + govr_mask = (vo->govr->mod == VPP_MOD_GOVRH) ? + 0x1 : 0x2; + govr_enable_mask |= (vo->status & + VPP_VOUT_STS_BLANK) ? 0 : govr_mask; + } + } + for (i = 0; i < VPP_VOUT_INFO_NUM; i++) { + govr = (i == 0) ? p_govrh : p_govrh2; + govr_mask = 0x1 << i; + govrh_set_MIF_enable(govr, + (govr_enable_mask & govr_mask) ? 1 : 0); + } } return 0; } -int vout_set_mode(int no, enum vout_inf_mode_t mode) +int vout_set_mode(int no, vout_inf_mode_t mode) { - struct vout_t *vo; + vout_t *vo; DBG_DETAIL("(%d,%d)\n", no, mode); @@ -689,58 +712,57 @@ int vout_set_mode(int no, enum vout_inf_mode_t mode) return 0; } -int vout_config(struct vout_info_t *info, struct fb_videomode *vmode, - vdo_framebuf_t *fb) +int vout_config(unsigned int mask, + vout_info_t *info, struct fb_videomode *vmode) { - struct vout_t *vo; + vout_t *vo; + unsigned int govr_mask = 0; int i; - DBG_DETAIL("\n"); + DBG_DETAIL("(0x%x)\n", mask); - if (!vmode && !fb) + if (mask == 0) return 0; - if (vmode) { - /* option for interface & device config */ - info->resx = vmode->xres; - info->resy = vmode->yres; - info->fps = (vmode->refresh == 59) ? 60 : vmode->refresh; - info->option = (vmode->vmode & FB_VMODE_INTERLACED) ? - VPP_OPT_INTERLACE : 0; - info->option |= (vmode->sync & FB_SYNC_HOR_HIGH_ACT) ? - VPP_DVO_SYNC_POLAR_HI : 0; - info->option |= (vmode->sync & FB_SYNC_VERT_HIGH_ACT) ? - VPP_DVO_VSYNC_POLAR_HI : 0; - } - + /* option for interface & device config */ + info->resx = vmode->xres; + info->resy = vmode->yres; + info->fps = (vmode->refresh == 59) ? 60 : vmode->refresh; + info->option = (vmode->vmode & FB_VMODE_INTERLACED) ? + VPP_OPT_INTERLACE : 0; + info->option |= (vmode->sync & FB_SYNC_HOR_HIGH_ACT) ? + VPP_DVO_SYNC_POLAR_HI : 0; + info->option |= (vmode->sync & FB_SYNC_VERT_HIGH_ACT) ? + VPP_DVO_VSYNC_POLAR_HI : 0; for (i = 0; i < VPP_VOUT_NUM; i++) { - vo = info->vout[i]; + if ((mask & (0x1 << i)) == 0) + continue; + + vo = vout_get_entry(i); if (vo == 0) - break; + continue; if (vo->govr == 0) continue; - if (vmode) { + if ((govr_mask & (0x1 << vo->govr->mod)) == 0) { govrh_set_videomode(vo->govr, vmode); - - if (vo->inf) { - vo->inf->config(vo, (int)info); - if (vo->dev) - vo->dev->config(info); - } + govr_mask |= (0x1 << vo->govr->mod); } - if (fb) - govrh_set_framebuffer(vo->govr, fb); + if (vo->inf) { + vo->inf->config(vo, (int)info); + if (vo->dev) + vo->dev->config(info); + } } return 0; } int vout_chkplug(int no) { - struct vout_t *vo; - struct vout_inf_t *inf; + vout_t *vo; + vout_inf_t *inf; int ret = 0; DBG_DETAIL("(%d)\n", no); @@ -764,10 +786,10 @@ int vout_chkplug(int no) return ret; } -int vout_inf_chkplug(int no, enum vout_inf_mode_t mode) +int vout_inf_chkplug(int no, vout_inf_mode_t mode) { - struct vout_t *vo; - struct vout_inf_t *inf; + vout_t *vo; + vout_inf_t *inf; int plugin = 0; DBG_MSG("(%d,%d)\n", no, mode); @@ -785,7 +807,7 @@ int vout_inf_chkplug(int no, enum vout_inf_mode_t mode) char *vout_get_edid(int no) { - struct vout_t *vo; + vout_t *vo; int ret; DBG_DETAIL("(%d)\n", no); @@ -837,7 +859,7 @@ char *vout_get_edid(int no) int vout_get_edid_option(int no) { - struct vout_t *vo; + vout_t *vo; DBG_DETAIL("(%d)\n", no); @@ -860,29 +882,22 @@ int vout_get_edid_option(int no) return vo->edid_info.option; } -unsigned int vout_get_mask(struct vout_info_t *vo_info) +unsigned int vout_get_mask(vout_info_t *vo_info) { - unsigned int mask; - int i; + if (g_vpp.dual_display == 0) + return VPP_VOUT_ALL; if (g_vpp.virtual_display) { if (vo_info->num == 0) return 0; return VPP_VOUT_ALL; } - - mask = 0; - for (i = 0; i <= VPP_VOUT_NUM; i++) { - if (vo_info->vout[i] == 0) - break; - mask |= (0x1 << vo_info->vout[i]->num); - } - return mask; + return vo_info->vo_mask; } int vout_check_plugin(int clr_sts) { - struct vout_t *vo; + vout_t *vo; int i; int plugin = 0; @@ -917,25 +932,5 @@ int vout_check_plugin(int clr_sts) } return plugin; } - -enum vout_tvformat_t vout_get_tvformat(void) -{ - char buf[40] = {0}; - int varlen = 40; - enum vout_tvformat_t s_tvformat = TV_MAX; - - if (wmt_getsyspara("wmt.display.tvformat", buf, &varlen) == 0) { - if (!strnicmp(buf, "PAL", 3)) - s_tvformat = TV_PAL; - else if (!strnicmp(buf, "NTSC", 4)) - s_tvformat = TV_NTSC; - else - s_tvformat = TV_UNDEFINED; - } else - s_tvformat = TV_UNDEFINED; - - return s_tvformat; -} - /*--------------------End of Function Body -----------------------------------*/ #undef VOUT_C diff --git a/drivers/video/wmt/vout.h b/drivers/video/wmt/vout.h index d6dbcb66..069cc32e 100755..100644 --- a/drivers/video/wmt/vout.h +++ b/drivers/video/wmt/vout.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/vout.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -45,8 +45,7 @@ extern "C" { /*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/ /* typedef void vo_xxx_t; *//*Example*/ - -enum vout_mode_t { +typedef enum { VOUT_SD_ANALOG, VOUT_SD_DIGITAL, VOUT_LCD, @@ -58,9 +57,9 @@ enum vout_mode_t { VOUT_BOOT, VOUT_MODE_MAX, VOUT_MODE_ALL = VOUT_MODE_MAX -}; +} vout_mode_t; -enum vout_dev_mode_t { +typedef enum { VOUT_DEV_VGA, VOUT_DEV_DVI, VOUT_DEV_LCD, @@ -68,123 +67,27 @@ enum vout_dev_mode_t { VOUT_DEV_SDD, VOUT_DEV_LVDS, VOUT_DEV_MODE_MAX -}; +} vout_dev_mode_t; -enum vout_inf_mode_t { +typedef enum { VOUT_INF_DVI, VOUT_INF_HDMI, VOUT_INF_LVDS, VOUT_INF_MODE_MAX -}; +} vout_inf_mode_t; -enum vout_tvformat_t { +typedef enum { TV_PAL, TV_NTSC, TV_UNDEFINED, TV_MAX -}; - -/* wmt.display.fb0 - op:[type:op1:op2:resx:resy:fps]:[...]:[...] -<op>:[<type>:<op1>:<op2>:<resx>:<resy>:<fps>]:[...]... -[H] <op>:= -<op>.Bit[3:0] : fb type (0-GE,1-alloc & fix,2-dynamic alloc,3-GE overscan) -<op>.Bit[7:4] : hwc type (0-normal,1-scale,2-overscan,3-virtual) -<op>.Bit[8] : multi display -<op>.Bit[9] : color format valid flag -<op>.Bit[23:16] : color format - -[H] <type>:= -1: SDA -[H]<op1>:= mode (0-YCbCr,1-VGA,2-YPbPr,4-SVideo,5-CVBS) -[H]<op2> -2: LCD -[H]<op1>:= lcd id (0-auto or OEM,1-Chilin,2-Innolux,3-AUO,4-Eking,5-Hannstar) -[H]<op2>:= -<op2>.Bit[7:0] : bit per pixel -<op2>.Bit[10:8] : rgb mode (0-888,1-555,2-666,3-565) -<op2>.Bit[11] : msb(0-lsb,1-msb) -<op2>.Bit[13:12] : swap (0-RGB [7-0], 1-RGB [0-7], 2-BGR [7-0], 3-BGR [0-7]) -3: DVI -[H]<op1> := -<op1>.Bit[7:0] : color format(6-ARGB) -<op1>.Bit[11:8] : dvi i2c bus id -<op1>.Bit[15:12] : dvi interrupt gpio no -[H]<op2> := -<op2>.Bit[0] : (0-12bit,1-24bit) -<op2>.Bit[1] : (1:interlace) -<op2>.Bit[2] : disable external device -<op2>.Bit[3] : disable external device interrupt -<op2>.Bit[4] : dvi i2c bus id valid -<op2>.Bit[5] : dvi interrupt gpio no valid -<op2>.Bit[10:8] : rgb mode (0-888,1-555,2-666,3-565) -<op2>.Bit[11] : (0-lsb,1-msb) -<op2>.Bit[13:12] : swap (0-RGB [7-0], 1-RGB [0-7], 2-BGR [7-0], 3-BGR [0-7]) -4: HDMI -[H]<op1> (1-422,3-444,6-ARGB) -[H]<op2> := -<op2>.Bit[0] : (0-12bit,1-24bit) -<op2>.Bit[1] : (1:interlace) -<op2>.Bit[2] : (1:CEC) -<op2>.Bit[3] : (1:disable) -<op2>.Bit[4] : (1:sp mode) -6:LVDS -same as LCD -8: virtual frame buffer -[H]<op1> (0-disable,1-enable) - -[D] <resx> := horizontal resolution -[D] <resy> := vertical resolution -[D] <fps> := frame per second -*/ - -#define WMT_DISP_FB_MULTI BIT(8) -#define WMT_DISP_FB_COLFMT BIT(9) -#define WMT_DISP_FB_COLFMT_MASK 0xFF0000 - -#define WMT_DISP_FB_GET_BPP(a) (a & 0xFF) -#define WMT_DISP_FB_GET_RGB_MODE(a) ((a & 0x700) >> 8) -#define WMT_DISP_FB_MSB BIT(11) -#define WMT_DISP_FB_RGB_SWAP(a) ((a & 0x3000) >> 12) - -#define WMT_DISP_FB_DVI_24BIT BIT(0) -#define WMT_DISP_FB_INTERLACE BIT(1) -#define WMT_DISP_FB_DISABLE_EXTDEV BIT(2) -#define WMT_DISP_FB_DISBALE_DVI_INT BIT(3) -#define WMT_DISP_FB_DVI_I2C BIT(4) -#define WMT_DISP_FB_DVI_INT BIT(5) - -#define WMT_DISP_FB_HDMI_CEC BIT(2) -#define WMT_DISP_FB_HDMI_DISABLE BIT(3) -#define WMT_DISP_FB_HDMI_SP_MODE BIT(4) - -enum vout_alloc_mode_t { - VOUT_ALLOC_GE, - VOUT_ALLOC_FIX_MB, - VOUT_ALLOC_DYNAMIC_MB, - VOUT_ALLOC_GE_OVERSCAN, - VOUT_ALLOC_MODE_MAX -}; - -enum vout_hwc_mode_t { - VOUT_HWC_NORMAL, - VOUT_HWC_SCALE, - VOUT_HWC_OVERSCAN, - VOUT_HWC_VIRTUAL, - VOUT_HWC_MODE_MAX -}; - -struct vout_info_t { +} vout_tvformat_t; + +typedef struct { int num; - struct vout_t *vout[VPP_VOUT_NUM + 1]; - int multi; /* multi display in same time */ - - /* frame buffer alloc */ - enum vout_alloc_mode_t alloc_mode; - enum vout_hwc_mode_t hwc_mode; - void *fb_info_p; /* fb info pointer */ -#ifdef CONFIG_KERNEL - struct semaphore sem; -#endif + unsigned int vo_mask; /* vo bit mask for multi vout */ + int govr_mod; /* govr module type */ + govrh_mod_t *govr; /* govr pointer */ int resx; int resy; @@ -196,58 +99,52 @@ struct vout_info_t { unsigned int option; struct fb_videomode *fixed_vmode; - int fixed_width; - int fixed_height; vdo_framebuf_t fb; #ifdef CONFIG_UBOOT struct fb_videomode *p_vmode; #endif - struct vpp_dbg_timer_t pandisp_timer; - unsigned int mb; - unsigned int mb_size; -}; + vpp_dbg_timer_t pandisp_timer; +} vout_info_t; -struct vout_audio_t { +typedef struct { int fmt; /* sample bits */ int sample_rate; /* sample rate */ int channel; /* channel count */ -}; +} vout_audio_t; -struct vout_t; -struct vout_inf_t; +struct vout_s; +struct vout_inf_s; #define VOUT_DEV_CAP_FIX_RES 0x1 #define VOUT_DEV_CAP_EDID 0x2 #define VOUT_DEV_CAP_AUDIO 0x4 #define VOUT_DEV_CAP_FIX_PLUG 0x8 -struct vout_dev_t { - struct vout_dev_t *next; +typedef struct vout_dev_s { + struct vout_dev_s *next; char name[10]; - enum vout_inf_mode_t mode; - struct vout_t *vout; + vout_inf_mode_t mode; + struct vout_s *vout; unsigned int capability; - int (*init)(struct vout_t *vo); + int (*init)(struct vout_s *vo); void (*set_power_down)(int enable); int (*set_mode)(unsigned int *option); - int (*config)(struct vout_info_t *info); + int (*config)(vout_info_t *info); int (*check_plugin)(int hotplug); int (*get_edid)(char *buf); - int (*set_audio)(struct vout_audio_t *arg); + int (*set_audio)(vout_audio_t *arg); int (*interrupt)(void); void (*poll)(void); - int (*suspend)(void); - int (*resume)(void); -}; +} vout_dev_t; -enum vout_blank_t { +typedef enum { VOUT_BLANK_UNBLANK, /* screen: unblanked, hsync: on, vsync: on */ VOUT_BLANK_NORMAL, /* screen: blanked, hsync: on, vsync: on */ VOUT_BLANK_VSYNC_SUSPEND,/* screen: blanked, hsync: on, vsync: off */ VOUT_BLANK_HSYNC_SUSPEND,/* screen: blanked, hsync: off, vsync: on */ VOUT_BLANK_POWERDOWN /* screen: blanked, hsync: off, vsync: off */ -}; +} vout_blank_t; #define VOUT_CAP_INTERFACE 0x000000FF #define VOUT_CAP_BUS 0x00000F00 @@ -257,16 +154,16 @@ enum vout_blank_t { #define VOUT_CAP_AUDIO 0x00040000 #define VOUT_CAP_EDID 0x00080000 -struct vout_t { +typedef struct vout_s { int num; unsigned int fix_cap; - struct vout_info_t *info; - struct vout_inf_t *inf; /* interface ops */ - struct vout_dev_t *dev; /* device ops */ - struct govrh_mod_t *govr; + unsigned int var_cap; + struct vout_inf_s *inf; /* interface ops */ + vout_dev_t *dev; /* device ops */ + vout_dev_t *ext_dev; + govrh_mod_t *govr; int resx; int resy; - int fps; int pixclk; unsigned int status; #ifdef CONFIG_VOUT_EDID_ALLOC @@ -274,26 +171,25 @@ struct vout_t { #else char edid[128*EDID_BLOCK_MAX]; #endif - struct edid_info_t edid_info; + edid_info_t edid_info; unsigned int option[3]; - enum vout_blank_t pre_blank; - int disable; -}; + vout_blank_t pre_blank; +} vout_t; #define VOUT_INF_CAP_FIX_PLUG BIT(0) -struct vout_inf_t { - enum vout_inf_mode_t mode; +typedef struct vout_inf_s { + vout_inf_mode_t mode; unsigned int capability; /* function */ - int (*init)(struct vout_t *vo, int arg); - int (*uninit)(struct vout_t *vo, int arg); - int (*blank)(struct vout_t *vo, enum vout_blank_t arg); - int (*config)(struct vout_t *vo, int arg); - int (*chkplug)(struct vout_t *vo, int arg); - int (*get_edid)(struct vout_t *vo, int arg); -/* int (*ioctl)(struct vout_t *vo,int arg); */ -}; + int (*init)(vout_t *vo, int arg); + int (*uninit)(vout_t *vo, int arg); + int (*blank)(vout_t *vo, vout_blank_t arg); + int (*config)(vout_t *vo, int arg); + int (*chkplug)(vout_t *vo, int arg); + int (*get_edid)(vout_t *vo, int arg); +/* int (*ioctl)(vout_t *vo,int arg); */ +} vout_inf_t; /*-------------------- EXPORTED PRIVATE VARIABLES ---------------------------*/ #ifdef VOUT_C /* allocate memory for variables only in vout.c */ @@ -304,14 +200,14 @@ const char *vout_adpt_str[] = {"SD_DIGITAL", "SD_DIGITAL", "LCD", "DVI", "HDMI", "DVO2HDMI", "LVDS", "VGA", "BOOT"}; #else -#define EXTERN extern +#define EXTERN extern extern const char *vout_inf_str[]; extern const char *vout_adpt_str[]; #endif /* ifdef VOUT_C */ -EXTERN struct vout_info_t *vout_info[VPP_VOUT_INFO_NUM]; +EXTERN vout_info_t vout_info[VPP_VOUT_INFO_NUM]; /* EXTERN int vo_xxx; *//*Example*/ EXTERN int (*vout_board_info)(int arg); @@ -323,51 +219,49 @@ EXTERN int (*vout_board_info)(int arg); /*--------------------- EXPORTED PRIVATE FUNCTIONS -------------------------*/ /* extern void vo_xxx(void); *//*Example*/ -void vout_register(int no, struct vout_t *vo); -struct vout_t *vout_get_entry(int no); -struct vout_info_t *vout_get_info_entry(int no); -void vout_change_status(struct vout_t *vo, int mask, int sts); -int vout_query_inf_support(int no, enum vout_inf_mode_t mode); +void vout_register(int no, vout_t *vo); +vout_t *vout_get_entry(int no); +vout_info_t *vout_get_info_entry(int no); +void vout_change_status(vout_t *vo, int mask, int sts); +int vout_query_inf_support(int no, vout_inf_mode_t mode); -int vout_inf_register(enum vout_inf_mode_t mode, struct vout_inf_t *inf); -struct vout_inf_t *vout_inf_get_entry(enum vout_inf_mode_t mode); +int vout_inf_register(vout_inf_mode_t mode, vout_inf_t *inf); +vout_inf_t *vout_inf_get_entry(vout_inf_mode_t mode); -int vout_device_register(struct vout_dev_t *ops); -struct vout_dev_t *vout_get_device(struct vout_dev_t *ops); +int vout_device_register(vout_dev_t *ops); +vout_dev_t *vout_get_device(vout_dev_t *ops); -struct vout_t *vout_get_entry_adapter(enum vout_mode_t mode); -struct vout_inf_t *vout_get_inf_entry_adapter(enum vout_mode_t mode); -int vout_info_add_entry(int no, struct vout_t *vo); -struct vout_info_t *vout_info_get_entry(int no); +vout_t *vout_get_entry_adapter(vout_mode_t mode); +vout_inf_t *vout_get_inf_entry_adapter(vout_mode_t mode); +int vout_info_add_entry(vout_t *vo); +vout_info_t *vout_info_get_entry(int no); void vout_info_set_fixed_timing(int no, struct fb_videomode *vmode); -struct govrh_mod_t *vout_info_get_govr(int no); -enum vpp_vout_s vout_get_mode_adapter(struct vout_t *vout); - -int vout_config(struct vout_info_t *info, struct fb_videomode *vmode, - vdo_framebuf_t *fb); -int vout_set_mode(int no, enum vout_inf_mode_t mode); -int vout_set_blank(int no, enum vout_blank_t blank); -void vout_set_framebuffer(struct vout_info_t *info, vdo_framebuf_t *fb); +govrh_mod_t *vout_info_get_govr(int no); + +int vout_config(unsigned int mask, + vout_info_t *info, struct fb_videomode *vmode); +int vout_set_mode(int no, vout_inf_mode_t mode); +int vout_set_blank(unsigned int mask, vout_blank_t blank); +void vout_set_tg_enable(unsigned int mask, int enable); +void vout_set_framebuffer(unsigned int mask, vdo_framebuf_t *fb); int vout_chkplug(int no); void vout_set_int_type(int type); char *vout_get_edid(int no); int vout_get_edid_option(int no); int vout_check_plugin(int clr_sts); -void vout_print_entry(struct vout_t *vo); int vout_init(void); int vout_exit(void); int vo_i2c_proc(int id, unsigned int addr, unsigned int index, char *pdata, int len); -int vout_set_audio(struct vout_audio_t *arg); -int vout_find_edid_support_mode(struct edid_info_t *info, +int vout_set_audio(vout_audio_t *arg); +int vout_find_edid_support_mode(edid_info_t *info, unsigned int *resx, unsigned int *resy, unsigned int *fps, int r_16_9); int vout_check_ratio_16_9(unsigned int resx, unsigned int resy); -unsigned int vout_get_mask(struct vout_info_t *vo_info); +unsigned int vout_get_mask(vout_info_t *vo_info); void vout_set_int_enable(int enable); int vout_get_clr_int(void); void vo_hdmi_set_clock(int enable); -enum vout_tvformat_t vout_get_tvformat(void); #ifndef CONFIG_VPOST int vout_find_match_mode(int fbnum, struct fb_videomode *vmode, int match); @@ -379,9 +273,7 @@ int vout_find_match_mode(int fbnum, #define VOUT_MODE_OPTION_PROGRESS BIT4 struct fb_videomode *vout_get_video_mode(int vout_num, struct fb_videomode *vmode, int option); -int vout_get_width_height(int fbnum, int *width, int *height); void vo_hdmi_cp_set_enable_tmr(int sec); -struct vout_dev_t *lcd_get_dev(void); #ifdef __cplusplus } #endif diff --git a/drivers/video/wmt/vpp-osif.c b/drivers/video/wmt/vpp-osif.c index 52bcca10..a8505a59 100755..100644 --- a/drivers/video/wmt/vpp-osif.c +++ b/drivers/video/wmt/vpp-osif.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/osif.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -43,6 +43,7 @@ static DEFINE_SPINLOCK(vpp_irqlock); static unsigned long vpp_lock_flags; #endif +int vpp_dvi_i2c_id; /*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ /* void lvds_xxx(void); *//*Example*/ @@ -52,34 +53,34 @@ static unsigned long vpp_lock_flags; #include <asm/io.h> #include <linux/proc_fs.h> #else -inline unsigned int inl(unsigned int offset) +__inline__ U32 inl(U32 offset) { - return *(unsigned int *)(offset); + return REG32_VAL(offset); } -inline void outl(unsigned int val, unsigned int offset) +__inline__ void outl(U32 val, U32 offset) { - (*(unsigned int *)(offset)) = val; + REG32_VAL(offset) = val; } -inline unsigned short inw(unsigned int offset) +static __inline__ U16 inw(U32 offset) { - return *(unsigned short *)(offset); + return REG16_VAL(offset); } -inline void outw(unsigned short val, unsigned int offset) +static __inline__ void outw(U16 val, U32 offset) { - (*(unsigned short *)(offset)) = val; + REG16_VAL(offset) = val; } -inline unsigned char inb(unsigned int offset) +static __inline__ U8 inb(U32 offset) { - return *(unsigned char *)(offset); + return REG8_VAL(offset); } -inline void outb(unsigned char val, unsigned int offset) +static __inline__ void outb(U8 val, U32 offset) { - (*(unsigned char *)(offset)) = val; + REG8_VAL(offset) = val; } #ifndef CFG_LOADER int get_key(void) @@ -103,6 +104,7 @@ void mdelay(int ms) #endif #endif +extern unsigned int wmt_read_oscr(void); void vpp_udelay(unsigned int us) { #if 1 @@ -131,6 +133,39 @@ void vpp_udelay(unsigned int us) } /* Internal functions */ +U8 vppif_reg8_in(U32 offset) +{ + return inb(offset); +} + +U8 vppif_reg8_out(U32 offset, U8 val) +{ + outb(val, offset); + return val; +} + +U16 vppif_reg16_in(U32 offset) +{ + return inw(offset); +} + +U16 vppif_reg16_out(U32 offset, U16 val) +{ + outw(val, offset); + return val; +} + +U32 vppif_reg32_in(U32 offset) +{ + return inl(offset); +} + +U32 vppif_reg32_out(U32 offset, U32 val) +{ + outl(val, offset); + return val; +} + U32 vppif_reg32_write(U32 offset, U32 mask, U32 shift, U32 val) { U32 new_val; @@ -144,13 +179,11 @@ U32 vppif_reg32_write(U32 offset, U32 mask, U32 shift, U32 val) outl(new_val, offset); return new_val; } -EXPORT_SYMBOL(vppif_reg32_write); U32 vppif_reg32_read(U32 offset, U32 mask, U32 shift) { return (inl(offset) & mask) >> shift; } -EXPORT_SYMBOL(vppif_reg32_read); U32 vppif_reg32_mask(U32 offset, U32 mask, U32 shift) { @@ -183,21 +216,12 @@ void vpp_free_irq(unsigned int irq_no, void *arg) #ifndef __KERNEL__ int wmt_getsyspara(char *varname, char *varval, int *varlen) { -#ifdef CONFIG_VPOST - struct env_para_def param; -#endif int i = 0; char *p; -#ifdef CONFIG_VPOST - p = 0; - if (env_read_para(varname, ¶m) == 0) - p = param.value; -#else p = getenv(varname); -#endif if (!p) { - /* printf("## Warning: %s not defined\n", varname); */ + printf("## Warning: %s not defined\n", varname); return -1; } while (p[i] != '\0') { @@ -206,14 +230,12 @@ int wmt_getsyspara(char *varname, char *varval, int *varlen) } varval[i] = '\0'; *varlen = i; -/* printf("getsyspara: %s,len %d\n", p, *varlen); */ -#ifdef CONFIG_VPOST - free(param.value); -#endif + /* printf("getsyspara: %s,len %d\n", p, *varlen); */ return 0; } #endif +#ifndef CONFIG_VPOST int vpp_parse_param(char *buf, unsigned int *param, int cnt, unsigned int hex_mask) { @@ -229,13 +251,8 @@ int vpp_parse_param(char *buf, unsigned int *param, p = (char *)buf; for (i = 0; i < cnt; i++) { -#ifdef CONFIG_VPOST - param[i] = strtoul(p, &endp, - (hex_mask & (0x1 << i)) ? 16 : 0); -#else param[i] = simple_strtoul(p, &endp, (hex_mask & (0x1 << i)) ? 16 : 0); -#endif if (*endp == '\0') break; p = endp + 1; @@ -245,6 +262,7 @@ int vpp_parse_param(char *buf, unsigned int *param, } return i + 1; } +#endif unsigned int vpp_lock_cnt; void vpp_lock_l(void) @@ -355,7 +373,7 @@ int vpp_i2c_xfer(struct i2c_msg_s *msg, unsigned int num, int bus_id) return ret; } #elif defined(CONFIG_VPOST) - ret = i2c_transfer(msg, num); + ret = i2c_transfer(msg, 1); #else ret = wmt_i2c_transfer(msg, num, bus_id); #endif @@ -370,6 +388,7 @@ int vpp_i2c_init(int i2c_id, unsigned short addr) DBGMSG("id %d,addr 0x%x\n", i2c_id, addr); + vpp_dvi_i2c_id = i2c_id; if (i2c_id & VPP_DVI_I2C_SW_BIT) return 0; @@ -394,6 +413,7 @@ int vpp_i2c_init(int i2c_id, unsigned short addr) DBG_ERR("i2c_add_driver fail\n"); return ret; #else + vpp_dvi_i2c_id = i2c_id & 0xF; return 0; #endif } @@ -446,6 +466,8 @@ int vpp_i2c_enhanced_ddc_read(int id, unsigned int addr, vpp_i2c_lock = 1; + if (id & VPP_DVI_I2C_BIT) + id = vpp_dvi_i2c_id; id = id & VPP_DVI_I2C_ID_MASK; buf2[0] = 0x1; buf2[1] = 0x0; @@ -492,6 +514,8 @@ int vpp_i2c_read(int id, unsigned int addr, vpp_i2c_lock = 1; + if (id & VPP_DVI_I2C_BIT) + id = vpp_dvi_i2c_id; id = id & VPP_DVI_I2C_ID_MASK; switch (id) { case 0 ... 0xF: /* hw i2c */ @@ -559,6 +583,8 @@ int vpp_i2c_write(int id, unsigned int addr, unsigned int index, vpp_i2c_lock = 1; + if (id & VPP_DVI_I2C_BIT) + id = vpp_dvi_i2c_id; id = id & VPP_DVI_I2C_ID_MASK; switch (id) { case 0 ... 0xF: /* hw i2c */ @@ -624,7 +650,7 @@ int vpp_dbg_diag_index; int vpp_dbg_diag_delay; #endif -int vpp_check_dbg_level(enum vpp_dbg_level_t level) +int vpp_check_dbg_level(vpp_dbg_level_t level) { if (level == VPP_DBGLVL_ALL) return 1; @@ -731,7 +757,7 @@ void vpp_dbg_wake_up(void) wake_up(&vpp_dbg_wq); } -int vpp_dbg_get_period_usec(struct vpp_dbg_period_t *p, int cmd) +int vpp_dbg_get_period_usec(vpp_dbg_period_t *p, int cmd) { struct timeval tv; int tm_usec = 0; @@ -766,7 +792,7 @@ int vpp_dbg_get_period_usec(struct vpp_dbg_period_t *p, int cmd) return tm_usec; } -void vpp_dbg_timer(struct vpp_dbg_timer_t *p, char *str, int cmd) +void vpp_dbg_timer(vpp_dbg_timer_t *p, char *str, int cmd) { struct timeval tv; int tm_usec = 0; @@ -805,9 +831,9 @@ void vpp_dbg_timer(struct vpp_dbg_timer_t *p, char *str, int cmd) int us_1t; us_1t = p->sum / p->cnt; - MSG("%s(Cnt %d)Sum %d us,Avg %d,Min %d,Max %d,", - str, p->cnt, p->sum, us_1t, p->min, p->max); - MSG("fps %d.%02d\n", 1000000 / us_1t, + MSG("%s(Cnt %d)Sum %d us,Avg %d,Min %d,Max %d,fps %d.%02d\n", + str, p->cnt, p->sum, us_1t, + p->min, p->max, 1000000 / us_1t, (100000000 / us_1t) % 100); initial = 1; } @@ -863,50 +889,3 @@ void vpp_dbg_back_trace(void) } EXPORT_SYMBOL(vpp_dbg_back_trace); #endif - -void vpp_reg_dump(unsigned int addr, int size) -{ - int i; - - for (i = 0; i < size; i += 16) { - DPRINT("0x%8x : 0x%08x 0x%08x 0x%08x 0x%08x\n", - addr + i, inl(addr + i), - inl(addr + i + 4), - inl(addr + i + 8), - inl(addr + i + 12)); - } -} - -unsigned int *vpp_backup_reg(unsigned int addr, unsigned int size) -{ - unsigned int *ptr; - int i; - - size += 4; - ptr = kmalloc(size, GFP_KERNEL); - if (ptr == 0) { - DPRINT("[VPP] *E* malloc backup fail\n"); - return 0; - } - - for (i = 0; i < size; i += 4) - ptr[i / 4] = inl(addr + i); - return ptr; -} - -int vpp_restore_reg(unsigned int addr, unsigned int size, - unsigned int *reg_ptr) -{ - int i; - - if (reg_ptr == NULL) - return 0; - - size += 4; - for (i = 0; i < size; i += 4) - outl(reg_ptr[i / 4], addr + i); - kfree(reg_ptr); - reg_ptr = 0; - return 0; -} - diff --git a/drivers/video/wmt/vpp-osif.h b/drivers/video/wmt/vpp-osif.h index ddc561e7..988766fd 100755..100644 --- a/drivers/video/wmt/vpp-osif.h +++ b/drivers/video/wmt/vpp-osif.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/vpp-osif.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -69,8 +69,6 @@ #define DBGMSG(fmt, args...) #endif -#define HW_REG volatile - /* -------------------------------------------------- */ #ifdef CONFIG_KERNEL #include <linux/version.h> @@ -145,6 +143,9 @@ extern "C" { #define mdelay(x) wmt_delayus(1000 * x) #define udelay(x) wmt_delayus(x) +#define REG32_VAL(addr) (*(volatile unsigned int *)(addr)) +#define REG16_VAL(addr) (*(volatile unsigned short *)(addr)) +#define REG8_VAL(addr) (*(volatile unsigned char *)(addr)) #define mb_alloc(a) malloc(a) #define kmalloc(a, b) malloc(a) @@ -168,6 +169,7 @@ extern "C" { #define KERN_INFO #define printk printf +#define BIT(x) (1 << x) #endif /*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/ @@ -195,13 +197,6 @@ extern void wmt_i2c_xfer_continue_if(struct i2c_msg *msg, extern void wmt_i2c_xfer_if(struct i2c_msg *msg); extern int wmt_i2c_xfer_continue_if_4(struct i2c_msg *msg, unsigned int num, int bus_id); -#else -inline unsigned int inl(unsigned int offset); -inline void outl(unsigned int val, unsigned int offset); -inline unsigned short inw(unsigned int offset); -inline void outw(unsigned short val, unsigned int offset); -inline unsigned char inb(unsigned int offset); -inline void outb(unsigned char val, unsigned int offset); #endif #ifdef CONFIG_UBOOT @@ -222,7 +217,6 @@ extern int get_num(unsigned int min, unsigned int max, char *message, unsigned int retry); #endif -extern unsigned int wmt_read_oscr(void); int wmt_getsyspara(char *varname, char *varval, int *varlen); int vpp_request_irq(unsigned int irq_no, void *routine, unsigned int flags, char *name, void *arg); @@ -245,16 +239,6 @@ int vpp_i2c_init(int i2c_id, unsigned short addr); int vpp_i2c_release(void); void vpp_set_clock_enable(enum dev_id dev, int enable, int force); void vpp_udelay(unsigned int us); -unsigned int vppif_reg32_write(unsigned int offset, - unsigned int mask, unsigned int shift, unsigned int val); -unsigned int vppif_reg32_read(unsigned int offset, - unsigned int mask, unsigned int shift); -unsigned int vppif_reg32_mask(unsigned int offset, - unsigned int mask, unsigned int shift); -void vpp_reg_dump(unsigned int addr, int size); -unsigned int *vpp_backup_reg(unsigned int addr, unsigned int size); -int vpp_restore_reg(unsigned int addr, - unsigned int size, unsigned int *reg_ptr); #ifdef __cplusplus } diff --git a/drivers/video/wmt/vpp.c b/drivers/video/wmt/vpp.c index 544d9dbf..8b0865ac 100755..100644 --- a/drivers/video/wmt/vpp.c +++ b/drivers/video/wmt/vpp.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/vpp.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -28,16 +28,16 @@ #include "vpp.h" -struct vpp_mod_base_t *vpp_mod_base_list[VPP_MOD_MAX]; +vpp_mod_base_t *vpp_mod_base_list[VPP_MOD_MAX]; unsigned int vpp_get_chipid(void) { /* byte 3,2: chip id, byte 1:ver id, byte 0:sub id */ /* ex: 0x34290101 (0x3429 A0), 0x34290102 (0x3429 A1) */ - return inl(SYSTEM_CFG_CTRL_BASE_ADDR); + return REG32_VAL(SYSTEM_CFG_CTRL_BASE_ADDR); } -inline void vpp_cache_sync(void) +__inline__ void vpp_cache_sync(void) { /* TODO */ } @@ -67,7 +67,7 @@ void vpp_set_clock_enable(enum dev_id dev, int enable, int force) /*----------------------- vpp module --------------------------------------*/ void vpp_mod_unregister(vpp_mod_t mod) { - struct vpp_mod_base_t *mod_p; + vpp_mod_base_t *mod_p; if (mod >= VPP_MOD_MAX) return; @@ -81,10 +81,10 @@ void vpp_mod_unregister(vpp_mod_t mod) vpp_mod_base_list[mod] = 0; } -struct vpp_mod_base_t *vpp_mod_register(vpp_mod_t mod, +vpp_mod_base_t *vpp_mod_register(vpp_mod_t mod, int size, unsigned int flags) { - struct vpp_mod_base_t *mod_p; + vpp_mod_base_t *mod_p; if (mod >= VPP_MOD_MAX) return 0; @@ -101,10 +101,10 @@ struct vpp_mod_base_t *vpp_mod_register(vpp_mod_t mod, mod_p->mod = mod; if (flags & VPP_MOD_FLAG_FRAMEBUF) { - mod_p->fb_p = kmalloc(sizeof(struct vpp_fb_base_t), GFP_KERNEL); + mod_p->fb_p = kmalloc(sizeof(vpp_fb_base_t), GFP_KERNEL); if (!mod_p->fb_p) goto error; - memset(mod_p->fb_p, 0, sizeof(struct vpp_fb_base_t)); + memset(mod_p->fb_p, 0, sizeof(vpp_fb_base_t)); } DBG_DETAIL(" %d,0x%x,0x%x\n", mod, (int)mod_p, (int)mod_p->fb_p); return mod_p; @@ -114,16 +114,16 @@ error: return 0; } -struct vpp_mod_base_t *vpp_mod_get_base(vpp_mod_t mod) +vpp_mod_base_t *vpp_mod_get_base(vpp_mod_t mod) { if (mod >= VPP_MOD_MAX) return 0; return vpp_mod_base_list[mod]; } -struct vpp_fb_base_t *vpp_mod_get_fb_base(vpp_mod_t mod) +vpp_fb_base_t *vpp_mod_get_fb_base(vpp_mod_t mod) { - struct vpp_mod_base_t *mod_p; + vpp_mod_base_t *mod_p; mod_p = vpp_mod_get_base(mod); if (mod_p) return mod_p->fb_p; @@ -132,7 +132,7 @@ struct vpp_fb_base_t *vpp_mod_get_fb_base(vpp_mod_t mod) vdo_framebuf_t *vpp_mod_get_framebuf(vpp_mod_t mod) { - struct vpp_mod_base_t *mod_p; + vpp_mod_base_t *mod_p; mod_p = vpp_mod_get_base(mod); if (mod_p && mod_p->fb_p) @@ -142,7 +142,7 @@ vdo_framebuf_t *vpp_mod_get_framebuf(vpp_mod_t mod) void vpp_mod_set_clock(vpp_mod_t mod, vpp_flag_t enable, int force) { - struct vpp_mod_base_t *base; + vpp_mod_base_t *base; enum dev_id pll_dev; int cur_sts; int ret; @@ -209,20 +209,17 @@ unsigned int vpp_get_base_clock(vpp_mod_t mod) return clock; } +#if 1 void vpp_show_timing(char *str, struct fb_videomode *vmode, vpp_clock_t *clk) { DPRINT("----- %s timing -----\n", str); if (vmode) { - int pixclk; - - pixclk = (vmode->pixclock) ? PICOS2KHZ(vmode->pixclock) : 0; - pixclk *= 1000; - DPRINT("res(%d,%d),fps %d\n", vmode->xres, vmode->yres, vmode->refresh); DPRINT("pixclk %d(%d),hsync %d,vsync %d\n", vmode->pixclock, - pixclk, vmode->hsync_len, vmode->vsync_len); + (int)(PICOS2KHZ(vmode->pixclock) * 1000), + vmode->hsync_len, vmode->vsync_len); DPRINT("left %d,right %d,upper %d,lower %d\n", vmode->left_margin, vmode->right_margin, vmode->upper_margin, vmode->lower_margin); @@ -275,6 +272,7 @@ void vpp_show_videomode(char *str, struct fb_videomode *v) (v->vmode & FB_VMODE_DOUBLE) ? 1 : 0); DPRINT("-----------------------\n"); } +#endif vpp_csc_t vpp_check_csc_mode(vpp_csc_t mode, vdo_color_fmt src_fmt, vdo_color_fmt dst_fmt, unsigned int flags) @@ -322,6 +320,19 @@ int vpp_set_recursive_scale(vdo_framebuf_t *src_fb, #endif } +void vpp_reg_dump(unsigned int addr, int size) +{ + int i; + + for (i = 0; i < size; i += 16) { + DPRINT("0x%8x : 0x%08x 0x%08x 0x%08x 0x%08x\n", + addr + i, vppif_reg32_in(addr + i), + vppif_reg32_in(addr + i + 4), + vppif_reg32_in(addr + i + 8), + vppif_reg32_in(addr + i + 12)); + } +} /* End of vpp_reg_dump */ + unsigned int vpp_convert_colfmt(int yuv2rgb, unsigned int data) { unsigned int r, g, b; @@ -367,6 +378,39 @@ unsigned int vpp_convert_colfmt(int yuv2rgb, unsigned int data) return data; } +unsigned int *vpp_backup_reg(unsigned int addr, unsigned int size) +{ + unsigned int *ptr; + int i; + + size += 4; + ptr = kmalloc(size, GFP_KERNEL); + if (ptr == 0) { + DPRINT("[VPP] *E* malloc backup fail\n"); + return 0; + } + + for (i = 0; i < size; i += 4) + ptr[i / 4] = REG32_VAL(addr + i); + return ptr; +} /* End of vpp_backup_reg */ + +int vpp_restore_reg(unsigned int addr, unsigned int size, + unsigned int *reg_ptr) +{ + int i; + + if (reg_ptr == NULL) + return 0; + + size += 4; + for (i = 0; i < size; i += 4) + REG32_VAL(addr + i) = reg_ptr[i / 4]; + kfree(reg_ptr); + reg_ptr = 0; + return 0; +} /* End of vpp_restore_reg */ + void vpp_get_sys_parameter(void) { #ifndef CONFIG_VPOST @@ -381,15 +425,11 @@ void vpp_get_sys_parameter(void) g_vpp.hdmi_audio_interface = VPP_HDMI_AUDIO_SPDIF; g_vpp.hdmi_cp_enable = 1; -#ifdef CONFIG_KERNEL - if (govrh_get_MIF_enable(p_govrh)) - g_vpp.govrh_preinit = 1; - if (govrh_get_MIF_enable(p_govrh2)) - g_vpp.govrh_preinit = 1; - MSG("[VPP] govrh preinit %d\n", g_vpp.govrh_preinit); -#else - g_vpp.govrh_preinit = 0; - p_scl->scale_sync = 1; +#if 0 + if (wmt_getsyspara("wmt.display.direct_path", buf, &varlen) == 0) { + sscanf(buf, "%d", &g_vpp.direct_path); + DPRINT("[VPP] direct path %d\n", g_vpp.direct_path); + } #endif #ifndef CONFIG_VPOST @@ -400,6 +440,16 @@ void vpp_get_sys_parameter(void) g_vpp.hdmi_audio_interface = VPP_HDMI_AUDIO_SPDIF; } + if (wmt_getsyspara("wmt.display.hdmi.vmode", buf, &varlen) == 0) { + if (memcmp(buf, "720p", 4) == 0) + g_vpp.hdmi_video_mode = 720; + else if (memcmp(buf, "1080p", 5) == 0) + g_vpp.hdmi_video_mode = 1080; + else + g_vpp.hdmi_video_mode = 0; + DPRINT("[VPP] HDMI video mode %d\n", g_vpp.hdmi_video_mode); + } + g_vpp.mb_colfmt = VPP_UBOOT_COLFMT; /* [uboot parameter] fb param : no:xresx:yres:xoffset:yoffset */ if (wmt_getsyspara("wmt.gralloc.param", buf, &varlen) == 0) { @@ -414,6 +464,19 @@ void vpp_get_sys_parameter(void) p_govrh->fb_p->fb.col_fmt = g_vpp.mb_colfmt; p_govrh2->fb_p->fb.col_fmt = g_vpp.mb_colfmt; + /* [uboot parameter] dual display : 0-single display, 1-dual display */ + g_vpp.dual_display = 1; + if (wmt_getsyspara("wmt.display.dual", buf, &varlen) == 0) { + unsigned int parm[1]; + + MSG("display dual : %s\n", buf); + vpp_parse_param(buf, (unsigned int *)parm, 1, 0); + g_vpp.dual_display = parm[0]; + } + + if (g_vpp.dual_display == 0) + g_vpp.alloc_framebuf = 0; + if (wmt_getsyspara("wmt.display.hdmi", buf, &varlen) == 0) { unsigned int parm[1]; @@ -424,47 +487,6 @@ void vpp_get_sys_parameter(void) if (wmt_getsyspara("wmt.hdmi.disable", buf, &varlen) == 0) g_vpp.hdmi_disable = 1; - - /* [uboot parameter] reg operation : addr op val */ - if (wmt_getsyspara("wmt.display.regop", buf, &varlen) == 0) { - unsigned int addr; - unsigned int val; - char op; - char *p, *endp; - - p = buf; - while (1) { - addr = simple_strtoul(p, &endp, 16); - if (*endp == '\0') - break; - - op = *endp; - if (endp[1] == '~') { - val = simple_strtoul(endp + 2, &endp, 16); - val = ~val; - } else - val = simple_strtoul(endp + 1, &endp, 16); - - DBG_DETAIL(" reg op: 0x%X %c 0x%X\n", addr, op, val); - switch (op) { - case '|': - outl(inl(addr) | val, addr); - break; - case '=': - outl(val, addr); - break; - case '&': - outl(inl(addr) & val, addr); - break; - default: - DBG_ERR("Error, Unknown operator %c\n", op); - } - - if (*endp == '\0') - break; - p = endp + 1; - } - } #else if (env_read_para("wmt.display.hdmi", ¶m) == 0) { g_vpp.hdmi_sp_mode = strtoul(param.value, 0, 16); @@ -475,9 +497,12 @@ void vpp_get_sys_parameter(void) void vpp_init(void) { - struct vpp_mod_base_t *mod_p; + vpp_mod_base_t *mod_p; unsigned int mod_mask; int i; + int no; + + vpp_get_sys_parameter(); auto_pll_divisor(DEV_NA12, CLK_ENABLE, 0, 0); auto_pll_divisor(DEV_VPP, CLK_ENABLE, 0, 0); @@ -489,8 +514,20 @@ void vpp_init(void) auto_pll_divisor(DEV_LVDS, CLK_ENABLE, 0, 0); auto_pll_divisor(DEV_HDMILVDS, CLK_ENABLE, 0, 0); auto_pll_divisor(DEV_SCL444U, CLK_ENABLE, 0, 0); +#ifdef CONFIG_KERNEL + if (1) { + if (govrh_get_MIF_enable(p_govrh)) + g_vpp.govrh_preinit = 1; + if (govrh_get_MIF_enable(p_govrh2)) + g_vpp.govrh_preinit = 1; + MSG("[VPP] govrh preinit %d\n", g_vpp.govrh_preinit); + } +#endif - vpp_get_sys_parameter(); +#ifndef CONFIG_VPP_DYNAMIC_ALLOC + if (g_vpp.alloc_framebuf) + g_vpp.alloc_framebuf(VPP_HD_MAX_RESX, VPP_HD_MAX_RESY); +#endif /* init video out module first */ if (g_vpp.govrh_preinit == 0) { @@ -505,14 +542,11 @@ void vpp_init(void) } } -#ifdef CONFIG_UBOOT - mod_mask = BIT(VPP_MOD_SCL) | BIT(VPP_MOD_SCLW); -#else +#ifndef CONFIG_UBOOT /* init other module */ mod_mask = BIT(VPP_MOD_GOVW) | BIT(VPP_MOD_GOVM) | BIT(VPP_MOD_SCL) | BIT(VPP_MOD_SCLW) | BIT(VPP_MOD_VPU) | BIT(VPP_MOD_VPUW) | BIT(VPP_MOD_PIP) | BIT(VPP_MOD_VPPM); -#endif for (i = 0; i < VPP_MOD_MAX; i++) { if (!(mod_mask & (0x01 << i))) continue; @@ -520,6 +554,7 @@ void vpp_init(void) if (mod_p && mod_p->init) mod_p->init(mod_p); } +#endif #ifdef WMT_FTBLK_LVDS if (!g_vpp.govrh_preinit) @@ -529,11 +564,53 @@ void vpp_init(void) hdmi_init(); #endif + vpp_set_clock_enable(DEV_SCL444U, 0, 1); + #ifndef CONFIG_VPOST /* init vout device & get default resolution */ vout_init(); #endif - vpp_set_clock_enable(DEV_SCL444U, 0, 1); + +#ifdef CONFIG_KERNEL + no = (g_vpp.virtual_display_mode == 1) ? 1 : 0; + if (g_vpp.govrh_preinit) { + struct fb_videomode vmode; + vout_info_t *info; + govrh_mod_t *govr; + + info = vout_get_info_entry(no); + govr = vout_info_get_govr(no); + govrh_get_videomode(govr, &vmode); + govrh_get_framebuffer(govr, &info->fb); + g_vpp.govrh_init_yres = vmode.yres; + if ((info->resx != vmode.xres) || (info->resy != vmode.yres)) { + g_vpp.govrh_preinit = 0; + DPRINT("preinit not match (%dx%d) --> (%dx%d)\n", + vmode.xres, vmode.yres, info->resx, info->resy); + if (g_vpp.virtual_display || (g_vpp.dual_display == 0)) { + if(!hdmi_get_plugin()) { + vout_t *vo = vout_get_entry(VPP_VOUT_NUM_DVI); + if(vo->dev && !strcmp(vo->dev->name, "CS8556") && vo->dev->init) { + vo->dev->init(vo); + } + } + } + } + } + + if (!g_vpp.govrh_preinit) { + struct fb_videomode vmode; + vout_info_t *info; + + info = vout_get_info_entry(no); + memset(&vmode, 0, sizeof(struct fb_videomode)); + vmode.xres = info->resx; + vmode.yres = info->resy; + vmode.refresh = info->fps; + if (vout_find_match_mode(no, &vmode, 1) == 0) + vout_config(VPP_VOUT_ALL, info, &vmode); + } +#endif vpp_set_clock_enable(DEV_HDMII2C, 0, 0); vpp_set_clock_enable(DEV_HDMI, 0, 0); vpp_set_clock_enable(DEV_HDCE, 0, 0); @@ -614,20 +691,20 @@ void vpp_set_NA12_hiprio(int type) switch (type) { case 0: /* restore NA12 priority */ - outl(reg1, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8); - outl(reg2, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC); + vppif_reg32_out(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8, reg1); + vppif_reg32_out(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC, reg2); break; case 1: /* set NA12 to high priority */ - reg1 = inl(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8); - reg2 = inl(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC); - outl(0x600000, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8); - outl(0x0ff00000, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC); + reg1 = vppif_reg32_in(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8); + reg2 = vppif_reg32_in(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC); + vppif_reg32_out(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8, 0x600000); + vppif_reg32_out(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC, 0x0ff00000); break; case 2: - reg1 = inl(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8); - reg2 = inl(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC); - outl(0x20003f, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8); - outl(0x00ffff00, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC); + reg1 = vppif_reg32_in(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8); + reg2 = vppif_reg32_in(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC); + vppif_reg32_out(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8, 0x20003f); + vppif_reg32_out(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC, 0x00ffff00); break; default: break; @@ -638,16 +715,170 @@ void vpp_set_NA12_hiprio(int type) #ifdef __KERNEL__ int vpp_set_audio(int format, int sample_rate, int channel) { - struct vout_audio_t info; + vout_audio_t info; - MSG("set audio(fmt %d,rate %d,ch %d)\n", + DBG_MSG("set audio(fmt %d,rate %d,ch %d)\n", format, sample_rate, channel); info.fmt = format; info.sample_rate = sample_rate; info.channel = channel; return vout_set_audio(&info); } + +static DEFINE_SEMAPHORE(vpp_sem); +static DEFINE_SEMAPHORE(vpp_sem2); +void vpp_set_mutex(int idx, int lock) +{ + struct semaphore *sem; + + sem = ((g_vpp.dual_display == 0) || (idx == 0)) ? &vpp_sem : &vpp_sem2; + if (lock) + down(sem); + else + up(sem); +} + +void vpp_free_framebuffer(void) +{ + if (g_vpp.mb[0] == 0) + return; + MSG("mb free 0x%x\n", g_vpp.mb[0]); + mb_free(g_vpp.mb[0]); + vpp_lock(); + g_vpp.mb[0] = 0; + vpp_unlock(); +} + +int vpp_alloc_framebuffer(unsigned int resx, unsigned int resy) +{ + unsigned int y_size; + unsigned int fb_size; + unsigned int colfmt; + int y_bpp, c_bpp; + int i; + +#ifdef CONFIG_VPP_DYNAMIC_ALLOC + if (g_vpp.mb[0]) { + vpp_free_framebuffer(); + } +#endif + + if ((resx == 0) && (resy == 0)) { + return -1; + } + + /* alloc govw & govrh frame buffer */ + if (g_vpp.mb[0] == 0) { + unsigned int mb_resx, mb_resy; + int fb_num; + unsigned int phy_base; + +#ifdef CONFIG_VPP_DYNAMIC_ALLOC + mb_resx = resx; + mb_resy = resy; + colfmt = g_vpp.mb_colfmt; + vpp_get_colfmt_bpp(colfmt, &y_bpp, &c_bpp); + fb_num = VPP_MB_ALLOC_NUM; +#else + char buf[100]; + int varlen = 100; + + if (wmt_getsyspara("wmt.display.mb", (unsigned char *)buf, + &varlen) == 0) { + unsigned int parm[10]; + + vpp_parse_param(buf, (unsigned int *)parm, 4, 0); + MSG("boot parm mb (%d,%d),bpp %d,fb %d\n", + parm[0], parm[1], parm[2], parm[3]); + mb_resx = parm[0]; + mb_resy = parm[1]; + y_bpp = parm[2] * 8; + c_bpp = 0; + fb_num = parm[3]; + } else { + mb_resx = VPP_HD_MAX_RESX; + mb_resy = VPP_HD_MAX_RESY; + colfmt = g_vpp.mb_colfmt; + vpp_get_colfmt_bpp(colfmt, &y_bpp, &c_bpp); + fb_num = VPP_MB_ALLOC_NUM; + } #endif + mb_resx = vpp_calc_align(mb_resx, + VPP_FB_ADDR_ALIGN / (y_bpp / 8)); + y_size = mb_resx * mb_resy * y_bpp / 8; + fb_size = mb_resx * mb_resy * (y_bpp + c_bpp) / 8; + g_vpp.mb_fb_size = fb_size; + g_vpp.mb_y_size = y_size; + phy_base = mb_alloc(fb_size * fb_num); + if (phy_base) { + MSG("mb alloc 0x%x,%d\n", phy_base, fb_size * fb_num); + for (i = 0; i < fb_num; i++) { + g_vpp.mb[i] = (unsigned int)(phy_base + + (fb_size * i)); + MSG("mb 0x%x,fb %d,y %d\n", g_vpp.mb[i], + fb_size, y_size); + } + } else { + DBG_ERR("alloc fail\n"); + return -1; + } + if (!g_vpp.govrh_preinit) { /* keep uboot logo */ + memset(mb_phys_to_virt(phy_base), 0, fb_size); + MSG("mb clean 0x%x %d\n", phy_base, fb_size); + } + } + + vpp_lock(); +#ifdef CONFIG_VPP_STREAM_ROTATE + { + unsigned int resx_mb; + + g_vpp.stream_mb_cnt = VPP_MB_ALLOC_NUM; + colfmt = VDO_COL_FMT_YUV422H; + vpp_get_colfmt_bpp(colfmt, &y_bpp, &c_bpp); + resx_mb = vpp_calc_fb_width(colfmt, resx); + y_size = resx_mb * resy * y_bpp / 8; + fb_size = vpp_calc_align(resx_mb, 64) * resy * + (y_bpp + c_bpp) / 8; + for (i = 0; i < g_vpp.stream_mb_cnt; i++) { + g_vpp.stream_mb[i] = g_vpp.mb[0] + fb_size * i; + } + } +#else + /* assign mb to stream mb */ + { + int index = 0, offset = 0; + unsigned int size = g_vpp.mb_fb_size; + unsigned int resx_fb; + + colfmt = VPP_UBOOT_COLFMT; + vpp_get_colfmt_bpp(colfmt, &y_bpp, &c_bpp); + resx_fb = vpp_calc_fb_width(colfmt, resx); + y_size = resx_fb * resy * y_bpp / 8; + fb_size = vpp_calc_align(resx_fb, 64) * resy * (y_bpp + c_bpp) / 8; + g_vpp.stream_mb_y_size = y_size; + g_vpp.stream_mb_cnt = VPP_STREAM_MB_ALLOC_NUM; + for (i = 0; i < VPP_STREAM_MB_ALLOC_NUM; i++) { + if (size < fb_size) { + index++; + if (index >= VPP_MB_ALLOC_NUM) { + index = 0; + g_vpp.stream_mb_cnt = i; + break; + } + offset = 0; + size = g_vpp.mb_fb_size; + } + g_vpp.stream_mb[i] = g_vpp.mb[index] + offset; + size -= fb_size; + offset += fb_size; + DBG_DETAIL("stream mb %d 0x%x\n", i, g_vpp.stream_mb[i]); + } + } +#endif + vpp_unlock(); + return 0; +} /* End of vpp_alloc_framebuffer */ /*----------------------- vpp mb for stream ---------------------------------*/ #ifdef CONFIG_VPP_STREAM_CAPTURE @@ -677,12 +908,11 @@ int vpp_mb_get(unsigned int phy) #ifdef CONFIG_VPP_STREAM_BLOCK vpp_unlock(); - if (g_vpp.stream_mb_sync_flag) - vpp_dbg_show(VPP_DBGLVL_STREAM, 0, "mb_get wait"); - - i = wait_event_interruptible_timeout(vpp_mb_event, - (g_vpp.stream_mb_sync_flag != 1), HZ / 20); + i = wait_event_interruptible(vpp_mb_event, + (g_vpp.stream_mb_sync_flag != 1)); vpp_lock(); + if (i) + return -1; #else /* non-block */ if (g_vpp.stream_mb_sync_flag) { /* not new mb updated */ vpp_dbg_show(VPP_DBGLVL_STREAM, 0, @@ -766,10 +996,49 @@ int vpp_mb_irqproc_sync(int arg) return 0; } +void vpp_mb_scale_bitblit(vdo_framebuf_t *fb) +{ + int index = g_vpp.stream_mb_index; + vdo_framebuf_t src, dst; + + if (p_scl->scale_complete == 0) + return; + +#ifdef CONFIG_VPP_STREAM_ROTATE + index = g_vpp.stream_mb_index + 1; + index = (index >= g_vpp.stream_mb_cnt) ? 0 : index; +#else + do { + index++; + if (index >= g_vpp.stream_mb_cnt) + index = 0; + + if (g_vpp.stream_mb_lock & (0x1 << index)) + continue; + break; + } while (1); +#endif + + g_vpp.stream_mb_index = index; + p_scl->scale_sync = 1; + src = *fb; +#ifdef CONFIG_VPP_STREAM_FIX_RESOLUTION + dst = g_vpp.stream_fb; +#else + dst = *fb; + dst.col_fmt = VDO_COL_FMT_YUV422H; + dst.fb_w = vpp_calc_align(dst.fb_w, 64); +#endif + dst.y_addr = g_vpp.stream_mb[index]; + dst.c_addr = dst.y_addr + (dst.fb_w * dst.img_h); + vpp_set_recursive_scale(&src, &dst); +} +#endif + /*----------------------- irq proc --------------------------------------*/ -struct vpp_irqproc_t *vpp_irqproc_array[32]; +vpp_irqproc_t *vpp_irqproc_array[32]; struct list_head vpp_irqproc_free_list; -struct vpp_proc_t vpp_proc_array[VPP_PROC_NUM]; +vpp_proc_t vpp_proc_array[VPP_PROC_NUM]; static void vpp_irqproc_do_tasklet(unsigned long data); void vpp_irqproc_init(void) @@ -782,7 +1051,7 @@ void vpp_irqproc_init(void) list_add_tail(&vpp_proc_array[i].list, &vpp_irqproc_free_list); } -struct vpp_irqproc_t *vpp_irqproc_get_entry(enum vpp_int_t vpp_int) +vpp_irqproc_t *vpp_irqproc_get_entry(vpp_int_t vpp_int) { int no; @@ -795,9 +1064,9 @@ struct vpp_irqproc_t *vpp_irqproc_get_entry(enum vpp_int_t vpp_int) } if (vpp_irqproc_array[no] == 0) { /* will create in first use */ - struct vpp_irqproc_t *irqproc; + vpp_irqproc_t *irqproc; - irqproc = kmalloc(sizeof(struct vpp_irqproc_t), GFP_KERNEL); + irqproc = kmalloc(sizeof(vpp_irqproc_t), GFP_KERNEL); vpp_irqproc_array[no] = irqproc; INIT_LIST_HEAD(&irqproc->list); tasklet_init(&irqproc->tasklet, @@ -807,8 +1076,8 @@ struct vpp_irqproc_t *vpp_irqproc_get_entry(enum vpp_int_t vpp_int) return vpp_irqproc_array[no]; } /* End of vpp_irqproc_get_entry */ -void vpp_irqproc_set_ref(struct vpp_irqproc_t *irqproc, - enum vpp_int_t type, int enable) +void vpp_irqproc_set_ref(vpp_irqproc_t *irqproc, + vpp_int_t type, int enable) { if (enable) { irqproc->ref++; @@ -826,20 +1095,20 @@ static void vpp_irqproc_do_tasklet unsigned long data /*!<; // tasklet input data */ ) { - struct vpp_irqproc_t *irqproc; + vpp_irqproc_t *irqproc; vpp_lock(); irqproc = vpp_irqproc_get_entry(data); if (irqproc) { struct list_head *cur; struct list_head *next; - struct vpp_proc_t *entry; + vpp_proc_t *entry; next = (&irqproc->list)->next; while (next != &irqproc->list) { cur = next; next = cur->next; - entry = list_entry(cur, struct vpp_proc_t, list); + entry = list_entry(cur, vpp_proc_t, list); if (entry->func) { if (entry->func(entry->arg)) continue; @@ -864,7 +1133,7 @@ static void vpp_irqproc_do_tasklet } /* End of vpp_irqproc_do_tasklet */ int vpp_irqproc_work( - enum vpp_int_t type, /* interrupt type */ + vpp_int_t type, /* interrupt type */ int (*func)(void *argc), /* proc function pointer */ void *arg, /* proc argument */ int wait_ms, /* wait complete timeout (ms) */ @@ -872,14 +1141,12 @@ int vpp_irqproc_work( ) { int ret; - struct vpp_proc_t *entry; + vpp_proc_t *entry; struct list_head *ptr; - struct vpp_irqproc_t *irqproc; + vpp_irqproc_t *irqproc; + + /* DPRINT("[VPP] vpp_irqproc_work(type 0x%x,wait %d)\n",type,wait); */ -#if 0 - DPRINT("[VPP] vpp_irqproc_work(type 0x%x,wait %d,cnt %d)\n", - type, wait_ms, work_cnt); -#endif if ((vpp_irqproc_free_list.next == 0) || list_empty(&vpp_irqproc_free_list)) { if (func) @@ -891,7 +1158,7 @@ int vpp_irqproc_work( vpp_lock(); ptr = vpp_irqproc_free_list.next; - entry = list_entry(ptr, struct vpp_proc_t, list); + entry = list_entry(ptr, vpp_proc_t, list); list_del_init(ptr); entry->func = func; entry->arg = arg; @@ -940,24 +1207,24 @@ int vpp_irqproc_work( } /* End of vpp_irqproc_work */ void vpp_irqproc_del_work( - enum vpp_int_t type, /* interrupt type */ + vpp_int_t type, /* interrupt type */ int (*func)(void *argc) /* proc function pointer */ ) { - struct vpp_irqproc_t *irqproc; + vpp_irqproc_t *irqproc; vpp_lock(); irqproc = vpp_irqproc_get_entry(type); if (irqproc) { struct list_head *cur; struct list_head *next; - struct vpp_proc_t *entry; + vpp_proc_t *entry; next = (&irqproc->list)->next; while (next != &irqproc->list) { cur = next; next = cur->next; - entry = list_entry(cur, struct vpp_proc_t, list); + entry = list_entry(cur, vpp_proc_t, list); if (entry->func == func) { vpp_irqproc_set_ref(irqproc, type, 0); list_del_init(cur); @@ -986,9 +1253,11 @@ static struct switch_dev vpp_sdev_hdcp = { .name = "hdcp", }; +#if 0 static struct switch_dev vpp_sdev_audio = { .name = "hdmi_audio", }; +#endif struct vpp_netlink_proc_t vpp_netlink_proc[VPP_NETLINK_PROC_MAX]; static struct sock *vpp_nlfd; @@ -1056,109 +1325,107 @@ static ssize_t attr_show_parsed_edid(struct device *dev, if(strlen(edid_parsed.tv_name.monitor_name) != 0) DPRINT("Monitor Name: %s\n", edid_parsed.tv_name.monitor_name); - for (i = 0; i < AUD_SAD_NUM; i++) { - if (edid_parsed.sad[i].flag == 0) { - if (i == 0) - DPRINT("No SAD Data\n"); + for(i = 0; i < AUD_SAD_NUM; i++) { + if(edid_parsed.sad[i].flag == 0) { + if(i == 0) + printk("No SAD Data\n"); break; } DPRINT("SAD %d: 0x%02X 0x%02X 0x%02X\n", i, - edid_parsed.sad[i].sad_byte[0], - edid_parsed.sad[i].sad_byte[1], + edid_parsed.sad[i].sad_byte[0], edid_parsed.sad[i].sad_byte[1], edid_parsed.sad[i].sad_byte[2]); } DPRINT("--------------------------\n"); #endif /* print Vendor Name */ - if (strlen(edid_parsed.tv_name.vendor_name) != 0) { + if(strlen(edid_parsed.tv_name.vendor_name) != 0) { len += sprintf(buf + len, "%-16s", "Vendor Name"); len += sprintf(buf + len, ": %s\n", edid_parsed.tv_name.vendor_name); } /* print Monitor Name */ - if (strlen(edid_parsed.tv_name.monitor_name) != 0) { + if(strlen(edid_parsed.tv_name.monitor_name) != 0) { len += sprintf(buf + len, "%-16s", "Monitor Name"); len += sprintf(buf + len, ": %s\n", edid_parsed.tv_name.monitor_name); } - for (i = 0; i < AUD_SAD_NUM; i++) { - if (edid_parsed.sad[i].flag == 0) + for(i = 0; i < AUD_SAD_NUM; i++) { + if(edid_parsed.sad[i].flag == 0) break; /* SAD Byte 1 (format and number of channels): - bit 7: Reserved (0) - bit 6..3: Audio format code - 1 = Linear Pulse Code Modulation (LPCM) - 2 = AC-3 - 3 = MPEG1 (Layers 1 and 2) - 4 = MP3 - 5 = MPEG2 - 6 = AAC - 7 = DTS - 8 = ATRAC - 0, 15: Reserved - 9 = One-bit audio aka SACD - 10 = DD+ - 11 = DTS-HD - 12 = MLP/Dolby TrueHD - 13 = DST Audio - 14 = Microsoft WMA Pro - bit 2..0: number of channels minus 1 - (i.e. 000 = 1 channel; 001 = 2 channels; 111 = - 8 channels) + bit 7: Reserved (0) + bit 6..3: Audio format code + 1 = Linear Pulse Code Modulation (LPCM) + 2 = AC-3 + 3 = MPEG1 (Layers 1 and 2) + 4 = MP3 + 5 = MPEG2 + 6 = AAC + 7 = DTS + 8 = ATRAC + 0, 15: Reserved + 9 = One-bit audio aka SACD + 10 = DD+ + 11 = DTS-HD + 12 = MLP/Dolby TrueHD + 13 = DST Audio + 14 = Microsoft WMA Pro + bit 2..0: number of channels minus 1 (i.e. 000 = 1 channel; 001 = 2 channels; 111 = + 8 channels) */ audio_format = (edid_parsed.sad[i].sad_byte[0] & 0x78) >> 3; - if (audio_format == 0 || audio_format == 15) + if(audio_format == 0 || audio_format == 15) continue; /* print header */ len += sprintf(buf + len, "%-16s", "Audio Format"); len += sprintf(buf + len, ": "); - switch (audio_format) { - case 1: - len += sprintf(buf + len, "pcm"); + switch(audio_format) { + case 1: + len += sprintf(buf + len, "pcm"); break; - case 2: - len += sprintf(buf + len, "ac3"); + case 2: + len += sprintf(buf + len, "ac3"); break; - case 3: - len += sprintf(buf + len, "mpeg1"); + case 3: + len += sprintf(buf + len, "mpeg1"); break; - case 4: - len += sprintf(buf + len, "mp3"); + case 4: + len += sprintf(buf + len, "mp3"); break; - case 5: - len += sprintf(buf + len, "mpeg2"); + case 5: + len += sprintf(buf + len, "mpeg2"); break; - case 6: - len += sprintf(buf + len, "aac"); + case 6: + len += sprintf(buf + len, "aac"); break; - case 7: - len += sprintf(buf + len, "dts"); + case 7: + len += sprintf(buf + len, "dts"); break; - case 8: - len += sprintf(buf + len, "atrac"); + case 8: + len += sprintf(buf + len, "atrac"); break; - case 9: - len += sprintf(buf + len, "one_bit_audio"); + case 9: + len += sprintf(buf + len, "one_bit_audio"); break; - case 10: - len += sprintf(buf + len, "eac3"); + case 10: + len += sprintf(buf + len, "eac3"); break; - case 11: - len += sprintf(buf + len, "dts-hd"); + case 11: + len += sprintf(buf + len, "dts-hd"); break; - case 12: - len += sprintf(buf + len, "mlp"); + case 12: + len += sprintf(buf + len, "mlp"); break; - case 13: - len += sprintf(buf + len, "dst"); + case 13: + len += sprintf(buf + len, "dst"); break; - case 14: - len += sprintf(buf + len, "wmapro"); + case 14: + len += sprintf(buf + len, "wmapro"); break; - default: + default: break; } @@ -1166,8 +1433,7 @@ static ssize_t attr_show_parsed_edid(struct device *dev, len += sprintf(buf + len, ","); /* number of channels */ - len += sprintf(buf + len, "%d", - (edid_parsed.sad[i].sad_byte[0] & 0x7) + 1); + len += sprintf(buf + len, "%d", (edid_parsed.sad[i].sad_byte[0] & 0x7) + 1); /* separator */ len += sprintf(buf + len, ","); @@ -1185,85 +1451,78 @@ static ssize_t attr_show_parsed_edid(struct device *dev, */ sample_freq = edid_parsed.sad[i].sad_byte[1]; sample_freq_num = 0; - for (j = 0; j < 7; j++) { - if (sample_freq & (1 << j)) { - if (sample_freq_num != 0) - len += sprintf(buf + len, - "|"); /* separator */ - switch (j) { - case 0: - len += sprintf(buf + len, "32KHz"); + for(j = 0; j < 7; j++) { + if(sample_freq & (1 << j)) { + if(sample_freq_num != 0) + len += sprintf(buf + len, "|"); /* separator */ + switch(j) { + case 0: + len += sprintf(buf + len, "32KHz"); break; - case 1: - len += sprintf(buf + len, "44KHz"); + case 1: + len += sprintf(buf + len, "44KHz"); break; - case 2: - len += sprintf(buf + len, "48KHz"); + case 2: + len += sprintf(buf + len, "48KHz"); break; - case 3: - len += sprintf(buf + len, "88KHz"); + case 3: + len += sprintf(buf + len, "88KHz"); break; - case 4: - len += sprintf(buf + len, "96KHz"); + case 4: + len += sprintf(buf + len, "96KHz"); break; - case 5: - len += sprintf(buf + len, "176KHz"); + case 5: + len += sprintf(buf + len, "176KHz"); break; - case 6: - len += sprintf(buf + len, "192KHz"); + case 6: + len += sprintf(buf + len, "192KHz"); break; - default: + default: break; } sample_freq_num++; } } - if (sample_freq_num == 0) - len += sprintf(buf + len, "0"); + if(sample_freq_num == 0) + len += sprintf(buf +len, "0"); /* separator */ len += sprintf(buf + len, ","); /* SAD Byte 3 (bitrate): - For LPCM, bits 7:3 are reserved and the remaining bits - define bit depth - bit 2: 24 bit - bit 1: 20 bit - bit 0: 16 bit - For all other sound formats, bits 7..0 designate the maximum - supported bitrate divided by 8 kbit/s. + For LPCM, bits 7:3 are reserved and the remaining bits define bit depth + bit 2: 24 bit + bit 1: 20 bit + bit 0: 16 bit + For all other sound formats, bits 7..0 designate the maximum supported bitrate divided by + 8 kbit/s. */ bitrate = edid_parsed.sad[i].sad_byte[2]; bitrate_num = 0; - if (audio_format == 1) { /* for LPCM */ - for (j = 0; j < 3; j++) { - if (bitrate & (1 << j)) { - if (bitrate_num != 0) - len += sprintf(buf + len, - "|"); /* separator */ - switch (j) { - case 0: - len += sprintf(buf + len, - "16bit"); + if(audio_format == 1) { /* for LPCM */ + for(j = 0; j < 3; j++) { + if(bitrate & (1 << j)) { + if(bitrate_num != 0) + len += sprintf(buf + len, "|"); /* separator */ + switch(j) { + case 0: + len += sprintf(buf + len, "16bit"); break; - case 1: - len += sprintf(buf + len, - "20bit"); + case 1: + len += sprintf(buf + len, "20bit"); break; - case 2: - len += sprintf(buf + len, - "24bit"); + case 2: + len += sprintf(buf + len, "24bit"); break; - default: + default: break; } bitrate_num++; } } - } else if (audio_format >= 2 && - audio_format <= 8) /* From AC3 to ATRAC */ + } else if(audio_format >= 2 && audio_format <= 8) /* From AC3 to ATRAC */ len += sprintf(buf + len, "%dkbps", bitrate * 8); else /* From One-bit-audio to WMA Pro*/ len += sprintf(buf + len, "%d", bitrate); @@ -1271,7 +1530,7 @@ static ssize_t attr_show_parsed_edid(struct device *dev, len += sprintf(buf + len, "\n"); } - if (len == 0) + if(len == 0) len += sprintf(buf + len, "\n"); return len; @@ -1286,7 +1545,9 @@ void vpp_switch_state_init(void) switch_set_state(&vpp_sdev, hdmi_get_plugin() ? 1 : 0); switch_dev_register(&vpp_sdev_hdcp); switch_set_state(&vpp_sdev_hdcp, 0); +#if 0 switch_dev_register(&vpp_sdev_audio); +#endif device_create_file(vpp_sdev.dev, &dev_attr_edid_parsed); } @@ -1376,10 +1637,12 @@ void vpp_netlink_notify_plug(int vo_num, int plugin) if (plugin == 0) { int mask = 0; - if (vo_num == VPP_VOUT_ALL) + if (g_vpp.virtual_display) + mask = ~1; + else if (vo_num == VPP_VOUT_ALL) mask = ~0; else { - struct vout_info_t *vo_info; + vout_info_t *vo_info; vo_info = vout_get_info_entry(vo_num); if (vo_info) mask = 0x1 << (vo_info->num); @@ -1391,8 +1654,8 @@ void vpp_netlink_notify_plug(int vo_num, int plugin) return; /* if hdmi unplug, clear edid_parsed */ - if (hdmi_get_plugin() == 0) - memset(&edid_parsed, 0, sizeof(struct edid_parsed_t)); + if(hdmi_get_plugin() == 0) + memset(&edid_parsed, 0, sizeof(edid_parsed_t)); vpp_netlink_notify(USER_PID, DEVICE_PLUG_IN, plugin); vpp_netlink_notify(WP_PID, DEVICE_PLUG_IN, plugin); @@ -1407,7 +1670,5 @@ void vpp_netlink_notify_cp(int enable) { switch_set_state(&vpp_sdev_hdcp, enable); } -EXPORT_SYMBOL(vpp_netlink_notify_cp); - #endif /* CONFIG_VPP_NOTIFY */ #endif /* __KERNEL__ */ diff --git a/drivers/video/wmt/vpp.h b/drivers/video/wmt/vpp.h index b35f8db1..6da2a8b2 100755..100644 --- a/drivers/video/wmt/vpp.h +++ b/drivers/video/wmt/vpp.h @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/vpp.h * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -24,32 +24,29 @@ #include "vpp-osif.h" #include "./hw/wmt-vpp-hw.h" #include "com-vpp.h" -#ifdef CONFIG_KERNEL -#include "com-cec.h" -#endif #include "vout.h" #ifndef VPP_H #define VPP_H -#define CONFIG_VPP_SHENZHEN /* for ShenZhen code */ +/* #define CONFIG_VPP_SHENZHEN */ /* for ShenZhen code */ /* VPP feature config */ /* #define CONFIG_VPP_DEMO */ /* HDMI EDID, CP disable */ -#ifdef CONFIG_KERNEL #define CONFIG_VPP_STREAM_CAPTURE /* stream capture current video display */ #define CONFIG_VPP_STREAM_BLOCK -/* #define CONFIG_VPP_DISABLE_PM */ /* disable power management */ -#define CONFIG_VPP_VIRTUAL_DISPLAY /* virtual fb dev */ +#define CONFIG_VPP_STREAM_FIX_RESOLUTION +#define CONFIG_VPP_STREAM_ROTATE +/* #define CONFIG_VPP_DISABLE_PM */ /* disable power management */ +#define CONFIG_VPP_VIRTUAL_DISPLAY /* virtual fb dev */ #define CONFIG_VPP_NOTIFY -#endif -/* #define CONFIG_VPP_DYNAMIC_ALLOC */ /* frame buffer dynamic allocate */ +#define CONFIG_VPP_DYNAMIC_ALLOC /* frame buffer dynamic allocate */ /* VPP constant define */ #define VPP_MB_ALLOC_NUM 3 -#define VPP_STREAM_MB_ALLOC_NUM (VPP_MB_ALLOC_NUM * 2) +#define VPP_STREAM_MB_ALLOC_NUM (VPP_MB_ALLOC_NUM*2) -enum vpp_int_t { +typedef enum { VPP_INT_NULL = 0, VPP_INT_ALL = 0xffffffff, @@ -81,9 +78,9 @@ enum vpp_int_t { VPP_INT_MAX = BIT31, -}; +} vpp_int_t; -enum vpp_int_err_t { +typedef enum { /* SCL */ VPP_INT_ERR_SCL_TG = BIT0, VPP_INT_ERR_SCLR1_MIF = BIT1, @@ -98,7 +95,7 @@ enum vpp_int_err_t { /* GOVRH */ VPP_INT_ERR_GOVRH_MIF = BIT20, -}; +} vpp_int_err_t; /* VPP FB capability flag */ #define VPP_FB_FLAG_COLFMT 0xFFFF @@ -107,7 +104,7 @@ enum vpp_int_err_t { #define VPP_FB_FLAG_MEDIA BIT(18) #define VPP_FB_FLAG_FIELD BIT(19) -struct vpp_fb_base_t { +typedef struct { vdo_framebuf_t fb; vpp_csc_t csc_mode; int framerate; @@ -120,16 +117,16 @@ struct vpp_fb_base_t { void (*set_addr)(unsigned int yaddr, unsigned int caddr); void (*get_addr)(unsigned int *yaddr, unsigned int *caddr); void (*set_csc)(vpp_csc_t mode); - vdo_color_fmt(*get_color_fmt)(void); + vdo_color_fmt (*get_color_fmt)(void); void (*set_color_fmt)(vdo_color_fmt colfmt); void (*fn_view)(int read, vdo_view_t *view); -}; +} vpp_fb_base_t; #define VPP_MOD_BASE \ vpp_mod_t mod; /* module id*/\ void *mmio; /* regs base address */\ unsigned int int_catch; /* interrupt catch */\ - struct vpp_fb_base_t *fb_p; /* framebuf base pointer */\ + vpp_fb_base_t *fb_p; /* framebuf base pointer */\ unsigned int pm; /* power dev id,bit31-0:power off */\ unsigned int *reg_bk; /* register backup pointer */\ void (*init)(void *base); /* module initial */\ @@ -145,43 +142,43 @@ struct vpp_fb_base_t { void (*resume)(int sts) /* module resume */ /* End of vpp_mod_base_t */ -struct vpp_mod_base_t { +typedef struct { VPP_MOD_BASE; -}; +} vpp_mod_base_t; #define VPP_MOD_FLAG_FRAMEBUF BIT(0) #define VPP_MOD_CLK_ON BIT(31) -enum vpp_scale_mode_t { +typedef enum { VPP_SCALE_MODE_REC_TABLE, /* old design but 1/32 limit */ VPP_SCALE_MODE_RECURSIVE, /*no rec table,not smooth than bilinear mode*/ VPP_SCALE_MODE_BILINEAR,/*more smooth but less than 1/2 will drop line*/ VPP_SCALE_MODE_ADAPTIVE,/* scl dn 1-1/2 bilinear mode, other rec mode */ VPP_SCALE_MODE_MAX -}; +} vpp_scale_mode_t; -enum vpp_hdmi_audio_inf_t { +typedef enum { VPP_HDMI_AUDIO_I2S, VPP_HDMI_AUDIO_SPDIF, VPP_HDMI_AUDIO_MAX -}; +} vpp_hdmi_audio_inf_t; -enum vpp_filter_mode_t { +typedef enum { VPP_FILTER_SCALE, VPP_FILTER_DEBLOCK, VPP_FILTER_FIELD_DEFLICKER, VPP_FILTER_FRAME_DEFLICKER, VPP_FILTER_MODE_MAX -}; +} vpp_filter_mode_t; #define VPP_DBG_PERIOD_NUM 10 -struct vpp_dbg_period_t { +typedef struct { int index; int period_us[VPP_DBG_PERIOD_NUM]; struct timeval pre_tv; -}; +} vpp_dbg_period_t; -struct vpp_dbg_timer_t { +typedef struct { struct timeval pre_tv; unsigned int threshold; unsigned int reset; @@ -189,25 +186,25 @@ struct vpp_dbg_timer_t { unsigned int sum; unsigned int min; unsigned int max; -}; +} vpp_dbg_timer_t; #ifdef __KERNEL__ #define VPP_PROC_NUM 10 -struct vpp_proc_t { +typedef struct { int (*func)(void *arg); /* function pointer */ void *arg; /* function argument */ struct list_head list; - enum vpp_int_t type; /* interrupt type */ + vpp_int_t type; /* interrupt type */ struct semaphore sem; /* wait sem */ int wait_ms; /* wait complete timout (ms) */ int work_cnt; /* work counter if 0 then forever */ -}; +} vpp_proc_t; -struct vpp_irqproc_t { +typedef struct { struct list_head list; struct tasklet_struct tasklet; int ref; -}; +} vpp_irqproc_t; #endif #ifndef CFG_LOADER @@ -215,9 +212,11 @@ struct vpp_irqproc_t { #endif #include "lcd.h" +#ifndef CFG_LOADER /* #ifdef WMT_FTBLK_SCL */ #include "scl.h" /* #endif */ +#endif /* #ifdef WMT_FTBLK_GE #include "ge.h" @@ -239,7 +238,7 @@ struct vpp_irqproc_t { #include "edid.h" #endif -enum vpp_dbg_level_t { +typedef enum { VPP_DBGLVL_DISABLE = 0x0, VPP_DBGLVL_SCALE = 1, VPP_DBGLVL_DISPFB = 2, @@ -249,23 +248,24 @@ enum vpp_dbg_level_t { VPP_DBGLVL_DIAG = 6, VPP_DBGLVL_STREAM = 7, VPP_DBGLVL_ALL = 0xFF, -}; +} vpp_dbg_level_t; -struct vpp_info_t { +typedef struct { /* internal parameter */ int govrh_preinit; + int (*alloc_framebuf)(unsigned int resx, unsigned int resy); + int dual_display; /* use 2 govr */ int virtual_display; int fb0_bitblit; int fb_manual; /* not check var & internel timing */ int fb_recheck; /* recheck for plug but no change res */ int govrh_init_yres; - int stream_fb; + int virtual_display_mode; /* hdmi */ - enum vpp_hdmi_audio_inf_t hdmi_audio_interface; /* 0-I2S, 1-SPDIF */ + int hdmi_video_mode; /* 0-auto,720,1080 */ + vpp_hdmi_audio_inf_t hdmi_audio_interface; /* 0-I2S, 1-SPDIF */ int hdmi_cp_enable; /* 0-off, 1-on */ - int hdmi_audio_channel; - int hdmi_audio_freq; unsigned int hdmi_ctrl; unsigned int hdmi_audio_pb1; unsigned int hdmi_audio_pb4; @@ -279,9 +279,11 @@ struct vpp_info_t { int hdmi_certify_flag; int hdmi_sp_mode; int hdmi_disable; - int hdmi_ch_change; /* alloc frame buffer */ + unsigned int mb[VPP_MB_ALLOC_NUM]; + unsigned int mb_y_size; + unsigned int mb_fb_size; int mb_colfmt; /* debug */ @@ -289,11 +291,6 @@ struct vpp_info_t { int dbg_wait; int dbg_flag; - /* dvi */ - int dvi_int_disable; - int dvi_int_no; /* DVO external board interrupt use GPIOxx */ - int dvi_i2c_no; /* DVO external board i2c bus id */ - #if 0 /* HDMI DDC debug */ int dbg_hdmi_ddc_ctrl_err; @@ -308,10 +305,14 @@ struct vpp_info_t { int stream_mb_sync_flag; int stream_mb_index; unsigned int stream_mb[VPP_STREAM_MB_ALLOC_NUM]; + unsigned int stream_mb_y_size; int stream_mb_cnt; unsigned int stream_sync_cnt; +#ifdef CONFIG_VPP_STREAM_FIX_RESOLUTION + vdo_framebuf_t stream_fb; #endif -}; +#endif +} vpp_info_t; #ifdef __cplusplus extern "C" { @@ -346,13 +347,11 @@ const unsigned int vpp_csc_parm[VPP_CSC_MAX][7] = { {0x02dc00da, 0x1f88004a, 0x020b1e6d, 0x1e25020b, 0x00011fd0, 0x01010101, 0x00000000}, /* RGB2YUV_HDTV_16_235 */ {0x02590132, 0x1f530075, 0x02001ead, 0x1e530200, 0x00011fad, - 0x01010101, 0x00000000}, /* RGB2YUV_JFIF_0_255 */ + 0x00ff00ff, 0x00000000}, /* RGB2YUV_JFIF_0_255 */ {0x02590132, 0x1f500075, 0x020b1ea5, 0x1e4a020b, 0x00011fab, 0x01010101, 0x00000000}, /* RGB2YUV_SMPTE170M */ {0x02ce00d9, 0x1f890059, 0x02001e77, 0x1e380200, 0x00011fc8, 0x01010101, 0x00000000}, /* RGB2YUV_SMPTE240M */ - {0x02780142, 0x1e80007a, 0x04711d0e, 0x1c470471, 0x00001f46, - 0x01010101, 0x00000000} /* RGB2YUV_JFIF_VT1625 */ }; const struct fb_videomode vpp_videomode[] = { @@ -576,31 +575,34 @@ extern const unsigned int vpp_csc_parm[VPP_CSC_MAX][7]; extern char *vpp_colfmt_str[]; extern const struct fb_videomode vpp_videomode[]; extern char *vpp_mod_str[]; -#ifdef CONFIG_VPP_NOTIFY -extern struct switch_dev vpp_sdev; -#endif #endif -EXTERN struct vpp_info_t g_vpp; -#ifdef VPP_C -EXPORT_SYMBOL(g_vpp); -#endif +EXTERN vpp_info_t g_vpp; -static inline int vpp_get_hdmi_spdif(void) +static __inline__ int vpp_get_hdmi_spdif(void) { return (g_vpp.hdmi_audio_interface == VPP_HDMI_AUDIO_SPDIF) ? 1 : 0; } /* Internal functions */ EXTERN int get_key(void); +EXTERN U8 vppif_reg8_in(U32 offset); +EXTERN U8 vppif_reg8_out(U32 offset, U8 val); +EXTERN U16 vppif_reg16_in(U32 offset); +EXTERN U16 vppif_reg16_out(U32 offset, U16 val); +EXTERN U32 vppif_reg32_in(U32 offset); +EXTERN U32 vppif_reg32_out(U32 offset, U32 val); +EXTERN U32 vppif_reg32_write(U32 offset, U32 mask, U32 shift, U32 val); +EXTERN U32 vppif_reg32_read(U32 offset, U32 mask, U32 shift); +EXTERN U32 vppif_reg32_mask(U32 offset, U32 mask, U32 shift); EXTERN unsigned int vpp_get_chipid(void); /* Export functions */ EXTERN void vpp_mod_unregister(vpp_mod_t mod); -EXTERN struct vpp_mod_base_t *vpp_mod_register(vpp_mod_t mod, int size, +EXTERN vpp_mod_base_t *vpp_mod_register(vpp_mod_t mod, int size, unsigned int flags); -EXTERN struct vpp_mod_base_t *vpp_mod_get_base(vpp_mod_t mod); -EXTERN struct vpp_fb_base_t *vpp_mod_get_fb_base(vpp_mod_t mod); +EXTERN vpp_mod_base_t *vpp_mod_get_base(vpp_mod_t mod); +EXTERN vpp_fb_base_t *vpp_mod_get_fb_base(vpp_mod_t mod); EXTERN vdo_framebuf_t *vpp_mod_get_framebuf(vpp_mod_t mod); EXTERN void vpp_mod_init(void); EXTERN void vpp_mod_set_clock(vpp_mod_t mod, @@ -615,34 +617,35 @@ EXTERN void vpp_wait_vsync(int no, int cnt); EXTERN int vpp_get_gcd(int A, int B); EXTERN vpp_csc_t vpp_check_csc_mode(vpp_csc_t mode, vdo_color_fmt src_fmt, vdo_color_fmt dst_fmt, unsigned int flags); -EXTERN inline void vpp_cache_sync(void); +EXTERN __inline__ void vpp_cache_sync(void); EXTERN int vpp_calc_refresh(int pixclk, int xres, int yres); EXTERN int vpp_calc_align(int value, int align); EXTERN int vpp_calc_fb_width(vdo_color_fmt colfmt, int width); EXTERN void vpp_get_colfmt_bpp(vdo_color_fmt colfmt, int *y_bpp, int *c_bpp); -EXTERN int vpp_irqproc_work(enum vpp_int_t type, int (*func)(void *argc), +EXTERN int vpp_irqproc_work(vpp_int_t type, int (*func)(void *argc), void *arg, int wait_ms, int work_cnt); -EXTERN int vpp_check_dbg_level(enum vpp_dbg_level_t level); +EXTERN int vpp_check_dbg_level(vpp_dbg_level_t level); #ifdef __KERNEL__ EXTERN void vpp_dbg_show(int level, int tmr, char *str); EXTERN void vpp_dbg_wake_up(void); -EXTERN int vpp_dbg_get_period_usec(struct vpp_dbg_period_t *p, - int cmd); -EXTERN void vpp_dbg_timer(struct vpp_dbg_timer_t *p, char *str, int cmd); +EXTERN int vpp_dbg_get_period_usec(vpp_dbg_period_t *p, int cmd); +EXTERN void vpp_dbg_timer(vpp_dbg_timer_t *p, char *str, int cmd); EXTERN void vpp_dbg_back_trace(void); EXTERN void vpp_dbg_show_val1(int level, int tmr, char *str, int val); EXTERN void vpp_dbg_wait(char *str); EXTERN void vpp_irqproc_init(void); -EXTERN void vpp_irqproc_del_work(enum vpp_int_t type, +EXTERN void vpp_irqproc_del_work(vpp_int_t type, int (*func)(void *argc)); -EXTERN struct vpp_irqproc_t *vpp_irqproc_get_entry( - enum vpp_int_t vpp_int); +EXTERN vpp_irqproc_t *vpp_irqproc_get_entry(vpp_int_t vpp_int); /* dev-vpp.c */ -EXTERN int vpp_get_info(int fbn, struct fb_var_screeninfo *var); +EXTERN void vpp_get_info(int fbn, struct fb_var_screeninfo *var); EXTERN int vpp_set_par(struct fb_info *info); +EXTERN unsigned int *vpp_backup_reg(unsigned int addr, unsigned int size); +EXTERN int vpp_restore_reg(unsigned int addr, + unsigned int size, unsigned int *reg_ptr); EXTERN void vpp_backup_reg2(unsigned int addr, unsigned int size, unsigned int *ptr); EXTERN void vpp_restore_reg2(unsigned int addr, @@ -657,6 +660,7 @@ EXTERN void vpp_switch_state_init(void); EXTERN int vpp_set_blank(struct fb_info *info, int blank); #endif +EXTERN void vpp_reg_dump(unsigned int addr, int size); EXTERN unsigned int vpp_convert_colfmt(int yuv2rgb, unsigned int data); EXTERN void vpp_init(void); @@ -665,11 +669,15 @@ EXTERN void vpp_show_timing(char *str, struct fb_videomode *vmode, vpp_clock_t *clk); EXTERN void vpp_show_framebuf(char *str, vdo_framebuf_t *fb); EXTERN void vpp_show_videomode(char *str, struct fb_videomode *v); +EXTERN void vpp_set_mutex(int idx, int lock); EXTERN void vpp_set_NA12_hiprio(int type); +EXTERN void vpp_free_framebuffer(void); +EXTERN int vpp_alloc_framebuffer(unsigned int resx, unsigned int resy); EXTERN int vpp_mb_get(unsigned int phy); EXTERN int vpp_mb_put(unsigned int phy); EXTERN int vpp_mb_irqproc_sync(int arg); +EXTERN void vpp_mb_scale_bitblit(vdo_framebuf_t *fb); #undef EXTERN diff --git a/drivers/video/wmt/vppm.c b/drivers/video/wmt/vppm.c index 25882356..f3bc7d9f 100755..100644 --- a/drivers/video/wmt/vppm.c +++ b/drivers/video/wmt/vppm.c @@ -26,128 +26,127 @@ /* #define DEBUG_DETAIL */ #include "vppm.h" -HW_REG struct vppm_base_regs *vppm_regs = (void *) VPP_BASE_ADDR; -void vppm_set_int_enable(vpp_flag_t enable, enum vpp_int_t int_bit) +void vppm_set_int_enable(vpp_flag_t enable, vpp_int_t int_bit) { #ifdef WMT_FTBLK_SCL if (int_bit & VPP_INT_SCL_VBIE) - vppm_regs->int_en.b.scl_vbie = enable; + vppif_reg32_write(VPP_SCL_INTEN_VBIE, enable); if (int_bit & VPP_INT_SCL_VBIS) - vppm_regs->int_en.b.scl_vbis = enable; + vppif_reg32_write(VPP_SCL_INTEN_VBIS, enable); if (int_bit & VPP_INT_SCL_PVBI) - vppm_regs->int_en.b.scl_pvbi = enable; + vppif_reg32_write(VPP_SCL_INTEN_PVBI, enable); #endif #ifdef WMT_FTBLK_GOVRH if (int_bit & VPP_INT_GOVRH_VBIE) - vppm_regs->int_en.b.govrh_vbie = enable; + vppif_reg32_write(VPP_GOVRH_INTEN_VBIE, enable); if (int_bit & VPP_INT_GOVRH_VBIS) - vppm_regs->int_en.b.govrh_vbis = enable; + vppif_reg32_write(VPP_GOVRH_INTEN_VBIS, enable); if (int_bit & VPP_INT_GOVRH_PVBI) - vppm_regs->int_en.b.govrh_pvbi = enable; + vppif_reg32_write(VPP_GOVRH_INTEN_PVBI, enable); #endif #ifdef WMT_FTBLK_GOVRH if (int_bit & VPP_INT_GOVRH2_VBIE) - vppm_regs->int_en.b.govrh2_vbie = enable; + vppif_reg32_write(VPP_GOVRH2_INTEN_VBIE, enable); if (int_bit & VPP_INT_GOVRH2_VBIS) - vppm_regs->int_en.b.govrh2_vbis = enable; + vppif_reg32_write(VPP_GOVRH2_INTEN_VBIS, enable); if (int_bit & VPP_INT_GOVRH2_PVBI) - vppm_regs->int_en.b.govrh2_pvbi = enable; + vppif_reg32_write(VPP_GOVRH2_INTEN_PVBI, enable); #endif } -int vppm_get_int_enable(enum vpp_int_t int_bit) +int vppm_get_int_enable(vpp_int_t int_bit) { int ret = 0; #ifdef WMT_FTBLK_SCL if (int_bit & VPP_INT_SCL_VBIE) - ret = vppm_regs->int_en.b.scl_vbie; + ret = vppif_reg32_read(VPP_SCL_INTEN_VBIE); if (int_bit & VPP_INT_SCL_VBIS) - ret = vppm_regs->int_en.b.scl_vbis; + ret = vppif_reg32_read(VPP_SCL_INTEN_VBIS); if (int_bit & VPP_INT_SCL_PVBI) - ret = vppm_regs->int_en.b.scl_pvbi; + ret = vppif_reg32_read(VPP_SCL_INTEN_PVBI); #endif #ifdef WMT_FTBLK_GOVRH if (int_bit & VPP_INT_GOVRH_VBIE) - ret = vppm_regs->int_en.b.govrh_vbie; + ret = vppif_reg32_read(VPP_GOVRH_INTEN_VBIE); if (int_bit & VPP_INT_GOVRH_VBIS) - ret = vppm_regs->int_en.b.govrh_vbis; + ret = vppif_reg32_read(VPP_GOVRH_INTEN_VBIS); if (int_bit & VPP_INT_GOVRH_PVBI) - ret = vppm_regs->int_en.b.govrh_pvbi; + ret = vppif_reg32_read(VPP_GOVRH_INTEN_PVBI); #endif #ifdef WMT_FTBLK_GOVRH if (int_bit & VPP_INT_GOVRH2_VBIE) - ret = vppm_regs->int_en.b.govrh2_vbie; + ret = vppif_reg32_read(VPP_GOVRH2_INTEN_VBIE); if (int_bit & VPP_INT_GOVRH2_VBIS) - ret = vppm_regs->int_en.b.govrh2_vbis; + ret = vppif_reg32_read(VPP_GOVRH2_INTEN_VBIS); if (int_bit & VPP_INT_GOVRH2_PVBI) - ret = vppm_regs->int_en.b.govrh2_pvbi; + ret = vppif_reg32_read(VPP_GOVRH2_INTEN_PVBI); #endif return ret; } -enum vpp_int_t vppm_get_int_status(void) +vpp_int_t vppm_get_int_status(void) { unsigned int int_enable_reg; unsigned int int_sts_reg; - enum vpp_int_t int_sts = 0; + vpp_int_t int_sts = 0; - int_enable_reg = vppm_regs->int_en.val; - int_sts_reg = vppm_regs->int_sts.val; + int_enable_reg = vppif_reg32_in(REG_VPP_INTEN); + int_sts_reg = vppif_reg32_in(REG_VPP_INTSTS); #ifdef WMT_FTBLK_SCL - if (vppm_regs->int_en.b.scl_vbie && vppm_regs->int_sts.b.scl_vbie) + if ((int_enable_reg & BIT18) && (int_sts_reg & BIT18)) int_sts |= VPP_INT_SCL_VBIE; - if (vppm_regs->int_en.b.scl_vbis && vppm_regs->int_sts.b.scl_vbis) + if ((int_enable_reg & BIT17) && (int_sts_reg & BIT17)) int_sts |= VPP_INT_SCL_VBIS; - if (vppm_regs->int_en.b.scl_pvbi && vppm_regs->int_sts.b.scl_pvbi) + if ((int_enable_reg & BIT16) && (int_sts_reg & BIT16)) int_sts |= VPP_INT_SCL_PVBI; #endif #ifdef WMT_FTBLK_GOVRH - if (vppm_regs->int_en.b.govrh_pvbi && vppm_regs->int_sts.b.govrh_pvbi) - int_sts |= VPP_INT_GOVRH_PVBI; - if (vppm_regs->int_en.b.govrh_vbis && vppm_regs->int_sts.b.govrh_vbis) - int_sts |= VPP_INT_GOVRH_VBIS; - if (vppm_regs->int_en.b.govrh_vbie && vppm_regs->int_sts.b.govrh_vbie) + if ((int_enable_reg & BIT10) && (int_sts_reg & BIT10)) int_sts |= VPP_INT_GOVRH_VBIE; + if ((int_enable_reg & BIT9) && (int_sts_reg & BIT9)) + int_sts |= VPP_INT_GOVRH_VBIS; + if ((int_enable_reg & BIT8) && (int_sts_reg & BIT8)) + int_sts |= VPP_INT_GOVRH_PVBI; #endif #ifdef WMT_FTBLK_GOVRH - if (vppm_regs->int_en.b.govrh2_pvbi && vppm_regs->int_sts.b.govrh2_pvbi) - int_sts |= VPP_INT_GOVRH2_PVBI; - if (vppm_regs->int_en.b.govrh2_vbis && vppm_regs->int_sts.b.govrh2_vbis) - int_sts |= VPP_INT_GOVRH2_VBIS; - if (vppm_regs->int_en.b.govrh2_vbie && vppm_regs->int_sts.b.govrh2_vbie) + if ((int_enable_reg & BIT14) && (int_sts_reg & BIT14)) int_sts |= VPP_INT_GOVRH2_VBIE; + if ((int_enable_reg & BIT13) && (int_sts_reg & BIT13)) + int_sts |= VPP_INT_GOVRH2_VBIS; + if ((int_enable_reg & BIT12) && (int_sts_reg & BIT12)) + int_sts |= VPP_INT_GOVRH2_PVBI; #endif return int_sts; } -void vppm_clean_int_status(enum vpp_int_t int_sts) +void vppm_clean_int_status(vpp_int_t int_sts) { #ifdef WMT_FTBLK_SCL if (int_sts & VPP_INT_SCL_VBIE) - vppm_regs->int_sts.val = BIT18; + vppif_reg8_out(REG_VPP_INTSTS + 0x2, 0x4); if (int_sts & VPP_INT_SCL_VBIS) - vppm_regs->int_sts.val = BIT17; + vppif_reg8_out(REG_VPP_INTSTS + 0x2, 0x2); if (int_sts & VPP_INT_SCL_PVBI) - vppm_regs->int_sts.val = BIT16; + vppif_reg8_out(REG_VPP_INTSTS + 0x2, 0x1); #endif #ifdef WMT_FTBLK_GOVRH if (int_sts & VPP_INT_GOVRH_VBIE) - vppm_regs->int_sts.val = BIT10; + vppif_reg8_out(REG_VPP_INTSTS + 0x1, 0x4); if (int_sts & VPP_INT_GOVRH_VBIS) - vppm_regs->int_sts.val = BIT9; + vppif_reg8_out(REG_VPP_INTSTS + 0x1, 0x2); if (int_sts & VPP_INT_GOVRH_PVBI) - vppm_regs->int_sts.val = BIT8; + vppif_reg8_out(REG_VPP_INTSTS + 0x1, 0x1); #endif #ifdef WMT_FTBLK_GOVRH if (int_sts & VPP_INT_GOVRH2_VBIE) - vppm_regs->int_sts.val = BIT14; + vppif_reg32_out(REG_VPP_INTSTS, 0x00004000); if (int_sts & VPP_INT_GOVRH2_VBIS) - vppm_regs->int_sts.val = BIT13; + vppif_reg32_out(REG_VPP_INTSTS, 0x00002000); if (int_sts & VPP_INT_GOVRH2_PVBI) - vppm_regs->int_sts.val = BIT12; + vppif_reg32_out(REG_VPP_INTSTS, 0x00001000); #endif } @@ -164,12 +163,12 @@ void vppm_set_module_reset(vpp_mod_t mod) if (mod == VPP_MOD_GOVRH) value2 |= (BIT0 | BIT8 | BIT9); #endif - vppm_regs->sw_reset1.val = ~value1; - vppm_regs->sw_reset1.val = 0x1010101; - vppm_regs->sw_reset2.val = ~value2; - vppm_regs->sw_reset2.val = 0x1011311; - vppm_regs->sw_reset3.val = ~value3; - vppm_regs->sw_reset3.val = 0x10101; + vppif_reg32_out(REG_VPP_SWRST1_SEL, ~value1); + vppif_reg32_out(REG_VPP_SWRST1_SEL, 0x1010101); + vppif_reg32_out(REG_VPP_SWRST2_SEL, ~value2); + vppif_reg32_out(REG_VPP_SWRST2_SEL, 0x1011311); + vppif_reg32_out(REG_VPP_SWRST3_SEL, ~value3); + vppif_reg32_out(REG_VPP_SWRST3_SEL, 0x10101); } void vppm_reg_dump(void) @@ -180,31 +179,31 @@ void vppm_reg_dump(void) vpp_reg_dump(REG_VPP_BEGIN, REG_VPP_END - REG_VPP_BEGIN); DPRINT("---------- VPP Interrupt ----------\n"); - reg1 = vppm_regs->int_sts.val; - reg2 = vppm_regs->int_en.val; + reg1 = vppif_reg32_in(REG_VPP_INTSTS); + reg2 = vppif_reg32_in(REG_VPP_INTEN); DPRINT("GOVRH PVBI(En %d,%d),VBIS(En %d,%d),VBIE(En %d,%d)\n", - vppm_regs->int_en.b.govrh_pvbi, - vppm_regs->int_sts.b.govrh_pvbi, - vppm_regs->int_en.b.govrh_vbis, - vppm_regs->int_sts.b.govrh_vbis, - vppm_regs->int_en.b.govrh_vbie, - vppm_regs->int_sts.b.govrh_vbie); + vppif_reg32_read(VPP_GOVRH_INTEN_PVBI), + vppif_reg32_read(VPP_GOVRH_INTSTS_PVBI), + vppif_reg32_read(VPP_GOVRH_INTEN_VBIS), + vppif_reg32_read(VPP_GOVRH_INTSTS_VBIS), + vppif_reg32_read(VPP_GOVRH_INTEN_VBIE), + vppif_reg32_read(VPP_GOVRH_INTSTS_VBIE)); DPRINT("GOVRH2 PVBI(En %d,%d),VBIS(En %d,%d),VBIE(En %d,%d)\n", - vppm_regs->int_en.b.govrh2_pvbi, - vppm_regs->int_sts.b.govrh2_pvbi, - vppm_regs->int_en.b.govrh2_vbis, - vppm_regs->int_sts.b.govrh2_vbis, - vppm_regs->int_en.b.govrh2_vbie, - vppm_regs->int_sts.b.govrh2_vbie); + vppif_reg32_read(VPP_GOVRH2_INTEN_PVBI), + vppif_reg32_read(VPP_GOVRH2_INTSTS_PVBI), + vppif_reg32_read(VPP_GOVRH2_INTEN_VBIS), + vppif_reg32_read(VPP_GOVRH2_INTSTS_VBIS), + vppif_reg32_read(VPP_GOVRH2_INTEN_VBIE), + vppif_reg32_read(VPP_GOVRH2_INTSTS_VBIE)); DPRINT("SCL PVBI(En %d,%d),VBIS(En %d,%d),VBIE(En %d,%d)\n", - vppm_regs->int_en.b.scl_pvbi, - vppm_regs->int_sts.b.scl_pvbi, - vppm_regs->int_en.b.scl_vbis, - vppm_regs->int_sts.b.scl_vbis, - vppm_regs->int_en.b.scl_vbie, - vppm_regs->int_sts.b.scl_vbie); + vppif_reg32_read(VPP_SCL_INTEN_PVBI), + vppif_reg32_read(VPP_SCL_INTSTS_PVBI), + vppif_reg32_read(VPP_SCL_INTEN_VBIS), + vppif_reg32_read(VPP_SCL_INTSTS_VBIS), + vppif_reg32_read(VPP_SCL_INTEN_VBIE), + vppif_reg32_read(VPP_SCL_INTSTS_VBIE)); } #ifdef CONFIG_PM @@ -247,9 +246,9 @@ void vppm_resume(int sts) void vppm_init(void *base) { - struct vppm_mod_t *mod_p; + vppm_mod_t *mod_p; - mod_p = (struct vppm_mod_t *) base; + mod_p = (vppm_mod_t *) base; vppm_set_module_reset(0); vppm_set_int_enable(VPP_FLAG_ENABLE, mod_p->int_catch); @@ -258,10 +257,10 @@ void vppm_init(void *base) int vppm_mod_init(void) { - struct vppm_mod_t *mod_p; + vppm_mod_t *mod_p; - mod_p = (struct vppm_mod_t *) vpp_mod_register(VPP_MOD_VPPM, - sizeof(struct vppm_mod_t), 0); + mod_p = (vppm_mod_t *) vpp_mod_register(VPP_MOD_VPPM, + sizeof(vppm_mod_t), 0); if (!mod_p) { DPRINT("*E* VPP module register fail\n"); return -1; diff --git a/drivers/video/wmt/vppm.h b/drivers/video/wmt/vppm.h index 5fe26521..c0d3a418 100755..100644 --- a/drivers/video/wmt/vppm.h +++ b/drivers/video/wmt/vppm.h @@ -28,9 +28,9 @@ #ifndef VPPM_H #define VPPM_H -struct vppm_mod_t { +typedef struct { VPP_MOD_BASE; -}; +} vppm_mod_t; #ifdef __cplusplus extern "C" { @@ -42,13 +42,12 @@ extern "C" { #define EXTERN extern #endif -EXTERN struct vppm_mod_t *p_vppm; +EXTERN vppm_mod_t *p_vppm; -EXTERN void vppm_set_int_enable(vpp_flag_t enable, - enum vpp_int_t int_bit); -EXTERN int vppm_get_int_enable(enum vpp_int_t int_bit); -EXTERN enum vpp_int_t vppm_get_int_status(void); -EXTERN void vppm_clean_int_status(enum vpp_int_t int_sts); +EXTERN void vppm_set_int_enable(vpp_flag_t enable, vpp_int_t int_bit); +EXTERN int vppm_get_int_enable(vpp_int_t int_bit); +EXTERN vpp_int_t vppm_get_int_status(void); +EXTERN void vppm_clean_int_status(vpp_int_t int_sts); EXTERN void vppm_set_module_reset(vpp_mod_t mod_bit); EXTERN int vppm_mod_init(void); EXTERN void vppm_set_DVO_select(int govr1); diff --git a/drivers/video/wmt/wmt-mb.c b/drivers/video/wmt/wmt-mb.c index 61bc6855..375d53c8 100755..100644 --- a/drivers/video/wmt/wmt-mb.c +++ b/drivers/video/wmt/wmt-mb.c @@ -62,7 +62,7 @@ #define MB_VERSION_MAJOR 1 #define MB_VERSION_MINOR 0 #define MB_VERSION_MICRO 0 -#define MB_VERSION_BUILD 6 +#define MB_VERSION_BUILD 3 #define MB_DEBUG #define MB_INFO(fmt, args...) \ @@ -312,243 +312,420 @@ static spinlock_t mb_search_lock; static spinlock_t mb_ioctl_lock; static spinlock_t mb_task_mm_lock; static spinlock_t mb_task_lock; +static struct page *pg_user[12800]; /* 12800 pages = 50 MB */ static char show_mb_buffer[MB_SHOW_BUFSIZE]; static char show_mba_buffer[MBA_SHOW_BUFSIZE]; -static inline uint64_t checkSum(unsigned long phys, int size, int type) +#define MMU_SEARCH_DONE 1 +typedef int (*mb_page_proc)(void *, dma_addr_t, int); + +static inline int mmu_search_pte( + pte_t *pte, + unsigned long boundary, + unsigned long *addr, + unsigned long *offset, + mb_page_proc proc, + void *priv) { - char *d = (type) ? __va(phys) : mb_phys_to_virt(phys); - int i, pageSize, len, offset; - uint64_t sum, cs = 0; - - len = size; - offset = (unsigned long)d % PAGE_SIZE; - while (len > 0) { - sum = 0; - pageSize = min((int)(PAGE_SIZE - offset), len); - for (i = 0; i < pageSize; i++) - sum += d[i]; - MB_WDBG("[CS] addr %#lx ~ %#lx size %#x cs %#llx\n", - phys, phys + size, size, sum); - MB_WDBG("[CS:DATA] %02x %02x %02x %02x %02x %02x %02x %02x\n", - d[0] & 0xff, d[1] & 0xff, d[2] & 0xff, d[3] & 0xff, - d[4] & 0xff, d[5] & 0xff, d[6] & 0xff, d[7] & 0xff); - d += pageSize; - len -= pageSize; - cs += sum; - } - - return cs; + int ret = 0, index = 0; + + /* for each pte */ + while (pte && (*addr < boundary)) { + unsigned long pfn = pte_pfn(*pte); + struct page *pg = pfn_to_page(pfn); + void *virt = page_address(pg); + dma_addr_t phys = virt_to_phys(virt); + + MB_WDBG("\t\t[PTE%3d] PTE[%p]=%x n %lx V %p P %x U %lx[%lx]\n", + index++, pte, pte_val(*pte), pfn, + virt, phys, *addr, *offset); + if (!pfn_valid(pfn)) { + MB_WARN("invalid pfn %ld of addr %lx\n", pfn, *addr); + return -1; + } + if (*offset < PAGE_SIZE) { + ret = proc(priv, phys, *offset); + if (ret) + break; + *offset = 0; + } else + *offset -= PAGE_SIZE; + *addr += PAGE_SIZE; + pte++; +#ifdef MB_WORDY + msleep(30); +#endif + }; + return ret; } -unsigned long user_to_phys(unsigned long user) +static inline int mmu_search_pmd( + pmd_t *pmd, + unsigned long boundary, + unsigned long *addr, + unsigned long *offset, + mb_page_proc proc, + void *priv) { - unsigned long par, phys, offset; - offset = user % PAGE_SIZE; - - asm volatile( - "mcr p15, 0, %[user], c7, c8, 0\n" - "isb\n" - "mrc p15, 0, %[par], c7, c4, 0\n" - : [par] "=r" (par) - : [user] "r" (user)); - - phys = (par & PAGE_MASK) + offset; - MB_DBG("%s: user %lx par %lx phys %lx\n", - __func__, user, par, phys); - - return (par & 0x1) ? 0 : phys; + int ret = 0, index = 0; + unsigned long end; + pte_t *pte; + + /* for each pmd */ + while (pmd && (*addr < boundary)) { + /* from start to PMD alignment */ + end = (*addr + PMD_SIZE) & PMD_MASK; + end = min(end, boundary); + pte = pte_offset_map(pmd, *addr); + if (pte == NULL) { + MB_WARN("[%08lx] *pmd=%08llx unknown pte\n", + *addr, (long long)pmd_val(*pmd)); + return -1; + } + MB_WDBG("\t[PMD%3d, %lx, %lx] *(%p)=%x addr %lx\n", index++, + end - PMD_SIZE, end, pmd, pmd_val(*pmd), *addr); + ret = mmu_search_pte(pte, end, addr, offset, proc, priv); + if (ret) + break; + pmd++; + }; + return ret; } -EXPORT_SYMBOL(user_to_phys); -/* return address is guaranteeed only under page alignment */ -void *user_to_virt(unsigned long user) +static inline int mmu_search_pgd( + pgd_t *pgd, + unsigned long boundary, + unsigned long *addr, + unsigned long *offset, + mb_page_proc proc, + void *priv) { - unsigned long phys; - - phys = user_to_phys(user); - if (!phys) { - MB_WARN("user 0x%lx to virt fail.\n", user); - return 0; - } + int ret = 0, index = 0; + unsigned long end; + pmd_t *pmd; + pud_t *pud; + + /* for each pgd */ + while (pgd && (*addr < boundary)) { + /* from start to PGDIR alignment */ + end = (*addr + PGDIR_SIZE) & PGDIR_MASK; + end = min(end, boundary); + MB_WDBG("[PGD%3d, %lx, %lx] *(%p)=%x addr %lx\n", index++, + end - PGDIR_SIZE, end, pgd, pgd_val(*pgd), *addr); + pud = pud_offset(pgd, *addr); + if (pud_none(*pud) || pud_bad(*pud)) { + MB_WARN("[%08lx] *pgd=%08llx %s pud\n", + *addr, (long long)pgd_val(*pgd), + pud_none(*pud) ? "(None)" : "(Bad)"); + return -1; + } + pmd = pmd_offset(pud, *addr); + if (pmd == NULL) { + MB_WARN("[%08lx] *pgd=%08llx unknown pmd\n", + *addr, (long long)pgd_val(*pgd)); + return -1; + } + ret = mmu_search_pmd(pmd, end, addr, offset, proc, priv); + if (ret) + break; + pgd++; + }; - return __va(phys); + return ret; } -EXPORT_SYMBOL(user_to_virt); -struct prdt_info { +struct prdt_search_info { int index; int items; - int offset; - int size; - struct prdt_struct *prdt; - struct prdt_struct *last; + unsigned int size; + struct prdt_struct *prev; + struct prdt_struct *next; }; -static int prdt_proc(struct prdt_info *info, unsigned long phys) +static int __user_to_prdt_proc(void *priv, dma_addr_t phys, int offset) { - int len; + struct prdt_search_info *info = (struct prdt_search_info *)priv; + struct prdt_struct *prev = info->prev, *next = info->next; + int len = PAGE_SIZE - offset; - if (!info) { - MB_WARN("PRDT process fail. (NULL info)\n"); - return -1; - } - - /* PRDT has done or no PRDT space */ - if (info->size <= 0 || - (info->last && info->last->EDT)) - return 0; - - len = PAGE_SIZE - info->offset; - if (len > info->size) /* last page */ + if (len > info->size) len = info->size; /* Check it could combind with previous one */ - if (info->last && - /* prd size boundary check, MAX 60K */ - (info->last->size <= ((1 << 16) - (2 * PAGE_SIZE))) && - /* page continuity check */ - ((info->last->addr + info->last->size) == phys)) - info->last->size += len; + if (prev && + /* prd size boundary check, MAX 60K */ + (prev->size <= ((1 << 16) - (2 * PAGE_SIZE))) && + /* page continuity check */ + ((prev->addr + prev->size) == phys)) + prev->size += len; else { /* create new one */ + info->prev = prev = next; + info->next = next + 1; + prev->addr = phys + offset; + prev->size = len; + info->index++; + info->items--; if (!info->items) { MB_WARN("PRD table full (ptr %p # %d left %d).\n", - info->last+1, info->index+1, info->size); - if (info->last) - info->last->EDT = 1; + next, info->index, info->size); + prev->EDT = 1; return -1; } - if (info->last == NULL) - info->last = info->prdt; - else - info->last++; - info->last->addr = phys + info->offset; - info->last->size = len; - info->index++; - info->items--; - info->offset = 0; } info->size -= len; - info->last->reserve = 0; - info->last->EDT = (info->size) ? 0 : 1; - MB_WDBG("\t[PRD %3d] %p (0x%x ~ 0x%x, 0x%x, %x) phys 0x%lx offset 0x%x len 0x%x left %x\n", - info->index, info->last, info->last->addr, info->last->addr + info->last->size, - info->last->size, info->last->EDT, phys, info->offset, len, info->size); + prev->reserve = 0; + prev->EDT = (info->size) ? 0 : 1; + MB_WDBG("\t\t\t[PRD %3d] %p start %x(%x + %d) size %x edt %x left %x\n", + info->index, prev, prev->addr, phys, offset, + prev->size, prev->EDT, info->size); - return 0; -} - -static inline void show_prdt(struct prdt_struct *next) -{ - int idx = 1; + if (prev->EDT) + return MMU_SEARCH_DONE; - while (!next->EDT) { - MB_INFO("PRDT %d-th item: addr %x size %d EDT %d\n", - idx, next->addr, next->size, next->EDT); - idx++; - next++; - } - MB_INFO("PRDT last(%d-th) item: addr %x size %d EDT %d\n", - idx, next->addr, next->size, next->EDT); + return 0; } -int user_to_prdt( +static int __user_to_prdt( unsigned long user, unsigned int size, struct prdt_struct *prdt, unsigned int items) { - struct prdt_info info = {0}; - unsigned long addr; - int idx; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + unsigned long addr, end, offset; + struct prdt_search_info info = {0}; + unsigned int idx; + pgd_t *pgd; + int ret; if (!prdt || ((size / PAGE_SIZE) + 2) > items) { - MB_WARN("PRD table space not enough (ptr %p at least %lu but %d).\n", - prdt, (size/PAGE_SIZE)+2, items); + MB_WARN("PRD table space not enough (ptr %p at least %lu).\n", + prdt, (size/PAGE_SIZE)+2); return -EINVAL; } - MB_DBG("Memory(%#lx,%#x) PRDT(%p,%d)\n", user, size, prdt, items); - info.items = items; - info.offset = user % PAGE_SIZE; + MB_DBG("Memory(%#lx,%d) PRDT(%p,%d)\n", user, size, prdt, items); info.size = size; - info.prdt = prdt; - addr = user & PAGE_MASK; + info.next = prdt; + info.items = items; + addr = user; + + down_read(&mm->mmap_sem); while (info.size > 0) { - unsigned long phys = user_to_phys(addr); - if (!phys) { - MB_WARN("user to prdt fail: unknown addr %lx (%lx, %x)\n", - addr, user, size); - return -EINVAL; + vma = find_vma(mm, addr); + if (vma == NULL) { + MB_WARN("user addr %lx not found in task %s\n", + addr, current->comm); + info.next->EDT = 1; + goto fault; } - prdt_proc(&info, phys); - addr += PAGE_SIZE; + + MB_WDBG("VMA found: mm %p start %lx end %lx flags %lx\n", + mm, vma->vm_start, vma->vm_end, vma->vm_flags); + end = PAGE_ALIGN(vma->vm_end); + offset = addr - vma->vm_start; + addr = vma->vm_start; + pgd = pgd_offset(mm, vma->vm_start); + ret = mmu_search_pgd(pgd, end, &addr, &offset, + __user_to_prdt_proc, &info); + if (ret == MMU_SEARCH_DONE) + break; + if (ret) + goto fault; } - /* flush cache */ - MB_WDBG("flush PRDT %p, from %lx size %d\n", prdt, user, size); - dmac_flush_range((const void *)user, (const void *)(user + size)); + MB_WDBG("PRDT %p, from %lx size %d\n", prdt, user, size); for (idx = 0;; idx++) { - MB_WDBG("PRDT[%d] %p addr %x( ~ %x) size %d EDT %d (%p ~ %p)\n", - idx, &prdt[idx], prdt[idx].addr, prdt[idx].addr + prdt[idx].size, prdt[idx].size, - prdt[idx].EDT, __va(prdt[idx].addr), __va(prdt[idx].addr + prdt[idx].size)); + MB_WDBG("PRDT[%d] adddr %x size %d EDT %d\n", + idx, prdt[idx].addr, prdt[idx].size, prdt[idx].EDT); + dmac_flush_range(__va(prdt[idx].addr), + __va(prdt[idx].addr + prdt[idx].size)); outer_flush_range(prdt[idx].addr, prdt[idx].addr + prdt[idx].size); if (prdt[idx].EDT) break; } - - /* show_prdt(prdt); */ + up_read(&mm->mmap_sem); return 0; +fault: + MB_WARN("USER TO PRDT unfinished, remain size %d\n", info.size); + up_read(&mm->mmap_sem); + return -EFAULT; } -EXPORT_SYMBOL(user_to_prdt); -int mb_to_prdt( - unsigned long phys, +static int __user_to_prdt1( + unsigned long user, unsigned int size, - struct prdt_struct *prdt, + struct prdt_struct *next, unsigned int items) { - struct prdt_info info = {0}; - unsigned long addr; - void *virt = NULL; - int idx; + void *ptr_start, *ptr_end, *ptr, *virt = NULL; + int res, pg_size, pg_idx = 0, nr_pages = 0; + struct vm_area_struct *vma; + + ptr_start = ptr = (void *)user; + ptr_end = ptr_start + size; + MB_DBG("Memory(%#lx,%d) PRDT(%p,%d)\n", user, size, next, items); + + down_read(¤t->mm->mmap_sem); + vma = find_vma(current->mm, user); + up_read(¤t->mm->mmap_sem); + /* For kernel direct-mapped memory, take the easy way */ + if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff)) { + unsigned long phys = 0; + /* kernel-allocated, mmaped-to-usermode addresses */ + phys = (vma->vm_pgoff << PAGE_SHIFT) + (user - vma->vm_start); + virt = __va(phys); + MB_INFO("kernel-alloc, mmaped-to-user addr U %lx V %p P %lx", + user, virt, phys); + BUG_ON(1); + return -EFAULT; + } + MB_WDBG("VMA found: mm %p start %lx end %lx flags %lx\n", + current->mm, vma->vm_start, vma->vm_end, vma->vm_flags); - if (!prdt || ((size / PAGE_SIZE) + 2) > items) { - MB_WARN("PRD table space not enough (ptr %p at least %lu but %d).\n", - prdt, (size/PAGE_SIZE)+2, items); + nr_pages = (size + (PAGE_SIZE - 1)) / PAGE_SIZE; + if (!next || ((size/PAGE_SIZE)+2) > items || nr_pages > 2560) { + MB_WARN("PRD table space full (ptr %p pages %d prdt %d/%lu).\n", + next, nr_pages, items, (size/PAGE_SIZE)+2); return -EINVAL; } - MB_DBG("Memory(%#lx,%#x) PRDT(%p,%d)\n", phys, size, prdt, items); - info.items = items; - info.offset = phys % PAGE_SIZE; - info.size = size; - info.prdt = prdt; - addr = phys & PAGE_MASK; - while (info.size > 0) { - prdt_proc(&info, addr); - addr += PAGE_SIZE; + memset(pg_user, 0x0, sizeof(struct page *)*2560); + down_read(¤t->mm->mmap_sem); + res = get_user_pages(current, current->mm, + (unsigned long)ptr, nr_pages, 1, 0, pg_user, NULL); + while (res > 0 && size > 0) { + pg_size = PAGE_SIZE - ((unsigned long)ptr & ~PAGE_MASK); + virt = page_address(pg_user[pg_idx]) + + ((unsigned long)ptr & ~PAGE_MASK); + if (pg_size > size) + pg_size = size; + MB_DBG("Get %d-th user page s %d/%d u %p v %p p %lx\n", + pg_idx, pg_size, size, ptr, virt, __pa(virt)); + if ((next->addr + next->size) != __pa(virt) || + (next->size + pg_size) >= 65536 || !pg_idx) { + if (pg_idx) { + next->EDT = 0; + next++; + } + memset(next, 0x0, sizeof(struct prdt_struct)); + next->addr = __pa(virt); + } + next->size += pg_size; + next->EDT = 1; + size -= pg_size; + ptr += pg_size; + pg_idx++; + } + next->EDT = 1; + up_read(¤t->mm->mmap_sem); + return size; +} + +static int __user_to_prdt2( + unsigned long user, + unsigned int size, + struct prdt_struct *next, + unsigned int items) +{ + void *ptr_start, *ptr_end, *ptr, *virt = NULL; + int res, pg_size, pg_idx = 0, ret = 0; + struct vm_area_struct *vma; + struct page *pages = NULL; + + ptr_start = ptr = (void *)user; + ptr_end = ptr_start + size; + MB_DBG("Memory(%#lx,%d) PRDT(%p,%d)\n", user, size, next, items); + + down_read(¤t->mm->mmap_sem); + vma = find_vma(current->mm, user); + up_read(¤t->mm->mmap_sem); + /* For kernel direct-mapped memory, take the easy way */ + if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff)) { + unsigned long phys = 0; + /* kernel-allocated, mmaped-to-usermode addresses */ + phys = (vma->vm_pgoff << PAGE_SHIFT) + (user - vma->vm_start); + virt = __va(phys); + MB_INFO("kernel-alloc, user-mmaped addr U %lx V %p P %lx", + user, virt, phys); + BUG_ON(1); + return -EFAULT; } - /* flush cache */ - MB_WDBG("PRDT %p, from %lx size %d\n", prdt, phys, size); - virt = mb_phys_to_virt(phys); - dmac_flush_range(virt, virt + size); - for (idx = 0;; idx++) { - MB_WDBG("PRDT[%d] addr %x size %d EDT %d\n", - idx, prdt[idx].addr, prdt[idx].size, prdt[idx].EDT); - outer_flush_range(prdt[idx].addr, - prdt[idx].addr + prdt[idx].size); - if (prdt[idx].EDT) + if (!next || ((size/PAGE_SIZE)+2) > items) { + MB_WARN("PRD table space full (ptr %p at least %lu)\n", + next, (size/PAGE_SIZE)+2); + return -EINVAL; + } + + MB_WDBG("VMA found: mm %p start %lx end %lx flags %lx\n", + current->mm, vma->vm_start, vma->vm_end, vma->vm_flags); + + while (size) { + down_read(¤t->mm->mmap_sem); + res = get_user_pages(current, current->mm, + (unsigned long)ptr, 1, 1, 0, &pages, NULL); + up_read(¤t->mm->mmap_sem); + pg_size = PAGE_SIZE - ((unsigned long)ptr & ~PAGE_MASK); + if (res != 1) { + MB_ERROR("Get %d-th user pages (a %p s %d/%d) fail\n", + pg_idx, ptr, pg_size, size); + next->EDT = 1; + ret = -EFAULT; break; + } + virt = page_address(&pages[0]) + + ((unsigned long)ptr & ~PAGE_MASK); + pg_size = (pg_size > size) ? size : pg_size; + MB_DBG("Get %d-th user page s %d/%d u %p v %p p %lx\n", + pg_idx, pg_size, size, ptr, virt, __pa(virt)); + if ((next->addr + next->size) != __pa(virt) || + (next->size + pg_size) >= 65536 || !pg_idx) { + if (pg_idx) { + next->EDT = 0; + next++; + } + memset(next, 0x0, sizeof(struct prdt_struct)); + next->addr = __pa(virt); + } + next->size += pg_size; + next->EDT = 1; + size -= pg_size; + ptr += pg_size; + pg_idx++; } + return ret; +} - /* show_prdt(prdt); */ - return 0; +static void show_prdt(struct prdt_struct *next) +{ + int idx = 1; + while (!next->EDT) { + MB_INFO("PRDT %d-th item: addr %x size %d EDT %d\n", + idx, next->addr, next->size, next->EDT); + idx++; + next++; + } + MB_INFO("PRDT last(%d-th) item: addr %x size %d EDT %d\n", + idx, next->addr, next->size, next->EDT); } -EXPORT_SYMBOL(mb_to_prdt); +/*!************************************************************************* +* wmt_mmu_table_size +* +* Public Function +*/ +/*! +* \brief +* estimate request mmu table size for input size +* +* \parameter +* size [IN] convert size +* +* \retval size of needed mmu table +*/ unsigned int wmt_mmu_table_size(unsigned int size) { unsigned int nPte, nPde, need; @@ -556,42 +733,65 @@ unsigned int wmt_mmu_table_size(unsigned int size) if (!size) return 0; - nPte = (size / PAGE_SIZE) + 2; /* maybe cross page up and down boundary */ - nPde = PAGE_ALIGN(nPte * 4) / PAGE_SIZE; - need = PAGE_ALIGN(nPde * 4); + nPte = ((PAGE_ALIGN(size)) / PAGE_SIZE) + 1; + nPde = ALIGN(nPte, 1024) / 1024; + + need = (ALIGN(nPde, 1024) / 1024) * PAGE_SIZE; need += nPte * 4; - MB_DBG("PDE %d PTE %d RequestSize %d\n", nPde, nPte, need); + printk(KERN_DEBUG "PDE %d PTE %d RequestSize %d\n", nPde, nPte, need); return need; } EXPORT_SYMBOL(wmt_mmu_table_size); +/*!************************************************************************* +* wmt_mmu_table_check +* +* Public Function +*/ +/*! +* \brief +* check pre-allocated mmu table is valid for input size +* +* \parameter +* mmu_addr [IN] mmu table address +* mmu_size [IN] mmu table size +* size [IN] convert size +* +* \retval 1 if success +*/ int wmt_mmu_table_check( - unsigned int mmuPhys, - unsigned int mmuSize, + unsigned int *mmu_addr, + unsigned int mmu_size, unsigned int size) { - int request; + unsigned int nPte, nPde, request; if (!size) { - MB_WARN("mmu table failure. NULL size\n"); + printk(KERN_WARNING "mmu create failure. NULL size\n"); return 0; } - if (!mmuSize) { - MB_WARN("mmu table failure. NULL mmu size\n"); + if (!mmu_size) { + printk(KERN_WARNING "mmu create failure. NULL mmu size\n"); return 0; } - if (mmuPhys % PAGE_SIZE) { - MB_WARN("mmu table failure. PDE Table not align\n"); + if ((unsigned int)mmu_addr % PAGE_SIZE) { + printk(KERN_WARNING "mmu create fail. PDE Table not align\n"); return 0; } - request = wmt_mmu_table_size(size); - if (mmuSize < request) { - MB_WARN("mmu table failure. size %d < %d (request)\n", - mmuSize, request); + nPte = ((PAGE_ALIGN(size)) / PAGE_SIZE) + 1; + nPde = ALIGN(nPte, 1024) / 1024; + + request = (ALIGN(nPde, 1024) / 1024) * PAGE_SIZE; + request += nPte * 4; + + if (mmu_size < request) { + printk(KERN_WARNING "mmu create fail. out of mmu size\n"); + printk(KERN_WARNING "(pde %d pte %d request %d but %d)\n", + nPde, nPte, request, mmu_size); return 0; } @@ -599,254 +799,398 @@ int wmt_mmu_table_check( } EXPORT_SYMBOL(wmt_mmu_table_check); +/*!************************************************************************* +* wmt_mmu_table_dump +* +* Public Function +*/ +/*! +* \brief +* dump mmu table +* +* \parameter +* mmu_addr [IN] mmu table address +* size [IN] convert size +* virBufAddr [IN] offset combination of PDE, PTE, and ADDRESS +* +* \retval none +*/ void wmt_mmu_table_dump(struct mmu_table_info *info) { - unsigned int size, iPde, iPte, addrOffset; - unsigned int *mmuVirt, *pte = NULL, *pde = NULL; + unsigned int *mmu_addr; + unsigned int size; + unsigned int virBufAddr; + unsigned int *pte = NULL, *pde = NULL; + unsigned int pdeOffset, pteOffset, addrOffset, i = 0; if (info == 0) { - MB_ERROR("[WMT_MMU_TABLE] Null input pointer\n"); + printk(KERN_ERR "[WMT_MMU_TABLE] Null input pointer\n"); return; } - mmuVirt = (unsigned int *)mb_phys_to_virt(info->addr); + mmu_addr = (unsigned int *)mb_phys_to_virt(info->addr); size = info->size; - iPte = (info->offset >> 12) % 1024; - iPde = (info->offset >> 22) % 1024; - addrOffset = info->offset % PAGE_SIZE; + virBufAddr = info->offset; + + addrOffset = virBufAddr % PAGE_SIZE; + pteOffset = (virBufAddr >> 12) % 1024; + pdeOffset = (virBufAddr >> 22) % 1024; - MB_INFO("MMU (%x): offset pde %x pte %x addr %x\n", - info->offset, iPde, iPte, addrOffset); + printk(KERN_INFO "MMU (%x): offset pde %x pte %x addr %x\n", + virBufAddr, pdeOffset, pteOffset, addrOffset); + + pde = mmu_addr; + pde += pdeOffset; + pte = mb_phys_to_virt(*pde); + pte += pteOffset; - pde = mmuVirt; - pte = mb_phys_to_virt(pde[iPde]); while (size > 0) { - int pageSize = min((unsigned int)(PAGE_SIZE - addrOffset), size); - MB_INFO("PDE(%p/%#x @ %d) -> PTE(%p/%#x @ %d) -> %#x, s %#x # %#x\n", - pde + iPde, info->addr + iPde * sizeof(pde), iPde, - pte + iPte, pde[iPde] + iPte * sizeof(pte), iPte, - pte[iPte] + addrOffset, pageSize, size); - iPte++; + printk(KERN_INFO "[%5d] PDE(%p/%lx) -> PTE(%p/%lx) -> addr %x\n", + i, pde, mb_virt_to_phys(pde), pte, mb_virt_to_phys(pte), + *pte + addrOffset); + if ((size + addrOffset) < PAGE_SIZE) + break; + size -= PAGE_SIZE - addrOffset; addrOffset = 0; - size -= pageSize; - if (!(iPte % 1024)) { - iPde++; - iPte = 0; - pte = mb_phys_to_virt(pde[iPde]); - } + i++; + pte++; + if (!(i % 1024)) + pde++; } } EXPORT_SYMBOL(wmt_mmu_table_dump); -/* parameter: - mmuPhys [IN] mmu table phys address - mmuSize [IN] mmu table size - addr [IN] physical address of convert data - size [IN] convert size */ +/*!************************************************************************* +* wmt_mmu_table_from_phys +* +* Public Function +*/ +/*! +* \brief +* make up mmu table for physical memory +* +* \parameter +* mmu_addr [IN] mmu table address +* mmu_size [IN] mmu table size +* addr [IN] physical address of convert data +* size [IN] convert size +* +* \retval 0xFFFFFFFF if fail +* offset combination of PDE, PTE, and ADDRESS if success +*/ unsigned int wmt_mmu_table_from_phys( - unsigned int mmuPhys, - unsigned int mmuSize, + unsigned int *mmu_addr, + unsigned int mmu_size, unsigned int addr, unsigned int size) { - unsigned int iPde, iPte, nPte, nPde, virBufAddr; - unsigned int *pte, *pde, *mmuVirt; - int64_t len = size; - void *virt = NULL; + unsigned int iPte, nPte, nPde, gPde, virBufAddr; + unsigned int *pte = NULL, *pde = NULL; - iPde = iPte = nPte = nPde = 0; - if (!wmt_mmu_table_check(mmuPhys, mmuSize, size)) { - MB_WARN("phys %x (size %d) to mmu fail\n", addr, size); + iPte = gPde = nPte = nPde = 0; + if (!wmt_mmu_table_check(mmu_addr, mmu_size, size)) { + printk(KERN_WARNING + "phys %x (size %d) to mmu fail\n", addr, size); return 0xFFFFFFFF; } - virt = mb_phys_to_virt(addr); virBufAddr = addr % PAGE_SIZE; - nPte = size / PAGE_SIZE + 2; - nPde = PAGE_ALIGN(nPte * 4) / PAGE_SIZE; - pde = mmuVirt = mb_phys_to_virt(mmuPhys); - pte = pde + nPde * 1024; - *pde = mmuPhys + nPde * PAGE_SIZE; - MB_DBG("[%s] pde %p/%x # %d pte %p/%x # %d\n", - __func__, pde, mmuPhys, nPde, pte, *pde, nPte); - - while (len > 0) { - pte[iPte] = addr & PAGE_MASK; - iPte++; + nPte = ((PAGE_ALIGN(size)) / PAGE_SIZE); + if (virBufAddr) + nPte++; + nPde = ALIGN(nPte, 1024) / 1024; + gPde = ALIGN(nPde, 1024) / 1024; + + pde = mmu_addr; + pte = pde + (gPde * PAGE_SIZE / sizeof(pte)); + *pde = mb_virt_to_phys(pte); + pde++; + + size += virBufAddr; + while (size > 0) { + *pte = addr & PAGE_MASK; + pte++; iPte++; if (!(iPte % 1024)) { - pde[iPte + 1] = pde[iPte] + PAGE_SIZE; - iPte++; + *pde = mb_virt_to_phys(pte); + pde++; } + if (size < PAGE_SIZE) + break; + size -= PAGE_SIZE; addr += PAGE_SIZE; - len -= PAGE_SIZE; } - dmac_flush_range(virt, virt + size); - outer_flush_range(addr, addr + size); - return virBufAddr; } EXPORT_SYMBOL(wmt_mmu_table_from_phys); -struct mmu_info { + +struct mmu_search_info { + int iPte; + unsigned *pte; + unsigned *pde; unsigned int size; - unsigned int iPte; - unsigned int *pte; - unsigned int *pde; }; -static inline int wmt_mmu_table_proc(struct mmu_info *info, unsigned long phys) +static int wmt_mmu_table_from_user_proc( + void *priv, dma_addr_t phys, int offset) { - int pageSize, offset; - if (!info) { - MB_WARN("WMT MMU process fail. (NULL info)\n"); - return -1; - } - - if (info->size <= 0) { - MB_WARN("WMT MMU process fail. (size %d)\n", info->size); - return -1; - } + struct mmu_search_info *info = (struct mmu_search_info *)priv; - offset = phys % PAGE_SIZE; - pageSize = min((unsigned int)(PAGE_SIZE - offset), info->size); *info->pte = phys & PAGE_MASK; - info->size -= pageSize; - MB_WDBG("\t[PTE] PDE[%d](%p)=%x PTE[%d](%p)=%x size %#x left %#x\n", - info->iPte/1024, info->pde, *info->pde, info->iPte, - info->pte, *info->pte, pageSize, info->size); - info->pte++; + printk(KERN_DEBUG + "\t\t\t[PTE] PDE[%d](%p)=%x PTE[%d](%p)=%x left %d\n", + info->iPte/1024, info->pde, *info->pde, + info->iPte, info->pte, *info->pte, info->size); + info->size -= PAGE_SIZE; + if (info->size < PAGE_SIZE) + return MMU_SEARCH_DONE; info->iPte++; + info->pte++; if (!(info->iPte % 1024)) { *info->pde = mb_virt_to_phys(info->pte); info->pde++; } - return 0; } -/* parameter: - mmuPhys [IN] mmu table phys address - mmuSize [IN] mmu table size - addr [IN] physical address of convert data - size [IN] convert size */ +/*!************************************************************************* +* wmt_mmu_table_from_user +* +* Public Function +*/ +/*! +* \brief +* make up mmu table for user memory +* +* \parameter +* mmu_addr [IN] mmu table address +* mmu_size [IN] mmu table size +* addr [IN] physical address of convert data +* size [IN] convert size +* +* \retval 0xFFFFFFFF if fail +* offset combination of PDE, PTE, and ADDRESS if success +*/ unsigned int wmt_mmu_table_from_user( - unsigned int mmuPhys, - unsigned int mmuSize, + unsigned int *mmu_addr, + unsigned int mmu_size, unsigned int user, unsigned int size) { #ifndef __KERNEL__ - return wmt_mmu_table_from_phys(mmuPhys, mmuSize, user, size); + return wmt_mmu_table_from_phys(mmu_addr, mmu_size, user, size); #else - struct mmu_info info = {0}; - unsigned int nPte, nPde; - unsigned long addr = user; - int offset = user % PAGE_SIZE; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + unsigned long addr, end, offset; + unsigned int nPte, nPde, virBufAddr; + struct mmu_search_info info = {0}; + pgd_t *pgd; + int ret; - if (!wmt_mmu_table_check(mmuPhys, mmuSize, size)) { - printk(KERN_WARNING "user %x (size %d) to mmu fail\n", + nPte = nPde = 0; + if (!wmt_mmu_table_check(mmu_addr, mmu_size, size)) { + printk(KERN_WARNING "phys %x (size %d) to mmu fail\n", user, size); return 0xFFFFFFFF; } - MB_DBG("[%s] Memory(%#x,%#x) MMU(%#x,%d)\n", - __func__, user, size, mmuPhys, mmuSize); - nPte = size / PAGE_SIZE + 2; - nPde = PAGE_ALIGN(nPte * 4) / PAGE_SIZE; - info.size = size; - info.pde = mb_phys_to_virt(mmuPhys); - info.pte = info.pde + nPde * 1024; - *info.pde = mmuPhys + nPde * PAGE_SIZE; - dmac_flush_range((const void *)user, (const void *)(user + size)); + virBufAddr = user % PAGE_SIZE; + nPte = ((PAGE_ALIGN(size)) / PAGE_SIZE); + if (virBufAddr) + nPte++; + nPde = ALIGN(ALIGN(nPte, 1024) / 1024, 1024) / 1024; + + info.pde = mmu_addr; + info.pte = info.pde + (nPde * PAGE_SIZE / sizeof(info.pte)); + *info.pde = mb_virt_to_phys(info.pte); + info.pde++; + + printk(KERN_DEBUG "Memory(%#x,%d)\n", user, size); + down_read(&mm->mmap_sem); + info.size = size + virBufAddr; + addr = (unsigned long)user; while (info.size > 0) { - unsigned long phys = user_to_phys(addr); - int pageSize = min((unsigned int)(PAGE_SIZE - offset), info.size); - if (!phys) { - MB_WARN("user to mmu fail: unknown addr %lx (%x # %x)\n", - addr, user, size); - return -EINVAL; + vma = find_vma(mm, addr); + if (vma == NULL) { + printk(KERN_WARNING + "user addr %lx not found in task %s\n", + addr, current->comm); + goto fault; } - outer_flush_range(phys, phys + pageSize); - wmt_mmu_table_proc(&info, phys); - addr += pageSize; - offset = 0; + printk(KERN_DEBUG + "VMA found: start %lx end %lx\n", + vma->vm_start, vma->vm_end); + offset = addr - vma->vm_start; + addr = vma->vm_start; + end = PAGE_ALIGN(vma->vm_end); + pgd = pgd_offset(mm, vma->vm_start); + ret = mmu_search_pgd(pgd, end, &addr, &offset, + wmt_mmu_table_from_user_proc, &info); + if (ret == MMU_SEARCH_DONE) + break; + if (ret) + goto fault; } - - return user % PAGE_SIZE; + up_read(&mm->mmap_sem); + return virBufAddr; +fault: + printk(KERN_WARNING "USER TO PRDT unfinished, remain size %d\n", size); + up_read(&mm->mmap_sem); + return 0xFFFFFFFF; #endif } EXPORT_SYMBOL(wmt_mmu_table_from_user); -/* parameter: - addr [IN] start address (user or phys depends on addr_type) - size [IN] size of memory - addrType [IN] address type (0: phys 1: user) - info [out] pointer of mmu table info */ +/*!************************************************************************* +* wmt_mmu_table_create +* +* Public Function +*/ +/*! +* \brief +* automatically make up mmu table from giving address +* +* \parameter +* addr [IN] start address (user of phys depends on addr_type) +* size [IN] size of memory +* addr_type [IN] address type (0: phys 1: user) +* info [out] pointer of mmu table info +* +* \retval 0 if success, otherwise error code +*/ unsigned int wmt_mmu_table_create( unsigned int addr, unsigned int size, - unsigned int addrType, + unsigned int addr_type, struct mmu_table_info *info) { - int i, nPde, nPte, *pde, mmuSize; + unsigned int mmuSize = 0; unsigned int *mmuAddr = NULL; - if (!addr || !size || !info || addrType > 1) { - MB_ERROR("[WMT_MMU_TABLE] invalid args:\n"); - MB_ERROR("\t addr %x # %x type %x info %p\n", - addr, size, addrType, info); + if (!addr || !size || !info || addr_type > 1) { + printk(KERN_ERR "[WMT_MMU_TABLE] invalid args:\n"); + printk(KERN_ERR "\t addr %x # %x type %x info %p\n", + addr, size, addr_type, info); return -EINVAL; } mmuSize = wmt_mmu_table_size(size); + info->addr = mb_alloc(mmuSize); - info->size = size; - MB_DBG("[%s] mmu table (%#x # %#x) addr %#x size %#x type %d\n", - __func__, info->addr, mmuSize, addr, size, addrType); if (!info->addr) { - MB_ERROR("[%s] fail. Out of MB (%d)\n", __func__, mmuSize); + printk(KERN_ERR "[WMT_MMU_TABLE] create fail. Out of MB (%d)\n", + mmuSize); return -ENOMEM; } + info->size = size; + mmuAddr = (unsigned int *)mb_phys_to_virt(info->addr); - pde = mmuAddr = (unsigned int *)mb_phys_to_virt((unsigned long)info->addr); - memset(mmuAddr, 0x0, mmuSize); - nPte = (size / PAGE_SIZE) + 2; /* maybe cross page up and down boundary */ - nPde = PAGE_ALIGN(nPte * 4) / PAGE_SIZE; - for (i = 1; i <= nPde; i++, pde++) - *pde = info->addr + i * PAGE_SIZE; - info->offset = (addrType) ? - wmt_mmu_table_from_user(info->addr, mmuSize, addr, size) : - wmt_mmu_table_from_phys(info->addr, mmuSize, addr, size); + info->offset = (addr_type) ? + wmt_mmu_table_from_user(mmuAddr, mmuSize, addr, size) : + wmt_mmu_table_from_phys(mmuAddr, mmuSize, addr, size); if (info->offset == 0xFFFFFFFF) { - MB_ERROR("[WMT_MMU_TABLE] create fail:"); - MB_ERROR("\ttype %x addr %x # %x mmuAddr %p/%x # %d\n", - addrType, addr, size, mmuAddr, info->addr, info->size); - mb_free(info->addr); + printk(KERN_ERR "[WMT_MMU_TABLE] create fail:"); + printk(KERN_ERR "\ttype %x addr %x # %x mmuAddr %p/%x # %d\n", + addr_type, addr, size, mmuAddr, info->addr, mmuSize); return -EFAULT; } - MB_DBG("[%s] success! (addr %#x size %#x offset %#x)\n", - __func__, info->addr, info->size, info->offset); return 0; } EXPORT_SYMBOL(wmt_mmu_table_create); +/*!************************************************************************* +* wmt_mmu_table_destroy +* +* Public Function +*/ +/*! +* \brief +* automatically make up mmu table from giving address +* +* \parameter +* info [IN] start address (user of phys depends on addr_type) +* +* \retval 1 if success +*/ unsigned int wmt_mmu_table_destroy(struct mmu_table_info *info) { if (!info) { - MB_ERROR("[WMT_MMU_TABLE] destroy fail. NULL mmu table info"); + printk(KERN_ERR "[WMT_MMU_TABLE] destroy fail. NULL mmu table info"); return -EINVAL; } - MB_DBG("[%s] success! addr %#x\n", __func__, info->addr); mb_free(info->addr); return 0; } EXPORT_SYMBOL(wmt_mmu_table_destroy); +/* return address is guaranteeed only under page alignment */ +void *user_to_virt(unsigned long user) +{ + struct vm_area_struct *vma; + unsigned long flags; + void *virt = NULL; + + spin_lock_irqsave(&mb_task_mm_lock, flags); + vma = find_vma(current->mm, user); + /* For kernel direct-mapped memory, take the easy way */ + if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff)) { + unsigned long phys = 0; + /* kernel-allocated, mmaped-to-usermode addresses */ + phys = (vma->vm_pgoff << PAGE_SHIFT) + (user - vma->vm_start); + virt = __va(phys); + MB_INFO("%s kernel-alloc, user-mmaped addr U %lx V %p P %lx", + __func__, user, virt, phys); + } else { + /* otherwise, use get_user_pages() for general userland pages */ + int res, nr_pages = 1; + struct page *pages; + down_read(¤t->mm->mmap_sem); + res = get_user_pages(current, current->mm, + user, nr_pages, 1, 0, &pages, NULL); + up_read(¤t->mm->mmap_sem); + if (res == nr_pages) + virt = page_address(&pages[0]) + (user & ~PAGE_MASK); + MB_INFO("%s userland addr U %lx V %p", __func__, user, virt); + } + spin_unlock_irqrestore(&mb_task_mm_lock, flags); + + return virt; +} +EXPORT_SYMBOL(user_to_virt); + +int user_to_prdt( + unsigned long user, + unsigned int size, + struct prdt_struct *next, + unsigned int items) +{ + int ret; + + switch (USR2PRDT_METHOD) { + case 1: + ret = __user_to_prdt1(user, size, next, items); + break; + case 2: + ret = __user_to_prdt2(user, size, next, items); + break; + default: + ret = __user_to_prdt(user, size, next, items); + break; + } + + if (MBMSG_LEVEL > 1) + show_prdt(next); + + return ret; +} +EXPORT_SYMBOL(user_to_prdt); + static int mb_show_mb( struct mb_struct *mb, char *msg, @@ -2510,147 +2854,6 @@ RESCAN_MBA: spin_unlock_irqrestore(&mb_ioctl_lock, flags); return 0; - /* _IOW(MB_IOC_MAGIC, 19, unsigned long) // I: phys address */ - case MBIO_STATIC_GET: - get_user(value, (unsigned long *)arg); - if (!value || !mbti->task_name || tgid == MB_DEF_TGID) { - MB_WARN("GET(STATIC): invalid args %lx/%d/%s\n", - value, tgid, mbti->task_name); - return -EINVAL; - } - - ret = mb_do_get(value, MB_DEF_TGID, mbti->task_name); - if (ret != 0) - MB_WARN("GET(STATIC): fail (args %lx/%d/%s). ret %d\n", - value, tgid, mbti->task_name, ret); - MB_OPDBG("GET(STATIC): phys %8lx done\n\n", value); - break; - - /* _IOW(MB_IOC_MAGIC, 20, unsigned long) // I: phys address */ - case MBIO_STATIC_PUT: - get_user(value, (unsigned long *)arg); - if (!value || !mbti->task_name || tgid == MB_DEF_TGID) { - MB_WARN("PUT(STATIC): invalid args %lx/%d/%s\n", - value, tgid, mbti->task_name); - return -EINVAL; - } - - ret = mb_do_put(value, MB_DEF_TGID, mbti->task_name); - if (ret != 0) - MB_WARN("PUT(STATIC): fail (args %lx/%d/%s). ret %d\n", - value, tgid, mbti->task_name, ret); - MB_OPDBG("PUT(STATIC): phys %8lx done\n\n", value); - break; - - /* _IOWR(MB_IOC_MAGIC, 100, unsigned long) - I: user address O: physical address */ - case MBIO_TEST_USER2PHYS: - get_user(value, (unsigned long *)arg); - if (!value) { - MB_WARN("USER2PHYS: invalid args %lx/%d/%s\n", - value, tgid, mbti->task_name); - return -EINVAL; - } - phys = user_to_phys(value); - put_user(phys, (unsigned long *)arg); - if (!phys) - MB_WARN("USER2PHYS fail: value %#lx phys %#lx\n", value, phys); - break; - - /* _IOWR(MB_IOC_MAGIC, 101, unsigned long) - I: user address, size, prdt addr, and prdt size */ - case MBIO_TEST_USER2PRDT: - /* _IOW(MB_IOC_MAGIC, 103, unsigned long) - * I: user address, size, prdt addr, and prdt size */ - case MBIO_TEST_MB2PRDT: { - int items, type = (cmd == MBIO_TEST_MB2PRDT) ? 0 : 1; - unsigned long size, data[4] = {0}; - struct prdt_struct *prdt; - copy_from_user(data, (const void *)arg, 4 * sizeof(unsigned long)); - if (!data[0] || !data[1] || !data[2] || !data[3]) { - MB_WARN("%s: invalid args [%#lx, %#lx, %#lx, %#lx]\n", - type ? "MB2PRDT" : "USER2PRDT", - data[0], data[1], data[2], data[3]); - return -EINVAL; - } - items = data[1] / PAGE_SIZE + 2; - size = items * sizeof(struct prdt_struct); - if (data[3] < size) { - MB_WARN("%s: invalid args. prdt size %#lx < %#lx\n", - type ? "MB2PRDT" : "USER2PRDT", data[3], size); - return -EINVAL; - } - prdt = kmalloc(size, GFP_ATOMIC); - if (prdt == NULL) { - MB_WARN("%s: fail, no prdt space %d for size %ld\n", - type ? "MB2PRDT" : "USER2PRDT", - items * sizeof(struct prdt_struct), data[1]); - return -EINVAL; - } - MB_DBG("%s: IN %#lx, %#lx, %#lx, %#lx\n", - type ? "MB2PRDT" : "USER2PRDT", - data[0], data[1], data[2], data[3]); - memset(prdt, 0x0, items * sizeof(struct prdt_struct)); - if ((!type && !mb_to_prdt(data[0], data[1], prdt, items)) || - (!user_to_prdt(data[0], data[1], prdt, items))) { - if (MBMSG_LEVEL) - show_prdt(prdt); - copy_to_user((void __user *)data[2], prdt, size); - MB_INFO("%s: Done %#lx, %#lx, %#lx, %#lx\n", - type ? "MB2PRDT" : "USER2PRDT", - data[0], data[1], data[2], data[3]); - } else { - MB_WARN("%s: fail.\n", type ? "MB2PRDT" : "USER2PRDT"); - ret = -EINVAL; - } - kfree(prdt); - break; - } - - /* _IOWR(MB_IOC_MAGIC, 102, unsigned long) - I: user address, size, mmu addr, and mmu size O: mmu physical addr */ - case MBIO_TEST_USER2MMUT: - /* _IOWR(MB_IOC_MAGIC, 104, unsigned long) - I: user address, size, mmu addr, and mmu size O: mmu physical addr */ - case MBIO_TEST_MB2MMUT: { - int type = (cmd == MBIO_TEST_MB2MMUT) ? 0 : 1; - unsigned long mmuSize, data[4] = {0}; - struct mmu_table_info info = {0}; - copy_from_user(data, (const void *)arg, 4 * sizeof(unsigned long)); - if (!data[0] || !data[1] || !data[2] || !data[3]) { - MB_WARN("%s: invalid args [%#lx, %#lx, %#lx, %#lx]\n", - type ? "USER2MMUT" : "PHYS2MMUT", - data[0], data[1], data[2], data[3]); - return -EINVAL; - } - mmuSize = wmt_mmu_table_size(data[1]); - if (data[3] < mmuSize) { - MB_WARN("%s: invalid args. mmu size %#lx < %#lx\n", - type ? "MB2PRDT" : "USER2PRDT", data[3], mmuSize); - return -EINVAL; - } - MB_DBG("%s: IN %#lx, %#lx, %#lx, %#lx(req %#lx)\n", - type ? "USER2MMUT" : "PHYS2MMUT", - data[0], data[1], data[2], data[3], mmuSize); - if (wmt_mmu_table_create(data[0], data[1], type, &info) == 0) { - void *mmuAddr = mb_phys_to_virt((unsigned long)info.addr); - if (MBMSG_LEVEL) - wmt_mmu_table_dump(&info); - copy_to_user((void __user *)data[2], mmuAddr, mmuSize); - put_user(info.addr, (unsigned long *)arg); - ret = mb_do_get(info.addr, MB_DEF_TGID, mbti->task_name); - wmt_mmu_table_destroy(&info); - MB_INFO("%s: Done %#lx, %#lx, %#lx, %#lx\n", - type ? "USER2MMUT" : "PHYS2MMUT", - data[0], data[1], data[2], data[3]); - } else { - MB_WARN("%s: fail. no mmu table space for size %ld\n", - type ? "USER2MMUT" : "PHYS2MMUT", data[1]); - return -EINVAL; - } - break; - } - default: ret = -ENOTTY; break; diff --git a/drivers/video/wmt/wmt-sync.c b/drivers/video/wmt/wmt-sync.c index 2bc39edd..cc4136dc 100755..100644 --- a/drivers/video/wmt/wmt-sync.c +++ b/drivers/video/wmt/wmt-sync.c @@ -58,7 +58,7 @@ static DECLARE_WAIT_QUEUE_HEAD(wmt_sync_wait); static struct class *wmt_sync_class; static int wmt_sync_major; unsigned int wmt_vsync_flag; -enum vpp_int_t wmt_sync_type; + int wmt_sync_set_vsync(void *arg) { wmt_vsync_flag++; @@ -72,20 +72,21 @@ static int wmt_sync_open( struct file *filp ) { - struct govrh_mod_t *govr; + int ret = 0; + vpp_int_t type; DBG_MSG("\n"); down(&wmt_sync_sem); - - /* non-dual use govrh2, because HDMI should slow down */ - govr = vout_info_get_govr((g_vpp.virtual_display) ? 1 : 0); - wmt_sync_type = (govr->mod == VPP_MOD_GOVRH) ? + if (g_vpp.dual_display) { + type = (vout_info[0].govr_mod == VPP_MOD_GOVRH) ? VPP_INT_GOVRH_VBIS : VPP_INT_GOVRH2_VBIS; - vpp_irqproc_work(wmt_sync_type, wmt_sync_set_vsync, 0, 0, 0); - + } else { + type = VPP_INT_GOVRH2_VBIS; /* HDMI should slow down */ + } + vpp_irqproc_work(type, wmt_sync_set_vsync, 0, 0, 0); up(&wmt_sync_sem); - return 0; + return ret; } /* End of wmt_sync_open() */ static int wmt_sync_release( @@ -93,12 +94,17 @@ static int wmt_sync_release( struct file *filp ) { + int ret = 0; + vpp_int_t type; + DBG_MSG("\n"); down(&wmt_sync_sem); - vpp_irqproc_del_work(wmt_sync_type, wmt_sync_set_vsync); + type = (vout_info[0].govr_mod == VPP_MOD_GOVRH) ? + VPP_INT_GOVRH_VBIS : VPP_INT_GOVRH2_VBIS; + vpp_irqproc_del_work(type, wmt_sync_set_vsync); up(&wmt_sync_sem); - return 0; + return ret; } /* End of wmt_sync_release() */ static long wmt_sync_ioctl(struct file *filp, unsigned int cmd, @@ -156,7 +162,7 @@ static ssize_t wmt_sync_read( retval = wait_event_interruptible(wmt_sync_wait, data); if (retval == 0) retval = put_user(data, (unsigned int __user *)buf); -read_end: +read_end: up(&wmt_sync_sem); return retval; } /* wmt_sync_read */ diff --git a/drivers/video/wmt/wmtfb.c b/drivers/video/wmt/wmtfb.c index 72029bbc..bac0973f 100755..100644 --- a/drivers/video/wmt/wmtfb.c +++ b/drivers/video/wmt/wmtfb.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/wmtfb.c * WonderMedia frame buffer driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * 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 @@ -56,7 +56,7 @@ /* int fbut_xxx; *//*Example*/ static struct fb_fix_screeninfo wmtfb_fix = { - .id = "wmtfbx", + .id = "wmtfb", .smem_start = 0, .smem_len = 0, .type = FB_TYPE_PACKED_PIXELS, @@ -66,16 +66,16 @@ static struct fb_fix_screeninfo wmtfb_fix = { .ypanstep = 1, .ywrapstep = 1, .line_length = 0, - .mmio_start = 0, - .mmio_len = 0, + .mmio_start = 0xD8050000, + .mmio_len = 0x0700, .accel = FB_ACCEL_NONE }; static struct fb_var_screeninfo wmtfb_var = { - .xres = 0, - .yres = 0, - .xres_virtual = 0, - .yres_virtual = 0, + .xres = VPP_HD_DISP_RESX, + .yres = VPP_HD_DISP_RESY, + .xres_virtual = VPP_HD_DISP_RESX, + .yres_virtual = VPP_HD_DISP_RESY, #if 0 .bits_per_pixel = 32, .red = {16, 8, 0}, @@ -92,7 +92,7 @@ static struct fb_var_screeninfo wmtfb_var = { .activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE, .height = -1, .width = -1, - .pixclock = 0, + .pixclock = (VPP_HD_DISP_RESX*VPP_HD_DISP_RESY*VPP_HD_DISP_FPS), .left_margin = 40, .right_margin = 24, .upper_margin = 32, @@ -102,7 +102,7 @@ static struct fb_var_screeninfo wmtfb_var = { .vmode = FB_VMODE_NONINTERLACED }; -int wmtfb_probe_ready; +int wmtfb_fb1_probe; /*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ /* void fbut_xxx(void); *//*Example*/ @@ -111,14 +111,12 @@ int wmtfb_probe_ready; #ifdef DEBUG void wmtfb_show_var(char *str, struct fb_var_screeninfo *var) { - int pixclk; - - pixclk = (var->pixclock) ? (PICOS2KHZ(var->pixclock) * 1000) : 0; DPRINT("----- %s ------------------------\n", str); DPRINT("res(%d,%d),vir(%d,%d),offset(%d,%d)\n", var->xres, var->yres, var->xres_virtual, var->yres_virtual, var->xoffset, var->yoffset); - DPRINT("pixclk %d(%d),hsync %d,vsync %d\n", var->pixclock, pixclk, + DPRINT("pixclk %d(%d),hsync %d,vsync %d\n", var->pixclock, + (int)(PICOS2KHZ(var->pixclock) * 1000), var->hsync_len, var->vsync_len); DPRINT("left %d,right %d,upper %d,lower %d\n", var->left_margin, var->right_margin, var->upper_margin, var->lower_margin); @@ -132,30 +130,1448 @@ void wmtfb_show_var(char *str, struct fb_var_screeninfo *var) } #endif -static DEFINE_SEMAPHORE(vpp_sem); -static DEFINE_SEMAPHORE(vpp_sem2); -void wmtfb_set_mutex(struct fb_info *info, int lock) +#ifdef CONFIG_PROC_FS +#define CONFIG_VPP_PROC +#ifdef CONFIG_VPP_PROC +unsigned int vpp_proc_value; +char vpp_proc_str[16]; +static ctl_table vpp_table[]; +static int vpp_do_proc(ctl_table *ctl, int write, + void *buffer, size_t *len, loff_t *ppos) { - struct vout_info_t *par = (struct vout_info_t *) info->par; + int ret; + int ctl_name; - if (lock) - down(&par->sem); - else - up(&par->sem); + ctl_name = (((int)ctl - (int)vpp_table) / sizeof(ctl_table)) + 1; + if (!write) { + switch (ctl_name) { + case 1: + vpp_proc_value = g_vpp.dbg_msg_level; + break; + case 2: + vpp_proc_value = g_vpp.dbg_wait; + break; + case 3: + vpp_proc_value = g_vpp.dbg_flag; + break; + case 8: + case 9: + vpp_proc_value = vpp_get_base_clock((ctl_name == 8) ? + VPP_MOD_GOVRH : VPP_MOD_GOVRH2); + break; + case 10: + vpp_proc_value = p_scl->scale_mode; + break; + case 11: + vpp_proc_value = p_scl->filter_mode; + break; +#ifdef CONFIG_WMT_HDMI + case 12: + vpp_proc_value = g_vpp.hdmi_cp_enable; + break; + case 13: + vpp_proc_value = g_vpp.hdmi_3d_type; + break; + case 14: + vpp_proc_value = g_vpp.hdmi_certify_flag; + break; +#endif + case 15: + vpp_proc_value = govrh_get_brightness(p_govrh); + break; + case 16: + vpp_proc_value = govrh_get_contrast(p_govrh); + break; + case 17: + vpp_proc_value = govrh_get_saturation(p_govrh); + break; + default: + break; + } + } + + ret = proc_dointvec(ctl, write, buffer, len, ppos); + if (write) { + switch (ctl_name) { + case 1: + DPRINT("---------- VPP debug level ----------\n"); + DPRINT("0-disable,255-show all\n"); + DPRINT("1-scale,2-disp fb,3-interrupt,4-timer\n"); + DPRINT("5-ioctl,6-diag,7-stream\n"); + DPRINT("-------------------------------------\n"); + g_vpp.dbg_msg_level = vpp_proc_value; + break; + case 2: + g_vpp.dbg_wait = vpp_proc_value; + vpp_dbg_wake_up(); + break; + case 3: + g_vpp.dbg_flag = vpp_proc_value; + break; +#ifdef CONFIG_WMT_EDID + case 6: + { + vout_t *vo; + + vo = vout_get_entry_adapter(vpp_proc_value); + if ((vo->inf) && (vo->inf->get_edid)) { + vo->status &= ~VPP_VOUT_STS_EDID; + if (vout_get_edid(vo->num)) { + int i; + + vo->edid_info.option = 0; + edid_dump(vo->edid); + for (i = 1; i <= vo->edid[126]; i++) + edid_dump(vo->edid + 128 * i); + if (!edid_parse(vo->edid, + &vo->edid_info)) + DBG_ERR("parse EDID\n"); + } else { + DBG_ERR("read EDID\n"); + } + } + } + break; +#endif + case 8: + case 9: + govrh_set_clock((ctl_name == 8) ? p_govrh : p_govrh2, + vpp_proc_value); + DPRINT("set govr pixclk %d\n", vpp_proc_value); + break; + case 10: + DPRINT("---------- scale mode ----------\n"); + DPRINT("0-recursive normal\n"); + DPRINT("1-recursive sw bilinear\n"); + DPRINT("2-recursive hw bilinear\n"); + DPRINT("3-realtime noraml (quality but x/32 limit)\n"); + DPRINT("4-realtime bilinear (fit edge w skip line)\n"); + DPRINT("-------------------------------------\n"); + p_scl->scale_mode = vpp_proc_value; + break; + case 11: + p_scl->filter_mode = vpp_proc_value; + break; +#ifdef CONFIG_WMT_HDMI + case 12: + g_vpp.hdmi_cp_enable = vpp_proc_value; + hdmi_set_cp_enable(vpp_proc_value); + break; + case 13: + g_vpp.hdmi_3d_type = vpp_proc_value; + hdmi_tx_vendor_specific_infoframe_packet(); + break; + case 14: + g_vpp.hdmi_certify_flag = vpp_proc_value; + break; +#endif + case 15: + govrh_set_brightness(p_govrh, vpp_proc_value); + break; + case 16: + govrh_set_contrast(p_govrh, vpp_proc_value); + break; + case 17: + govrh_set_saturation(p_govrh, vpp_proc_value); + break; + default: + break; + } + } + return ret; } -int vpp_set_blank(struct fb_info *info, int blank) +struct proc_dir_entry *vpp_proc_dir; +static ctl_table vpp_table[] = { + { /* .ctl_name = 1, */ + .procname = "dbg_msg", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 2, */ + .procname = "dbg_wait", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 3, */ + .procname = "dbg_flag", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 4, */ + .procname = "edid_disable", + .data = &edid_disable, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 5, */ + .procname = "edid_msg", + .data = &edid_msg_enable, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 6, */ + .procname = "vout_edid", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 7, */ + .procname = "vo_mode", + .data = vpp_proc_str, + .maxlen = 12, + .mode = 0666, + .proc_handler = &proc_dostring, + }, + { /* .ctl_name = 8, */ + .procname = "govr1_pixclk", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 9, */ + .procname = "govr2_pixclk", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 10, */ + .procname = "scl_scale_mode", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 11, */ + .procname = "scl_filter", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 12 */ + .procname = "hdmi_cp_enable", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 13 */ + .procname = "hdmi_3d", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 14 */ + .procname = "hdmi_certify", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 15 */ + .procname = "brightness", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 16 */ + .procname = "contrast", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* .ctl_name = 17 */ + .procname = "saturation", + .data = &vpp_proc_value, + .maxlen = sizeof(int), + .mode = 0666, + .proc_handler = &vpp_do_proc, + }, + { /* end of table */ + } +}; + +static ctl_table vpp_root_table[] = { + { + .procname = "vpp", /* create path ==> /proc/sys/vpp */ + .mode = 0555, + .child = vpp_table + }, + { /* end of table */ + } +}; +static struct ctl_table_header *vpp_table_header; +#endif + +static int vpp_sts_read_proc(char *buf, char **start, off_t offset, + int len, int *eof, void *data) { - struct vout_info_t *par = (struct vout_info_t *) info->par; + volatile struct govrh_regs *regs = + (volatile struct govrh_regs *) REG_GOVRH_BASE1_BEGIN; + unsigned int yaddr, caddr; + char *p = buf; + unsigned int reg; + + p += sprintf(p, "--- VPP HW status ---\n"); +#ifdef WMT_FTBLK_GOVRH + p += sprintf(p, "GOVRH memory read underrun error %d,cnt %d,cnt2 %d\n", + (regs->interrupt.val & 0x200) ? 1 : 0, + p_govrh->underrun_cnt, p_govrh2->underrun_cnt); + p_govrh->clr_sts(VPP_INT_ALL); +#endif + +#ifdef WMT_FTBLK_SCL + p += sprintf(p, "---------------------------------------\n"); + p += sprintf(p, "SCL TG error %d\n", + vppif_reg32_read(SCL_INTSTS_TGERR)); + p += sprintf(p, "SCLR MIF1 read error %d\n", + vppif_reg32_read(SCLR_INTSTS_R1MIFERR)); + p += sprintf(p, "SCLR MIF2 read error %d\n", + vppif_reg32_read(SCLR_INTSTS_R2MIFERR)); + p += sprintf(p, "SCLW RGB fifo overflow %d\n", + vppif_reg32_read(SCLW_INTSTS_MIFRGBERR)); + p += sprintf(p, "SCLW Y fifo overflow %d\n", + vppif_reg32_read(SCLW_INTSTS_MIFYERR)); + p += sprintf(p, "SCLW C fifo overflow %d\n", + vppif_reg32_read(SCLW_INTSTS_MIFCERR)); + p_scl->clr_sts(VPP_INT_ALL); +#endif + + p += sprintf(p, "---------------------------------------\n"); + p += sprintf(p, "(880.0)GOVRH Enable %d,(900.0)TG %d\n", + regs->mif.b.enable, regs->tg_enable.b.enable); + + reg = REG32_VAL(PM_CTRL_BASE_ADDR + 0x258); + p += sprintf(p, "--- POWER CONTROL ---\n"); + p += sprintf(p, "0x%x = 0x%x\n", PM_CTRL_BASE_ADDR + 0x258, reg); + p += sprintf(p, "HDCP %d,VPP %d,SCL %d,HDMI I2C %d\n", + (reg & BIT7) ? 1 : 0, (reg & BIT18) ? 1 : 0, + (reg & BIT21) ? 1 : 0, (reg & BIT22) ? 1 : 0); + p += sprintf(p, "HDMI %d,GOVR %d,NA12 %d\n", + (reg & BIT23) ? 1 : 0, (reg & BIT25) ? 1 : 0, + (reg & BIT16) ? 1 : 0); + p += sprintf(p, "DVO %d,HDMI OUT %d,LVDS %d\n", (reg & BIT29) ? 1 : 0, + (reg & BIT30) ? 1 : 0, (reg & BIT14) ? 1 : 0); + + p += sprintf(p, "--- VPP fb Address ---\n"); + p += sprintf(p, "GOV mb 0x%x 0x%x\n", g_vpp.mb[0], g_vpp.mb[1]); + +#ifdef WMT_FTBLK_GOVRH + govrh_get_fb_addr(p_govrh, &yaddr, &caddr); + p += sprintf(p, "GOVRH fb addr Y(0x%x) 0x%x, C(0x%x) 0x%x\n", + REG_GOVRH_YSA, yaddr, REG_GOVRH_CSA, caddr); + govrh_get_fb_addr(p_govrh2, &yaddr, &caddr); + p += sprintf(p, "GOVRH2 fb addr Y(0x%x) 0x%x, C(0x%x) 0x%x\n", + REG_GOVRH2_YSA, yaddr, REG_GOVRH2_CSA, caddr); +#endif + p_govrh->underrun_cnt = 0; + p_govrh2->underrun_cnt = 0; + return p - buf; +} /* End of vpp_sts_read_proc */ + +static int vpp_reg_read_proc(char *buf, char **start, off_t offset, + int len, int *eof, void *data) +{ + char *p = buf; + vpp_mod_base_t *mod_p; int i; - DBG_MSG("(%d,%d)\n", info->node, blank); + DPRINT("Product ID:0x%x\n", vpp_get_chipid()); + for (i = 0; i < VPP_MOD_MAX; i++) { + mod_p = vpp_mod_get_base(i); + if (mod_p && mod_p->dump_reg) + mod_p->dump_reg(); + } +#ifdef WMT_FTBLK_HDMI + hdmi_reg_dump(); +#endif +#ifdef WMT_FTBLK_LVDS + lvds_reg_dump(); +#endif + return p - buf; +} /* End of vpp_reg_read_proc */ +#endif + +/*----------------------- fb ioctl --------------------------------------*/ +int vpp_common_ioctl(unsigned int cmd, unsigned long arg) +{ + vpp_mod_base_t *mod_p; + vpp_fb_base_t *mod_fb_p; + int retval = 0; + + switch (cmd) { + case VPPIO_VPPGET_INFO: + { + int i; + vpp_cap_t parm; + + parm.chip_id = vpp_get_chipid(); + parm.version = 0x01; + parm.resx_max = VPP_HD_MAX_RESX; + parm.resy_max = VPP_HD_MAX_RESY; + parm.pixel_clk = 400000000; + parm.module = 0x0; + for (i = 0; i < VPP_MOD_MAX; i++) { + mod_p = vpp_mod_get_base(i); + if (mod_p) + parm.module |= (0x01 << i); + } + parm.option = VPP_CAP_DUAL_DISPLAY; + copy_to_user((void *)arg, (void *) &parm, sizeof(vpp_cap_t)); + } + break; + case VPPIO_VPPSET_INFO: + { + vpp_cap_t parm; + + copy_from_user((void *)&parm, (const void *)arg, + sizeof(vpp_cap_t)); + } + break; + case VPPIO_I2CSET_BYTE: + { + vpp_i2c_t parm; + unsigned int id; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_i2c_t)); + id = (parm.addr & 0x0000FF00) >> 8; + vpp_i2c_write(id, (parm.addr & 0xFF), parm.index, + (char *)&parm.val, 1); + } + break; + case VPPIO_I2CGET_BYTE: + { + vpp_i2c_t parm; + unsigned int id; + int len; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_i2c_t)); + id = (parm.addr & 0x0000FF00) >> 8; + len = parm.val; + { + unsigned char buf[len]; + + vpp_i2c_read(id, (parm.addr & 0xFF), parm.index, + buf, len); + parm.val = buf[0]; + } + copy_to_user((void *)arg, (void *) &parm, sizeof(vpp_i2c_t)); + } + break; + case VPPIO_VPPSET_FBDISP: + break; + case VPPIO_VPPGET_FBDISP: + { + vpp_dispfb_info_t parm; + copy_to_user((void *)arg, (void *) &parm, + sizeof(vpp_dispfb_info_t)); + } + break; + case VPPIO_WAIT_FRAME: + vpp_wait_vsync(0, arg); + break; + case VPPIO_MODULE_FRAMERATE: + { + vpp_mod_arg_t parm; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_mod_arg_t)); + mod_fb_p = vpp_mod_get_fb_base(parm.mod); + if (!mod_fb_p) + break; + if (parm.read) { + parm.arg1 = mod_fb_p->framerate; + copy_to_user((void *)arg, (void *) &parm, + sizeof(vpp_mod_arg_t)); + } else { + mod_fb_p->framerate = parm.arg1; + } + } + break; + case VPPIO_MODULE_ENABLE: + { + vpp_mod_arg_t parm; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_mod_arg_t)); + mod_p = vpp_mod_get_base(parm.mod); + if (!mod_p) + break; + + if (parm.read) { + /* not used */ + } else { + mod_p->set_enable(parm.arg1); +#ifdef WMT_FTBLK_GOVRH_CURSOR + if (parm.mod == VPP_MOD_CURSOR) { + p_cursor->enable = parm.arg1; + if (p_cursor->enable) { + vpp_irqproc_work(VPP_INT_GOVRH_PVBI, + (void *)govrh_CUR_irqproc, 0, + 0, 0); + } else { + vpp_irqproc_del_work(VPP_INT_GOVRH_PVBI, + (void *)govrh_CUR_irqproc); + } + } +#endif + } + } + break; + case VPPIO_MODULE_TIMING: + DPRINT("remove for new arch\n"); + break; + case VPPIO_MODULE_FBADDR: + { + vpp_mod_arg_t parm; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_mod_arg_t)); + mod_fb_p = vpp_mod_get_fb_base(parm.mod); + if (!mod_fb_p) + break; + mod_p = vpp_mod_get_base(parm.mod); + if (parm.read) { + mod_fb_p->get_addr(&parm.arg1, &parm.arg2); + copy_to_user((void *)arg, (void *) &parm, + sizeof(vpp_mod_arg_t)); + } else { + mod_fb_p->set_addr(parm.arg1, parm.arg2); + } + } + break; + case VPPIO_MODULE_FBINFO: + { + vpp_mod_fbinfo_t parm; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_mod_fbinfo_t)); + + if (g_vpp.virtual_display) + parm.mod = (hdmi_get_plugin()) ? + VPP_MOD_GOVRH : VPP_MOD_GOVRH2; + mod_fb_p = vpp_mod_get_fb_base(parm.mod); + if (!mod_fb_p) + break; + mod_p = vpp_mod_get_base(parm.mod); + if (parm.read) { + parm.fb = mod_fb_p->fb; + switch (parm.mod) { + case VPP_MOD_GOVRH: + case VPP_MOD_GOVRH2: + govrh_get_framebuffer((govrh_mod_t *)mod_p, + &parm.fb); + break; + default: + break; + } + copy_to_user((void *)arg, (void *) &parm, + sizeof(vpp_mod_fbinfo_t)); + } else { + mod_fb_p->fb = parm.fb; + mod_fb_p->set_framebuf(&parm.fb); + + if (g_vpp.virtual_display) { +#ifdef CONFIG_VPP_STREAM_CAPTURE + if (g_vpp.stream_enable) + vpp_mb_scale_bitblit(&mod_fb_p->fb); + else +#endif + { + if(g_vpp.mb[0] != 0) + vpp_free_framebuffer(); + } + + if (vpp_check_dbg_level(VPP_DBGLVL_FPS)) + vpp_dbg_timer( + &vout_info[1].pandisp_timer, + "fbinfo", 2); + } + } + } + break; + case VPPIO_MODULE_VIEW: + { + vpp_mod_view_t parm; + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_mod_view_t)); + + mod_fb_p = vpp_mod_get_fb_base(parm.mod); + if (!mod_fb_p) + break; + mod_p = vpp_mod_get_base(parm.mod); + if (parm.read) { + mod_fb_p->fn_view(VPP_FLAG_RD, &parm.view); + copy_to_user((void *)arg, (void *) &parm, + sizeof(vpp_mod_view_t)); + } else { + mod_fb_p->fn_view(0, &parm.view); + } + } + break; +#ifdef CONFIG_VPP_STREAM_CAPTURE + case VPPIO_STREAM_ENABLE: + g_vpp.stream_enable = arg; + g_vpp.stream_mb_sync_flag = 0; + + MSG("[VPP] VPPIO_STREAM_ENABLE %d\n", g_vpp.stream_enable); +#ifdef CONFIG_VPP_STREAM_FIX_RESOLUTION + memset(&g_vpp.stream_fb, 0, sizeof(vdo_framebuf_t)); + g_vpp.stream_fb.img_w = 1280; + g_vpp.stream_fb.img_h = 720; + g_vpp.stream_fb.fb_w = + vpp_calc_align(g_vpp.stream_fb.img_w, 64); + g_vpp.stream_fb.fb_h = g_vpp.stream_fb.img_h; + g_vpp.stream_fb.bpp = 16; + g_vpp.stream_fb.col_fmt = VDO_COL_FMT_YUV422H; + g_vpp.stream_fb.y_size = g_vpp.stream_fb.fb_w * + g_vpp.stream_fb.fb_h; + g_vpp.stream_fb.c_size = g_vpp.stream_fb.fb_w * + g_vpp.stream_fb.fb_h; +#endif +#ifdef CONFIG_VPP_STREAM_ROTATE + g_vpp.stream_mb_lock= 0; + g_vpp.stream_mb_index = 0xFF; + vpp_netlink_notify(WP_PID, DEVICE_STREAM, + (g_vpp.stream_enable) ? 1 : 0); +#else +#ifndef CONFIG_VPP_DYNAMIC_ALLOC + if (g_vpp.alloc_framebuf == 0) { +#endif + { + if (arg) { +#ifdef CONFIG_VPP_STREAM_FIX_RESOLUTION + vpp_alloc_framebuffer(g_vpp.stream_fb.fb_w, + g_vpp.stream_fb.fb_h); +#else + vout_info_t *info; + + info = vout_info_get_entry(0); + vpp_alloc_framebuffer(info->resx, info->resy); +#endif + } else { + vpp_free_framebuffer(); + } + } + vpp_mod_set_clock(VPP_MOD_SCL, g_vpp.stream_enable, 0); + vpp_pan_display(0, 0); + if (!g_vpp.stream_enable) { + vpp_lock(); + vpp_mb_put(0); + vpp_unlock(); + } +#endif + { +#if 0 + vpp_int_t type; + + type = (vout_info[0].govr_mod == VPP_MOD_GOVRH) ? + VPP_INT_GOVRH_VBIS : VPP_INT_GOVRH2_VBIS; + if (g_vpp.stream_enable) { + vpp_irqproc_work(type, (void *)vpp_mb_irqproc_sync, + vout_info[0].govr, 0, 0); + } else { + vpp_irqproc_del_work(type, (void *)vpp_mb_irqproc_sync); + } +#endif + wmt_enable_mmfreq(WMT_MMFREQ_MIRACAST, g_vpp.stream_enable); + } + break; + case VPPIO_STREAM_GETFB: + { + vdo_framebuf_t fb; + + vpp_lock(); +#ifdef CONFIG_VPP_STREAM_ROTATE + if (g_vpp.stream_mb_index == 0xFF) { /* not avail */ + retval = -1; + vpp_unlock(); + break; + } + fb = vout_info[1].fb; +#else +#ifdef CONFIG_VPP_STREAM_FIX_RESOLUTION + fb = g_vpp.stream_fb; +#else + fb = vout_info[0].fb; +#endif +#endif + fb.fb_w = vpp_calc_align(fb.fb_w, 64); + fb.y_addr = g_vpp.stream_mb[g_vpp.stream_mb_index]; + fb.y_size = fb.fb_w * fb.img_h; + fb.c_addr = fb.y_addr + fb.y_size; + fb.c_size = fb.y_size; + fb.col_fmt = VDO_COL_FMT_YUV422H; + + copy_to_user((void *)arg, (void *) &fb, sizeof(vdo_framebuf_t)); + retval = vpp_mb_get(fb.y_addr); + vpp_unlock(); + } + break; + case VPPIO_STREAM_PUTFB: + { + vdo_framebuf_t fb; + copy_from_user((void *) &fb, (const void *)arg, + sizeof(vdo_framebuf_t)); + vpp_lock(); + vpp_mb_put(fb.y_addr); + vpp_unlock(); + } + break; +#endif + case VPPIO_MODULE_CSC: + { + vpp_mod_arg_t parm; + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_mod_arg_t)); + mod_fb_p = vpp_mod_get_fb_base(parm.mod); + if (!mod_fb_p) + break; + mod_p = vpp_mod_get_base(parm.mod); + if (parm.read) { + parm.arg1 = mod_fb_p->csc_mode; + copy_to_user((void *)arg, (void *) &parm, + sizeof(vpp_mod_arg_t)); + } else { + mod_fb_p->csc_mode = parm.arg1; + mod_fb_p->set_csc(mod_fb_p->csc_mode); + } + } + break; + case VPPIO_MULTIVD_ENABLE: + wmt_enable_mmfreq(WMT_MMFREQ_MULTI_VD, arg); + break; + default: + retval = -ENOTTY; + break; + } + return retval; +} /* End of vpp_common_ioctl */ + +int vout_ioctl(unsigned int cmd, unsigned long arg) +{ + int retval = 0; + + switch (cmd) { + case VPPIO_VOGET_INFO: + { + vpp_vout_info_t parm; + vout_t *vo; + int num; + vout_inf_t *inf; + int fb_num; + vout_info_t *vo_info; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_vout_info_t)); + fb_num = (parm.num & 0xF0) >> 4; + num = parm.num & 0xF; + DBGMSG("VPPIO_VOGET_INFO %d,%d\n", fb_num, num); + if ((fb_num >= VPP_VOUT_INFO_NUM) || (num >= VOUT_MODE_MAX)) { + retval = -ENOTTY; + DBG_MSG("fb_num or num invalid\n"); + break; + } + memset(&parm, 0, sizeof(vpp_vout_info_t)); + vo = vout_get_entry_adapter(num); + if (vo == 0) { + retval = -ENOTTY; + DBG_MSG("vo null\n"); + break; + } + inf = vout_get_inf_entry_adapter(num); + if (inf == 0) { + retval = -ENOTTY; + DBG_MSG("inf null\n"); + break; + } + vo_info = vout_get_info_entry(vo->num); + if (vo_info == 0) { + retval = -ENOTTY; + DBG_MSG("vo_info null\n"); + break; + } + if ((g_vpp.dual_display == 1) && (g_vpp.virtual_display == 0) + && (fb_num != vo_info->num)) { + retval = -ENOTTY; + DBG_MSG("fb num not match\n"); + break; + } + DBGMSG("VPPIO_VOGET_INFO %d,fb%d,0x%x,0x%x\n", num, + vo_info->num, (int)vo, (int)inf); + if ((vo == 0) || (inf == 0)) + goto label_get_info; + + parm.num = num; + parm.status = vo->status | VPP_VOUT_STS_REGISTER; + strncpy(parm.name, vout_adpt_str[num], 10); + switch (inf->mode) { + case VOUT_INF_DVI: + parm.status &= ~VPP_VOUT_STS_ACTIVE; + if (vo->dev) { + /* check current DVI is dvi/dvo2hdmi/lcd */ + switch (num) { + case VOUT_DVI: + if (strcmp("VT1632", + vo->dev->name) == 0) + parm.status |= + VPP_VOUT_STS_ACTIVE; + parm.status |= VPP_VOUT_STS_ACTIVE; + break; + case VOUT_LCD: + if (strcmp("LCD", + vo->dev->name) == 0) + parm.status |= + VPP_VOUT_STS_ACTIVE; + break; + case VOUT_DVO2HDMI: + if (strcmp("SIL902X", + vo->dev->name) == 0) + parm.status |= + VPP_VOUT_STS_ACTIVE; + break; + default: + break; + } + } else { /* dvi hw mode */ + if (num == VOUT_DVI) + parm.status |= VPP_VOUT_STS_ACTIVE; + } + + if (g_vpp.virtual_display) { + if (vout_chkplug(VPP_VOUT_NUM_HDMI)) + parm.status &= ~VPP_VOUT_STS_ACTIVE; + } + break; + case VOUT_INF_HDMI: + case VOUT_INF_LVDS: + /* check current HDMI is HDMI or LVDS */ + if (vo->inf != inf) + parm.status = VPP_VOUT_STS_REGISTER; + break; + default: + break; + } + + if (parm.status & VPP_VOUT_STS_ACTIVE) { + if (vout_chkplug(vo->num)) + parm.status |= VPP_VOUT_STS_PLUGIN; + else + parm.status &= ~VPP_VOUT_STS_PLUGIN; + } else { + parm.status = VPP_VOUT_STS_REGISTER; + } +label_get_info: + copy_to_user((void *)arg, (const void *) &parm, + sizeof(vpp_vout_info_t)); + } + break; + case VPPIO_VOSET_MODE: + { + vpp_vout_parm_t parm; + vout_t *vo; + vout_inf_t *inf; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_vout_parm_t)); + vo = vout_get_entry_adapter(parm.num); + inf = vout_get_inf_entry_adapter(parm.num); + if (vo && inf) { + DBG_DETAIL("VPPIO_VOSET_MODE %d %d\n", + vo->num, parm.arg); + if (g_vpp.dual_display == 0) { + int plugin; + + plugin = vout_chkplug(VPP_VOUT_NUM_HDMI); + vout_set_blank((0x1 << VPP_VOUT_NUM_HDMI), + (plugin) ? 0 : 1); + vout_set_blank((0x1 << VPP_VOUT_NUM_DVI), + (plugin) ? 1 : 0); + break; + } + vout_set_blank((0x1 << vo->num), (parm.arg) ? 0 : 1); + retval = vout_set_mode(vo->num, inf->mode); + } + } + break; + case VPPIO_VOSET_BLANK: + { + vpp_vout_parm_t parm; + vout_t *vo; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_vout_parm_t)); + vo = vout_get_entry_adapter(parm.num); + if (vo) + retval = vout_set_blank((0x1 << vo->num), parm.arg); + } + break; + case VPPIO_VOSET_OPTION: + { + vpp_vout_option_t option; + vout_t *vo; + int num; + vout_inf_t *inf; + + copy_from_user((void *) &option, (const void *)arg, + sizeof(vpp_vout_option_t)); + num = option.num; + if (num >= VOUT_MODE_MAX) { + retval = -ENOTTY; + break; + } + vo = vout_get_entry_adapter(num); + inf = vout_get_inf_entry_adapter(num); + if (vo && inf) { + vo->option[0] = option.option[0]; + vo->option[1] = option.option[1]; + vo->option[2] = option.option[2]; + vout_set_mode(vo->num, inf->mode); + } + } + break; + case VPPIO_VOGET_OPTION: + { + vpp_vout_option_t option; + vout_t *vo; + int num; + + copy_from_user((void *) &option, (const void *)arg, + sizeof(vpp_vout_option_t)); + num = option.num; + if (num >= VOUT_MODE_MAX) { + retval = -ENOTTY; + break; + } + memset(&option, 0, sizeof(vpp_vout_info_t)); + vo = vout_get_entry_adapter(num); + if (vo) { + option.num = num; + option.option[0] = vo->option[0]; + option.option[1] = vo->option[1]; + option.option[2] = vo->option[2]; + } + copy_to_user((void *)arg, (const void *) &option, + sizeof(vpp_vout_option_t)); + } + break; + case VPPIO_VOUT_VMODE: + { + vpp_vout_vmode_t parm; + int i; + struct fb_videomode *vmode; + unsigned int resx, resy, fps; + unsigned int pre_resx, pre_resy, pre_fps; + int index, from_index; + int support; + unsigned int option, pre_option; +#ifdef CONFIG_WMT_EDID + edid_info_t *edid_info; +#endif + struct fb_videomode *edid_vmode; + vpp_vout_t mode; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_vout_vmode_t)); + from_index = parm.num; + parm.num = 0; + mode = parm.mode & 0xF; +#ifdef CONFIG_VPP_DEMO + parm.parm[parm.num].resx = 1920; + parm.parm[parm.num].resy = 1080; + parm.parm[parm.num].fps = 60; + parm.parm[parm.num].option = 0; + parm.num++; +#else +#ifdef CONFIG_WMT_EDID + { + vout_t *vo; + + vo = vout_get_entry_adapter(mode); + if (!vo) + goto vout_vmode_end; + + if (!(vo->status & VPP_VOUT_STS_PLUGIN)) { + DPRINT("*W* not plugin\n"); + goto vout_vmode_end; + } + + if (vout_get_edid(vo->num) == 0) { + DPRINT("*W* read EDID fail\n"); + goto vout_vmode_end; + } + if (edid_parse(vo->edid, &vo->edid_info) == 0) { + DPRINT("*W* parse EDID fail\n"); + goto vout_vmode_end; + } + edid_info = &vo->edid_info; + } +#endif + index = 0; + resx = resy = fps = option = 0; + pre_resx = pre_resy = pre_fps = pre_option = 0; + for (i = 0; ; i++) { + vmode = (struct fb_videomode *) &vpp_videomode[i]; + if (vmode->pixclock == 0) + break; + resx = vmode->xres; + resy = vmode->yres; + fps = vmode->refresh; + option = fps & EDID_TMR_FREQ; + option |= (vmode->vmode & FB_VMODE_INTERLACED) ? + EDID_TMR_INTERLACE : 0; + if ((pre_resx == resx) && (pre_resy == resy) && + (pre_fps == fps) && (pre_option == option)) + continue; + pre_resx = resx; + pre_resy = resy; + pre_fps = fps; + pre_option = option; + support = 0; +#ifdef CONFIG_WMT_EDID + if (edid_find_support(edid_info, resx, resy, + option, &edid_vmode)) +#else + if (1) +#endif + support = 1; + + switch (mode) { + case VPP_VOUT_HDMI: + case VPP_VOUT_DVO2HDMI: + if (g_vpp.hdmi_video_mode) { + if (resy > g_vpp.hdmi_video_mode) + support = 0; + } + break; + default: + break; + } + + if (support) { + if (index >= from_index) { + parm.parm[parm.num].resx = resx; + parm.parm[parm.num].resy = resy; + parm.parm[parm.num].fps = fps; + parm.parm[parm.num].option = + vmode->vmode; + parm.num++; + } + index++; + if (parm.num >= VPP_VOUT_VMODE_NUM) + break; + } + } +#ifdef CONFIG_WMT_EDID +vout_vmode_end: +#endif +#endif + if(parm.num == 0) { /* if no EDID*/ + if(g_vpp.virtual_display || (g_vpp.dual_display == 0)) { + if(mode == VPP_VOUT_DVI) { + char buf[40] = {0}; + int varlen = 40; + + if(wmt_getsyspara("wmt.display.tvformat", buf, &varlen) == 0) { + if(!strnicmp(buf, "PAL", 3) || !strnicmp(buf, "NTSC", 4)) { + parm.parm[0].resx = 720; + parm.parm[0].resy = 576; + parm.parm[0].fps = 50; + parm.parm[0].option = 0; + + parm.parm[1].resx = 720; + parm.parm[1].resy = 480; + parm.parm[1].fps = 60; + parm.parm[1].option = 0; + + parm.num = 2; + } + } + } + } + } + + DBG_MSG("[VPP] get support vmode %d\n", parm.num); + copy_to_user((void *)arg, (const void *) &parm, + sizeof(vpp_vout_vmode_t)); + } + break; + case VPPIO_VOGET_EDID: + { + vpp_vout_edid_t parm; + char *edid; + vout_t *vo; + int size; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_vout_edid_t)); + size = 0; +#ifdef CONFIG_WMT_EDID + vo = vout_get_entry_adapter(parm.mode); + if (!vo) + goto vout_edid_end; + + if (!(vo->status & VPP_VOUT_STS_PLUGIN)) { + DBG_ERR("*W* not plugin\n"); + goto vout_edid_end; + } - for (i = 0; i < VPP_VOUT_NUM; i++) { - if (par->vout[i] == 0) + edid = vout_get_edid(vo->num); + if (edid == 0) { + DBG_ERR("*W* read EDID fail\n"); + goto vout_edid_end; + } + size = (edid[0x7E] + 1) * 128; + if (size > parm.size) + size = parm.size; + copy_to_user((void *) parm.buf, (void *) edid, size); +vout_edid_end: +#endif + parm.size = size; + copy_to_user((void *)arg, (const void *) &parm, + sizeof(vpp_vout_edid_t)); + } + break; + case VPPIO_VOGET_CP_INFO: + { + vpp_vout_cp_info_t parm; + int num; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_vout_cp_info_t)); + num = parm.num; + if (num >= VOUT_MODE_MAX) { + retval = -ENOTTY; break; - vout_set_blank(par->vout[i]->num, blank); + } + memset(&parm, 0, sizeof(vpp_vout_cp_info_t)); + switch (num) { + case VOUT_HDMI: + if (!g_vpp.hdmi_certify_flag) { + if (g_vpp.hdmi_bksv[0] == 0) { + hdmi_get_bksv(&g_vpp.hdmi_bksv[0]); + DBG_MSG("get BKSV 0x%x 0x%x\n", + g_vpp.hdmi_bksv[0], + g_vpp.hdmi_bksv[1]); + } + } + case VOUT_DVO2HDMI: + parm.bksv[0] = g_vpp.hdmi_bksv[0]; + parm.bksv[1] = g_vpp.hdmi_bksv[1]; + break; + default: + parm.bksv[0] = parm.bksv[1] = 0; + break; + } + copy_to_user((void *)arg, (const void *) &parm, + sizeof(vpp_vout_cp_info_t)); + } + break; + case VPPIO_VOSET_CP_KEY: + if (g_vpp.hdmi_cp_p == 0) { + g_vpp.hdmi_cp_p = + (char *)kmalloc(sizeof(vpp_vout_cp_key_t), + GFP_KERNEL); + } + if (g_vpp.hdmi_cp_p) { + copy_from_user((void *) g_vpp.hdmi_cp_p, + (const void *)arg, sizeof(vpp_vout_cp_key_t)); + if (hdmi_cp) + hdmi_cp->init(); + } + break; +#ifdef WMT_FTBLK_HDMI + case VPPIO_VOSET_AUDIO_PASSTHRU: + vppif_reg32_write(HDMI_AUD_SUB_PACKET, (arg) ? 0xF : 0x0); + break; +#endif +#ifdef CONFIG_VPP_VIRTUAL_DISPLAY + case VPPIO_VOSET_VIRTUAL_FBDEV: + g_vpp.fb0_bitblit = (arg) ? 0 : 1; + MSG("[VPP] virtual display %d\n", (int)arg); + break; +#endif + default: + retval = -ENOTTY; + break; } + return retval; +} /* End of vout_ioctl */ + +int govr_ioctl(unsigned int cmd, unsigned long arg) +{ + int retval = 0; + + switch (cmd) { +#ifdef WMT_FTBLK_GOVRH + case VPPIO_GOVRSET_DVO: + { + vdo_dvo_parm_t parm; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vdo_dvo_parm_t)); + govrh_set_dvo_enable(p_govrh, parm.enable); + govrh_set_dvo_color_format(p_govrh, parm.color_fmt); + govrh_set_dvo_clock_delay(p_govrh, parm.clk_inv, + parm.clk_delay); + govrh_set_dvo_outdatw(p_govrh, parm.data_w); + govrh_set_dvo_sync_polar(p_govrh, parm.sync_polar, + parm.vsync_polar); + p_govrh->fb_p->set_csc(p_govrh->fb_p->csc_mode); + } + break; +#endif +#ifdef WMT_FTBLK_GOVRH_CURSOR + case VPPIO_GOVRSET_CUR_COLKEY: + { + vpp_mod_arg_t parm; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vdo_dvo_parm_t)); + govrh_CUR_set_color_key(p_cursor, VPP_FLAG_ENABLE, + 0, parm.arg1); + } + break; + case VPPIO_GOVRSET_CUR_HOTSPOT: + { + vpp_mod_arg_t parm; + vdo_view_t view; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vdo_dvo_parm_t)); + p_cursor->hotspot_x = parm.arg1; + p_cursor->hotspot_y = parm.arg2; + view.posx = p_cursor->posx; + view.posy = p_cursor->posy; + p_cursor->fb_p->fn_view(0, &view); + } + break; +#endif + default: + retval = -ENOTTY; + break; + } + return retval; +} /* End of govr_ioctl */ + +int scl_ioctl(unsigned int cmd, unsigned long arg) +{ + int retval = 0; + extern int ge_do_alpha_bitblt(vdo_framebuf_t *src, + vdo_framebuf_t *src2, vdo_framebuf_t *dst); + + switch (cmd) { + case VPPIO_SCL_SCALE_OVERLAP: + { + vpp_scale_overlap_t parm; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_scale_overlap_t)); + if (vpp_check_dbg_level(VPP_DBGLVL_FPS)) + vpp_dbg_timer(&p_scl->overlap_timer, 0, 1); + + p_scl->scale_sync = 1; + retval = scl_set_scale_overlap(&parm.src_fb, + &parm.src2_fb, &parm.dst_fb); + + if (vpp_check_dbg_level(VPP_DBGLVL_FPS)) + vpp_dbg_timer(&p_scl->overlap_timer, "overlap", 2); + } + break; + case VPPIO_SCL_SCALE_ASYNC: + case VPPIO_SCL_SCALE: + { + vpp_scale_t parm; + + p_scl->scale_sync = (cmd == VPPIO_SCL_SCALE) ? 1 : 0; + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_scale_t)); + if (vpp_check_dbg_level(VPP_DBGLVL_FPS)) + vpp_dbg_timer(&p_scl->scale_timer, 0, 1); + + vpp_set_NA12_hiprio(1); + retval = vpp_set_recursive_scale(&parm.src_fb, &parm.dst_fb); + vpp_set_NA12_hiprio(0); + + if (vpp_check_dbg_level(VPP_DBGLVL_FPS)) + vpp_dbg_timer(&p_scl->scale_timer, "scale", 2); + copy_to_user((void *)arg, (void *)&parm, sizeof(vpp_scale_t)); + } + break; +#ifdef WMT_FTBLK_SCL + case VPPIO_SCL_DROP_LINE_ENABLE: + scl_set_drop_line(arg); + break; +#endif + case VPPIO_SCL_SCALE_FINISH: + retval = p_scl->scale_finish(); + break; + case VPPIO_SCLSET_OVERLAP: + { + vpp_overlap_t parm; + + copy_from_user((void *) &parm, (const void *)arg, + sizeof(vpp_overlap_t)); + vpp_mod_set_clock(VPP_MOD_SCL, VPP_FLAG_ENABLE, 0); + scl_set_overlap(&parm); + vpp_mod_set_clock(VPP_MOD_SCL, VPP_FLAG_DISABLE, 0); + } + break; + default: + retval = -ENOTTY; + break; + } + return retval; +} /* End of scl_ioctl */ + +int vpp_ioctl(unsigned int cmd, unsigned long arg) +{ + int retval = 0; + int err = 0; + int skip_mutex = 0; + +/* DBGMSG("vpp_ioctl\n"); */ + switch (_IOC_TYPE(cmd)) { + case VPPIO_MAGIC: + break; + default: + return -ENOTTY; + } + + /* check argument area */ + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void __user *) arg, + _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void __user *) arg, + _IOC_SIZE(cmd)); + + if (err) + return -EFAULT; + + if (vpp_check_dbg_level(VPP_DBGLVL_IOCTL)) { + switch (cmd) { + case VPPIO_VPPSET_FBDISP: + case VPPIO_VPPGET_FBDISP: + case VPPIO_MODULE_VIEW: /* cursor pos */ + break; + default: + DPRINT("[VPP] ioctl cmd 0x%x,arg 0x%x\n", + _IOC_NR(cmd), (int)arg); + break; + } + } + + switch (cmd) { + case VPPIO_STREAM_GETFB: /* block mode should wait vsync */ + skip_mutex = 1; + break; + default: + /* scale should wait complete */ + if ((_IOC_NR(cmd) >= VPPIO_SCL_BASE) && + (_IOC_NR(cmd) < VPPIO_MAX)) + skip_mutex = 1; + break; + } + + if (!skip_mutex) + vpp_set_mutex(1, 1); + + switch (_IOC_NR(cmd)) { + case VPPIO_VPP_BASE ... (VPPIO_VOUT_BASE-1): + /* DBGMSG("VPP command ioctl\n"); */ + retval = vpp_common_ioctl(cmd, arg); + break; + case VPPIO_VOUT_BASE ... (VPPIO_GOVR_BASE-1): + /* DBGMSG("VOUT ioctl\n"); */ + retval = vout_ioctl(cmd, arg); + break; + case VPPIO_GOVR_BASE ... (VPPIO_SCL_BASE-1): + /* DBGMSG("GOVR ioctl\n"); */ + retval = govr_ioctl(cmd, arg); + break; + case VPPIO_SCL_BASE ... (VPPIO_MAX-1): + /* DBGMSG("SCL ioctl\n"); */ + retval = scl_ioctl(cmd, arg); + break; + default: + retval = -ENOTTY; + break; + } + + if (!skip_mutex) + vpp_set_mutex(1, 0); + + if (vpp_check_dbg_level(VPP_DBGLVL_IOCTL)) { + switch (cmd) { + case VPPIO_VPPSET_FBDISP: + case VPPIO_VPPGET_FBDISP: + case VPPIO_MODULE_VIEW: + break; + default: + DPRINT("[VPP] ioctl cmd 0x%x,ret 0x%x\n", + _IOC_NR(cmd), (int)retval); + break; + } + } + return retval; +} /* End of vpp_ioctl */ + +int vpp_set_blank(struct fb_info *info, int blank) +{ + vout_info_t *vo_info; + unsigned int vout_blank_mask = 0, vout_unblank_mask = 0; + + if ((g_vpp.dual_display == 0) && (info->node == 1)) + return 0; + + DBG_MSG("(%d,%d)\n", info->node, blank); + + vo_info = vout_info_get_entry(info->node); + if (blank) + vout_blank_mask = vout_get_mask(vo_info); + else + vout_unblank_mask = vout_get_mask(vo_info); + + if (g_vpp.virtual_display || (g_vpp.dual_display == 0)) { + if (blank) { + vout_blank_mask = ~0; + vout_unblank_mask = 0; + } else { + int plugin; + + plugin = vout_chkplug(VPP_VOUT_NUM_HDMI); + vout_blank_mask &= ~((0x1 << VPP_VOUT_NUM_DVI) + + (0x1 << VPP_VOUT_NUM_HDMI)); + vout_unblank_mask &= ~((0x1 << VPP_VOUT_NUM_DVI) + + (0x1 << VPP_VOUT_NUM_HDMI)); + vout_blank_mask |= (plugin) ? + (0x1 << VPP_VOUT_NUM_DVI) : + (0x1 << VPP_VOUT_NUM_HDMI); + vout_unblank_mask |= (plugin) ? + (0x1 << VPP_VOUT_NUM_HDMI) : + (0x1 << VPP_VOUT_NUM_DVI); + } + } + vout_set_blank(vout_blank_mask, 1); + vout_set_blank(vout_unblank_mask, 0); return 0; } @@ -165,29 +1581,266 @@ void vpp_set_lvds_blank(int blank) return; if (blank == 0) { - outl(inl(GPIO_BASE_ADDR + 0xC0) | BIT10, GPIO_BASE_ADDR + 0xC0); - outl(inl(GPIO_BASE_ADDR + 0x80) | BIT10, GPIO_BASE_ADDR + 0x80); + REG32_VAL(GPIO_BASE_ADDR+0xC0) |= 0x400; + REG32_VAL(GPIO_BASE_ADDR+0x80) |= 0x400; mdelay(6); } if (blank) msleep(50); - vout_set_blank(VPP_VOUT_NUM_LVDS, + vout_set_blank((0x1 << VPP_VOUT_NUM_LVDS), (blank) ? VOUT_BLANK_POWERDOWN : VOUT_BLANK_UNBLANK); lvds_set_power_down((blank) ? 1 : 0); if (blank) { mdelay(6); /* GPIO10 off 8ms -> clock -> off */ - outl(inl(GPIO_BASE_ADDR + 0xC0) & ~BIT10, - GPIO_BASE_ADDR + 0xC0); + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x400; + } +} + +irqreturn_t vpp_interrupt_routine(int irq, void *dev_id) +{ + vpp_int_t int_sts; + + switch (irq) { + case VPP_IRQ_VPPM: /* VPP */ + int_sts = p_vppm->get_sts(); + p_vppm->clr_sts(int_sts); + + vpp_dbg_show_val1(VPP_DBGLVL_INT, 0, "[VPP] VPPM INT", int_sts); + { + int i; + unsigned int mask; + vpp_irqproc_t *irqproc; + + for (i = 0, mask = 0x1; (i < 32) && int_sts; i++, mask <<= 1) { + if ((int_sts & mask) == 0) + continue; + + irqproc = vpp_irqproc_get_entry(mask); + if (irqproc) { + if (list_empty(&irqproc->list) == 0) + tasklet_schedule(&irqproc->tasklet); + } else { + irqproc = vpp_irqproc_get_entry(VPP_INT_MAX); + if (list_empty(&irqproc->list) == 0) { + vpp_proc_t *entry; + struct list_head *ptr; + + ptr = (&irqproc->list)->next; + entry = list_entry(ptr, vpp_proc_t, + list); + if (entry->type == mask) + tasklet_schedule( + &irqproc->tasklet); + } + } + int_sts &= ~mask; + } + } + break; +#ifdef WMT_FTBLK_SCL + case VPP_IRQ_SCL: /* SCL */ + int_sts = p_scl->get_sts(); + p_scl->clr_sts(int_sts); + vpp_dbg_show_val1(VPP_DBGLVL_INT, 0, "[VPP] SCL INT", int_sts); + break; +#endif +#ifdef WMT_FTBLK_GOVRH + case VPP_IRQ_GOVR: /* GOVR */ + case VPP_IRQ_GOVR2: + { + govrh_mod_t *govr; + + govr = (irq == VPP_IRQ_GOVR) ? p_govrh : p_govrh2; + int_sts = govr->get_sts(); + govr->clr_sts(int_sts); + vpp_dbg_show_val1(VPP_DBGLVL_INT, 0, "[VPP] GOVR INT", int_sts); + govr->underrun_cnt++; +#ifdef VPP_DBG_DIAG_NUM + vpp_dbg_show(VPP_DBGLVL_DIAG, 3, "GOVR MIF Err"); + vpp_dbg_diag_delay = 10; +#endif + } + break; +#endif + default: + DPRINT("*E* invalid vpp isr\n"); + break; + } + return IRQ_HANDLED; +} /* End of vpp_interrupt_routine */ + +int vpp_dev_init(void) +{ + g_vpp.alloc_framebuf = vpp_alloc_framebuffer; + vpp_irqproc_init(); + vpp_netlink_init(); + vpp_init(); +#ifdef CONFIG_VPP_PROC + /* init system proc */ + if (vpp_proc_dir == 0) { + struct proc_dir_entry *res; + + vpp_proc_dir = proc_mkdir("driver/vpp", NULL); + res = create_proc_entry("sts", 0, vpp_proc_dir); + if (res) + res->read_proc = vpp_sts_read_proc; + res = create_proc_entry("reg", 0, vpp_proc_dir); + if (res) + res->read_proc = vpp_reg_read_proc; + vpp_table_header = register_sysctl_table(vpp_root_table); + } +#endif + + /* init interrupt service routine */ +#ifdef WMT_FTBLK_SCL + if (vpp_request_irq(VPP_IRQ_SCL, vpp_interrupt_routine, + SA_INTERRUPT, "scl", (void *)&g_vpp)) { + DPRINT("*E* request VPP ISR fail\n"); + return -1; + } +#endif + if (vpp_request_irq(VPP_IRQ_VPPM, vpp_interrupt_routine, + SA_INTERRUPT, "vpp", (void *)&g_vpp)) { + DPRINT("*E* request VPP ISR fail\n"); + return -1; + } +#ifdef WMT_FTBLK_GOVRH + if (vpp_request_irq(VPP_IRQ_GOVR, vpp_interrupt_routine, + SA_INTERRUPT, "govr", (void *)&g_vpp)) { + DPRINT("*E* request VPP ISR fail\n"); + return -1; + } + + if (vpp_request_irq(VPP_IRQ_GOVR2, vpp_interrupt_routine, + SA_INTERRUPT, "govr2", (void *)&g_vpp)) { + DPRINT("*E* request VPP ISR fail\n"); + return -1; + } +#endif + vpp_switch_state_init(); + return 0; +} + +int vpp_exit(struct fb_info *info) +{ + DBG_MSG("vpp_exit\n"); + + vout_exit(); +#ifdef CONFIG_VPP_PROC + unregister_sysctl_table(vpp_table_header); +#endif + return 0; +} + +void vpp_wait_vsync(int no, int cnt) +{ + int govr_mask = 0; + + if (g_vpp.virtual_display || (g_vpp.dual_display == 0)) { + if (govrh_get_MIF_enable(p_govrh)) + govr_mask |= BIT0; + if (govrh_get_MIF_enable(p_govrh2)) + govr_mask |= BIT1; + } else { + vout_info_t *vo_info; + vout_t *vo; + int vo_mask; + int i; + + vo_info = vout_info_get_entry(no); + vo_mask = vout_get_mask(vo_info); + for (i = 0; i < VPP_VOUT_NUM; i++) { + if ((vo_mask & (0x1 << i)) == 0) + continue; + vo = vout_get_entry(i); + if (vo) { + if (vo->govr == p_govrh) + govr_mask |= BIT0; + if (vo->govr == p_govrh2) + govr_mask |= BIT1; + } + } } + + if (govr_mask) { +#if 0 + if (vpp_check_dbg_level(VPP_DBGLVL_FPS)) + MSG("[VPP] vpp_wait_vsync %d\n", no); +#endif + vpp_irqproc_work((govr_mask & BIT0) ? VPP_INT_GOVRH_VBIS : + VPP_INT_GOVRH2_VBIS, 0, 0, 100 * cnt, cnt); + } +} /* End of vpp_wait_vsync */ + +/* struct list_head *vpp_modelist; */ +void vpp_get_info(int fbn, struct fb_var_screeninfo *var) +{ + static int vpp_init_flag = 1; + vout_info_t *info; + govrh_mod_t *govr; + + if (vpp_init_flag) { +#if 0 + int num; + + INIT_LIST_HEAD(vpp_modelist); + for (num = 0; ; num++) { + if (vpp_videomode[num].xres == 0) + break; + } + fb_videomode_to_modelist(vpp_videomode, num, vpp_modelist); +#endif + vpp_dev_init(); + vpp_init_flag = 0; + } + + info = vout_info_get_entry(fbn); + govr = vout_info_get_govr(fbn); + if (govr) { + struct fb_videomode vmode; + + govrh_get_framebuffer(govr, &info->fb); + govrh_get_videomode(govr, &vmode); + fb_videomode_to_var(var, &vmode); + } else { + var->pixclock = + KHZ2PICOS((info->resx * info->resy * 60) / 1000); + } + var->xres = info->resx; + var->yres = info->resy; + var->xres_virtual = info->fb.fb_w; + var->yres_virtual = var->yres * VPP_MB_ALLOC_NUM; + if (g_vpp.mb_colfmt == VDO_COL_FMT_ARGB) { + var->bits_per_pixel = 32; + var->red.offset = 16; + var->red.length = 8; + var->red.msb_right = 0; + var->green.offset = 8; + var->green.length = 8; + var->green.msb_right = 0; + var->green.offset = 0; + var->green.length = 8; + var->green.msb_right = 0; + var->transp.offset = 24; + var->transp.length = 8; + var->transp.msb_right = 0; + } + DBG_MSG("(%d,%dx%d,%dx%d,%d,%d)\n", fbn, var->xres, var->yres, + var->xres_virtual, var->yres_virtual, + var->pixclock, var->bits_per_pixel); +#ifdef DEBUG + wmtfb_show_var("get_info", var); +#endif } void vpp_var_to_fb(struct fb_var_screeninfo *var, struct fb_info *info, vdo_framebuf_t *fb) { + extern unsigned int fb_egl_swap; unsigned int addr; int y_bpp, c_bpp; @@ -221,6 +1874,7 @@ void vpp_var_to_fb(struct fb_var_screeninfo *var, y_bpp = 8; c_bpp = 8; } + var->xres_virtual = vpp_calc_fb_width(fb->col_fmt, var->xres); fb->img_w = var->xres; fb->img_h = var->yres; @@ -239,157 +1893,163 @@ void vpp_var_to_fb(struct fb_var_screeninfo *var, fb->c_addr = fb->y_addr + fb->y_size; fb->c_size = var->xres_virtual * var->yres * (c_bpp >> 3); } -} - -void vpp_pan_display_bitblit(struct vout_info_t *par) -{ - vdo_framebuf_t src, dst; - struct fb_videomode vmode; - struct govrh_mod_t *govr; - struct fb_info *dfb_info; - struct vout_info_t *d_info; - int fb_no; - - /* DBG_MSG("fb0 bitblit\n"); */ - src = par->fb; - for (fb_no = 1; ; fb_no++) { - d_info = vout_info_get_entry(fb_no); - if (!d_info) - break; - - govr = vout_info_get_govr(fb_no); - if (govr == 0) - break; - govrh_get_framebuffer(govr, &dst); - govrh_get_videomode(govr, &vmode); - dst.img_w = vmode.xres; - dst.fb_w = vpp_calc_fb_width(dst.col_fmt, dst.img_w); - dst.img_h = vmode.yres; - dst.fb_h = vmode.yres; - dst.y_size = dst.fb_w * dst.img_h * (dst.bpp >> 3); - - dfb_info = (struct fb_info *) d_info->fb_info_p; - if (dfb_info) { - dfb_info->var.yoffset = - (dfb_info->var.yoffset) ? 0 : dst.img_h; - dst.y_addr = dfb_info->fix.smem_start + - (dst.fb_w * dfb_info->var.yoffset * - (dst.bpp >> 3)); - dst.c_addr = 0; - } else { - govrh_get_fb_addr(govr, &dst.y_addr, &dst.c_addr); - } - if (d_info->alloc_mode == VOUT_ALLOC_GE_OVERSCAN) { - if (!d_info->mb) { - int size = dst.y_size * VPP_MB_ALLOC_NUM; + if (info && (info->node == 0) && (fb_egl_swap != 0)) /* for Android */ + fb->y_addr = fb_egl_swap; - d_info->mb = mb_alloc(size); - if (d_info->mb) { - MSG("mb alloc 0x%x,%d\n", - d_info->mb, size); - } else { - DBG_ERR("alloc fail\n"); - return; - } - } - dst.y_addr = d_info->mb + - (dst.fb_w * dfb_info->var.yoffset * - (dst.bpp >> 3)); - } - - if (dst.y_addr) { - p_scl->scale_sync = 1; - vpp_set_recursive_scale(&src, &dst); - vout_set_framebuffer(d_info, &dst); - } - } } int vpp_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct vout_info_t *par = (struct vout_info_t *) info->par; + vout_info_t *vo_info; + vdo_framebuf_t *uboot_fb = 0; if (g_vpp.hdmi_certify_flag) return 0; + vo_info = vout_info_get_entry((info) ? info->node : 0); + DBG_DETAIL("fb %d\n", (info) ? info->node : 0); - vpp_var_to_fb(var, info, &par->fb); - if (wmtfb_probe_ready && g_vpp.fb0_bitblit && (info->node == 0)) - vpp_pan_display_bitblit(par); - else - vout_set_framebuffer(par, &par->fb); + + if (wmtfb_fb1_probe == 0) { + uboot_fb = kmalloc(sizeof(vdo_framebuf_t), GFP_KERNEL); + *uboot_fb = vo_info->fb; + uboot_fb->img_h = g_vpp.govrh_init_yres; + } + + vpp_var_to_fb(var, info, &vo_info->fb); + + if (uboot_fb) { + DMSG("uboot copy fb%d\n", info->node); + p_scl->scale_sync = 1; + vpp_set_recursive_scale(uboot_fb, &vo_info->fb); + kfree(uboot_fb); + } + + /* for 8:1:0 mode change resolution garbage frame */ + if ((g_vpp.virtual_display_mode == 1) && (info->node == 1)) { + vdo_framebuf_t fb; + + govrh_get_framebuffer(p_govrh, &fb); + vo_info->fb.y_addr = fb.y_addr; + vo_info->fb.c_addr = 0; + } + vout_set_framebuffer(vout_get_mask(vo_info), &vo_info->fb); + + if (g_vpp.fb0_bitblit) { + vdo_framebuf_t src, dst; + struct fb_videomode vmode; + govrh_mod_t *govr; + + src = vo_info->fb; + govr = vout_info_get_govr(1); + p_scl->scale_sync = 1; + govrh_get_framebuffer(govr, &dst); + govrh_get_videomode(govr, &vmode); + dst.img_w = vmode.xres; + dst.fb_w = vpp_calc_fb_width(dst.col_fmt, dst.img_w); + dst.img_h = vmode.yres; + dst.fb_h = vmode.yres; + dst.y_size = dst.fb_w * dst.img_h * dst.bpp / 8; +#ifdef CONFIG_VPP_DYNAMIC_ALLOC + if (g_vpp.mb[0] == 0) + vpp_alloc_framebuffer(dst.img_w, dst.img_h); +#endif + g_vpp.stream_mb_index = (g_vpp.stream_mb_index) ? 0 : 1; + dst.y_addr = g_vpp.mb[0] + (dst.y_size * g_vpp.stream_mb_index); + dst.c_addr = 0; + vpp_set_recursive_scale(&src, &dst); + vout_set_framebuffer(VPP_VOUT_ALL, &dst); + } #ifdef CONFIG_VPP_STREAM_CAPTURE - if (g_vpp.stream_enable && (par->hwc_mode == VOUT_HWC_VIRTUAL)) { - g_vpp.stream_mb_index = var->yoffset / var->yres; - vpp_dbg_show_val1(VPP_DBGLVL_STREAM, 0, - "stream pan disp", g_vpp.stream_mb_index); + if (g_vpp.stream_enable) { +#ifdef CONFIG_VPP_STREAM_ROTATE + if (info && (info->node == 1)) { + g_vpp.stream_mb_index = var->yoffset / var->yres; + vpp_dbg_show_val1(VPP_DBGLVL_STREAM, 0, + "stream pan disp", g_vpp.stream_mb_index); + } +#else + if ((info && (info->node == 0)) || (info == 0)) + vpp_mb_scale_bitblit(&vo_info->fb); +#endif } #endif - if (vpp_check_dbg_level(VPP_DBGLVL_DISPFB)) { + if (vo_info->govr && vpp_check_dbg_level(VPP_DBGLVL_DISPFB)) { char buf[50]; - unsigned int yaddr = 0, caddr = 0; - struct govrh_mod_t *govr; + unsigned int yaddr, caddr; - govr = vout_info_get_govr(info->node); - if (govr) - govrh_get_fb_addr(govr, &yaddr, &caddr); - sprintf(buf, "pan_display %d,0x%x", par->num, yaddr); - vpp_dbg_show(VPP_DBGLVL_DISPFB, par->num + 1, buf); + govrh_get_fb_addr(vo_info->govr, &yaddr, &caddr); + sprintf(buf, "pan_display %d,%s,0x%x", vo_info->num, + vpp_mod_str[vo_info->govr_mod], yaddr); + vpp_dbg_show(VPP_DBGLVL_DISPFB, vo_info->num + 1, buf); } - if (vpp_check_dbg_level(VPP_DBGLVL_FPS)) { - char buf[10]; - - sprintf(buf, "fb%d", par->num); - vpp_dbg_timer(&par->pandisp_timer, buf, 2); - } + if (vo_info->govr && vpp_check_dbg_level(VPP_DBGLVL_FPS)) + vpp_dbg_timer(&vo_info->pandisp_timer, + (vo_info->num == 0) ? "fb0" : "fb1", 2); return 0; } int vpp_set_par(struct fb_info *info) { - struct vout_info_t *par = (struct vout_info_t *) info->par; - vdo_framebuf_t fb; - struct fb_videomode var, cur; - struct govrh_mod_t *govr; + vout_info_t *vo_info; + unsigned int mask; + int i; if (g_vpp.hdmi_certify_flag) return 0; - govr = vout_info_get_govr(info->node); - if (!govr) + if ((g_vpp.dual_display == 0) && (info->node == 1)) return 0; - wmtfb_set_mutex(info, 1); + if (g_vpp.govrh_preinit) + g_vpp.govrh_preinit = 0; - /* check frame buffer */ - vpp_var_to_fb(&info->var, info, &fb); - par->fb.fb_h = fb.fb_h; - if (memcmp(&fb.img_w, &par->fb.img_w, 32)) { - if ((wmtfb_probe_ready == 0) && g_vpp.govrh_preinit) { - MSG("[uboot logo] fb%d\n", info->node); - govrh_get_framebuffer(govr, &par->fb); - vpp_set_recursive_scale(&par->fb, &fb); - } + vpp_set_mutex(info->node, 1); + +for (i = 0; i < VPP_VOUT_INFO_NUM; i++) { + vo_info = vout_info_get_entry(i); + mask = vout_get_mask(vo_info); + + /* set frame buffer */ + if (mask) { + vdo_framebuf_t fb; + + vpp_var_to_fb(&info->var, info, &fb); + vo_info->fb.fb_h = fb.fb_h; + if (memcmp(&fb.img_w, &vo_info->fb.img_w, 32)) { #ifdef DEBUG - MSG("set_par %d : set framebuf\n", - info->node); - vpp_show_framebuf("cur", &par->fb); - vpp_show_framebuf("new", &fb); + DPRINT("[wmtfb_set_par] set_par %d : set framebuf\n", + info->node); + vpp_show_framebuf("cur", &vo_info->fb); + vpp_show_framebuf("new", &fb); #endif - par->fb = fb; - } else { - fb.img_w = 0; + vo_info->fb = fb; + vout_set_framebuffer(mask, &vo_info->fb); + } } - /* check timing */ - fb_var_to_videomode(&var, &info->var); - govrh_get_videomode(govr, &cur); - if ((cur.xres == var.xres) && (cur.yres == var.yres)) { + /* set timing */ + if (vo_info->govr && !(g_vpp.virtual_display && (info->node == 0))) { + struct fb_videomode var, cur; + govrh_mod_t *govr; unsigned int cur_pixclk, new_pixclk; + govr = vout_info_get_govr(info->node); + fb_var_to_videomode(&var, &info->var); + if(g_vpp.virtual_display) { + if (vout_find_match_mode(info->node, &var, 1)) { + DPRINT("[wmtfb] not support\n"); + vpp_set_mutex(info->node, 0); + return -1; + } + fb_videomode_to_var(&info->var, &var); + var.flag = FB_MODE_IS_FROM_VAR; + } + govrh_get_videomode(govr, &cur); + if ((cur.xres == var.xres) && (cur.yres == var.yres)) { /* diff less than 500K */ cur_pixclk = PICOS2KHZ(cur.pixclock); new_pixclk = PICOS2KHZ(var.pixclock); @@ -397,190 +2057,20 @@ int vpp_set_par(struct fb_info *info) var.pixclock = cur.pixclock; var.refresh = cur.refresh; } - /* diff less than 2 */ - if (abs(var.refresh - cur.refresh) <= 2) + if (abs(var.refresh - cur.refresh) <= 2) /* diff less than 2 */ var.refresh = cur.refresh; - } - - //var.sync &= (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT); - var.sync = cur.sync; - if (memcmp(&var, &cur, sizeof(struct fb_videomode))) { -#ifdef DEBUG - DPRINT("[wmtfb] set_par %d: set timing\n", info->node); - vpp_show_timing("cur", &cur, 0); - vpp_show_timing("new", &var, 0); -#endif - } else { - var.xres = 0; - } - vout_config(par, (var.xres) ? &var : 0, (fb.img_w) ? &fb : 0); - wmtfb_set_mutex(info, 0); - return 0; -} - -int vpp_get_info(int fbn, struct fb_var_screeninfo *var) -{ - struct vout_info_t *par; - - par = vout_info_get_entry(fbn); - if (!par) - return -1; - - var->xres = par->resx; - var->yres = par->resy; - var->xres_virtual = par->resx_virtual; - var->yres_virtual = var->yres * VPP_MB_ALLOC_NUM; - var->bits_per_pixel = (g_vpp.mb_colfmt == VDO_COL_FMT_ARGB) ? 32 : 16; - var->pixclock = par->resx * par->resy * par->fps; - var->pixclock = (var->pixclock) ? (var->pixclock / 1000) : 0; - var->pixclock = (var->pixclock) ? KHZ2PICOS(var->pixclock) : 0; - var->left_margin = 0; - var->right_margin = 0; - var->upper_margin = 0; - var->lower_margin = 0; - var->hsync_len = 0; - var->vsync_len = 0; - if (par->option & VPP_OPT_INTERLACE) { - var->vmode |= FB_VMODE_INTERLACED; - var->pixclock *= 2; - } -#ifdef DEBUG - MSG("[get_info] fb%d\n", fbn); - wmtfb_show_var("get_info", var); -#endif - return 0; -} - -int wmtfb_alloc(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct vout_info_t *par = (struct vout_info_t *) info->par; - unsigned int size; - int no_alloc = 0; - vdo_color_fmt colfmt; - int y_bpp, c_bpp; - unsigned int mb_resx, mb_resy, fb_num; - int i; - - colfmt = (var->nonstd) ? WMT_FB_COLFMT(var->nonstd) : - ((var->bits_per_pixel == 16) ? - VDO_COL_FMT_RGB_565 : VDO_COL_FMT_ARGB); - vpp_get_colfmt_bpp(colfmt, &y_bpp, &c_bpp); - - switch (par->alloc_mode) { - case VOUT_ALLOC_FIX_MB: - if (info->fix.smem_start) { - no_alloc = 1; - break; - } - - { - char buf[100]; - int varlen = 100; - - if (wmt_getsyspara("wmt.display.mb", - (unsigned char *)buf, &varlen) == 0) { - unsigned int parm[10]; - - vpp_parse_param(buf, (unsigned int *)parm, 4, 0); - MSG("boot parm mb (%d,%d),bpp %d,fb %d\n", - parm[0], parm[1], parm[2], parm[3]); - mb_resx = parm[0]; - mb_resy = parm[1]; - y_bpp = parm[2] * 8; - c_bpp = 0; - fb_num = parm[3]; - } else { - mb_resx = VPP_HD_MAX_RESX; - mb_resy = VPP_HD_MAX_RESY; - fb_num = VPP_MB_ALLOC_NUM; - } - } - break; - case VOUT_ALLOC_DYNAMIC_MB: - if ((par->hwc_mode == VOUT_HWC_VIRTUAL) - && !wmtfb_probe_ready) { - no_alloc = 1; - break; - } - mb_resx = var->xres_virtual; - mb_resy = var->yres; - fb_num = VPP_MB_ALLOC_NUM; - break; - case VOUT_ALLOC_GE_OVERSCAN: - if (!info->fix.smem_start) { - struct vout_info_t *fb0_par; - struct fb_info *fb0_info; - - fb0_par = vout_info_get_entry(0); - fb0_info = (struct fb_info *) fb0_par->fb_info_p; - info->fix.smem_start = fb0_info->fix.smem_start; - info->fix.smem_len = fb0_info->fix.smem_len; - info->screen_base = fb0_info->screen_base; - info->screen_size = fb0_info->screen_size; } - default: - no_alloc = 1; - break; - } -#if 0 - DBG_MSG("fb%d,mode %d,size %d,len %d,%dx%d,no alloc %d\n", - info->node, par->alloc_mode, size, info->fix.smem_len, - var->xres, var->yres, no_alloc); + if (memcmp(&var, &cur, sizeof(struct fb_videomode))) { +#ifdef DEBUG + DPRINT("[wmtfb] set_par %d: set timing\n", info->node); + vpp_show_timing("cur", &cur, 0); + vpp_show_timing("new", &var, 0); #endif - if (no_alloc) - return 0; /* don't need */ - - size = mb_resx * mb_resy * ((y_bpp + c_bpp) / 8) * fb_num ; - if (size == info->fix.smem_len) - return 0; - - /* free pre mb */ - if (info->fix.smem_start) { - mb_free(info->fix.smem_start); - info->fix.smem_start = 0; - info->fix.smem_len = 0; - info->screen_base = 0; - info->screen_size = 0; - MSG("[wmtfb] fb%d free mb\n", info->node); - } - - if ((var->xres == 0) || (var->yres == 0)) - return -1; - - info->fix.smem_start = mb_alloc(size); - if (!info->fix.smem_start) { - DBG_ERR("fb%d alloc mb fail %d\n", info->node, size); - return -1; - } - info->fix.smem_len = size; - info->screen_base = mb_phys_to_virt(info->fix.smem_start); - info->screen_size = size; - MSG("[wmtfb] fb%d mb 0x%x,len %d,base 0x%x(%d,%d,%d)\n", info->node, - (int) info->fix.smem_start, info->fix.smem_len, - (int) info->screen_base, mb_resx, mb_resy, fb_num); - - if (wmtfb_probe_ready) { - int ysize, csize; - - size = size / fb_num; - ysize = mb_resx * mb_resy * y_bpp / 8; - csize = mb_resx * mb_resy * c_bpp / 8; - for (i = 0; i < fb_num; i++) { - memset(info->screen_base + i * size, 0x0, ysize); - if (c_bpp) - memset(info->screen_base + i * size + ysize, - 0x80, csize); + vout_config(mask, vo_info, &var); } } - - if (par->hwc_mode == VOUT_HWC_VIRTUAL) { - vpp_lock(); - g_vpp.stream_mb_cnt = VPP_MB_ALLOC_NUM; - size = var->xres_virtual * var->yres * ((y_bpp + c_bpp) / 8); - for (i = 0; i < g_vpp.stream_mb_cnt; i++) - g_vpp.stream_mb[i] = info->fix.smem_start + size * i; - vpp_unlock(); - } +} + vpp_set_mutex(info->node, 0); return 0; } @@ -592,7 +2082,7 @@ static int wmtfb_open { DBG_MSG("Enter wmtfb_open\n"); return 0; -} +} /* End of wmtfb_open */ static int wmtfb_release ( @@ -602,58 +2092,61 @@ static int wmtfb_release { DBG_MSG("Enter wmtfb_release\n"); return 0; -} +} /* End of wmtfb_release */ int wmtfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct vout_info_t *par; int temp; int force = 0; -#ifdef DEBUG_DETAIL - DMSG("Enter %d\n", info->node); - wmtfb_show_var("[check_var beg] cur var", &info->var); - wmtfb_show_var("[check_var beg] new var", var); -#endif - if (!info->par) { /* link fb & vout info */ - par = vout_info_get_entry(info->node); - info->par = (void *) par; - par->fb_info_p = (void *) info; - } + DBG_DETAIL("Enter %d\n", info->node); - par = (struct vout_info_t *) info->par; - if (par->alloc_mode == VOUT_ALLOC_GE_OVERSCAN) { - struct vout_info_t *fb0_par; + var->xres_virtual = vpp_calc_fb_width((var->bits_per_pixel == 16) ? + VDO_COL_FMT_RGB_565 : VDO_COL_FMT_ARGB, var->xres); - fb0_par = vout_info_get_entry(0); - var->xres_virtual = fb0_par->resx_virtual; - var->yres_virtual = fb0_par->resy_virtual * VPP_MB_ALLOC_NUM; - } else { - var->xres_virtual = vpp_calc_fb_width( - (var->bits_per_pixel == 16) ? - VDO_COL_FMT_RGB_565 : VDO_COL_FMT_ARGB, - (var->xres_virtual < var->xres) ? - var->xres : var->xres_virtual); + if ((info->node == 1) && g_vpp.alloc_framebuf) { + if( (g_vpp.mb[0] == 0) || ((var->xres != info->var.xres) || + (var->yres != info->var.yres))) { + if (var->nonstd) { + g_vpp.mb_colfmt = WMT_FB_COLFMT(var->nonstd); + } else { + g_vpp.mb_colfmt = (var->bits_per_pixel == 16) ? + VDO_COL_FMT_RGB_565 : VDO_COL_FMT_ARGB; + } + if (g_vpp.virtual_display_mode == 1) { +#ifdef CONFIG_VPP_DYNAMIC_ALLOC + vpp_free_framebuffer(); +#endif + } else { + if (g_vpp.alloc_framebuf(var->xres, var->yres)) + return -ENOMEM; + + info->fix.smem_start = g_vpp.mb[0]; + info->fix.smem_len = + g_vpp.mb_fb_size * VPP_MB_ALLOC_NUM; + info->screen_base = + mb_phys_to_virt(info->fix.smem_start); + } + } } - if (wmtfb_alloc(var, info)) - return -ENOMEM; - if ((var->xres == 0) || (var->yres == 0)) return -1; - temp = var->xres_virtual * (var->bits_per_pixel >> 3); - temp = (temp) ? (info->fix.smem_len / temp) : 0; - if (temp < var->yres_virtual) { - var->yres_virtual = temp; + temp = (info->fix.smem_len / + (var->xres_virtual * var->yres * (var->bits_per_pixel >> 3))); + if (temp < 2) { + DBG_MSG("smem_len %d,%d\n", info->fix.smem_len, temp); + temp = 2; } + if (var->yres_virtual > (var->yres * temp)) + var->yres_virtual = var->yres * temp; /* more than 1M is khz not picos (for ut_vpp) */ if (var->pixclock > 1000000) { - temp = var->pixclock / 1000; - temp = (temp) ? KHZ2PICOS(temp) : 0; - DBG_MSG("pixclock patch(>1000000)%d-->%d\n", - var->pixclock, temp); + temp = KHZ2PICOS(var->pixclock / 1000); + DBG_MSG("pixclock patch(>1000000)%d-->%d(%d)\n", + var->pixclock, temp, (int)PICOS2KHZ(temp) * 1000); var->pixclock = temp; } @@ -665,11 +2158,13 @@ int wmtfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->left_margin; vtotal = var->yres + var->lower_margin + var->vsync_len + var->upper_margin; - temp = (htotal * vtotal * var->pixclock) / 1000; - temp = (temp) ? KHZ2PICOS(temp) : 0; - DBG_MSG("pixclock patch(<100)%d-->%d\n", var->pixclock, temp); + temp = htotal * vtotal * var->pixclock; + temp = KHZ2PICOS(temp / 1000); + DBG_MSG("pixclock patch(<100)%d-->%d(%d)\n", + var->pixclock, temp, (int)PICOS2KHZ(temp) * 1000); var->pixclock = temp; } + #ifdef DEBUG_DETAIL wmtfb_show_var("cur var", &info->var); wmtfb_show_var("new var", var); @@ -688,7 +2183,7 @@ int wmtfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->transp.length = 0; } break; - case 16: /* ARGB 1555 */ + case 16: /* ARGB 1555 */ if (var->transp.length) { var->red.offset = 10; var->red.length = 5; @@ -698,7 +2193,7 @@ int wmtfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->blue.length = 5; var->transp.offset = 15; var->transp.length = 1; - } else { /* RGB 565 */ + } else { /* RGB 565 */ var->red.offset = 11; var->red.length = 5; var->green.offset = 5; @@ -709,8 +2204,8 @@ int wmtfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->transp.length = 0; } break; - case 24: /* RGB 888 */ - case 32: /* ARGB 8888 */ + case 24: /* RGB 888 */ + case 32: /* ARGB 8888 */ var->red.offset = 16; var->red.length = 8; var->green.offset = 8; @@ -725,9 +2220,6 @@ int wmtfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) if (g_vpp.fb_manual) return 0; - if (!wmtfb_probe_ready) - force = 1; - if (g_vpp.fb_recheck & (0x1 << info->node)) { force = 1; g_vpp.fb_recheck &= ~(0x1 << info->node); @@ -737,7 +2229,6 @@ int wmtfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) memcmp(&info->var.pixclock, &var->pixclock, 4 * 9) || force) { struct fb_videomode varfbmode; unsigned int yres_virtual; - unsigned int xres_virtual; DPRINT("[wmtfb_check_var] fb%d res(%d,%d)->(%d,%d),force %d\n", info->node, info->var.xres, info->var.yres, @@ -747,7 +2238,6 @@ int wmtfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) wmtfb_show_var("new var", var); #endif yres_virtual = var->yres_virtual; - xres_virtual = var->xres_virtual; fb_var_to_videomode(&varfbmode, var); #ifdef DEBUG DPRINT("new fps %d\n", varfbmode.refresh); @@ -758,14 +2248,12 @@ int wmtfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) } fb_videomode_to_var(var, &varfbmode); var->yres_virtual = yres_virtual; - var->xres_virtual = xres_virtual; #ifdef DEBUG wmtfb_show_var("[wmtfb] time change", var); #endif - vout_get_width_height(info->node, &var->width, &var->height); } return 0; -} +} /* End of wmtfb_check_var */ static int wmtfb_set_par ( @@ -782,10 +2270,11 @@ static int wmtfb_set_par info->fix.visual = FB_VISUAL_PSEUDOCOLOR; else info->fix.visual = FB_VISUAL_TRUECOLOR; + info->node = 1; vpp_set_par(info); info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; return 0; -} +} /* End of vt8430fb_set_par */ static int wmtfb_setcolreg ( @@ -799,7 +2288,7 @@ static int wmtfb_setcolreg { return 0; -} +} /* End of wmtfb_setcolreg */ static int wmtfb_pan_display ( @@ -811,7 +2300,7 @@ static int wmtfb_pan_display DBG_DETAIL("Enter wmtfb_pan_display\n"); - wmtfb_set_mutex(info, 1); + vpp_set_mutex(1, 1); if (var->activate & FB_ACTIVATE_VBL) { struct timeval tv2; @@ -828,47 +2317,30 @@ static int wmtfb_pan_display } vpp_pan_display(var, info); do_gettimeofday(&tv1); - wmtfb_set_mutex(info, 0); + vpp_set_mutex(1, 0); DBG_DETAIL("Exit wmtfb_pan_display\n"); return 0; -} +} /* End of wmtfb_pan_display */ -#define UMP_INVALID_SECURE_ID ((unsigned int)-1) -#define GET_UMP_SECURE_ID _IOWR('m', 310, unsigned int) -#define GET_UMP_SECURE_ID_BUF1 _IOWR('m', 311, unsigned int) -#define GET_UMP_SECURE_ID_BUF2 _IOWR('m', 312, unsigned int) -int wmtfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) +static int wmtfb_ioctl +( + struct fb_info *info, /*!<; // a pointer point to struct fb_info */ + unsigned int cmd, /*!<; // ioctl command */ + unsigned long arg /*!<; // a argument pointer */ +) { int retval = 0; - switch (cmd) { - case FBIO_WAITFORVSYNC: - vpp_wait_vsync(info->node, 1); - break; - case GET_UMP_SECURE_ID: - case GET_UMP_SECURE_ID_BUF1: - case GET_UMP_SECURE_ID_BUF2: - { - unsigned int ump_id; - extern unsigned int (*mali_get_ump_secure_id) - (unsigned int addr, unsigned int size); - if (mali_get_ump_secure_id) - ump_id = (*mali_get_ump_secure_id)(info->fix.smem_start, - info->fix.smem_len); - else - ump_id = UMP_INVALID_SECURE_ID; - printk("[wmtfb] ump_id %d,0x%x,len %d\n", ump_id, - (int)info->fix.smem_start, info->fix.smem_len); - return put_user((unsigned int) ump_id, - (unsigned int __user *) arg); - } - break; - default: - break; - } +/* printk("Enter wmtfb_ioctl %x\n",cmd); */ + if (_IOC_TYPE(cmd) != VPPIO_MAGIC) + return retval; + + unlock_fb_info(info); + retval = vpp_ioctl(cmd, arg); + lock_fb_info(info); return retval; -} +} /* End of wmtfb_ioctl */ static int wmtfb_mmap ( @@ -905,14 +2377,13 @@ static int wmtfb_mmap if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; - DBGMSG("Exit wmtfb_mmap\n"); return 0; -} +} /* End of wmtfb_mmap */ int wmtfb_hw_cursor(struct fb_info *info, struct fb_cursor *cursor) { return 0; -} +} /* End of wmtfb_hw_cursor */ int wmtfb_blank(int blank, struct fb_info *info) { @@ -951,58 +2422,102 @@ static int __init wmtfb_probe ) { struct fb_info *info; - struct fb_var_screeninfo var; - int i; - - DBG_MSG("Enter\n"); + int cmap_len; + u32 map_size; + char mode_option[20]; - for (i = 1; ; i++) { - memcpy(&var, &wmtfb_var, sizeof(struct fb_var_screeninfo)); - if (vpp_get_info(i, &var)) - break; - info = framebuffer_alloc(0, &dev->dev); - if (!info) - return -ENOMEM; - info->fbops = &wmtfb_ops; - memcpy(&info->fix, &wmtfb_fix, - sizeof(struct fb_fix_screeninfo)); - info->fix.id[5] = '0' + i; - info->flags = FBINFO_DEFAULT; - if (register_framebuffer(info) < 0) - return -EINVAL; + sprintf(mode_option, "%dx%d@%d", + VPP_HD_DISP_RESX, VPP_HD_DISP_RESY, VPP_HD_DISP_FPS); - MSG(KERN_INFO "fb%d: %s frame buffer device\n", - info->node, info->fix.id); + /* Dynamically allocate memory for fb_info and par.*/ + info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); + if (!info) { + release_mem_region(info->fix.smem_start, info->fix.smem_len); + return -ENOMEM; + } - wmtfb_check_var(&var, info); - memcpy(&info->var, &var, sizeof(struct fb_var_screeninfo)); - wmtfb_set_par(info); - wmtfb_pan_display(&info->var, info); + /* Set default fb_info */ + info->fbops = &wmtfb_ops; + info->fix = wmtfb_fix; - if (info->node == 1) { - info->dev->power.async_suspend = 1; - dev_set_drvdata(&dev->dev, info); - } +#if 1 + if (g_vpp.alloc_framebuf) { + info->fix.smem_start = g_vpp.mb[0]; + info->fix.smem_len = g_vpp.mb_fb_size * VPP_MB_ALLOC_NUM; + info->screen_base = mb_phys_to_virt(info->fix.smem_start); + } +#endif +#if 0 + /* Set video memory */ + if (!request_mem_region(info->fix.smem_start, + info->fix.smem_len, "wmtfb")) { + printk(KERN_WARNING + "wmtfb: abort, cannot reserve video memory at 0x%lx\n", + info->fix.smem_start); } - for (i = 0; i < VPP_VOUT_NUM; i++) { - int blank; - struct vout_t *vout; - - vout = vout_get_entry(i); - if (!vout) - continue; - blank = (vout->status & VPP_VOUT_STS_ACTIVE) ? - VOUT_BLANK_UNBLANK : VOUT_BLANK_POWERDOWN; - blank = (vout->status & VPP_VOUT_STS_BLANK) ? - VOUT_BLANK_NORMAL : blank; - vout_set_blank(i, blank); + info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); + if (!info->screen_base) { + printk(KERN_ERR + "wmtfb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n", + info->fix.smem_len, info->fix.smem_start); + return -EIO; } - DBG_MSG("Leave\n"); - wmtfb_probe_ready = 1; - g_vpp.govrh_preinit = 0; +#endif + printk(KERN_INFO "wmtfb: framebuffer at 0x%lx, mapped to 0x%p, " + "using %d, total %d\n", + info->fix.smem_start, info->screen_base, + info->fix.smem_len, info->fix.smem_len); + + /* + * Do as a normal fbdev does, but allocate a larger memory for GE. + */ + map_size = PAGE_ALIGN(info->fix.smem_len); + + /* + * The pseudopalette is an 16-member array for fbcon. + */ + info->pseudo_palette = info->par; + info->par = NULL; + info->flags = FBINFO_DEFAULT; /* flag for fbcon. */ + + /* + * This has to been done !!! + */ + cmap_len = 256; /* Be the same as VESA. */ + fb_alloc_cmap(&info->cmap, cmap_len, 0); + + /* + * The following is done in the case of + * having hardware with a static mode. + */ + info->var = wmtfb_var; + vpp_get_info(1, &info->var); + + /* + * This should give a reasonable default video mode. + */ + + /* + * For drivers that can... + */ + wmtfb_check_var(&info->var, info); + + /* + * It's safe to allow fbcon to do it for you. + * But in this case, we need it here. + */ + wmtfb_set_par(info); + + if (register_framebuffer(info) < 0) + return -EINVAL; + info->dev->power.async_suspend = 1; + printk(KERN_INFO "fb%d: %s frame buffer device\n", + info->node, info->fix.id); + dev_set_drvdata(&dev->dev, info); + wmtfb_fb1_probe = 1; return 0; -} +} /* End of wmtfb_probe */ static int wmtfb_remove ( @@ -1020,37 +2535,176 @@ static int wmtfb_remove } #ifdef CONFIG_PM +unsigned int vpp_vout_blank_mask; + static int wmtfb_suspend ( struct platform_device *pDev, /*!<; // a pointer struct device */ pm_message_t state /*!<; // suspend state */ ) { + vpp_mod_base_t *mod_p; + vout_t *vo; + int i; + + DBGMSG("Enter wmtfb_suspend\n"); + vpp_vout_blank_mask = 0; + for (i = 0; i <= VPP_VOUT_NUM; i++) { + vo = vout_get_entry(i); + if (vo && !(vo->status & VPP_VOUT_STS_BLANK)) + vpp_vout_blank_mask |= (0x1 << i); + } + vout_set_blank(VPP_VOUT_ALL, VOUT_BLANK_POWERDOWN); + if (vout_check_plugin(1)) + vpp_netlink_notify_plug(VPP_VOUT_ALL ,0); + else + wmt_set_mmfreq(0); + + /* disable module */ + for (i = 0; i < VPP_MOD_MAX; i++) { + mod_p = vpp_mod_get_base(i); + if (mod_p && mod_p->suspend) + mod_p->suspend(0); + } +#ifdef WMT_FTBLK_HDMI + hdmi_suspend(0); +#endif + wmt_suspend_mmfreq(); +#ifdef WMT_FTBLK_LVDS + lvds_suspend(0); +#endif + /* disable tg */ + for (i = 0; i < VPP_MOD_MAX; i++) { + mod_p = vpp_mod_get_base(i); + if (mod_p && mod_p->suspend) + mod_p->suspend(1); + } +#ifdef WMT_FTBLK_HDMI + hdmi_suspend(1); +#endif +#ifdef WMT_FTBLK_LVDS + lvds_suspend(1); +#endif + /* backup registers */ + for (i = 0; i < VPP_MOD_MAX; i++) { + mod_p = vpp_mod_get_base(i); + if (mod_p && mod_p->suspend) + mod_p->suspend(2); + } +#ifdef WMT_FTBLK_HDMI + hdmi_suspend(2); +#endif +#ifdef WMT_FTBLK_LVDS + lvds_suspend(2); +#endif +#if 0 + if (lcd_get_lvds_id() == LCD_LVDS_1024x600) { + mdelay(5); + /* GPIO10 off 8ms -> clock -> off */ + REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x400; + } +#endif return 0; -} +} /* End of wmtfb_suspend */ static int wmtfb_resume ( struct platform_device *pDev /*!<; // a pointer struct device */ ) { + vpp_mod_base_t *mod_p; + int i; + +#if 0 + if (lcd_get_lvds_id() == LCD_LVDS_1024x600) { + /* GPIO10 6ms -> clock r0.02.04 */ + REG32_VAL(GPIO_BASE_ADDR+0x80) |= 0x400; + REG32_VAL(GPIO_BASE_ADDR+0xC0) |= 0x400; + } +#endif + + DBGMSG("Enter wmtfb_resume\n"); + + /* restore registers */ + for (i = 0; i < VPP_MOD_MAX; i++) { + mod_p = vpp_mod_get_base(i); + if (mod_p && mod_p->resume) + mod_p->resume(0); + } +#ifdef WMT_FTBLK_LVDS + lvds_resume(0); +#endif +#ifdef WMT_FTBLK_HDMI + hdmi_check_plugin(0); + hdmi_resume(0); +#endif + /* enable tg */ + for (i = 0; i < VPP_MOD_MAX; i++) { + mod_p = vpp_mod_get_base(i); + if (mod_p && mod_p->resume) + mod_p->resume(1); + } +#ifdef WMT_FTBLK_LVDS + lvds_resume(1); +#endif +#ifdef WMT_FTBLK_HDMI + hdmi_resume(1); +#endif + /* wait */ + if(!(g_vpp.virtual_display || g_vpp.dual_display == 0)) + msleep(150); + + /* enable module */ + for (i = 0; i < VPP_MOD_MAX; i++) { + mod_p = vpp_mod_get_base(i); + if (mod_p && mod_p->resume) + mod_p->resume(2); + } +#ifdef WMT_FTBLK_LVDS + lvds_resume(2); +#endif + if (lcd_get_lvds_id() != LCD_LVDS_1024x600) + vout_set_blank(vpp_vout_blank_mask, VOUT_BLANK_UNBLANK); + wmt_resume_mmfreq(); + if (vout_check_plugin(0)) + vpp_netlink_notify_plug(VPP_VOUT_ALL, 1); + else { + wmt_set_mmfreq(0); + } + +#ifdef WMT_FTBLK_HDMI + hdmi_resume(2); +#endif return 0; +} /* End of wmtfb_resume */ + +static void wmtfb_shutdown +( + struct platform_device *pDev /*!<; // a pointer struct device */ +) +{ + DPRINT("wmtfb_shutdown\n"); + hdmi_set_power_down(1); + lvds_set_power_down(1); } + #else #define wmtfb_suspend NULL #define wmtfb_resume NULL +#define wmtfb_shutdown NULL #endif /*************************************************************************** device driver struct define ****************************************************************************/ static struct platform_driver wmtfb_driver = { - .driver.name = "wmtfb", - .driver.bus = &platform_bus_type, - .probe = wmtfb_probe, - .remove = wmtfb_remove, - .suspend = wmtfb_suspend, - .resume = wmtfb_resume, + .driver.name = "wmtfb", + .driver.bus = &platform_bus_type, + .probe = wmtfb_probe, + .remove = wmtfb_remove, + .suspend = wmtfb_suspend, + .resume = wmtfb_resume, + .shutdown = wmtfb_shutdown, }; /*************************************************************************** @@ -1090,7 +2744,7 @@ static int __init wmtfb_init(void) } return ret; -} +} /* End of wmtfb_init */ module_init(wmtfb_init); static void __exit wmtfb_exit(void) @@ -1100,7 +2754,7 @@ static void __exit wmtfb_exit(void) platform_driver_unregister(&wmtfb_driver); platform_device_unregister(&wmtfb_device); return; -} +} /* End of wmtfb_exit */ module_exit(wmtfb_exit); MODULE_AUTHOR("WonderMedia SW Team"); |