From patchwork Sat Aug 8 14:25:03 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 505324 X-Patchwork-Delegate: hdegoede@redhat.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id B618E14016A for ; Sun, 9 Aug 2015 00:25:47 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 57F9E4BDC5; Sat, 8 Aug 2015 16:25:44 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5HV9hinZBck7; Sat, 8 Aug 2015 16:25:44 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0854E4BDD4; Sat, 8 Aug 2015 16:25:30 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 131874BDC7 for ; Sat, 8 Aug 2015 16:25:18 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ItnJr59F2FOU for ; Sat, 8 Aug 2015 16:25:17 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by theia.denx.de (Postfix) with ESMTPS id 83F934BDC6 for ; Sat, 8 Aug 2015 16:25:17 +0200 (CEST) Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 15E0391C08; Sat, 8 Aug 2015 14:25:16 +0000 (UTC) Received: from shalem.localdomain.com (vpn1-6-199.ams2.redhat.com [10.36.6.199]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t78EP62L020815; Sat, 8 Aug 2015 10:25:15 -0400 From: Hans de Goede To: Ian Campbell , Anatolij Gustschin Date: Sat, 8 Aug 2015 16:25:03 +0200 Message-Id: <1439043904-31492-5-git-send-email-hdegoede@redhat.com> In-Reply-To: <1439043904-31492-1-git-send-email-hdegoede@redhat.com> References: <1439043904-31492-1-git-send-email-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH 4/5] video: Add support for the ANX9804 parallel lcd to dp bridge chip X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add support for the ANX9804 bridge chip, which can take pixel data coming from a parallel LCD interface and translate it on the flight into a DP interface for driving eDP TFT displays. It uses I2C for configuration. Signed-off-by: Hans de Goede Acked-by: Anatolij Gustschin --- drivers/video/Kconfig | 8 +++ drivers/video/Makefile | 1 + drivers/video/anx9804.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/video/anx9804.h | 25 +++++++ 4 files changed, 222 insertions(+) create mode 100755 drivers/video/anx9804.c create mode 100644 drivers/video/anx9804.h diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 9ae23e8..71cbff9 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -145,6 +145,14 @@ config FRAMEBUFFER_VESA_MODE default 0x11B if FRAMEBUFFER_VESA_MODE_11B default 0x117 if FRAMEBUFFER_VESA_MODE_USER +config VIDEO_LCD_ANX9804 + bool "ANX9804 bridge chip" + default n + ---help--- + Support for the ANX9804 bridge chip, which can take pixel data coming + from a parallel LCD interface and translate it on the flight into a DP + interface for driving eDP TFT displays. It uses I2C for configuration. + config VIDEO_LCD_SSD2828 bool "SSD2828 bridge chip" default n diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 2ead7f1..e414e8c 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_VIDEO_COREBOOT) += coreboot_fb.o obj-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o obj-$(CONFIG_VIDEO_DA8XX) += da8xx-fb.o videomodes.o obj-$(CONFIG_VIDEO_IMX25LCDC) += imx25lcdc.o videomodes.o +obj-$(CONFIG_VIDEO_LCD_ANX9804) += anx9804.o obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o obj-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o diff --git a/drivers/video/anx9804.c b/drivers/video/anx9804.c new file mode 100755 index 0000000..83d60d6 --- /dev/null +++ b/drivers/video/anx9804.c @@ -0,0 +1,188 @@ +/* + * (C) 2015 Hans de Goede + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Support for the ANX9804 bridge chip, which can take pixel data coming + * from a parallel LCD interface and translate it on the flight into a DP + * interface for driving eDP TFT displays. + */ + +#include +#include +#include "anx9804.h" + +#define BIT(x) (1 << (x)) + +/* Registers at i2c address 0x38 */ + +#define ANX9804_HDCP_CONTROL_0_REG 0x01 + +#define ANX9804_SYS_CTRL2_REG 0x81 +#define ANX9804_SYS_CTRL2_CHA_STA 0x04 + +#define ANX9804_SYS_CTRL3_REG 0x82 +#define ANX9804_SYS_CTRL3_VALID_CTRL BIT(0) +#define ANX9804_SYS_CTRL3_F_VALID BIT(1) +#define ANX9804_SYS_CTRL3_HPD_CTRL BIT(4) +#define ANX9804_SYS_CTRL3_F_HPD BIT(5) + +#define ANX9804_LINK_BW_SET_REG 0xa0 +#define ANX9804_LANE_COUNT_SET_REG 0xa1 +#define ANX9804_TRAINING_PTN_SET_REG 0xa2 +#define ANX9804_TRAINING_LANE0_SET_REG 0xa3 +#define ANX9804_TRAINING_LANE1_SET_REG 0xa4 +#define ANX9804_TRAINING_LANE2_SET_REG 0xa5 +#define ANX9804_TRAINING_LANE3_SET_REG 0xa6 + +#define ANX9804_LINK_TRAINING_CTRL_REG 0xa8 +#define ANX9804_LINK_TRAINING_CTRL_EN BIT(0) + +#define ANX9804_LINK_DEBUG_REG 0xb8 +#define ANX9804_PLL_CTRL_REG 0xc7 +#define ANX9804_ANALOG_POWER_DOWN_REG 0xc8 + +/* Registers at i2c address 0x39 */ + +#define ANX9804_DEV_IDH_REG 0x03 + +#define ANX9804_POWERD_CTRL_REG 0x05 +#define ANX9804_POWERD_AUDIO BIT(4) + +#define ANX9804_RST_CTRL_REG 0x06 + +#define ANX9804_RST_CTRL2_REG 0x07 +#define ANX9804_RST_CTRL2_AUX BIT(2) +#define ANX9804_RST_CTRL2_AC_MODE BIT(6) + +#define ANX9804_VID_CTRL1_REG 0x08 +#define ANX9804_VID_CTRL1_VID_EN BIT(7) +#define ANX9804_VID_CTRL1_EDGE BIT(0) + +#define ANX9804_VID_CTRL2_REG 0x09 +#define ANX9804_ANALOG_DEBUG_REG1 0xdc +#define ANX9804_ANALOG_DEBUG_REG3 0xde +#define ANX9804_PLL_FILTER_CTRL1 0xdf +#define ANX9804_PLL_FILTER_CTRL3 0xe1 +#define ANX9804_PLL_FILTER_CTRL 0xe2 +#define ANX9804_PLL_CTRL3 0xe6 + +/** + * anx9804_init() - Init anx9804 parallel lcd to edp bridge chip + * + * This function will init an anx9804 parallel lcd to dp bridge chip + * using the passed in parameters. + * + * @i2c_bus: Number of the i2c bus to which the anx9804 is connected. + * @lanes: Number of displayport lanes to use + * @data_rate: Register value for the bandwidth reg 0x06: 1.62G, 0x0a: 2.7G + * @bpp: Bits per pixel, must be 18 or 24 + */ +void anx9804_init(unsigned int i2c_bus, u8 lanes, u8 data_rate, int bpp) +{ + unsigned int orig_i2c_bus = i2c_get_bus_num(); + u8 c, colordepth; + int i; + + i2c_set_bus_num(i2c_bus); + + if (bpp == 18) + colordepth = 0x00; /* 6 bit */ + else + colordepth = 0x10; /* 8 bit */ + + /* Reset */ + i2c_reg_write(0x39, ANX9804_RST_CTRL_REG, 1); + mdelay(100); + i2c_reg_write(0x39, ANX9804_RST_CTRL_REG, 0); + + /* Write 0 to the powerdown reg (powerup everything) */ + i2c_reg_write(0x39, ANX9804_POWERD_CTRL_REG, 0); + + c = i2c_reg_read(0x39, ANX9804_DEV_IDH_REG); + if (c != 0x98) { + printf("Error anx9804 chipid mismatch\n"); + i2c_set_bus_num(orig_i2c_bus); + return; + } + + for (i = 0; i < 100; i++) { + c = i2c_reg_read(0x38, ANX9804_SYS_CTRL2_REG); + i2c_reg_write(0x38, ANX9804_SYS_CTRL2_REG, c); + c = i2c_reg_read(0x38, ANX9804_SYS_CTRL2_REG); + if ((c & ANX9804_SYS_CTRL2_CHA_STA) == 0) + break; + + mdelay(5); + } + if (i == 100) + printf("Error anx9804 clock is not stable\n"); + + i2c_reg_write(0x39, ANX9804_VID_CTRL2_REG, colordepth); + + /* Set a bunch of analog related register values */ + i2c_reg_write(0x38, ANX9804_PLL_CTRL_REG, 0x07); + i2c_reg_write(0x39, ANX9804_PLL_FILTER_CTRL3, 0x19); + i2c_reg_write(0x39, ANX9804_PLL_CTRL3, 0xd9); + i2c_reg_write(0x39, ANX9804_RST_CTRL2_REG, ANX9804_RST_CTRL2_AC_MODE); + i2c_reg_write(0x39, ANX9804_ANALOG_DEBUG_REG1, 0xf0); + i2c_reg_write(0x39, ANX9804_ANALOG_DEBUG_REG3, 0x99); + i2c_reg_write(0x39, ANX9804_PLL_FILTER_CTRL1, 0x7b); + i2c_reg_write(0x38, ANX9804_LINK_DEBUG_REG, 0x30); + i2c_reg_write(0x39, ANX9804_PLL_FILTER_CTRL, 0x06); + + /* Force HPD */ + i2c_reg_write(0x38, ANX9804_SYS_CTRL3_REG, + ANX9804_SYS_CTRL3_F_HPD | ANX9804_SYS_CTRL3_HPD_CTRL); + + /* Power up and configure lanes */ + i2c_reg_write(0x38, ANX9804_ANALOG_POWER_DOWN_REG, 0x00); + i2c_reg_write(0x38, ANX9804_TRAINING_LANE0_SET_REG, 0x00); + i2c_reg_write(0x38, ANX9804_TRAINING_LANE1_SET_REG, 0x00); + i2c_reg_write(0x38, ANX9804_TRAINING_LANE2_SET_REG, 0x00); + i2c_reg_write(0x38, ANX9804_TRAINING_LANE3_SET_REG, 0x00); + + /* Reset AUX CH */ + i2c_reg_write(0x39, ANX9804_RST_CTRL2_REG, + ANX9804_RST_CTRL2_AC_MODE | ANX9804_RST_CTRL2_AUX); + i2c_reg_write(0x39, ANX9804_RST_CTRL2_REG, + ANX9804_RST_CTRL2_AC_MODE); + + /* Powerdown audio and some other unused bits */ + i2c_reg_write(0x39, ANX9804_POWERD_CTRL_REG, ANX9804_POWERD_AUDIO); + i2c_reg_write(0x38, ANX9804_HDCP_CONTROL_0_REG, 0x00); + i2c_reg_write(0x38, 0xa7, 0x00); + + /* Set data-rate / lanes */ + i2c_reg_write(0x38, ANX9804_LINK_BW_SET_REG, data_rate); + i2c_reg_write(0x38, ANX9804_LANE_COUNT_SET_REG, lanes); + + /* Link training */ + i2c_reg_write(0x38, ANX9804_LINK_TRAINING_CTRL_REG, + ANX9804_LINK_TRAINING_CTRL_EN); + mdelay(5); + for (i = 0; i < 100; i++) { + c = i2c_reg_read(0x38, ANX9804_LINK_TRAINING_CTRL_REG); + if ((c & 0x01) == 0) + break; + + mdelay(5); + } + if(i == 100) { + printf("Error anx9804 link training timeout\n"); + i2c_set_bus_num(orig_i2c_bus); + return; + } + + /* Enable */ + i2c_reg_write(0x39, ANX9804_VID_CTRL1_REG, + ANX9804_VID_CTRL1_VID_EN | ANX9804_VID_CTRL1_EDGE); + /* Force stream valid */ + i2c_reg_write(0x38, ANX9804_SYS_CTRL3_REG, + ANX9804_SYS_CTRL3_F_HPD | ANX9804_SYS_CTRL3_HPD_CTRL | + ANX9804_SYS_CTRL3_F_VALID | ANX9804_SYS_CTRL3_VALID_CTRL); + + i2c_set_bus_num(orig_i2c_bus); +} diff --git a/drivers/video/anx9804.h b/drivers/video/anx9804.h new file mode 100644 index 0000000..6c5daf9 --- /dev/null +++ b/drivers/video/anx9804.h @@ -0,0 +1,25 @@ +/* + * (C) 2015 Hans de Goede + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Support for the ANX9804 bridge chip, which can take pixel data coming + * from a parallel LCD interface and translate it on the flight into a DP + * interface for driving eDP TFT displays. + */ + +#ifndef _ANX9804_H +#define _ANX9804_H + +#define ANX9804_DATA_RATE_1620M 0x06 +#define ANX9804_DATA_RATE_2700M 0x0a + +#ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804 +void anx9804_init(unsigned int i2c_bus, u8 lanes, u8 data_rate, int bpp); +#else +static inline void anx9804_init(unsigned int i2c_bus, u8 lanes, u8 data_rate, + int bpp) {} +#endif +#endif